JavaScript作为一门弱类型语言,并不像C、Java那样有明确的类型定义如int、boolean、string、float、double等数据类型,而js同时又是一门脚本语言,逐行编译运行的,为了防止运行出错,就存在了变量类型的隐式转换
本人使用js也有一段时间了,但是对这个转换规则还是有点不理解全面,所以从网上学习回来,总结了这个隐式转换规则,从此以后不再纠结于这个东西,请往下看
ECMA规范:
非布尔类型转换为布尔类型时:
长度为0的字符串、undefined、null、0、±0、NaN会转换为false
非0且不为NaN的number类型、长度大于0的字符串、复杂类型会转换为true
代码解读复制代码console.log(1+{a:1}) // '1[object Object]'
{a:1}是object类型,会先调用valueOf()方法,依旧返回{a:1},不为原始类型,则调用toString()方法,返回'[object Object]',为string类型,ok,进行字符串拼接,得到上面的结果
为了验证是不是这个过程,我们先重写toString方法,使其返回'{a:1}'
结果如下:
继续改写valueOf()方法,使其返回1
结果如下:
看来确实是这样的转换过程
代码解读复制代码console.log(undefined+1) // undefined + 1 -> NaN + 1 = NaNNaN
console.log(undefined+'1') // undefined + '1' -> 'undefined' + '1' = 'undefined1'
console.log(null+1) // null + 1 -> 0 + 1 =1
console.log(null+'1') // null + '1' -> 'null' + '1' = 'null1'
console.log(null+undefined) // null + undefined -> 0 + NaN = NaN
console.log(undefined+[1,2]) // undefined + [1,2] -> 'undefined' + '1,2' = 'undefinde1,2'
console.log(null+[1,2]) // null + [1,2] -> 'null' + '1,2' = 'null1,2'
代码解读复制代码console.log(![] == []) // true
首先,等式左边为![],存在!,将[]直接转换为boolean类型,![] -> !true = false
所以 (![] == []) -> (false == []) -> (0 == 0) = true
代码解读复制代码{}+1 // 1
1+{} // '1[object Object]'
一开始以为 {}+1 的值会是 '[object Object]1',结果却是1,其实并不是转换的问题,而是{}的问题,解释如下:
1+{},因为+在前,所以{}被当成运算符,它的值是'[object Object]',所以整个运算会自动类型转换{}+1,{}在前,整个语句并没有被解析成一个表达式,被分开执行,就变成了:js
代码解读复制代码{
};
+1
于是真正的语句就变成了+1,结果就是1了
只要加个小括号,就能去除二义性了js
代码解读复制代码({})+1)