为什么 '?'[0] === '?' 但是 '??'[0] !== '??'?

Wil*_*nik 3 javascript string unicode

'\xe2\x9d\x8c'[0] === '\xe2\x9d\x8c' // true\n'\xe2\x9c\x94\xef\xb8\x8f'[0] === '\xe2\x9c\x94\xef\xb8\x8f' // false\n'\xe2\x9c\x94\xef\xb8\x8f'[0] === '\xe2\x9c\x94'  // true\n\n
Run Code Online (Sandbox Code Playgroud)\n

我怀疑它与 unicode 相关,但想准确了解发生了什么以及如何正确比较这些字符。为什么 '\xe2\x9c\x94\xef\xb8\x8f' 的处理方式与 '\xe2\x9d\x8c' 不同?

\n

我在这个简单的字符计数中遇到了它

\n
'\xe2\x9c\x94\xef\xb8\x8f\xe2\x9d\x8c\xe2\x9c\x94\xef\xb8\x8f\xe2\x9d\x8c'.split('').filter(e => e === '\xe2\x9d\x8c').length // 2\n'\xe2\x9c\x94\xef\xb8\x8f\xe2\x9d\x8c\xe2\x9c\x94\xef\xb8\x8f\xe2\x9d\x8c'.split('').filter(e => e === '\xe2\x9c\x94\xef\xb8\x8f').length // 0\n
Run Code Online (Sandbox Code Playgroud)\n

Max*_*rok 6

因为\xe2\x9c\x94\xef\xb8\x8f需要两个字符:\n"\xe2\x9c\x94\xef\xb8\x8f".length === 2

\n

"\xe2\x9c\x94\xef\xb8\x8f"[0] === "\xe2\x9c\x94"我认为an"\xe2\x9c\x94\xef\xb8\x8f"[1]表示颜色。

\n

所以"\xe2\x9d\x8c".length === 1它只需要一个字符。

\n

这与不同肤色的表情符号的工作方式类似。

\n

至于如何比较,我认为"\xe2\x9c\x94\xef\xb8\x8f".codePointAt(0)(不要与 混淆charCodeAt())可能会有所帮助。请参阅https://thekevinscott.com/emojis-in-javascript/

\n
\n

codePointAt 和 fromCodePoint 是 ES2015 中引入的新方法,可以处理 UTF-16 编码大于 16 位的 unicode 字符,其中包括表情符号。使用这些而不是 charCodeAt,它不能正确处理表情符号。

\n
\n