JavaScript 比较运算符:身份与平等

IT技术 javascript operators comparison-operators equivalence
2021-02-09 11:41:45

我一直试图理解 JavaScript 的比较运算符之间的区别:身份和相等。从我读到的内容来看,如果您使用 == 检查两个对象的相等性,JavaScript 将尝试确定它们是否是相同的类型,如果不是,则尝试将它们设为相同的类型。但是, === 的行为方式不同。举个例子:

var n = "1";
console.log(n==1);        // outputs true
console.log(n===1);       // outputs false

那么这些“身份”运算符和常规的相等运算符有什么区别呢?两者兼得有什么好处?

性能上有区别吗?我认为身份运算符会更快,因为它不进行转换。

此外,当涉及到更复杂的对象(如数组)时,它们有何不同?最重要的是,约定何时应该使用一个而不是另一个,为什么?

4个回答

相等运算符将在进行比较之前尝试使数据类型相同。另一方面,身份运算符要求两种数据类型相同作为先决条件。

还有很多其他帖子类似于这个问题。看:

PHP 等式(== 双等式)和恒等式(=== 三等式)比较运算符有何不同?(有一个很好的比较图表)
在 JavaScript 比较中应该使用哪个等于运算符 (== vs ===)?

在实践中,当您想确定一个布尔值是真还是假时,身份运算符就派上用场了,因为...

1 == true     => true
true == true  => true
1 === true    => false
true === true => true

不同之处在于 ==、<=、>= 和 != 会进行类型强制——例如,强制将字符串计算为数字。===、<==、>== 和 !== 不会进行类型强制。他们会将字符串与数字进行比较,由于字符串“1”与数值 1 不同,因此结果为假。

参考在这里:https :
//developer.mozilla.org/en/JavaScript/Reference/Operators/Comparison_Operators

@Joel...很棒的链接!谢谢!但是,它没有列出 <== 和 >==。那些合法吗?
2021-03-24 11:41:45
但是 '<==' 和 '>==' 不存在。
2021-03-29 11:41:45
明白了......所以它就像我上面概述的一样简单。身份运算符不检查类型,但相等运算符会检查类型。
2021-03-30 11:41:45
@Tim Down,在你的例子中,这是不必要的,但它错了吗?无论如何使用 === 有缺点吗?在这个例子之外,我唯一能想到的就是强制显式强制转换/强制转换。
2021-04-11 11:41:45
至于什么时候用哪一个;Douglas Crockford使用 === 和 !== 运算符几乎总是更好。== 和 != 运算符进行类型强制。特别是,不要使用 == 与虚假值进行比较。
2021-04-14 11:41:45

==是一样的东西===,除了==类型转换

为了向您展示我的意思,这里有一个 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**

等式和恒等运算符特别值得注意。相等运算符将尝试将操作数强制(转换)为相同类型以评估相等性。这是一个方便的功能,只要您知道它正在发生。此代码块显示了操作中的相等运算符。

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");
}

在这个例子中,恒等运算符会认为这两个变量是不同的。此运算符不强制类型。该脚本的结果如下:

他们是不一样的