以下比较在javascript中返回true。
alert("café" == "caf\u00e9"); //returns true
但是,如果我将ASCII字符“e”与急性重音的unicode值连接起来,并将相等性与“é”进行比较,则结果为false。但是,两种情况下的外观完全相同。
var v1 = "é";
var v2 = "e"+"\u0301";
alert(v1 == v2); //returns false
有人可以解释这背后的原因。
答案 0 :(得分:7)
有人可以解释这背后的原因。
这是因为它们是不同的代码单元序列。 JavaScript没有每个字符的内置矩阵与每个组合标记相结合,并且映射到它们存在的等效单个字符。 (但请参见下文......)JavaScript字符串为just sequences of UTF-16 code units(与UTF-16不同,可以容忍无效序列)。
这里有关于字符串相等性的the spec says(链接算法的步骤5a):
如果 x 和 y 完全相同的代码单元序列(相应索引处的长度和代码单位相同),则返回 true ;否则,返回 false 。
正如您所看到的那样,没有任何条款可以确定组合标记是否已组合形成一个字符,该字符在Unicode中也可用作自己的字符。
但是,正如Yury Tarabanko中a comment所指出的,ECMAScript Internationalization API规范定义了整理对象(spec | MDN) 。桌面浏览器可以很好地支持国际化API(Safari是一个令人遗憾的例外),但不是在移动浏览器上。
使用默认的collator,你的两个字符串确实是等价的:
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")
);
}