You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unicode表情长度差异:不同Firefox环境下👨‍🍳长度为何不同?

问题原因及解决方案

核心原因

Firefox 115.13.0(ESR版本)的JavaScript引擎(SpiderMonkey)存在ZWJ连接型emoji的String.length计算bug,而Firefox 128.0.3已经修复了该问题。

详细解释

厨师表情👨‍🍳由3个Unicode代码点组成:

  • U+1F468(男性符号,属于Unicode补充平面,UTF-16编码占2个代码单元)
  • U+200D(零宽连接符ZWJ,属于基本多语言平面,UTF-16编码占1个代码单元)
  • U+1F373(煎蛋符号,补充平面,UTF-16编码占2个代码单元)

按UTF-16编码规则,总共有2+1+2=5个代码单元,因此正确的String.length值应为5。但旧版本Firefox的JS引擎对这类ZWJ拼接的emoji序列解析逻辑不完善,错误地统计出7个代码单元。

你可以在生产环境的Firefox 115中执行以下代码验证:

const chefEmoji = '👨‍🍳';
for (let i = 0; i < chefEmoji.length; i++) {
  console.log(`索引${i}: ${chefEmoji.charCodeAt(i).toString(16)}`);
}

正确输出应为5个十六进制值(d83d、dc68、200d、d83c、df73),错误情况下会输出7个值,说明引擎错误拆分了代码点的编码。

兼容方案

如果需要兼容旧版本Firefox,不要依赖String.length统计字符(它只返回UTF-16代码单元数量,不是视觉字符或代码点数量),可以用以下两种方式:

  • 按**视觉字符(grapheme cluster)**计数(符合用户感知的单个表情):
    const segmenter = new Intl.Segmenter('zh-CN', { granularity: 'grapheme' });
    const visualCharCount = [...segmenter.segment('👨‍🍳')].length; // 返回1
    
  • 按Unicode代码点计数:
    const codePointCount = Array.from('👨‍🍳').length; // 返回3,对应3个代码点
    

内容的提问来源于stack exchange,提问作者Bisasam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 06:54:54