简体   繁体   中英

How does 'this" work in closure?

I got to this document which says there is a closure happening here:

function addHandler(){
    document.getElementById('el').onclick = function(){
        this.style.backgroundColor = 'red';
    };
}

While this code removes the closure:

function addHandler() {
    var clickHandler = function() {
        this.style.backgroundColor = 'red';
    };
    (function() {
        var el = document.getElementById('el');
        el.onclick = clickHandler;
    })();
}

I can't see how the second one solves the closure issue. Why would not the code at el.onclick = clickHandler create a closure? clickHandler 's this has to be fulfilled with el .

Your example is not correct. The document you have linked to states that this code block creates a closure which may leak memory (note the variable in the outer function):

function addHandler() {
    var el = document.getElementById('el');
    el.onclick = function() {
        this.style.backgroundColor = 'red';
    };
}

Both examples you posted do not create a closure (or only an empty one), but they use different means to avoid it.

Also note that this problem seems to affect IE's JS engine only. Other engines, auch as V8 / Chrome, seem to only capture the variables used in inner functions in closures, so that I'd expect that no circular reference would be created in this code example, and even if it would they should be able to handle the garbage collection with the circular reference.

I can't see how the second one solves the closure issue.

It doesn't. You still have a closure. None of the closed over variables are used in it though.

You could rewrite it to avoid using a closure like so:

var clickHandler = function() {
    this.style.backgroundColor = 'red';
};
function addHandler() {
    var el = document.getElementById('el');
    el.onclick = clickHandler;
}

You could, in addition, change clickHandler to be created with a function declaration instead of a function expression.

clickHandler 's this has to be fulfilled with el .

No, it doesn't. If you were to use a closure, the you could use el instead of using this .

The value of this is determined by how a function is called . The closure in the original code serves no purpose. When an event handler is fired on an element, this will be the element.

I don't think you read the documentation you refer to correctly. The issue isn't with a closure reference to 'this', it's if you have variables in the outer scope. So if you use a var el = ... variable, that will create a closure in IE. But in your first snipet you don't use a variable, so you're good to go.

As they say on mdn: "There are a number of workarounds for this problem. The simplest is not to use the el variable."

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM