{}+[]與console.log({}+[])結果不同?從JavaScript的大括號談起


看到這樣一個問題:為什么直接在控制台運行{} + []和用console.log({} + [])輸出,兩者結果不一樣?

於是乎打開chrome的控制台運行了一下:

為什么結果會這樣呢?不得已學習一下JS中的{}吧

復合語句

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

聲明對象直接量

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

建議在初始化變量之前一定要先聲明,這樣可以避免不聲明而直接初始化變量造成的錯誤。

當在某個環境中使用一個標識符時,必須先通過搜索來確定該標識符代表什么。搜索過程從作用域鏈的前端開始,向上逐級查詢與給定名字匹配的標識符。若在該環境中找到了該標識符,則搜索停止,變量就緒。若在該局部環境沒有找到該變量,則繼續沿作用域鏈向上搜索,一直追溯到全局環境的變量對象。若在全局環境中沒有找到該標識符,則說明該變量尚未聲明。

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);

這樣寫的優勢:

1、window和undefined都是為了減少變量查找所經過的scope作用域。當window通過傳遞給閉包內部之后,在閉包內部使用它的時候,可以把它當成一個局部變量,顯然比原先在window scope下查找的時候要快一些。(原來的window處於作用域鏈的最頂端,查找速度慢)

2、在jquery壓縮版本jquery.min.js中可以將局部變量window替換成單個字母,減小文件大小,提高加載速度

3、undefined也是JavaScript中的全局屬性。將undefined作為參數傳遞給閉包,因為沒給它傳遞值,它的值就是undefined,這樣閉包內部在使用它的時候就可以把它當做局部變量使用,從而提高查找速度。undefined並不是JavaScript的保留字或者關鍵字。

4、undefined在某些低版本的瀏覽器(例如IE8、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]

 

以上

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM