为什么 [1] == 1 的结果会是true
就是如果在console中写入
[1] == 1
他返回的竟然是 true
让我很不解,一个数组和数字比较,他是怎么转化的呢?直接将数组转换成什么呢?
对此,我又进行了如下的测试
[2] == 1
false
[2] == 2
true
[1,3] == 1
false
[1,3] == 2
false
[1,3] == 3
false
['a'] == 'a'
true
['a','b'] == 'a'
false
['a','b'] == 'ab'
false
总的来看,似乎是如果只有一个元素,那么就和这一个元素判断是否相等,如果多个就进行正常的判断,请问是这样么?
另外对于这种情况的转化规则是什么?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
这是因为
[1]
在和1
进行比较的时候,首先会被转成数字类型,而转成数字类型在实现上又是通过new Number()
来完成的。所以,
[1] == 1
会变成(new Number([1])).valueOf() == 1
。同时,
Number
的构造函数其实是接受一个字符串作为参数的,加上[1].toString() === "1"
,所以new Number([1])
相当于写new Number("1")
,于是很显然(new Number([1])).valueOf()
就是1
了。当然啦,上面那些都是从浏览器实现的角度来说明问题,其实之前就有人问过和答过几乎一样的问题,重复这个论调太 low。接下来,我还是从 ECMAScript 262 的标准角度来解答,看看为什么浏览器会实现成这样,没耐心的同学可以略过了。
要通过
==
比较值,且运算符两边的变量类型一个是 Number 另一个是对象,javascript 标准的 11.9.3 节规定应该将对象使用ToPrimitive
这个抽象操作(abstract operation)将对象转换成基本类型(primitive)再进行比较。原文是:
那么接下来问题就是,
Array
如何转换成基本类型?这在标准的 9.1 节有规定,其具体实现细节则写在 8.12.8 节。在 hint 为
Number
时,标准规定:valueOf
方法,如果返回值为基本类型,这个值就是最终值;toString
方法,如果返回值为基本类型(字符串是基本类型之一),这个值就是最终值;对于
Array
来说:valueOf
返回是Array
本身,所以不符合第 1 条;toString
返回的时"1"
,符合第 2 条,因此ToPrimitive
的结果就是"1"
。那么,比较
[1] == 1
就变成比较"1" == 1
了。对于这种比较,标准的 11.9.3 节规定的很明白,就是ToNumber("1") == 1
,注意这里的ToNumber
也是个抽象操作,并非实际函数,具体规则在标准的 9.3.1 节定义,简单说就是通过类似new Number()
的算法将字符串变成数字,毫无疑问"1"
应该变成数字1
。因此,
[1] == 1
是 true,而[1, 2] == 1
相当于"1,2" == 1
结果就是 false 了。补充说明一下,为什么 @zonxin 的答案从现象上来说差不多正确,但实际上没那么简单。
从我的答案可看出,
ToPrimitive
最终是调用了toString
来获得字符串值并和数字进行比较,所以一般来说把[1] == 1
理解成[1].toString() == 1
是没问题的。可问题是,假如
toString
返回的不是基础类型怎么办呢?这说明至少 Chrome 的实现是非常符合标准的,也同时说明,简单将
[1] == 1
理解成[1].toString() == 1
并不是十分精确。当然,以上都是吹毛求疵,了解一下就好啦。
不是,是
toString()
是先调用
valueOf()
但是默认的valueOf()
返回的是对象,所以再去调用toString()
简单说是 比较运算符 == 会在比较之前判断操作数的类型是否相等,如果不相等,就想转换成合适的类型,再比较。
举例:
当需要明确操作数的类型和值的时候,或者操作数的确切类型非常重要时,应使用严格相等操作符。否则,当你允许操作数在比较前进行类型转换时,可以使用标准相等操作符来比较。
当比较运算设计类型转换时 (i.e., non–strict comparison), JavaScript 会按以下规则对字符串,数字,布尔或对象类型的操作数进行操作:
当比较数字和字符串时,字符串会转换成数字值。 JavaScript 尝试将数字字面量转换为数字类型的值。 首先, 一个数学上的值会从数字字面量中衍生出来,然后得到被四舍五入后的数字类型的值。
如果其中一个操作数为布尔类型,那么布尔操作数如果为true,那么会转换为1,如果为false,会转换为整数0,即0。
如果是一个对象与数字或字符串向比较,JavaScript会尝试返回对象的默认值。操作符会尝试将对象转换为其原始值(一个字符串或数字值)通过方法valueOf和toString。如果尝试转换失败,会产生一个运行时错误。
注意:当且仅当与原始值比较时,对象会被转换为原始值。当两个操作数均为对象时,它们作为对象进行比较,仅当它们引用相同对象是返回true。
讨论 js 的
==
操作符没有意义。本来就是一大堆人设的规则,而逻辑是无法进行推导的。js有===这个运算符,同时判断值和类型
因为
js
品味很差...JS是弱类型语言。