这篇文章介绍ES6中针对unicode字符串的几个新增函数。

  1. String.prototype.codePointAt
    函数类型:

    (index?: number)=> number|undefined

    codePointAt是一个原型函数,它依据传入的index参数,返回字符串中位于该处的字符的码点code point)值。这个办法能够辨认utf-16中的4字节码点,反对的范畴比原型函数charCodeAt更广,charCodeAt只能辨认2字节根本立体字符(BMP)。另外,当index越界时,codePointAt返回undefinedcharCodeAt返回NaN

    除了这两点之外,codePointAtcharCodeAt的后果基本一致:

    • index的参数默认值都为0
    • 当字符处于根本立体字符集的时候,二者返回的后果是一样的。

      const str = 'abc'; //字符 'a' 位于根本立体字符集中console.log(str.codePointAt(0));//97//index默认值为0console.log(str.codePointAt());//97//index越界时,返回undefinedconsole.log(str.codePointAt(5));//undefinedconsole.log(str.charCodeAt(0));//97//index默认值为0console.log(str.charCodeAt());//97//index越界时,返回NaNconsole.log(str.charCodeAt(5));//NaN
  • 当字符处于辅助立体字符集的时候,codePointAt可能正确辨认,并返回对应字符的码点(code point)。charCodeAt不能正确辨认,只能返回以后地位的2字节字符的码点

    比方,对于辅助立体的低音字符,它由两个2字节的根本立体字符 0xd8340xdd1e 示意。当咱们对

    应用charCodeAt时,只能失去对应地位的码点。

    const str = '\ud834\udd1e'; //辅助立体字符 低音字符 console.log(str.charCodeAt(0).toString(16)); //d834 console.log(str.charCodeAt(1).toString(16)); //dd1e

    当咱们应用codePointAt时,能够失去的码点0x1d11e

    console.log(str.codePointAt(0).toString(16)); //1d11e//当index为1时,'\udd1e'前面没有另一个代码单元,被认为只是一个2字节的字符,而非是一对代码单元,所以此时只返回'\udd1e'的码点,而非'\ud834\udd1e'的码点console.log(str.codePointAt(1).toString(16)); //dd1e
  1. String.fromCodePoint

    函数类型:

    (...codePoints: number[])=> string

    动态函数fromCodePoint是依据传入的unicode码点返回对应的字符串,和fromCharCode相比,它反对间接传入辅助立体的码点值了。还是以低音符号为例,应用fromCodePoint能够间接传入码点值0x1d11e,而fromCharCode值须要传入0xd8340xdd1e

    console.log(String.fromCodePoint(0x1d11e)); //console.log(String.fromCodePoint(0xd834, 0xdd1e)); //console.log(String.fromCharCode(0x1d11e)); //턞 不能正确辨认,乱码console.log(String.fromCharCode(0xd834, 0xdd1e)); //

    对于根本立体的字符,fromCodePointfromCharCode后果是一样的。

    console.log(String.fromCodePoint(97)); //'a'console.log(String.fromCodePoint(97, 98)); //'ab'console.log(String.fromCodePoint()); //''console.log(String.fromCharCode(97)); //'a'console.log(String.fromCharCode(97, 98)); //'ab'console.log(String.fromCharCode()); //''
  2. String.prototype.normalize

    函数类型:

    (form:'NFC'|'NFD'|'NFKC'|'NFKD')=>string

    原型函数normalize承受一个指定正规化(如果你不明确NFC、NFD等的意义,点一下)模式的参数formform默认值为'NFC'(Normalization Form Canonical Composition,以规范等价形式来合成,而后以规范等价重组),返回正规化的字符串。

    unicode合成符号(字符中的字母带有腔调等附加符号)提供了两种示意形式,一种是应用一个unicode码点示意,一种是将合成字符中的字母与附加符号组合,应用两个码点,比方ń是一个合成符号,咱们既能够应用一个码点0x0144示意,也能够应用两个码点0x006e0x0301示意。

    const str1 = '\u0144'; //ńconst str2 = '\u006e\u0301'; //ńconsole.log({    str1,    str2,});//{ str1: 'ń', str2: 'n' }

    这两种示意形式,是视觉和语义上都是雷同的,它们是规范等价的。然而,在代码层面它们却是不同的,str1一个码点str2两个码点,这很有可能会导致问题。

    console.log(str1.length, str2.length);//1 2console.log(str1 === str2);//false

    normalize函数便是为了解决这种问题,两个字符串通过normalize函数实现正规化之后,就不会再呈现这种问题了。

    let str1 = '\u0144'; //ńlet str2 = '\u006e\u0301'; //ń//正规化str1 = str1.normalize();str2 = str2.normalize();console.log({    str1,    str2,}); //{ str1: 'ń', str2: 'n' }console.log(str1.length, str2.length); //1 1console.log(str1 === str2); //true
  3. 新增的unicode示意办法

    在之前,咱们示意unicode字符能够通过\u+码点的形式,ES6新增了一种示意形式,即\u+{ 码点 }

    这两种形式的不同之处,也很容易想到,\u+{ 码点 }反对写入辅助立体的4字节码点,而\u+码点仅反对根本立体的2字节码点。

    //对于根本立体的2字节码点,两种没有区别const str1 = '\u{0144}';const str2 = '\u0144';console.log(str1 === str2); //true//低音符号const str3 = '\u{1d11e}';//谬误的示意办法,被辨认为了 \u1d11 和 e 两个字符const str4 = '\u1d11e';console.log(str4,str3===str4); //e false
    unicode的确让人头痛,如果有敌人对于unicode不太理解,能够在评论区留言,我会再发一篇具体介绍unicode与JS的文章。