内容基本上来自于:《you dont know javascript》中卷 第4章 类型与文法javascript
[] + {} // "[object Object]" {} + [] // 0
先看第一个表达式,[ ] + { }
, 由于[]
会被强制转换为""
, 而后+
运算符 连接一个{ }
, { }
强制转换为字符串就是"[object Object]"
。 最终结果就是后者。html
在看第二个表达式, 表达式第一个就是{ }
,这时候编译器只会把这个{ }
看成一个空代码块。【es6以前尚未块级做用,只有函数做用域和全局做用域,能够就理解为全局做用域下面一个多余的{ }
符号而已】,{ } + [ ]
就能够看成是+ [ ]
, 而 + [ ]
是强制将[ ]
转换为number ,转换的过程是 + [ ]
--> +""
-->0
最终的结果就是0。java
好,咱们举几个例子吧。es6
{}var a = 5; {} console.log(a); {var b = 6;} console.log(b) {var c = 7;}console.log(c);
这些语句都能在chrome控制台正确的运行。web
可能你的疑问来了,好比在控制台里面输入{ name: “kevin” },也是能正常运行的,而且打印了这个对象。由于这时候它是一个表达式语句,就和在控制台输入5的时候是同样的,这时候chrome控制台打印的是定义的这个值。chrome
可是咱们这样输入,加一个分号 { name: “kevin” }; 你看控制台发生了什么变化,打印了"kevin", 由于这个语句的意思是,给字符串"kevin"打一个标签!! wtf ,的确是这样的。 若是很差理解的话 咱们将字符串换成一个函数。svg
咱们先定义了一个函数function bar(){}
, 而后给他打标签
{ barTag: bar };
就等于 barTag: bar
就等于 barTag: bar;
, 为何{barTag: bar};
有这个分号,在chrome控制台里面,不加分号他就会被解析成一个对象。若是在html文件的script标签里面,加或者不加是同样的,都是打标签。函数
可是标签不是是字符串,就是说不能够这样 "barTag":bar
spa
这里的打标签和for循环打标签相似:code
foo: for (var i = 0; i < 4; i++) { for (let j = 0; j < 4; j++) { if (i * j >=3 ) { console.log('stopping', i, j) break foo } console.log(i, j) } }
然鹅咱们也能够给代码块打标签:
function foo() { bar: { console.log('hello') break bar console.log('never runs') } console.log('world') }
function bar() {} {func: bar} // chrome 控制台打印的是什么 {func: bar}; // 这个呢?
看上面两个,一个打印的对象,一个是函数!第二个就是函数,func就是函数bar的标签。
咱们也能够强制让{}+[]
的结果变成了0, 加一个括号便可。({}+[])
,只要不在一个语句的头部检测到{}
或者 ;{}
这种形式,那么它就不是一个代码块。(可能还有其余形式)。
可是咱们执行console.log({}+[])
和console.log([]+{})
,结果是同样的,由于{}没有一个语句或者表达式的头部。
上面的全部实验是在chrome 控制台下的结果。
你也能够在html的script标签里面作一些实验。