闭包如何访问被破坏的变量?
How can closures access destructed variables?
当我学习创建对象的方法时,我发现了 持久构造函数模式,它依赖于闭包和创建私有变量的方法。
例如:
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
而其内存在构造函数执行完毕后已被释放。
不,垃圾收集器只清理未被引用的变量。
闭包将 sayName
函数的引用添加到 Person
的执行上下文,这是引用 name
.
的范围
只要 sayName
被引用,该引用就会一直存在。在您释放 m
(或直接 m.sayName
)之前,该变量不会被垃圾处理。
闭包必须被视为从函数到创建它的范围的引用(这也是为什么闭包经常被指出是 JavaScript 中内存泄漏的常见原因之一)。该引用使得从内部函数访问创建作用域的变量成为可能(它们不是副本,这意味着两个内部函数共享相同的变量)。
对闭包作用域的引用在您的代码中是隐藏的,但您可以使用开发人员工具查看它。这是我在 Chrome 中执行 console.dir(m)
时看到的内容:
当我学习创建对象的方法时,我发现了 持久构造函数模式,它依赖于闭包和创建私有变量的方法。
例如:
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
而其内存在构造函数执行完毕后已被释放。
不,垃圾收集器只清理未被引用的变量。
闭包将 sayName
函数的引用添加到 Person
的执行上下文,这是引用 name
.
只要 sayName
被引用,该引用就会一直存在。在您释放 m
(或直接 m.sayName
)之前,该变量不会被垃圾处理。
闭包必须被视为从函数到创建它的范围的引用(这也是为什么闭包经常被指出是 JavaScript 中内存泄漏的常见原因之一)。该引用使得从内部函数访问创建作用域的变量成为可能(它们不是副本,这意味着两个内部函数共享相同的变量)。
对闭包作用域的引用在您的代码中是隐藏的,但您可以使用开发人员工具查看它。这是我在 Chrome 中执行 console.dir(m)
时看到的内容: