[JS]《你不知道的Javascript·上》——函數做用域和塊做用域

函數做用域

爲了隱藏內部實現,能夠經過在任意代碼片斷外部添加包裝函數,可是這並不理想,由於必須聲明一個具名函數,意味着這個函數名稱自己會污染函數所在的做用域;同時必須經過顯式地調用函數才能運行其中的代碼。函數

*:區分函數聲明和表達式最簡單的方法是看function關鍵字出如今聲明中的位置。若是function是聲明中的第一個詞,那麼就是一個函數聲明,不然就是一個函數表達式。code

JS提供了同時解決這兩個問題的方案:作用域

var a=2;
(function foo(){
    var a=3;
    console.log(a);//3
})();

console.log(a);//2

以上這種模式稱爲當即執行函數表達式(IIFE)。io

有一個改進的形式:console

var a=2;
(function foo(){
    var a=3;
    console.log(a);//3
}());//調用的括號包含在用來包裝的()裏

console.log(a);//2

兩種形式在功能上是一致的。function

IIFE有一個進階用法:把它們看成函數調用並傳遞參數進去。進階

var a=2;
(function IIFE(global){
    var a=3;
    console.log(a);//3
    console.log(global.a);//2
})(window);

console.log(a);//2

IIFE還有一種變化的用途是倒置代碼的運行順序,將須要運行的函數放在第二位。循環

var a=2;
(function IIFE(def){
    def(window);
})(funtion def(global){
    var a=3;
    console.log(a);//3
    console.log(global.a);//2
})

塊做用域

let

只要聲明是有效的,在聲明中的任意位置均可以使用{...}括號來爲let建立一個用於綁定的塊。方法

var foo=true;
if(foo){
    {//顯式的塊
        let bar=foo*2;
        console.log(bar);//2
    }
     console.log(bar);//ReferenceError
}
console.log(bar);//ReferenceError

**:let循環:for的循環頭部使用let,不只將i綁定到for的塊中,事實上它將其從新綁定到了循環的每一個迭代中,確保使用上一個循環迭代結束時的值從新進行賦值。co

*:塊做用域不該該徹底做爲函數做用域的替代方案,兩種功能應該同時存在。

相關文章
相關標籤/搜索