简体   繁体   English

“这个”如何在关闭中起作用?

[英]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? 为什么el.onclick = clickHandler的代码el.onclick = clickHandler创建闭包? clickHandler 's this has to be fulfilled with el . clickHandlerthis必须用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. 另请注意,此问题似乎只会影响IE的JS引擎。 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. 其他引擎,如V8 / Chrome,似乎只捕获闭包中内部函数中使用的变量,所以我希望在这个代码示例中不会创建循环引用,即使它们应该能够使用循环引用处理垃圾收集。

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

clickHandler 's this has to be fulfilled with el . clickHandlerthis必须用el来实现。

No, it doesn't. 不,它没有。 If you were to use a closure, the you could use el instead of using this . 如果你要使用一个闭包,你可以使用el而不是使用this

The value of this is determined by how a function is called . this是通过一个函数是如何被调用来确定。 The closure in the original code serves no purpose. 原始代码中的闭包没有任何意义。 When an event handler is fired on an element, this will be the element. 在元素上触发事件处理程序时, this将是元素。

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. 问题不在于对'this'的闭包引用,如果你在外部作用域中有变量的话。 So if you use a var el = ... variable, that will create a closure in IE. 因此,如果您使用var el = ...变量,那将在IE中创建一个闭包。 But in your first snipet you don't use a variable, so you're good to go. 但是在你的第一个snipet你没有使用变量,所以你很高兴。

As they say on mdn: "There are a number of workarounds for this problem. The simplest is not to use the el variable." 正如他们在mdn上所说:“这个问题有很多变通方法。最简单的就是不使用el变量。”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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