{}+[]與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]

 

以上

相關文章
相關標籤/搜索