JavaScript比较中应该使用哪种等于运算符(== vs ===)?

5647

我使用JSLint检查JavaScript代码,它建议将比较语句中的==(两个等号)替换为===(三个等号),例如在if语句中比较idSele_UNVEHtype.value.length == 0

使用===代替==是否有性能优势?

任何性能提升都是受欢迎的,因为存在许多比较运算符。

如果不涉及类型转换,是否会比使用==更快?

48个回答

5
使用===的一个未提及的原因是,当您与/交叉编译到/从coffee-script一起存在时。来自Little Book on CoffeeScript...

JavaScript中的弱等比较具有某些令人困惑的行为,并且经常是令人困惑的错误的根源。

解决方案是改用严格相等运算符,它由三个等号组成:===。它的工作方式与普通的等式运算符完全相同,但没有任何类型强制转换。建议始终使用严格相等运算符,并在需要时明确转换类型。

如果您经常转换到和从coffee-script,则应该只使用===。实际上,coffee-script编译器将强制您这样做...

CoffeeScript通过简单地将所有弱比较替换为严格比较来解决此问题,换句话说,将所有==比较器转换为===。您无法在CoffeeScript中进行弱等比较,如果必要,应显式转换类型后再进行比较。


2

严格相等通常更好

在使用JavaScript时,需要时刻牢记它是一种弱类型语言。只要数据结构相同,没有理由不使用严格相等。使用普通相等时,值往往会自动进行隐式转换,这可能会对代码产生深远的影响。由于这些转换是自动进行的,因此很容易出现问题。

使用严格相等时,不会进行自动隐式转换,因为值必须已经具有正确的数据结构。


2

首先,关于JavaScript字符串相等的一些术语:双等号被正式称为抽象相等比较运算符,而三个等号则被称为严格相等比较运算符。它们之间的区别可以概括如下:在进行比较之前,抽象相等会尝试通过类型强制转换来解析数据类型。如果类型不同,严格相等会返回false。考虑以下示例:

console.log(3 == "3"); // true
console.log(3 === "3"); // false.
console.log(3 == "3"); // true
console.log(3 === "3"); // false.

使用两个等号返回 true,因为在比较之前字符串“3”被转换为数字 3。三个等号看到类型不同,返回 false。这是另一个例子:

console.log(true == '1'); // true
console.log(true === '1'); // false
console.log(true == '1'); // true
console.log(true === '1'); // false

再次说明,抽象相等比较会进行类型转换。在这种情况下,布尔值true和字符串'1'都被转换为数字1,结果为true。严格相等返回false。

如果你理解了这一点,就可以很好地区分==和===之间的区别。然而,在某些情况下,这些运算符的行为是不直观的。让我们看一些更多的例子:

console.log(undefined == null); // true
console.log(undefined === null); // false. Undefined and null are distinct types and are not interchangeable.
console.log(undefined == null); // true     
console.log(undefined === null); // false. Undefined and null are distinct types and are not interchangeable.

console.log(true == 'true'); // false. A string will not be converted to a boolean and vice versa.
console.log(true === 'true'); // false
console.log(true == 'true'); // false. A string will not be converted to a boolean and vice versa.
console.log(true === 'true'); // false

下面的例子很有趣,因为它说明了字符串字面量与字符串对象是不同的。
console.log("This is a string." == new String("This is a string.")); // true
console.log("This is a string." === new String("This is a string.")); // false
console.log("This is a string." == new String("This is a string.")); // true
console.log("This is a string." === new String("This is a string.")); // false

1
JavaScript和PHP一样是弱类型语言。
var x = "20";
var y =20;

if (x===y) // false

这将始终给您一个错误,因为尽管变量的值相同,但数据类型不同。其中一个是字符串,另一个是整数。
If(x==y)//true

然而,这只是检查内容是否相同,不考虑数据类型...

我不想说这些值相等,因为从逻辑上讲,字符串值不能等于整数值。


1

建议将==替换为===的原因是===运算符比==更可靠。在我们的上下文中,可靠性意味着===还进行类型检查。考虑到最佳编程实践,我们应该始终选择可靠性更高的功能而不是可靠性较低的功能。再次强调,每当我们考虑到“完全相等”的运算符时,大多数情况下,我们默认认为类型应该相同。由于===提供了相同的功能,我们应该选择它。


1
"在JavaScript比较中,我应该使用==还是===的困境,类似于一个问题:“我应该用‘勺子’还是‘叉子’来吃饭。”这个问题的唯一合理答案是:
  1. 您应该使用动态类型比较,例如:==进行宽松类型比较。
  2. 您应该使用静态类型比较,例如:===进行强类型比较。
因为它们不同。它们没有相同的目的,也不适用于相同的目的。
当然,“叉子”和“勺子”都是用来“吃”的,但您将根据所要食用的食物而选择使用它们。
意思是:您将使用“勺子”,即==来喝汤,使用“叉子”,即===来夹菜。"
询问在“吃饭”时使用“叉子”还是“勺子”更好 - 就像询问在JS中使用静态[===]还是动态[==]相等运算符一样,两个问题都同样错误,并反映出对所讨论主题的非常狭隘或肤浅的理解。

JSLint(或Crockford)坚持要求您在处理相同类型的值时使用严格类型比较是错误的。JavaScript的length属性始终是数字类型,因此不存在虚假阳性的可能性。此外,当您可以使用直接的简写!dSele_UNVEHtype.value.length时,就不需要dSele_UNVEHtype.value.length === 0了。 - Bekim Bacaj
3
为什么你要回答一个已经有49个答案并且已经有一个被接受的回答得到超过5k赞的9年老问题,而你的回答包含一个奇怪的比喻且没有解释任何之前已经被说过的内容? - Jasper
2
因为JavaScript被许多专业人士误用,无论他们的年龄有多大。例如,您无法理解它的全部内容,也无法抓住Live Script与静态类型语言之间的区别所在以及为什么我们需要其智能动态性。JavaScript是为有创造力和智慧的人而设计的,而不是为傻瓜而设的。 - Bekim Bacaj
2
是的,我同意JavaScript被滥用的情况很多。然而,我仍然认为你的比喻很奇怪,因为它很容易被误解,并且没有以有意义的方式涵盖核心基础知识。 - Jasper
所给的比喻是它们之间差异和用例质量的最佳说明。即使您是 JavaScript 的完全新手,这是学习绝对本质的最佳简短文章。并且与我关于如何真正清空 JS 数组的晚回答同样好,甚至更好。 - Bekim Bacaj

1
如果您想在JavaScript中比较几个内容,可以使用 === ,这被称为严格相等,它意味着只有当类型和值都相同时才会返回true,因此您不必担心类型问题。如果您使用 == ,则基本上不关心类型,在许多情况下,您可能会遇到松散的等式比较问题。

使用===进行严格相等

严格相等比较两个值是否相等。在比较之前,没有任何一个值会被隐式转换为其他值。如果这些值具有不同的类型,则这些值被认为是不相等的。否则,如果这些值具有相同的类型并且不是数字,则如果它们具有相同的值,则被认为是相等的。最后,如果这两个值都是数字,则如果它们都不是NaN并且是相同的值,或者其中一个是+0,另一个是-0,则它们被认为是相等的。

var num = 0;
var obj = new String('0');
var str = '0';

console.log(num === num); // true
console.log(obj === obj); // true
console.log(str === str); // true

console.log(num === obj); // false
console.log(num === str); // false
console.log(obj === str); // false
console.log(null === undefined); // false
console.log(obj === null); // false
console.log(obj === undefined); // false


使用 == 进行宽松相等性比较

宽松相等性比较两个值的相等性,在将两个值转换为公共类型后进行。在转换之后(一个或两个值可能会经过转换),最终的相等性比较将与 === 完全相同。宽松相等性是对称的:对于任何 A 和 B 的值,A == B 总是具有与 B == A 相同的语义(除了应用转换的顺序)。

var num = 0;
var obj = new String('0');
var str = '0';

console.log(num == num); // true
console.log(obj == obj); // true
console.log(str == str); // true

console.log(num == obj); // true
console.log(num == str); // true
console.log(obj == str); // true
console.log(null == undefined); // true

// both false, except in rare cases
console.log(obj == null);
console.log(obj == undefined);

我认为在关于你应该/不应该做什么方面,这是主观的,并且告诉某人总是使用特定的操作是具有误导性的。虽然我同意在大多数情况下我们关心使用 '===' vs. '==',但可能有一种特殊情况,您希望进行类型转换。 - 我无法立即想到一个确切的用例,但也许设计是要进行宽松检查。无论如何,如果语言中包含了某些内容,那么它就有其存在的理由。在我看来,我们应该尽量避免“总是做x”的笼统陈述。 - sramzan
我有点同意你的观点,如果你读完我的整个回答,你会发现我后来详细解释了。说实话,在JavaScript中我们很少使用和需要宽松比较...我可以说不到5%,甚至更少,但是对于那些没有js背景的人,我总是使用“always”,他们认为==在JavaScript中检查严格比较,他们学会了小心谨慎地不使用它,但是随着他们变得更加专业,他们知道在哪些罕见的情况下可能会使用它。这就是为什么我写出这样的答案。 - Alireza

0
var a = new String("123");
var b = "123";

alert(a === b); // returns false !! (but they are equal and of the same type)

在其中一个答案中看到了这个。 在这种情况下,ab实际上不是相同的类型,如果你检查typeof(a),你会得到'object',而typeof(b)'string'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接