开发者

Closure - when a new closure is created what happens to the existing one?

document.getElementById("innbutt").onclick = (function(){
    var newvar = "hello"; 
    return function(){
        alert(newvar);
    }
})();

When we keep clicking innbutt, new closures keeps on getting created.

So, what happens to the old ones?

1) Does it get deleted? OR

2) Does it stays in memory?

Edit:

function addLinks () {
    for (var i=0, link; i<5; i++) {
        link = document.cr开发者_如何学CeateElement("a");
        link.innerHTML = "Link " + i;
        link.onclick = function (num) {
            return function () {
                alert(num);
            };
        }(i);
        document.body.appendChild(link);
    }
}
window.onload = addLinks;

Source: javascript scope and closures

In this case for the link.onclick handler only 1 closure is created?


Only one closure gets created

Because you misunderstood the concept of event handler.

document.getElementById("innbutt").onclick = (function(){
    var newvar = "hello"; 
    return function(){
        alert(newvar);
    }
})();

is arguably equivalent to:

document.getElementById("innbutt").onclick = function() {
    alert("hello");
};

Because in the first case the immediately executing function returns anonymous with alert and that gets assigned to the onclick handler. Whenever you click on your button, this particular anonymous function gets executed. No new onclick handler assignment gets processed as you falsely think.


The first thing to note is the fact that the original closure which contains the definition of newvar is not being recreated every time you click on innbutt. It was executed one time and the namespace within that closure exists until you remove all references to the inner function which does an alert. So to answer your 1st question, the closure does not get deleted. To answer your second question, the namespace within the closure remains until you remove all references to the function that was assigned to the onclick of innbutt. In other words, if you set that onclick to null, the closure will no longer stay in memory unless, prior to that point, you assign that function to another variable.

Here is an example analogous to your example. This example has a closure which is executed immediately and then returns a function that has access to the namespace of that persistent closure:

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;

Notice that the secrets function is actually the function that was returned inside of the closure. In addition, this function has access to mySecrets which is a variable within the closure. Since I wrote fnSecrets to alias secrets, once I nulled out secrets, the closure still existed until fnSecrets was nulled out.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜