document.getElementById("innbutt").onclick = (function(){
var newvar = "hello";
return function(){
alert(newvar);
}
})();
当我们一直点击innbutt
时,新的闭包会不断创建。
那么,旧的会发生什么?
1)它被删除了吗? OR
2)它是否留在记忆中?
修改:
function addLinks () {
for (var i=0, link; i<5; i++) {
link = document.createElement("a");
link.innerHTML = "Link " + i;
link.onclick = function (num) {
return function () {
alert(num);
};
}(i);
document.body.appendChild(link);
}
}
window.onload = addLinks;
来源:javascript scope and closures
在这种情况下,link.onclick
处理程序只创建了一个闭包?
答案 0 :(得分:4)
因为你误解了事件处理程序的概念。
document.getElementById("innbutt").onclick = (function(){
var newvar = "hello";
return function(){
alert(newvar);
}
})();
可以说相当于:
document.getElementById("innbutt").onclick = function() {
alert("hello");
};
因为在第一种情况下,立即执行的函数返回匿名alert
并且被分配给onclick
处理程序。每当您单击按钮时,都会执行此特定的匿名函数。在您错误地思考时,不会处理新的onclick
处理程序分配。
答案 1 :(得分:2)
首先要注意的是,每次单击innbutt时都不会重新创建包含newvar定义的原始闭包。它执行了一次,并且该闭包内的命名空间一直存在,直到您删除对执行警报的内部函数的所有引用。所以要回答你的第一个问题,关闭不会被删除。要回答第二个问题,闭包内的命名空间将一直保留,直到您删除对分配给innbutt onclick的函数的所有引用。换句话说,如果将onclick设置为null,则闭包将不再保留在内存中,除非在此之前将该函数分配给另一个变量。
这是一个类似于你的例子的例子。这个例子有一个闭包,它立即执行,然后返回一个有权访问该持久性闭包的命名空间的函数:
secrets = (function() {
var mySecrets = {};
return function(name, value) {
if(arguments.length < 2)
return mySecrets[name + ""];
mySecrets[name + ""] = value;
};
})();
// Set my name.
secrets("my name", "Chris West");
// Set my friend's name.
secrets("my friend's name", "John Jacob");
// Get my name and my friend's name.
alert("My name is " + secrets("my name") + ".\n"
+ "My friend's name is " + secrets("my friend's name") + ".");
// Alias the secrets function.
fnSecrets = secrets;
// Remove one reference to the secrets function.
secrets = null;
// Remove the second reference to eliminate the closure from memory.
fnSecrets = null;
请注意,secrets函数实际上是在闭包内返回的函数。此外,此函数可以访问mySecrets,它是闭包内的变量。自从我写了fnSecrets到别名的秘密后,一旦我搞清楚了秘密,关闭仍然存在,直到fnSecrets被淘汰。