2015-05-03 45 views
1

當我正在學習創建對象的方法時,我發現了持久構造函數模式,它依賴於閉包和創建私有變量的方式。閉包如何訪問析構變量?

所以例如:

function Person(name, age, job){ 
    var o = new Object(); 

    o.sayName = function(){ 
    alert(name); 
    }; 

    return o; 
} 
var m = new Person('joe',20, 'anything'); 
m.sayName(); // 'joe' 

name是隻能由m.sayName訪問私有變量。

另外我知道當函數完成執行時垃圾收集器會執行內存清除操作,因此所有局部變量都將被釋放。

所以我的問題是如何m.sayName可以訪問name而其內存已被釋放後,構造函數完成執行。

回答

2

不,垃圾回收器只會清除未被引用的變量。

封閉將sayName函數的引用添加到Person的執行上下文中,該引用是範圍引用name

只要引用sayName,此引用就會保持活動狀態。直到您釋放m(或直接m.sayName),該變量纔會被清空。

閉包必須被看作是從函數到其創建範圍的引用(這也是爲什麼閉包經常被指向爲JavaScript中內存泄漏的常見原因之一)。這個引用使得可以從內部函數訪問創建範圍的變量(它們不是副本,這意味着兩個內部函數共享相同的變量)。

對代碼封閉的引用對您的代碼是隱藏的,但您可以使用開發人員工具查看它。下面是我所看到的,如果我在Chrome瀏覽器執行console.dir(m)

enter image description here

+0

這意味着,'sayName'有'name'參考? –

+0

@OmarElawady是的,是間接的。它對包含'name'的作用域有一個隱藏的引用。 –

+0

所以只需在函數中附加一個變量的名稱就可以創建對它的引用? –