javascript数据类型转换 []+{} 和 {}+[]

吐下槽,javascript数据类型真的很奇葩

看了一个页面《出几道JS的题》,当时确实挺感兴趣地就点进去了。但是看了那几道题,确实才感觉自己对javascript这个语言认识的缺乏。

{} + [] = ?

[] + 0 = ?

{} + 0 = ?

({} + []) = ?

之前看了《javascript高级程序设计》介绍数据类型的时候,知道在操作符的时候javascript的数据类型会出现转换在二元操作符"+"加法时,它会遵循一些规则:

1 两个操作符都是数值,就执行常规的加法运算 2 两个中有一个操作数是字符串
(1)两个操作数都是字符串,就把两个拼接起来
(2)其中有一个是字符串,那么就讲另外一个操作数转换成字符串,然后再拼接
3 有一个操作数是对象、数值或布尔值,就调用它们的toString()转换成字符串,而对于undefined和null就调用String()函数
但是上面执行的结果是什么呢?当时我马上就打开了chrome的控制台,把上面的几句代码敲进去了,看了看,出乎我的预料。
  • {} + [] =0
  • [] + 0 = "0"
  • {} + 0 = 0
  • ({} + []) =[object Object]

出现上面结果的原因

对于javascript解析器,我们要了解下
第一个就是{}符号的使用,如果是通过var 来定义一个变量并把{}赋值给那个变量的话,那么它就是相当于new Object()。但是如果直接在js文件中使用{},javascript解析器会把它当成语句块(虽然js是没有块级作用域的)来使用,它已经不是对象的意思了。
第二个是一元操作符“+”的使用,它对数据类型的转换是相当于调用Number()构造函数的,它也有一系列的规则
  • Boolean类型,true和false会分别被转换成1,0
  • null转换成0,undefined转换成NaN
  • 字符串类型,转换比较复杂。

    (1) 如果都是数字,就将其转换成十进制,并会忽略掉前导的零

    (2) 如果包含有效的小数点的话,它会转换成浮点类型

    (3) 如果包含有效的16进制的话, 会转换成10进制

    (4) 如果是空字符串的话,就转换成0

    (5) 其余的转换成NaN

  • 如果是对象的话

    (1) 先调用对象自身的valueOf方法,如果该方法返回原始类型的值(数值、字符串和布尔值),则直接对该值使用Number方法,不再进行后续步骤;

    (2) 如果valueOf方法返回复合类型的值,再调用对象自身的toString方法,如果toString方法返回原始类型的值,则对该值使用Number方法,不再进行后续步骤;

    (3) 如果toString方法返回的是复合类型的值,则报错

{} + [] = ?
结果0
原因:js解析器把最前面的{}当成语句块来执行,所以其实{}+[]就相当于执行+[] 而+[]相当与执行Number([]),它先调用[].valueOf()查看下还是返回原数组(复合元素),所以执行[].toString()得到了""表示空字符串,所以Number([])相当于执行Number(""),最后得到的是0。
[] + 0 = ?
结果"0"
原因:我们知道[]会执行[].toString()变成“”,注意现在已经变成字符串连接了,二元操作符+变成了字符串连接符,所以会把数值的0变成字符串“0”,然后再跟“”连接
{} + 0 = ?
结果0
原因:同第一个{}+[]
({} + []) = ?
结果"[object Object]"
原因:()有一种语义是强制表达式运算,所以现在的{}是不能看成语句块的,只能是对象,所以{}.toString执行完就是[object Object],在加上[].toString()为“”,所以就是"[object Object]"

参考文献

Javascript小括号“()”的多义性
数据类型转换(阮一峰好文章)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值