有一天,去面试,遇到这样的题:html
[]+[]
{}+{}
1+[]
复制代码
???WTF,谁会没事这么写代码,好吧,我错了,大佬别打我。懵逼以后要干吗?固然是要学习一波,因而我满世界找资料,有好东西固然是要分享一波,好了,接下来咱们就一块儿走进 JavaScript 隐式转换的世界吧。git
在 JavaScript 中加法运算规则很简单,它只作数字和字符串的加法操做,全部不是这两种类型的都会被转换成这两种原始数据类型再进行操做。github
在 JavaScript 中,数据类型分两种:面试
那么对象是如何转换成原始数据类型的呢?不要慌,咱们继续看。数组
JS 有一个内部运算 ToPrimitive()
,它用于对象转换为原始数据类型。浏览器
ToPrimitive(input, PreferredType?)
复制代码
这个函数接收两个参数:函数
下面咱们来看一下对于不一样的参数,它的转换过程是什么样的?学习
valueOf()
方法,若是结果为原始类型就直接返回。toString()
方法,若是结果为原始数据类型就返回。参数 String 就不细说了,当参数为 String 的时候,上面的第二步和第三步交换就好了,也就是先调用 toString()
再调用 valueOf()
。测试
value1 + value2
复制代码
上面的操做方式以下:ui
// PreferredType被省略,所以非日期为 Number,日期为 String。
prim1 = ToPrimitive(value1)
prim2 = ToPrimitive(value2)
复制代码
这两个都是 Object 的属性,能够本身定义,如今咱们无论,咱们去看看下面几种状况这两个方法返回的都是什么。
// 对象
const a1 = {
a: 1
};
console.log(a1.valueOf());
console.log(a1.toString());
// 数组
const a2 = [1,2,3];
console.log(a2.valueOf());
console.log(a2.toString());
// 方法
const a3 = function() {
const a = 1;
return 1;
};
console.log(a3.valueOf());
console.log(a3.toString());
复制代码
将上面的代码放到控制台打印一下就知道:
join(',')
的返回值,好比 [1,2,3].toString()
返回 "1,2,3"。好了,根据咱们上面说的,那些面试题简直洒洒水,咱们来看。
[]+{}
复制代码
咱们如何去分析呢?在这里,咱们首先将 [] 和 {} 转换成原始数据类型,也就是 ToPrimitive([]) 以及 ToPrimitive({}),PreferredType 默认为 Number,很明显 [].valueOf()
仍是一个对象,因此咱们继续,[].toString()
结果为 "",相同的解析过程 {} 转换成 "[object Object]"。
好了,如今这个式子是 "" + "[object Object]",咱们知道 + 运算只要有字符串就拼接操做数,因此结果是 "[object Object]"。
可是,在我进行测试的时候,发现了几个特殊的例子,{}+1
、{}+[]
这两个例子在控制台打印出的结果为 1
和 ""
,很奇怪是吧?我搜了搜资料发现,不一样浏览器对其的解析不一样,它会将前面一个 {} 当成代码块,因而上面的式子就变成了 +1
和 +[]
,因此得出了上面的结果。
好了,通过上面的探究,我相信你们不会再被这些问题难住了,可是要记住,{} 在前面的状况下可能会由于浏览器的差别会形成不一样的结果,固然,若是你这样将 {} 用 () 包起来就不会有问题了,或者是先声明在使用。
更多文章尽在 个人博客仓库,若是各位读者以为有用,欢迎 star,不胜感激。