为何{}+[] != []+{}

要弄明白这个问题首先咱们要了解JS中的类型转换以及引用类型的转换,咱们一般把值从一种类型转化为另外一种类型称为类型转换,这是显示的状况;隐式的状况称为强制类型转换javascript

1、引用类型的转换

在JavaScript中强制类型转换老是返回标量基本类型的值,不会返回对象和函数。java

对于对象(包括数组),为了将值转换为相应基本类型的值,抽象操做ToPrimitive会首先检查该值是否有valueOf()方法,若是有而且返回基本类型的值,就使用该方法进行强制类型转换;若是没有就使用toString()发放进行强制类型转换,若是valueof()toString()都不存则会报错。数组

咱们在对象obj一、obj2上面分别定义了 valueOf()toString(),对象先会在本身身上查找这两个方法,若是有则会覆盖原型的方法,若是对象没有这个方法,而后在到原型上查找。

下面这个例子没有定义上面的两个方法,则会调用原型链上的方法。 函数

下面这个例子中咱们使用Object.create(null)建立了一个对象,它没有继承任何原型方法,因为它的__proto__undefined,自身也没有定义valueOf()toString()因此在进行强制类型转换的时候会报错。 spa

若是咱们给它添加一个valueOf()toString()3d

2、字符串和数字的隐示强制类型转换

在不少时候咱们常常使用+来进行数字加法和字符串拼接。code

let a = '12'
let b = '10'
let c = 12
let d = 10
let add1 = a + b // '1210'
let add2 = c + d // 22
复制代码

这里会获得两个不一样的结果,缘由在于:第一个执行的是字符串拼接的操做,第二个执行的是数字加法操做。cdn

let arr1 = [1,2]
let arr2 = [3,4]
arr1 + arr2 = '1,23,4'
复制代码

由于上上面的数组经过toString()方法也能转换为字符串因此也是执行字符串拼接操做。对象

在书上这样写道:blog

若是某个操做数是字符串或则能经过如下操做转换为字符串的话,+将执行字符串拼接操做。若是其中一个操做数是对象(包括数组),则首先对其调用ToPrimitive抽象操做,该抽象操做再调用[[DefaultValue]],以数字做为上下文。

接下来就是讨论咱们今天的问题了:{}+[] != []+{}

咱们先对[]{}进行单独分析:

[].toString() // ""
+[] // 0 这里先执行toString()转换为"",而后使用 + 执行强制类型转换为 0
{}.toString() // "[object Object]"
+{} // NaN
复制代码
  • []+{}: 这里的加号执行的是字符串拼接的操做,[]和{}分别调用toString()方法,最后就至关于: "" + "[object Object]" 因此最后结果是:"[object Object]"
  • {}+[]: 这里有一点特殊 {}会被看做是一个独立的代码块,至关于:
{
    
}
+[]
复制代码

这里{}代码块不执行任何操做,并且代码块结尾不须要分号,因此也不存在语法上的问题,因此在这里就至关于执行 +[],因此最后结果是0.

最后因为本还在在校学生一名才疏学浅,有什么问题但愿你们提出来,但愿与你们一块儿进步。

参考书籍: 你不知道的JavaScript

相关文章
相关标签/搜索