赞
踩
有时,当我在编写Javascript时,我想举起双手说“这是胡说八道!”
在日常JavaScript编码过程中,可能很难看清相等运算符的工作方式。特别是当操作数具有不同类型时。有时会在条件错误中创建错误,这些错误很难识别。这是很容易理解为什么0 == 8
是false
或者'' == false
是true
。但是,为什么{} == true
是false
不是很明显看到。如果您有兴趣:
然后让自己舒服一些,让我们开始吧。
本文中使用以下术语:
==
比较两个值,身份运算符===
比较两个值及其类型,加法运算符+
将两个数字相加或将两个字符串连接在一起。0 == {}
,0
是第一个操作数,{}
第二个操作数。身份运算符
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()
返回原语,则对象将转换为该值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)==
:
null
与另一个操作数相等undefined
,则它们相等true
到1
和false
到0
。再次计算比较让我们考虑一些例子。例子1
1 == true
(转换true
为1
使用EEA规则2.3)1 == 1
(操作数具有相同的类型,数字。使用EEA规则1将等式转换为身份)1 === 1
(两个操作数都是数字,并且具有相同的值。基于IEA规则6,这是相等的)true
例子2
'' == 0
(一个操作数是字符串,另一个是数,基于EEA规则2.2的''
被转换成一个数字)0 == 0
(操作数是同一类型,请使用EEA规则1将等式转换为身份)0 === 0
(操作数是相同的类型,并且具有相同的值,因此根据IEA规则6,它是一个标识)true
例子3
null == 0
(null
是null类型的原语,0
是数字。应用EEA规则3)false
例子4
null == undefined
(基于EEA规则2.1,操作数相等)true
例子5
NaN == NaN
(两个操作数都是数字。使用EEA规则1将相等转换为身份)NaN === NaN
(基于规则IEA规则4,操作数并不严格相等)false
例子6
[''] == ''
(['']
是一个数组和''
一个字符串。应用EEA规则2.4,并使用OPCA规则2将数组转换为基本体)'' == ''
(两个操作数都是字符串,因此将等式转换为标识)'' === ''
(两个操作数是相同的类型,并且具有相同的值。使用IEA规则7是一个标识)true
例子7
{} == true
(使用EEA规则2.3,将true
操作数转换为1
){} == 1
(第一个操作数是一个对象,因此有必要使用OPCA将其转换为原语)"[object Object]" == 1
(由于第一个操作数是字符串,第二个是数字,我们需要"[object Object]"
使用EEA规则2.2将其转换为数字)NaN == 1
(两个操作数都是数字,因此请使用EEA规则1将等式转换为身份)NaN === 1
(基于IEA第4条规则,该规则说与a不相等NaN
,结果为false
)false
请参阅JS Bin中的示例有用的提示
即使详细检查了本文中的所有示例,并学习了算法,您也可能会发现复杂的内容,无法立即理解复杂的比较。老实说,这个操作员对我来说也是一个长期的黑匣子。
让我告诉您一些技巧。将此文章添加到书签中(使用Ctrl+D
),下次您看到一个有趣的情况时,请根据等式算法编写逐步的计算。如果您自己检查至少10个示例,则将来不会有任何问题。
立即开始!结果和详细解释是[0] == 0
什么?随时在回复中写评论。
等于运算符==
进行类型转换。结果,某些比较可能会产生意想不到的结果,例如{} == true
是false
(请参见示例7)。在大多数情况下,使用身份运算符更安全===
。结论
平等和认同可能是最常用的运算符之一。了解它们是编写稳定且漏洞较少的JavaScript的步骤之一。
原著作者:德米特里·帕夫鲁汀
文章来源:国外
原著链接:
Dmitri Pavlutin Blogdmitripavlutin.comPS:原著文章内容为英文版本,建议使用360极速浏览器进行翻译阅读。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。