在JavaScript中,使用typeof时为什么要使用===而不是==?

29

在许多第三方库和最佳实践博客/建议等中,经常会看到这样的语法:

typeof x === 'object' (instead of typeof x == 'object')
typeof y === 'string' (instead of typeof x == 'string')
typeof z === 'function' (instead of typeof x == 'function')
如果typeof运算符已经返回一个字符串,为什么还需要检查返回值的类型呢?如果无论x是什么,typeof(typeof(x))始终是字符串,那么==应该足够了,而===则是不必要的。
在什么情况下typeof不会返回字符串字面量?即使存在一些边缘情况,为什么还要对对象、字符串、函数等使用额外的类型检查呢?

8
没有任何情况。大多数人只是因为某些原因(咳嗽 Crockford)极度害怕类型转换。 - MooGoo
3
当JavaScript中的类型转换规则如此武断时,不信任它可能是件好事。 - Skilldrick
1
当然,但我只是在询问使用typeof时。如果人们只是在使用某个IDE将每个**==都盲目地改为===**,那么我认为这是错误的。 - Eric P
1
@Eric 我认为保持一致是更好的选择。在任何地方使用 === 有什么问题呢? - Skilldrick
2
@Skilldrick:我认为学习在使用==运算符时关于类型强制转换的规则比说“哇,这有点奇怪”并完全避免它要好。 - Tim Down
显示剩余8条评论
5个回答

21
回答主要问题 - 在使用typeof==时没有危险。以下是为什么您可能想要使用===的原因。
Crockford的建议是在许多情况下使用===更安全,如果您要在某些情况下使用它,最好保持一致并将其用于所有内容。
认为您可以每次检查相等性时都考虑使用=====,也可以养成习惯始终编写===
几乎没有理由使用==而不是=== - 如果您与truefalse进行比较并且您想要强制转换(例如,您希望0''计算为false),则只需使用if(!empty_str)而不是if(empty_str == false)
对于那些不了解==问题的人,从The Good Parts中看到此内容:
'' == '0'          // false
0 == ''            // true
0 == '0'           // true

false == 'false'   // false
false == '0'       // true

false == undefined // false
false == null      // false
null == undefined  // true

' \t\r\n ' == 0    // true

2
不,那不是我所问的:我特别是在询问使用typeof运算符时。 - Eric P
4
我知道,但我想说的是使用 === 的原因是为了与代码的其他部分保持一致。 - Skilldrick
1
@Eric 许多良好的编程实践都与风格有关。这并不意味着它们是浪费时间的。 - Skilldrick
3
@Eric,我认为这种不信任是完全有根据的!类型强制转换的规则非常奇怪。 - Skilldrick
1
当涉及到typeof时,我们应用了一个内置运算符,它声明返回特定类型的值,这意味着你不信任该运算符。 - Eric P
显示剩余8条评论

6
如果typeof操作符已经返回了一个字符串,那么为什么还需要检查返回值的类型?如果typeof(typeof(x))总是字符串,无论x实际上是什么,那么==应该足够而===则是不必要的。
这是主观的。您可以轻松地将其反过来,并问:“当您不希望进行隐式转换时,为什么要使用==?”两者在此处都可以正常工作,因此请使用您认为更能表达您意图的方式。尽量在项目中保持一致。

1
谢谢。到目前为止,风格胜过需求似乎是共识。 - Eric P

3

在这种情况下,没有任何理由偏爱===而不是==,因为两个操作数都保证是字符串,因此两个运算符将产生相同的结果。由于==少一个字符,我会更喜欢使用它。

Crockford对此的建议是始终使用===,这对初学者来说是合理的建议,但如果您了解问题(其他答案中已经涵盖),则毫无意义。


谢谢。目前似乎达成了共识——追求风格胜于必要性。 - Eric P

2

因为 === 比 == 更快,因为省略了类型转换。虽然这可能是微不足道的差异,但它仍然存在。


4
这不一定是正确的:如果你查看ECMAScript规范中每个运算符所需执行的步骤,实际上在比较两个相同类型的对象(比如两个字符串)时,它们是完全相同的。可以尝试进行基准测试。 - Tim Down

1

三个等号运算符主要用于变量类型和值的检查(在一个表达式中完成),也被称为无类型强制转换的相等性

例子:

var a = 1;
var b = 1;
var c = "1";
var d = "1";

alert (a === b); //True, same value and same type (numeric)
alert(c === d); //True, same value and same type (string)
alert(b === c); //False, different type but same value of 1

请查看Doug Crockford关于类型转换的YUI Theater


如果typeof运算符已经返回一个字符串,那么还需要对返回值进行类型检查吗?如果typeof(typeof(x))始终是字符串,无论x实际上是什么,那么==应该足够了,而===则是不必要的。
不使用typeof而使用===运算符最有效的原因是为了在浏览器之间进行类型强制转换(解释)。一些浏览器可以将6=="6"传递为true,而有些浏览器则不会(取决于JS解释器的严格程度),因此通过引入类型强制转换可以澄清这一点。此外,它还将“面向对象”的方法引入其中,因为JavasScript的变量不是基于类型的变量(即变量类型不像Java中的编译时声明)。
例如,在Java中,这将失败:
if ("6" instanceof Number) { // false

希望我回答了你的问题。

1
不,我特别是在涉及typeof运算符的情况下提问。typeof 6应该始终返回字符串文字“number”,因此不需要进行类型检查“typeof 6”。 - Eric P
typeof的结果取决于浏览器如何解释变量或值...因此,你的typeof在一个浏览器上可以工作,在另一个浏览器上可能会失败(典型情况是IE)。大多数JS开发人员希望使用一个库,在最小了解每个浏览器的情况下就能在所有浏览器上运行。因此,完全玩转语言而不学习每个浏览器的调整有所帮助。 - Buhake Sindi
在IE中,typeof不返回字符串字面量的例子是什么? - Eric P
@先生:typeof在各种浏览器中都有一致的实现。你有它在不同浏览器中运行不同的例子吗? - Tim Down
我同意typeof在各个浏览器中是一致的。但我的意思是,使用typeof需要您知道类型(这并不能保证每种类型在所有浏览器中都有效)。这就是我想说的。 - Buhake Sindi
1
我非常怀疑有任何Javascript解释器会将6=="6"评估为false - MooGoo

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