要弄明白这个问题首先咱们要了解JS中的类型转换以及引用类型的转换,咱们一般把值从一种类型转化为另外一种类型称为类型转换,这是显示的状况;隐式的状况称为强制类型转换。javascript
在JavaScript中强制类型转换老是返回标量基本类型的值,不会返回对象和函数。java
对于对象(包括数组),为了将值转换为相应基本类型的值,抽象操做ToPrimitive
会首先检查该值是否有valueOf()
方法,若是有而且返回基本类型的值,就使用该方法进行强制类型转换;若是没有就使用toString()
发放进行强制类型转换,若是valueof()
和toString()
都不存则会报错。数组
valueOf()
和
toString()
,对象先会在本身身上查找这两个方法,若是有则会覆盖原型的方法,若是对象没有这个方法,而后在到原型上查找。
下面这个例子没有定义上面的两个方法,则会调用原型链上的方法。 函数
下面这个例子中咱们使用Object.create(null)
建立了一个对象,它没有继承任何原型方法,因为它的__proto__
为undefined
,自身也没有定义valueOf()
和toString()
因此在进行强制类型转换的时候会报错。 spa
若是咱们给它添加一个valueOf()
或toString()
: 3d
在不少时候咱们常常使用+
来进行数字加法和字符串拼接。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