JavaScript 比较运算符:身份与平等
Posted
技术标签:
【中文标题】JavaScript 比较运算符:身份与平等【英文标题】:JavaScript comparison operators: Identity vs. Equality 【发布时间】:2011-07-23 18:03:50 【问题描述】:我一直试图理解 javascript 的比较运算符之间的区别:身份和相等。根据我的阅读,如果您使用 == 检查两个对象的相等性,JavaScript 将尝试确定它们是否为同一类型,如果不是,则尝试将它们设为同一类型。但是, === 的行为方式不同。举个例子:
var n = "1";
console.log(n==1); // outputs true
console.log(n===1); // outputs false
那么这些“身份”运算符和常规的相等运算符有什么区别呢?两者兼得有什么好处?
性能有差异吗?我认为身份运算符会更快,因为它不进行转换。
此外,当涉及到更复杂的对象(如数组)时,它们有何不同?最重要的是,关于什么时候应该使用一个而不是另一个,约定是怎么说的,为什么?
【问题讨论】:
这里我为JavaScript中的等号运算符***.com/questions/359494/…提供了一个真值表 【参考方案1】:在进行比较之前,相等运算符将尝试使数据类型相同。另一方面,身份运算符要求两种数据类型相同作为先决条件。
还有很多其他类似这个问题的帖子。见:
How do the php equality (== double equals) and identity (=== triple equals) comparison operators differ?(有一张漂亮的对比图)Which equals operator (== vs ===) should be used in JavaScript comparisons?
实际上,当您想确定布尔值是真还是假时,恒等运算符非常方便,因为...
1 == true => true
true == true => true
1 === true => false
true === true => true
【讨论】:
【参考方案2】:不同之处在于 ==、= 和 != 会进行类型强制 - 例如,强制将字符串作为数字进行计算。 ===、== 和 !== 不会进行类型强制。他们会将字符串与数字进行比较,由于字符串“1”与数值1不同,所以结果为假。
参考在这里:https://developer.mozilla.org/en/JavaScript/Reference/Operators/Comparison_Operators
【讨论】:
知道了......所以它就像我上面概述的那样简单。身份运算符不检查类型,但相等运算符会。 至于什么时候用哪一个; Douglas Crockford:使用 === 和 !== 运算符几乎总是更好。 == 和 != 运算符会进行类型强制。特别是,不要使用 == 与虚假值进行比较。 @Joel...很棒的链接!谢谢!但是,它没有列出 ==。这些合法吗? @Tim Down,在你的例子中,这是不必要的,但它错了吗?无论如何使用 === 有缺点吗?在这个例子之外,我唯一能想到的就是强制显式强制转换/强制。 但是 '==' 不存在。【参考方案3】:==
与===
相同,只是==
进行类型转换
为了向您展示我的意思是一个 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**
【讨论】:
【参考方案4】:相等和恒等运算符特别值得注意。相等运算符将尝试将操作数强制(转换)为相同类型以评估相等性。这是一个方便的功能,只要您知道它正在发生。这段代码展示了相等运算符的作用。
let firstVal = 5;
let secondVal = "5";
if (firstVal == secondVal)
console.log("They are the same");
else
console.log("They are NOT the same");
此脚本的输出如下:
它们是一样的
JavaScript 正在将两个操作数转换为相同的类型并进行比较。本质上,相等运算符测试值是否相同,而与它们的类型无关。
如果要测试确保值和类型相同,则需要使用恒等运算符(===,三个等号,而不是两个等号)
let firstVal = 5;
let secondVal = "5";
if (firstVal === secondVal)
console.log("They are the same");
else
console.log("They are NOT the same");
在这个例子中,恒等运算符会认为这两个变量是不同的。该运算符不强制类型。该脚本的结果如下:
他们不一样
【讨论】:
以上是关于JavaScript 比较运算符:身份与平等的主要内容,如果未能解决你的问题,请参考以下文章