Unicode 字符

368 阅读3分钟

这是我参与11月更文挑战的第11天,活动详情查看:2021最后一次更文挑战

前言

ECMAScript 6.0 简称ES6 , 是 JavaScript 语言的新一代的标准,于在 2015 年 6 月发布,正式名称就是《ECMAScript 2015 标准》。一般情况,泛指, 5.1版以后的标准,涵盖了 ES2015、ES2016、ES2017、ES2018、ES2019、ES2020、ES2021 等等

我们一起来学习吧。

字符的表示

JavaScript的字符是用Unicode表示的,具体的实现是 utf-16编码。

我们平时都是使用字符,然后使用'',"", ``把字符包裹起来。

var text = '人';
var text2 = "人";
var text3 = `人`;

ES6允许我们使用\uxxxx的形式表示字符,当然也需要用之前的三种形式包裹。

\uxxxx 有分为两部分:

  1. \u固定不点,可以认为是标志符
  2. xxxx 四位,是Unicode字符码点的16进制表示

我们以a字符为例子:

  1. 获取码点, "a".codePointAt(0), 结果为 97
  2. 获得其16进制的表示, 97..toString(16), 61
  3. 16,不足4位,补足四位, 0061
  4. \u0061
\u0061 // a

我们是不是可以写一个方法,把字符转为\uxxxx格式的字符串呢?

function charToUnStr(ch){
    return `\\u${ch.codePointAt(0).toString(16).padStart(4, "0")}`
}

charToUn("a") // '\u0061'
charToUn("人"); // '\u4eba'

再写一个\uxxxx转字符的方法, ES6也提供了方法String.fromCodePoint

function unStrToChar(unStr){
    return String.fromCodePoint(+`0x${unStr.slice(2)}`)
}

测试一下:

unStrToChar(charToUnStr('a'))  // a
unStrToChar(charToUnStr('人')) // 人
unStrToChar(charToUnStr('𠮷'))  // 吉

看起来很完美,但是charToUnStr转换的字符串 '\u20bb7'

charToUnStr('𠮷') // '\u20bb7'

你贴到浏览器的控制台看看结果, 返回的值并不是𠮷

image.png

之后的ES标准又做了改进,允许u{xxxxx}, x的个数是4+, 不受限于四位。

根据此方法,我们改进charToUnStr

function charToUnStr(ch){
    const code = ch.codePointAt(0);
    const val = code > xxFFFF ? code.toString(16): code.toString(16).padStart(4, "0")
    return `\\u{${val}}`
}

测试一下结果:

charToUnStr('𠮷') // '\u{20bb7}'

贴到浏览器控制台:

image.png
几乎完美哈哈。

字符的length

我们通过用 length来判断字符串的长度,我们一起来看看:

"a".length // 1
"人".length // 1
"𠮷".length // 2
String.fromCodePoint(0x22098).length // 2

String.fromCodePoint(0xffff).length  // 1
String.fromCodePoint(0x10000).length // 2

码点大于0xffff的字符的长度都是2,这也是utf-16编码导致的,因为大于0xffff的字符需要用四个字节来表示。

大家可还记得 html的input元素有一个length属性,我们今天一起来看看其length是不是也收到这个限制。

测试结果就是输入两个 𢂘𢂘字时候就无法继续输入了,因为𢂘的码点是0x22098, 大于 0xffff,需要四个字节,长度为2。 image.png

所以啊,假如是限制输入姓名字的时候,千万不要限制长度为4, 万一我的名字叫 欧阳𢂘𢂘, 可咋办。

小结

  1. JavaScript的字符是用utf-16编码表示的,码点小于0xffff字符用2个字节表示,的大于0xffff的占用四个字节。
  2. 字符可以用 \uxxxx表示
  3. ES6可以使用 \u{xxxxx}格式表示
  4. 大于0xffff的字符的长度为2
  5. html input的maxlength遵循同样的规律

今天你收获了吗?