在我正在创建的混合 Android/Cordova 游戏中,我让用户以表情符号 + 字母数字的形式提供标识符 - 即 0..9、A..Z、a..z - 名称。例如
️堆栈溢出
在服务器端,用户标识符与 Emoji 和 Name 部分分开存储,只有 Name 部分要求是唯一的。游戏不时显示“联赛表”,因此用户可以看到他们与其他玩家相比的表现如何。为此,服务器发回由表情符号、姓名和分数组成的十个“高分”值序列。
然后将其在包含三列的表格中呈现给用户 - 表情符号、名称和分数各一列。这是我遇到一个小问题的地方。最初,我非常天真地假设我可以通过简单地查看handle.codePointAt(0)
. 当我意识到 Emoji 实际上可能是一个或多个 16 位 Unicode 值的序列时,我将代码更改如下
第 1 部分:剖析用户提供的“句柄”
var i,username,
codepoints = [],
handle = "️StackOverflow",
len = handle,length;
while ((i < len) && (255 < handle.codePointAt(i)))
{codepoints.push(handle.codePointAt(i));i += 2;}
username = handle.substring(codepoints.length + 1);
在这一点上,我有“解剖”的句柄
codepoints = [128587, 8205, 65039];
username = 'Stackoverflow;
上面的解释i += 2
和使用说明handle.length
。 这篇文章建议
- 如果您点击前导代理,handle.codePointAt(n) 将返回完整代理对的代码点。在我的情况下,因为表情符号必须是第一个字符,所以表情符号的 16 位 Unicode 序列的主要代理是在
0,2,4...
. - 从同一篇文章中我了解到,
String.length
在 Javascript 中将返回16 位代码单元的数量。
第二部分 - 为“联赛表”重新生成表情符号
假设我的服务器返回到应用程序的排名表数据 {emoji: [128583, 8205, 65039],username:"Stackexchange",points:100}
包含表情符号字符 ️ 的条目。现在这是麻烦的事情。如果我做
var origCP = [],
i = 0,
origEmoji = '️',
origLen = origEmoji.length;
while ((i < origLen) && (255 < origEmoji.codePointAt(i))
{origCP.push(origEmoji.codePointAt(i);i += 2;}
我明白了
origLen = 5, origCP = [128583, 8205, 65039]
但是,如果我从提供的数据中重新生成表情符号
var reEmoji = String.fromCodePoint.apply(String,[128583, 8205, 65039]),
reEmojiLen = reEmoji.length;
我明白了
reEmoji = '️'
reEmojiLen = 4;
因此,尽管 reEmoji 拥有正确的表情符号,但它报告的长度却神秘地缩减为 4 个代码单元,而不是原来的 5 个。
如果我从重新生成的表情符号中提取代码点
var reCP = [],
i = 0;
while ((i < reEmojiLen) && (255 < reEmoji.codePointAt(i))
{reCP.push(reEmoji.codePointAt(i);i += 2;}
这给了我
reCP = [128583, 8205];
Even curioser,origEmoji.codePointAt(3)
给出尾随代理对的值,9794
而reEmoji.codePointAt(3)
给出下一个完整代理对的值65039
。
在这一点上我可以说
我真的在乎吗?
毕竟,我只想在单独的列中显示排名表表情符号,只要我得到正确的表情符号,引擎盖下发生的事情的细微之处并不重要。然而,这很可能会为未来储备问题。
这里的任何人都可以阐明正在发生的事情吗?