前两天排查个bug,界面上用户名截断后偶尔蹦出半个方块。根因挺典型:JS里拿字符串当数组下标去截断,碰上表情字符就翻车。
说白了,JS和Java的string按UTF-16码元计数,不是按你肉眼看到的"一个字"。一个笑脸emoji实际是代理对(surrogate pair),占两个码元,所以 .length 会返回 2。你以为取前5个字符,结果把emoji从中间劈开,渲染成乱码;更狠的是某些语言下标越界直接panic,整段逻辑炸掉。
我以前也一直天真地用 .length 加 substr 硬砍,直到线上出过这回鬼问题才长记性。正解是用码点层面遍历:Array.from(str) 先拆成码点数组再操作,或者上 grapheme 库按"字素簇"来切。肉眼里的一个字,代码里未必是一个长度单位,这坑踩过一次就记住了。
C’est la vie。