我们知道现在的开发人员都使用 === 来代替 ==, 为什么呢?
我在网上看到的大多数教程都认为, 要预测 JavaScript 强制转换是如何工作这太复杂了, 因此建议总是使用 ===.
这些都导致许多程序员将该语言的一部分排除在外, 并将其视为一种缺陷, 而不是去扩大他们的对该过程的理解.
下面通过两个使用案例, 说明使用 == 的好处.
1. 测试空值
- if (x == null)
- vs
- if (x === undefined || x === null)
2. 读取用户的输入
在本文中, 我们将通过对比差异, 理解强制性, 研究一些流行的用例, 并最终找到指导我们做出决定的准则, 来深入了解该主题.
简介
在 JavaScript 中, 相等由两个运算符完成.
=== - 严格相等比较也称为三等运算符.
== - 抽象的相等比较
我一直在使用 ===, 因为我被告知它比 == 更好和更好, 而且我根本不需要考虑它, 作为一个懒惰的人, 我觉得很方便.
直到我观看了 Kyle 或 [@getfiy][1] 的[You Do n't Know JS][2]作者在 Frontend Masters 上的" Deep JavaScript Foundations".
作为一名专业的程序员, 我没有深入思考我每天工作中使用的操作符, 这一事实激励我去传播意识, 并鼓励人们更多地理解和关注我们编写的代码.
事实的根源在哪里
知道真实的原因在哪里很重要. 不是在 Mozilla 的 W3school 上, 也不在声称 === 优于 == 的数百篇文章中, 而且在这篇文章中也绝对没有..
在 JavaScript 规范中, 我们可以找到关于 JavaScript 如何工作的[文档][3].
打破常识
(1) `==` 只检查值(松散)
如果看一下规范, 从定义中可以很清楚地看出, 算法要做的第一件事实际上就是检查类型.
(2) `===` 检查值和类型(严格)
在这里, 我们同样可以从规范中看到, 它检查类型, 如果它们不同, 则不会再检查值.
双等号和三等号之间的真正区别是我们是否允许强制转换.
JavaScript 中的强制转换
强制转换或类型转换是任何编程语言的基础之一. 这对于动态类型化的语言 (例如 JavaScript) 尤为重要, 因为如果类型更改, 编译器不会对它大喊大叫, 找它麻烦.
理解强制性意味着我们能够以与 JavaScript 相同的方式解释代码, 从而为我们提供了更大的可扩展性并最大程度地减少了错误.
(1) 显性强制转换
强制转换可以在程序员调用这些方法之一时显式发生, 从而强制改变变量的类型.
Boolean(), Number(), BigInt(), String(), Object()
事例:
- let x = 'foo';
- typeof x // string
- x = Boolean('foo')
- typeof x // boolean
(2) 隐藏转换
在 JavaScript 中, 变量的类型很弱, 因此这意味着它们可以自动转换(隐式强制). 当我们使用算术运算符 + / - *, 周围的上下文或使用 == 时, 通常是这种情况.
- 2 / '3' // '3' 强制转为 3
- new Date() + 1 // 强制转换为以 1 结尾的日期字符串
- if(x) // x 被强制为布尔值
- 1 == true // true 被强制为 1
- 1 == 'true' // 'true' 被强制为 NaN
- `this ${
- variable
- } will be coreced to string
隐性强制是一把双刃剑, 合理使用可以增加可读性, 减少冗长. 如果使用不当或被误解, 我们就会有一个让人失望的公式, 人们会咆哮并指责 JavaScript.
比较的算法
(1) == 运算符号的算法
如果 X 和 Y 是相同的类型, 则执行 ===.
如果 X 为 null 且 Y 未定义或反之, 则为 true.
如果一个是数字, 则将另一个强制为数字.
如果一个是对象, 则强制转换为原始对象.
其它, 返回 false.
(2) === 比较的算法
如果类型不匹配 false.
如果类型匹配 - 比较值, 为 NaN 时返回 false.
-0 - true.
流行的用例
(1) 同类型(多数情况)
如果类型相同, 则 === 与 == 完全相同. 因此, 应该使用语义性更强的那个.
- 1 == 1 // true
- 'foo' == 'foo' // true
类型不同, 我更喜欢用 ===.
(2) 不同类型(原始类型)
首先, 我想提醒您注意, 不同类型并不意味着未知类型. 不知道类型表明代码中的问题比仅使用 === vs== 更大. 了解类型表明对代码有更深入的理解, 这会减少更多的错误.
假设我们有一个数字或字符串的可能性. 请记住, 算法更偏向数字类型, 因此它将尝试使用 toNumber()
- let foo = 2;
- let bar = 32; // number 还是 string
- foo == bar // 如果 bar 是字符串, 它会转换成 number
- foo === Number(bar) // doing basically the same
- foo === bar // bar 为 string 则该结果为 false
(3) null 和 undefined
使用 == 时, null 和 undefined 彼此相等.
- let foo = null
- let bar = undefined;
- foo == bar // true
- foo === bar // false
(4) 非原始类型[对象, 数组]
不应该使用 == 或 === 来比较对象和数组等非原始类型的数据.
决策准则
在所有可以使用的情况下, 最好使用 ==.
== 具有已知类型, 可以选择强制类型转换.
知道类型总比不知道好.
如果不知道类型, 就不要使用 ==.
当类型不匹配时,=== 是没有意义的.
当类型匹配时,=== 是不必要的.
避免使用 == 情况
在某些情况下, 如果不真正了解 JavaScript 中的虚值, 则不应使用 ==.
- == with 0 or ""or" "
- == with non primtives
- == true or == false
总结
根据我的经验, 到目前为止, 我一直都知道我要处理的变量的类型, 如果我不知道, 我就使用 typeof 来只允许我所期望的变量.
需要注意的四点:
如果你不知道变量类型, 那么使用 === 是惟一合理的选择
不知道类型可能意味着你不理解代码, 请尝试重构你的代码
知道类型可以编写更好的代码.
如果类型已知, 则最好使用 ==.
来源: http://www.tuicool.com/articles/eAfi2u7