今天一位美女同事问了一个问题,就是解释下图 JavaScript 的运行结果。发在了部门的前端群里,引起了一些讨论,我写下我的一些理解。
JavaScript 的隐式转换
1 == '1' // true
在 JavaScript 里,字符串 1 和 数字 1 是相等的,因为相加时都做了 toString 的转化,使用 ‘===’ 来比较结果就不一致了。所以在 {} + [] 相加时,也会产生隐式转化,使其能够相加。
({}.toString()) // [object Object]
[].toString() // ''
Unary plus
符号 ‘+’ 可以用来数字相加、字符串相连,也可以做为一个一元运算符。比较常用的是快速将字符串转化为数字。
+'1' // 1
+undefined // NaN
块级作用域
{} 不仅可以作为对象,也可以用做块级作用域。在 es5 时期,JavaScript 是没有块级作用域,只有函数作用域。es6 配合 let 关键字和 {} 就能实现块级作用域,防止变量污染。
{
let s = 1;
}
console.log(s); // Uncaught ReferenceError: s is not defined
所以当对象字面量相加时,会涉及词法解析为对象或代码块的问题。一般 Chrome 会把 {}; 视为一个代码块,{} 视为对象,如此一来就不难理解上述的异常现象了。
运行这个有意思的例子
var toString = Object.prototype.toString
Object.prototype.valueOf = function () { return 'a'; }
Object.prototype.toString = function () { return 'b'; }
Object.prototype.toLocaleString = function () { return 'a'; }
var s = {a: 1};
console.log(toString.call(s), toString.call('a'))
console.log(s === 'a')
console.log(s == 'a')
console.log(String(s) === 'b')
写完,下班!