最近学习JavaScript的String类型、UTF-16、String.length属性后,知道字符串的length属性会返回“16bits”码元的个数,如果字符串中存在32bits码位(2个码元表示1个字符)的字符,那么length就不能正确的反映字符串中的字符数量。
疑问:应该如何去计算得到真实的字符数?
假设有目标字符串 strText = "....." // 内容省略
目前我还写不出来代码(js函数没学),但我看过了 codeCharAt()和 codePointAt()函数后,感觉可以用 codePointAt()来取得目标字符串 strText中指定索引字符的
但这时候会存在一个问题:
strText的字面量形式可能会对结果有影响吧。
因为所有的unicode字符都可以通过 unnnn的形式来书写。比如字符串"string" 可以写作 "u0073u0074u0072u0069u006eu0067"。
换句话说,当采用 unnnn的形式时,会不会造成codeCharAt()依次对 , u , 0 进行处理。。。
同时,还有一个问题,我在上网查资料的时候,发现了这两篇文章:
JS获取字符串实际长度!
String length中文字符长度
这两篇文章干的活我没看明白, 汉字的unicode范围是:0x4E00~0x9FA5,处于BMP(基本多语言平面)内,因此汉字只用一个最小单位即可表示。而这两篇文章是希望把汉字的长度弄成2,这有意义吗?我真没搞懂他们在干嘛,求指教,谢谢!
你说的没错,根据 EMCAScript 的规范,JS 应当采用 UCS-2 或者 UTF-16 编码。认为单字符可以只占 8 位的想法是没有意义的,可能是早期 JS 规范还不太流行的时候,一些人从别的语言中臆断的错误观念。
实际上 ES6 已经支持了对 32 位字符的支持,比如“?”。但是为了兼容性,原先的行为不作更改,比如
'?'.length
还是 2。但是你可以通过来获得正确的长度。而通过
'?'.codePointAt(0)
也可以正确获得它的编码 137538。charCodeAt
等为了兼容没有改变。这都可以在浏览器里自行验证。
另外,
'\u21942'
也为了兼容没有改,但是\u{21942}
可以正确得出“?”。(21942 是 137539 的 16 进制)关于
的问题,不存在的。不是写作
'u0073u0074u0072u0069u006eu0067'
,而是写作'\u0073\u0074\u0072\u0069\u006e\u0067'
,这跟'String'
是完全等价的,'\u0073'
是一个字符,不是 5个或者 6 个。