JavaScript如何取得字符串的真实字符数?大疑问

最近学习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,这有意义吗?我真没搞懂他们在干嘛,求指教,谢谢!

阅读 4.9k
1 个回答

你说的没错,根据 EMCAScript 的规范,JS 应当采用 UCS-2 或者 UTF-16 编码。认为单字符可以只占 8 位的想法是没有意义的,可能是早期 JS 规范还不太流行的时候,一些人从别的语言中臆断的错误观念。

实际上 ES6 已经支持了对 32 位字符的支持,比如“?”。但是为了兼容性,原先的行为不作更改,比如 '?'.length 还是 2。但是你可以通过

Array.from('?').length

来获得正确的长度。而通过 '?'.codePointAt(0) 也可以正确获得它的编码 137538。charCodeAt 等为了兼容没有改变。
这都可以在浏览器里自行验证。

另外,'\u21942' 也为了兼容没有改,但是\u{21942}可以正确得出“?”。(21942 是 137539 的 16 进制)

关于

因为所有的unicode字符都可以通过 unnnn的形式来书写。比如字符串"string" 可以写作
"u0073u0074u0072u0069u006eu0067"。 换句话说,当采用
unnnn的形式时,会不会造成codeCharAt()依次对 , u , 0 进行处理。。。

的问题,不存在的。不是写作 'u0073u0074u0072u0069u006eu0067' ,而是写作
'\u0073\u0074\u0072\u0069\u006e\u0067',这跟 'String' 是完全等价的,'\u0073' 是一个字符,不是 5
个或者 6 个。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题