javascript 中 string 的 length 属性返回 utf-16 编码单元数而非字符数,bmp 外字符(如 emoji)占两个单元,故 '?'.length 为 2;length 只读且不可配置,修改无效;获取真实字符数应使用 [...str].length 等方法。

JavaScript 中 String 类型的 length 属性返回字符串中 UTF-16 编码单元(code units)的个数,而不是字符(grapheme clusters)或 Unicode 码点(code points)的数量。这是理解其行为的关键。
length 统计的是 UTF-16 编码单元数量
JavaScript 字符串内部基于 UTF-16 编码。大多数常用字符(如 ASCII 字符、常见汉字)占用 1 个编码单元,length 值与直观字符数一致。但超出基本多文种平面(BMP)的字符(如某些 emoji、古文字、数学符号)需用两个编码单元(即代理对,surrogate pair)表示,此时 length 会返回 2,哪怕它在视觉上是一个“字符”。
-
'a'.length→ 1 -
'?'.length→ 2(U+1F60A 是 BMP 外字符,占两个 UTF-16 单元) -
'??'.length→ 5(含多个代理对和连接符 ZWJ)
length 是只读属性,不可赋值
虽然 length 是普通数据属性(非 accessor),但它被定义为 writable: false。尝试修改不会报错(严格模式下静默失败),也不会生效。
-
let s = 'abc'; s.length = 5;→s.length仍是 3 - 不能通过
Object.defineProperty重新配置为可写(因默认configurable: false)
空字符串和特殊字符的 length 表现
空字符串 '' 的 length 为 0;所有合法字符串(包括仅含控制字符、空格、BOM、零宽字符等)都会如实统计其 UTF-16 单元数。
-
'\u{FEFF}'.length(BOM)→ 1 -
''.length(零宽空格 U+200B)→ 1 -
'\uD83D\uDE00'.length(手动拼出 ? 的代理对)→ 2
获取真实字符数应使用其他方式
若需统计用户感知的“字符数”(即 Unicode 图形符号数量),不能依赖 length,而应使用:
-
[...str].length(扩展运算符 + 数组解构,按 Unicode 码点拆分) -
Array.from(str).length(同上,兼容性略好) -
str.normalize().split(/(?=.)/u).length(正则配合 Unicode 标志) - 第三方库如
grapheme-splitter(处理组合字符、emoji 序列更准确)
不复杂但容易忽略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











