{}+[]与console.log({}+[])结果不一样?从JavaScript的大括号谈起

看到这样一个问题:为何直接在控制台运行{} + []和用console.log({} + [])输出,二者结果不同?javascript

因而乎打开chrome的控制台运行了一下:前端

为何结果会这样呢?不得已学习一下JS中的{}吧java

复合语句jquery

 1 if() {
 2     //...
 3 }else {
 4     //...
 5 }
 6 for() {
 7     //...
 8 }
 9 while() {
10     //...
11 }
12 with(obj) {
13     //...
14 }

声明对象直接量chrome

1 var obj = {
2     name: 'Marco',
3     age:  22,
4     sex: male      
5 };

声明函数或函数直接量浏览器

1 function fn1() {
2      //...  
3 }
4 var fn2 = function() {
5     //...
6 }

没有块级做用域闭包

1 for( var i = 0; i < 10; i++) {
2     doSomething(i);  
3 }
4 
5 alert(i); //10

javascript只有函数做用域,如下作法会声明全局变量:函数

  1. 直接为window添加属性或者赋值  //window.a = 1;                  
  2. 在function内不使用var声明变量而直接使用
  3. 在function外使用声明变量(不管是否适用var声明)
 1 function(num1 , num2) {
 2     var sum = num1 + num2;
 3     return sum;  
 4 }
 5 
 6 var result = add(10,20);   //30
 7 alert(sum);   //错误
 8 
 9 
10 function(num1 , num2) {
11     sum = num1 + num2;
12     return sum;  
13 }
14 
15 var result = add(10,20);   //30
16 alert(sum);   //30

建议在初始化变量以前必定要先声明,这样能够避免不声明而直接初始化变量形成的错误。学习

当在某个环境中使用一个标识符时,必须先经过搜索来肯定该标识符表明什么。搜索过程从做用域链的前端开始,向上逐级查询与给定名字匹配的标识符。若在该环境中找到了该标识符,则搜索中止,变量就绪。若在该局部环境没有找到该变量,则继续沿做用域链向上搜索,一直追溯到全局环境的变量对象。若在全局环境中没有找到该标识符,则说明该变量还没有声明。spa

1 var num = 1;
2 
3 function getNum() {
4     var num = 10;
5     return num;
6 }
7 
8 alert(getNum());    //10

变量查询是有代价的。很明显,访问局部变量要比访问全局变量更快,由于不用向上搜索做用域链。来看看jquery这么作的:

(function(window, undefined) {
     var jQuery = function() {}
     // ...
     window.jQuery = window.$ = jQuery;
 })(window);

这样写的优点:

一、window和undefined都是为了减小变量查找所通过的scope做用域。当window经过传递给闭包内部以后,在闭包内部使用它的时候,能够把它当成一个局部变量,显然比原先在window scope下查找的时候要快一些。(原来的window处于做用域链的最顶端,查找速度慢)

二、在jquery压缩版本jquery.min.js中能够将局部变量window替换成单个字母,减少文件大小,提升加载速度

三、undefined也是JavaScript中的全局属性。将undefined做为参数传递给闭包,由于没给它传递值,它的值就是undefined,这样闭包内部在使用它的时候就能够把它当作局部变量使用,从而提升查找速度。undefined并非JavaScript的保留字或者关键字。

四、undefined在某些低版本的浏览器(例如IE八、IE7)中值是能够被修改的(在ECMAScript3中,undefined是可读/写的变量,能够给它赋任意值,这个错误在ECMAScript5中作了修正),将undefined做为参数而且不给它传值能够防止因undefined的值被修改而产生的错误。

结构化异常处理的语法符号 

1 try { 
2     //... 
3 }catch( ex ){ 
4     //... 
5 }finally{ 
6     //... 
7 } 

语句优先

当{}既能够被理解为复合语句块也能够被理解为对象直接量或函数声明的时候,JavaScript将会将其理解成为复合语句块

1 {a:10}  //返回1,而不是对象   : 为标签
2 
3 var x = { a:10 } // {a:10}做为右值出现,不能是语句块,只能理解为对象直接量

 

至此,{}的基本知识就说完了。那么最开始的问题也很好解释了:

{}+[] :根据语句优先原则  {}被理解为复合语句块,所以至关于 {}; +[]   。[]为空,结果为0

console.log({}+[]) : js把()中的语句当作一个表达式,所以{}不能被理解为语句块,而被理解为"[object Object]" + "",console.log("[object Object]"+"")打印结果为[object Object]。

其实 console.log({}+[])和[]+{}的结果相同,原理相同,{}做为右值出现被理解为对象直接量

{}+[] 和[]+{}结果不相同,是否是很神奇。

 

来来来,作几个练习题压压惊:

1 {a: 1} + 2     // 2
2 2 + {a: 1}     // 2[object Object]
3 + {a: 1}        // NaN
4 {foo:[1,2,3]}[0];  // [0]

 

以上

相关文章
相关标签/搜索