JS基礎-閉包

變量做用域

變量的做用域無非就是兩種:全局變量和局部變量。閉包

函數內部聲明變量的時候,必定要使用var命令。若是不用的話,你實際上聲明瞭一個全局變量!函數

閉包

有權訪問另外一個函數做用域的變量,常見的建立方式就是在一個函數內部建立另外一個函數,經過另外一個函數訪問這個函數的局部變量。性能

簡單的說就是,閉包就是可以讀取其餘函數內部變量的函數this

因爲在Javascript語言中,只有函數內部的子函數才能讀取局部變量,所以能夠把閉包簡單理解成"定義在一個函數內部的函數"。code

MDN中定義的是:對象

閉包是指可以訪問自由變量的函數。換句話說,在閉包中定義的函數能夠「記憶」它被建立的環境。

注:自由變量是既不是在本地聲明又不做爲參數傳遞的一類變量。ip

  • 簡單的例子
function A(){
    function B(){
        console.log("Hello Closure!");
    }
    return B;
}

var b = A();
b();//Hello Closure!

因此經過這個例子能夠簡單理解閉包。內存

* 定義一個函數A()
* A中定義了函數B()
* A中返回B
* 執行A(),把A的返回結果賦值給變量b
* 執行b()

總結一句話:函數A的內部函數B被函數A外的一個變量b引用。因此當一個內部函數被其外部函數以外的變量引用時,就造成了一個閉包資源

閉包的做用

在一個模塊中定義一個變量,但願這個變量保存在內存中又不會污染全局變量,就用閉包來定義這個模板。作用域

它的最大用處有兩個,一個是前面提到的能夠讀取函數內部的變量,另外一個就是讓這些變量的值始終保持在內存中。

閉包的注意點

  • 閉包優勢,也是缺點,局部變量駐留在內存中,能夠迴避使用全局變量,但因爲閉包裏的資源不會被馬上銷燬回收,因此可能佔用更多的內存,過分使用閉包會致使性能降低。
  • 閉包會在父函數外部,改變父函數內部變量的值。因此,若是你把父函數看成對象(object)使用,把閉包看成它的公用方法(Public Method),把內部變量看成它的私有屬性(private value),這時必定要當心,不要隨便改變父函數內部變量的值。

注意:可使用以後,給它加null,接觸引用。

舉例

例子1:

var name = "The Window"; // 全局
var object = {    
    name: "My Object", // 局部
    getNameFunc: function () { // 對象中的方法,this指向obj這個對象      
        return function () { // 閉包       
            return this.name; // this指向window    
        };     
    } 
};
     
alert(object.getNameFunc()()); // The Window

例子2:

var name = "The Window"; // 全局
var object = {    
    name: "My Object", // 局部
    getNameFunc: function () { // 對象中的方法,this指向obj這個對象 
        var that = this; // 將getNameFunc()的this保存在that變量中      
        return function () { // 閉包   
            return that.name; // that指向object    
        };     
    } 
};
     
alert(object.getNameFunc()()); // My Object

例子3:

var name = "The Window"; // 全局
var object = {    
    name: "My Object", // 局部
    getNameFunc: function () {   
        return function () { // 閉包   
            var that = this;  
            return that.name;     
        };     
    } 
};
     
alert(object.getNameFunc()()); // The Window

例子4:

var name = "The Window"; // 全局
var object = {    
    name: "My Object", // 局部
    getNameFunc: function () { // 對象中的方法,this指向obj這個對象      
        return function () { // 閉包   
            var that = this; // 將getNameFunc()的this保存在that變量中 
            return that.name; // this指向window    
        };     
    } 
};
     
alert(object.getNameFunc().call(object)); // My Object call改變this指向
相關文章
相關標籤/搜索