javascript中的unicode字符

dr_*_*dev 1 javascript unicode

以下比较在javascript中返回true.

alert("café" == "caf\u00e9"); //returns true

但是,如果我将ASCII字符"e"与急性重音的unicode值连接起来,并将相等性与"é"进行比较,则结果为false.但是,两种情况下的外观完全相同.

var v1 = "é";
var v2 = "e"+"\u0301";
alert(v1 == v2);  //returns false
Run Code Online (Sandbox Code Playgroud)

有人可以解释这背后的原因.

T.J*_*der 7

有人可以解释这背后的原因.

这是因为它们是不同的代码单元序列.JavaScript没有每个字符的内置矩阵与每个组合标记的组合,并且映射到它们存在的等效单个字符.(但请参见下文......)JavaScript字符串只是UTF-16代码单元的序列(与UTF-16不同,可以容忍无效序列).

以下是关于字符串相等性的规范说明(链接算法的步骤5a):

如果xy完全相同的代码单元序列(相应索引处的长度和代码单元相同),则返回true ; 否则,返回false.

正如您所看到的,没有任何规定可以确定组合标记是否已组合形成一个字符,该字符在Unicode中也可用作其自己的字符.

但是,正如Yury Tarabanko评论中指出的那样,ECMAScript国际化API规范定义了collat​​or对象(spec | MDN).桌面浏览器可以很好地支持国际化API(Safari是一个令人遗憾的例外),但不是在移动浏览器上.

使用默认的collat​​or,你的两个字符串确实是等价的:

var v1 = "é";
var v2 = "e\u0301";
var equal = v1 === v2;
console.log(
  "== says: " + (equal ? "Equal" : "Not equal")
);
var equivalent;
if (typeof Intl !== "object" || !Intl.Collator) {
  console.log("This browser doesn't have Intl.Collator");
} else {
  equivalent = Intl.Collator().compare(v1, v2) === 0;
  console.log(
    "Intl.Collator says: " +
    (equivalent ? "Equivalent" : "Not equivalent")
  );
}
Run Code Online (Sandbox Code Playgroud)