问题描述
其实这个问题是Can (a== 1 && a ==2 && a==3) ever evaluate to true?的延伸。
我们可能知道,loose equality operator (==) 的秘密会尝试将两个值转换为通用类型。因此,将调用一些函数。
ToPrimitive(A)
尝试将其对象参数转换为原始类型
值,通过调用 A.toString
和 A.valueOf
的不同序列
A 上的方法。
因此以下代码将按预期工作。
const a = {
i: 1,toString: function () {
return a.i++;
}
}
if(a == 1 && a == 2 && a == 3) {
console.log('Hello World!');
}
然而,strict equality (===)
的问题。 .valueOf
、.toString
或 Symbol.toPrimitive
等方法不会被 JavaScript 引擎调用。
我该如何解决?任何帮助将不胜感激。
const a = {
i: 1,toString: function () {
return a.i++;
}
}
if(a === 1 && a === 2 && a === 3) {
console.log('Never catch!');
}
解决方法
其他页面上的一些方法严格相等,避免使用 toString
或 valueOf
的方法。
let num = 1;
Object.defineProperty(window,'a',{ get() { return num++ } });
// or use `with` and an object with a getter instead of putting it on the window
if(a === 1 && a === 2 && a === 3) {
console.log('Never catch!');
}
这是有效的,因为 a
不是一个普通变量 - 它是窗口上的 getter,所以当标识符 a
被引用时,getter 运行并可以返回任何值。在这里,它将返回一个递增的整数。
如果您希望允许,链接问题中的其他方法将严格相等: