你不知道的javascript上卷總結(2)

一咻發表於2019-01-13

上一篇文章地址

詞法作用域後續

舉書上的例子
function foo(a){
    var b = a * 2;
    function bar(c){
        console.log(a,b,c);
    }
    bar(b*3);
}
foo(2);
複製程式碼

我在這裡把書中的例子再囉嗦一遍hhh

你不知道的javascript上卷總結(2)

2.2中主要講了開發者如何欺騙詞法

欺騙詞法主要有兩種途徑,在這裡提及一下,不做大篇幅的說明,作者也有說盡量避免使用

  • eval()
  • with

大家知道一下就可以啦,在這裡把作者不推薦使用的原因大概羅列一下把。

  • eval()和with會被嚴格模式所影響(限制)。
  • 這兩個機制的副作用是引擎無法在編譯時對作用域查詢進行優化,因為引擎只能謹慎的認為這樣的優化是無效的。使用者其中任何一個機制都將導致程式碼執行變慢。不要使用它們。

好啦第二者完結^_^,棒棒的。開啟第三章的總結

第三章 , 函式作用域和塊作用域

3.1函式中的作用域

明確概念

函式作用域的含義是指,屬於這個函式的全部變數都可以在整個函式的範圍內使用及複用(事實上在巢狀的作用域中也可以使用)。這種方案是非常有用的,能充分利用javascript變數可以根據需要改變值型別的**"動態"**特徵

3.2 隱藏在內部的實現

這裡著重說一下規避衝突

function foo(){
    function bar(a){
        i = 3;    //for迴圈的時候會修改所屬作用域中的 i
        console.log(a+i)
    }
    for(var i = 0;i<10;i++){
        bar(i*2)  //程式碼執行到這裡的時候就會將i賦值為3,從而導致無線迴圈
    }
}
複製程式碼

變數衝突常見的就是存在於全域性作用域中,當程式中載入了多個第三方庫時,如果它們沒有妥善的將內部私有的函式或者變數隱藏起來,就會很容易引發衝突,還有就是多人合作開發的時候,儘量將全域性變數都做好註釋,或者少用全域性變數。

類庫的通常做法是暴露出去一個物件

eg:

var Jquery = {
    hide: function(){
        /*doSomething*/
    },
    show: function(){
        /*doSomething*/
    }
}
複製程式碼
3.3函式作用域

我們知道在任何程式碼外面加都可以新增包裝函式,可以將內部的變數和函式定義**“隱藏”**起來,外部作用域無法訪問到包裝函式內部的任何內容。

eg

var a = 100;
var b = 200;
var c = a + b;

//這樣的程式碼我們通常會封裝成為一個功能型的函式
function add(a,b){
    return a + b;
}

//------------------------------------變形---------------------------------------------
(function(a,b){
    return a + b;
})(100,200);

//包裝函式的宣告以(function...而不僅僅是以function...開始,在這裡函式會被當做表示式而不是一個標準的函式宣告來處理。
複製程式碼
3.3.1 匿名和具名
  • 匿名函式
    • 匿名函式在棧記憶體追蹤中不會顯示出有意義的函式名,使得除錯很困難。
    • 對於程式碼的可讀性,有著很重要的作用,一個描述性的名稱可以讓程式碼不言而明。
3.3.2 立即執行函式
var a = 2;
(function(){
    var a = 3;
    console.log(a);  //3
})()
console.log(a)      //2
複製程式碼
3.4 塊級作用域
  • try/catch

非常少有人注意到Javascript的ES3規範中規定try/catch分句會建立一個塊作用域,其中宣告的變數僅在catch作用域內部有效

eg

try {
    undefined();   //執行一個非法操作
}
catch(err){
    console.log(err)  //能夠正常執行
}
console.log(err);     //err not found
複製程式碼
  • let

    • let關鍵字可以將變數繫結到所在的任意作用域中,通常是{....}內部。換句話說,let可以顯示的將作用域用{}清楚的分來,以便於程式的開發,以及維護。

    • let 宣告的變數不會再作用域內產生變數提升,宣告的程式碼在執行之前並不“存在”而非var 宣告的變數會輸出undefined

      eg

      //var 
      {
          console.log(a);  //undefined
          var a = 100;
      }
      // let 
      {
          console.log(a)
          let a = 100;    //ReferenceError!a is not defined
      }
      複製程式碼

好啦,今天先寫到這裡,待後續。。。

相關文章