JavaScript平等传递性很奇怪
我一直在阅读,我遇到了一个奇怪的例子,对我来说毫无意义:JavaScript平等传递性很奇怪,javascript,comparison-operators,equivalence,transitivity,Javascript,Comparison Operators,Equivalence,Transitivity,我一直在阅读,我遇到了一个奇怪的例子,对我来说毫无意义: '' == '0' // false 0 == '' // true 0 == '0' // true false == undefined // false false == null // false null == undefined // true 作者还提到“永远不要使用=和!=。相反,始终使用==和!=”。然而,他没有解释为什么会出现上述行
'' == '0' // false
0 == '' // true
0 == '0' // true
false == undefined // false
false == null // false
null == undefined // true
作者还提到“永远不要使用=
和!=
。相反,始终使用==
和!=
”。然而,他没有解释为什么会出现上述行为?所以我的问题是,为什么上面的结果是这样的?JavaScript中不考虑及物性吗
'' == '0' // false
左侧是一个空字符串,右侧是一个包含一个字符的字符串。它们是假的,因为它是在两个不完全相同的字符串之间进行比较(谢谢)
因此,为什么这个是真的,因为0
是falsy,而空字符串是falsy
这个有点棘手。规范规定,如果操作数是字符串和数字,则将字符串强制为数字<代码>'0'变为0
。谢谢
值undefined
在JavaScript中是特殊的,它不等于除null
之外的任何其他值。然而,这是虚假的
同样,null
是特殊的。它仅等于未定义的
。这也是错误的
null
和undefined
类似,但不相同null
不表示任何内容,而undefined
是未设置或不存在的变量的值。他们的价值观应该是平等的
如果你真的想弄糊涂,检查这个
'\n\r\t' == 0
仅由空格组成的字符串被视为等于0
道格拉斯·克罗克福德(Douglas Crockford)提出了很多建议,但你不必把它们当作福音。:)
提出了一个很好的建议,即研究平等测试以了解这些平等测试背后的整个故事
进一步阅读
这个问题的答案与JavaScript如何处理强制有关。在
==
的情况下。因此:
'='0'
等同于'==='0'
(两者都是字符串,因此不需要强制)
0=='
相当于0==0
,因为字符串'
成为数字0
(math.abs('==0
)
0=='0'
与0===0
具有相同的原因
false==undefined
相当于0===undefined
,因为当类型不匹配时,JavaScript强制布尔值为数字
出于同样的原因,false==null
等同于0===null
null==undefined
是真的,因为规范这么说
谢谢你问这个问题。我对
==
的理解要比研究它好得多。实际上,您可以编写一个JavaScript函数,其行为与==
完全相同,这会让您了解它的行为
向大家展示我在这里的意思是这个函数:
// loseEqual() behaves just like `==`
function loseEqual(x, y) {
// notice the function only uses "strict" operators
// like `===` and `!==` to do comparisons
if(typeof y === typeof x) return y === x;
if(typeof y === "function" || typeof x === "function") return false;
// treat null and undefined the same
var xIsNothing = (y === undefined) || (y === null);
var yIsNothing = (x === undefined) || (x === null);
if(xIsNothing || yIsNothing) return (xIsNothing && yIsNothing);
if(typeof x === "object") x = toPrimitive(x);
if(typeof y === "object") y = toPrimitive(y);
if(typeof y === typeof x) return y === x;
// convert x and y into numbers if they are not already use the "+" trick
if(typeof x !== "number") x = +x;
if(typeof y !== "number") y = +y;
return x === y;
}
function toPrimitive(obj) {
var value = obj.valueOf();
if(obj !== value) return value;
return obj.toString();
}
如您所见,==
有许多复杂的类型转换逻辑。正因为如此,很难预测你会得到什么样的结果
以下是一些您意想不到的结果示例:
意外的真相
[1] == true // returns true
'0' == false // returns true
[] == false // returns true
[[]] == false // returns true
[0] == false // returns true
'\r\n\t' == 0 // returns true
// IF an empty string '' is equal to the number zero (0)
'' == 0 // return true
// AND the string zero '0' is equal to the number zero (0)
'0' == 0 // return true
// THEN an empty string must be equal to the string zero '0'
'' == '0' // returns **FALSE**
// Below are examples of objects that
// implement `valueOf()` and `toString()`
var objTest = {
toString: function() {
return "test";
}
};
var obj100 = {
valueOf: function() {
return 100;
}
};
var objTest100 = {
toString: function() {
return "test";
},
valueOf: function() {
return 100;
}
};
objTest == "test" // returns true
obj100 == 100 // returns true
objTest100 == 100 // returns true
objTest100 == "test" // returns **FALSE**
意外结论
[1] == true // returns true
'0' == false // returns true
[] == false // returns true
[[]] == false // returns true
[0] == false // returns true
'\r\n\t' == 0 // returns true
// IF an empty string '' is equal to the number zero (0)
'' == 0 // return true
// AND the string zero '0' is equal to the number zero (0)
'0' == 0 // return true
// THEN an empty string must be equal to the string zero '0'
'' == '0' // returns **FALSE**
// Below are examples of objects that
// implement `valueOf()` and `toString()`
var objTest = {
toString: function() {
return "test";
}
};
var obj100 = {
valueOf: function() {
return 100;
}
};
var objTest100 = {
toString: function() {
return "test";
},
valueOf: function() {
return 100;
}
};
objTest == "test" // returns true
obj100 == 100 // returns true
objTest100 == 100 // returns true
objTest100 == "test" // returns **FALSE**
具有特殊功能的对象
[1] == true // returns true
'0' == false // returns true
[] == false // returns true
[[]] == false // returns true
[0] == false // returns true
'\r\n\t' == 0 // returns true
// IF an empty string '' is equal to the number zero (0)
'' == 0 // return true
// AND the string zero '0' is equal to the number zero (0)
'0' == 0 // return true
// THEN an empty string must be equal to the string zero '0'
'' == '0' // returns **FALSE**
// Below are examples of objects that
// implement `valueOf()` and `toString()`
var objTest = {
toString: function() {
return "test";
}
};
var obj100 = {
valueOf: function() {
return 100;
}
};
var objTest100 = {
toString: function() {
return "test";
},
valueOf: function() {
return 100;
}
};
objTest == "test" // returns true
obj100 == 100 // returns true
objTest100 == 100 // returns true
objTest100 == "test" // returns **FALSE**
回答这个问题的最好方法是阅读说明书:如果你真的想知道为什么上面的陈述是这样的,没有更好的方法了。准备好,在某些方面可能会有点困难,但如果你问这样的问题,这是非常值得的。@T.J.Crowder非常好的建议(+1),我将该链接编辑到我的答案中,希望你不介意。应该指出的是,第二组等式涉及
假,未定义,而且null
不违反及物性-它与A!=B、 A!=C、 B==C
@Nacht。。。是的,你说得对!但第一个很奇怪:PSee第三级:“道格拉斯·克罗克福德提出了很多建议,但你不必把它们当作福音。”。Crockford是一个聪明的人,他有意识地思考了很多关于语言的问题,因此很值得阅读他提出的观点和他提出的论点。然后得出你自己的结论。@alex。。。在你的第三段中,以“这个有点棘手”开头,你的意思是不是说=
检查类型?@Hristo=
不检查类型,只检查值。@alex。。。我不同意。我认为==
会检查类型和值=
不转换类型,只检查严格的相等性。@hr它确实会从实现角度检查类型(它会转换类型以进行比较),但我认为提及值可能更容易,即1='1'
。因此,在该示例中,'1'
将被强制为Number
。