有时,当我在编写Javascript时,我想举起双手说“这是胡说八道!”
在日常JavaScript编码过程中,可能很难看清相等运算符的工作方式。特别是当操作数具有不同类型时。有时会在条件错误中创建错误,这些错误很难识别。这是很容易理解为什么
0 == 8
是
false
或者
'' == false
是
true
。但是,为什么
{} == true
是
false
不是很明显看到。如果您有兴趣:
- 更好地了解平等和身份运营商
- 学习形式计算算法
- 练习很多例子
然后让自己舒服一些,让我们开始吧。
本文中使用以下术语:
- 运算符
是表示操作的符号。
例如,等于运算符
比较两个值,身份运算符==
比较两个值及其类型,加法运算符===
将两个数字相加或将两个字符串连接在一起。+
- 操作数
是运算的主题,是执行运算的数量。
在表达式中
, 是第一个操作数,0 == {}
第二个操作数。{}
- JavaScript中的 原始类型 被认为是数字,字符串,布尔值,null和undefined。
JavaScript正在执行相等性评估。解释器首先将两个操作数转换为相同的类型。然后执行身份比较。
身份评估算法(
IEA)
===
:
- 如果两个操作数的类型不同,则它们 不是严格相等的
- 如果两个操作数都为
,则它们 严格相等null
- 如果两个操作数都为
,则它们 严格相等undefined
- 如果一个或两个操作数是
,则它们 不是严格相等的NaN
- 如果两个操作数都是
或两者true
都 严格相等false
- 如果两个操作数都是数字并且具有相同的值,则它们 严格相等
- 如果两个操作数都是字符串并且具有相同的值,则它们 严格相等
- 如果两个操作数都引用相同的对象或函数,则它们 严格相等
- 在所有其他情况下,操作数 不是严格相等的 。
规则很简单。
值得一提的是,
NaN
在身份(和相等性)运算符中,与其他任何值相比,其总和为
false
。让我们考虑一些例子。这是记住严格比较算法的最佳方法。
例子1操作数是不同的类型(数字和字符串),并且根据IEA规则1,它们是不同的。
例子2操作数是相同的类型(数字)并且具有相同的值,因此根据IEA规则6,它们严格相等。
例子3这两个操作数都是
undefined
并且应用IEA规则3,这是相等的。
例子4由于操作数是不同的类型,因此根据IEA规则1,它们是不同的。
例子5操作数是相同的类型(数字),但是IEA规则4表示没有东西等于
NaN
。结果是
false
。
例子6这两个变量
firstObject
和
secondObject
都是对同一对象的引用,并且根据IEA规则8,身份运算符的计算结果为
true
。
例子7的
[]
字面创建一个新的数组引用。两个操作数是相同的类型(对象),但是引用了不同的对象。在国际能源署(IEA)第9条说,身份的计算结果为
false
。
请参阅JS Bin中的示例
将对象转换为基本体学习平等之前的另一步是了解对象向原始转换的过程。比较对象和原始值时,JavaScript使用它。对象到原始转换算法(
OPCA):
- 如果该方法
存在,则将调用它。如果valueOf()
返回原语,则对象将转换为该值valueOf()
- 在其他情况下,如果
存在该方法,则将其调用。如果toString()
返回原语,则对象将转换为该值toString()
- 在其他情况下,JavaScript会引发错误:
TypeError: Cannot convert object to primitive value
调用valueOf()方法时,大多数本机对象将返回对象本身。因此,toString()方法被更频繁地使用。
关于
Date
对象的说明:转换为基元时,使用
toString()
方法将对象立即转换为字符串。这样,规则1被跳过
Date
。普通的JavaScript对象(
{}
或
new Object()
通常会转换为)
"[object Object]"
。
通过使用
","
分隔符将其元素连接在一起,可以将数组转换为。例如
[1, 3, "four"]
转换为
"1,3,four"
。
等于运算符现在,这是有趣的部分。在阅读本文之前,如果您只是滚动到这里,我建议您对身份和对象到原始转换部分有一个很好的了解。
平等评估算法(
EEA)
==
:
- 如果操作数具有相同的类型,请使用 IEA 测试它们是否严格相等。如果它们不严格相等,则它们 不相等 ,否则 相等。
- 如果操作数具有不同的类型:
- 如果一个操作数
与另一个操作数 相等null
,则它们 相等undefined
- 如果一个操作数是数字,另一个是字符串,则将字符串转换为数字。再次计算比较
- 如果一个操作数是布尔,转变
到true
和1
到 。再次计算比较false
- 如果一个操作数是一个对象,另一个是数字或字符串,则使用 OPCA 将对象转换为原语。再次计算比较
- 在所有其他情况下,操作数 不相等
让我们考虑一些例子。
例子1-
(转换1 == true
为true
使用EEA规则2.3)1
-
(操作数具有相同的类型,数字。使用EEA规则1将等式转换为身份)1 == 1
-
(两个操作数都是数字,并且具有相同的值。基于IEA规则6,这是相等的)1 === 1
-
true
-
(一个操作数是字符串,另一个是数,基于EEA规则2.2的'' == 0
被转换成一个数字)''
-
(操作数是同一类型,请使用EEA规则1将等式转换为身份)0 == 0
-
(操作数是相同的类型,并且具有相同的值,因此根据IEA规则6,它是一个标识)0 === 0
-
true
-
(null == 0
是null类型的原语, 是数字。应用EEA规则3)null
-
false
-
(基于EEA规则2.1,操作数相等)null == undefined
-
true
-
(两个操作数都是数字。使用EEA规则1将相等转换为身份)NaN == NaN
-
(基于规则IEA规则4,操作数并不严格相等)NaN === NaN
-
false
-
([''] == ''
是一个数组和['']
一个字符串。应用EEA规则2.4,并使用OPCA规则2将数组转换为基本体)''
-
(两个操作数都是字符串,因此将等式转换为标识)'' == ''
-
(两个操作数是相同的类型,并且具有相同的值。使用IEA规则7是一个标识)'' === ''
-
true
-
(使用EEA规则2.3,将{} == true
操作数转换为true
)1
-
(第一个操作数是一个对象,因此有必要使用OPCA将其转换为原语){} == 1
-
(由于第一个操作数是字符串,第二个是数字,我们需要"[object Object]" == 1
使用EEA规则2.2将其转换为数字)"[object Object]"
-
(两个操作数都是数字,因此请使用EEA规则1将等式转换为身份)NaN == 1
-
(基于IEA第4条规则,该规则说与a不相等NaN === 1
,结果为NaN
)false
-
false
请参阅JS Bin中的示例
有用的提示即使详细检查了本文中的所有示例,并学习了算法,您也可能会发现复杂的内容,无法立即理解复杂的比较。老实说,这个操作员对我来说也是一个长期的黑匣子。
让我告诉您一些技巧。将此文章添加到书签中(使用
Ctrl+D
),下次您看到一个有趣的情况时,请根据等式算法编写逐步的计算。如果您自己检查至少10个示例,则将来不会有任何问题。
立即开始!结果和详细解释是
[0] == 0
什么?随时在回复中写评论。
等于运算符
==
进行类型转换。结果,某些比较可能会产生意想不到的结果,例如
{} == true
是
false
(请参见示例7)。在大多数情况下,使用身份运算符更安全
===
。
结论平等和认同可能是最常用的运算符之一。了解它们是编写稳定且漏洞较少的JavaScript的步骤之一。
原著作者:德米特里·帕夫鲁汀 文章来源:国外 原著链接: Dmitri Pavlutin Blogdmitripavlutin.com PS:原著文章内容为英文版本,建议使用360极速浏览器进行翻译阅读。