JavaScript comparison operators: Identity vs. Equality
我一直在试图理解JavaScript的比较运算符之间的区别:标识和相等。根据我读到的内容,如果使用==检查两个对象的相等性,javascript将尝试找出它们是否是同一类型,如果不是,则尝试将它们转换为同一类型。然而,==的行为方式不同。例如:
1 2 3 | var n ="1"; console.log(n==1); // outputs true console.log(n===1); // outputs false |
那么,这些"同一性"操作符和正规的等同性操作符之间有什么区别呢?两者都有什么好处?
性能有差异吗?我认为身份操作符会更快,因为它不进行转换。
另外,当涉及到更复杂的对象(如数组)时,它们有什么不同?最重要的是,关于什么时候应该使用一个公约而不是另一个公约,为什么?
相等运算符将尝试在进行比较之前使数据类型相同。另一方面,Identity运算符要求这两种数据类型作为前提条件相同。
有相当多的其他帖子类似于这个问题。见:
php equality(=double equals)和identity(=triple equals)比较运算符有什么不同?(有一个很好的比较图)
在JavaScript比较中应使用哪个等于运算符(==vs==)?
在实践中,当你想确定一个布尔值是真是假的时候,身份操作符就非常有用了,因为…
1 2 3 4 | 1 == true => true true == true => true 1 === true => false true === true => true |
区别在于==、<=、>=和!=将执行类型强制&mdash;例如,强制将字符串计算为数字。==、<==、>==和!==不执行类型强制。他们将把一个字符串与一个数字进行比较,由于字符串"1"与数值1不同,所以结果是假的。
参考资料如下:https://developer.mozilla.org/en/javascript/reference/operators/comparison_operators
为了向您展示我的意思,这里有一个javascript函数,它的行为与
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | // 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 2 3 4 5 6 7 8 9 | [1] == true // returns true '0' == false // returns true [] == false // returns true [[]] == false // returns true [0] == false // returns true ' \t' == 0 // returns true |
意料之外的结论
1 2 3 4 5 6 7 8 | // 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** |
具有特殊功能的对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | // 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** |
原因是,identity或strict运算符(==)与不进行类型转换相比,这意味着如果两个值没有相同的值和相同的类型,它们就不会被视为相等的。
以下链接中有更清晰的解释:
https://medium.com/@ludico8/identity-vs-equality-battle-of-understanding-vs-758d396e922.hhg396ey9