简体   繁体   English

JavaScript和jQuery,anonymos函数中的“ this”

[英]JavaScript and jQuery, “this” inside an anonymos function

I have this code: 我有以下代码:

PageList: function(url, index, classes){
    this.url = url;
    this.index = index;
    ...
};

PageList.prototype.toHTML = function(){
    var div = $('<div class="container"></div>');
    var p = $('<p></p>');
    var link = $('<a></a>');
    $.each(this.elements, function(index, array_value){
          console.log(this.url);
          ...
    }
}

And it worked as expected. 它按预期工作。

The problem was that console.log(this.url) was printing undefined , so I reworked the code to look like this: 问题是console.log(this.url)正在打印undefined ,所以我重新编写了代码,使其看起来像这样:

PageList.prototype.toHTML = function(){
    var div = $('<div class="container"></div>');
    var p = $('<p></p>');
    var link = $('<a></a>');
    var instance = this;
    $.each(this.elements, function(index, array_value){
               console.log(instance.url);
        }
}

I know that the problem was on the closure not taking this as the value of the instance, but as far as i know a reference to this inside a function that doesn't have an instance bound to it must refer to the window object, instead of undefined , at least that's the case on many of the browsers out there. 我知道问题出在闭包上,而不是将this作为实例的值,但是据我所知,在没有绑定实例的函数内部, this的引用必须引用window对象,而不是的undefined ,至少在许多浏览器中都是这种情况。

So what exactly is going on on my code. 那么我的代码到底发生了什么。

Note: I'm using jQuery and this.elements is already defined. 注意:我正在使用jQuery,并且this.elements已经定义。

Edit: Now im figuring out that $.each is a non-instance function, so my callback is being called from $.each but it must be window the reference to this , still thinking about it. 编辑:现在我想知道$.each是一个非实例函数,所以我的回调函数是从$.each调用的,但它必须是对this的引用的window ,仍然在思考它。

According to the jQuery docs for $.each : 根据$.eachjQuery文档

The value [of the current element] can also be accessed through the this keyword... [当前元素的]值也可以通过this关键字来访问...

In JavaScript, when you hand off a callback function to a higher-order function (in this case, $.each ), the higher-order function can decide what the value of this will be when the callback runs. 在JavaScript中,当你手头宽裕的回调函数的高阶函数 (在这种情况下, $.each ),高阶函数可以决定的价值来决定this回调运行时会。 There is no way for you to control this behavior -- simply don't use this (eg, by using a reference like instance in your example or via a closure). 您无法控制这种行为-根本就不要使用this (例如,通过在示例中使用类似instance的引用或通过闭包)。

Check out the context-setting functions Function.call and Function.apply to understand how a higher-order function like $.each sets the this context of a callback. 查看上下文设置函数Function.callFunction.apply以了解像$.each这样的高阶函数如何设置回调的this上下文。 Once you read those MDN pages, it might clear a few things up. 阅读这些MDN页面后,可能会清除一些内容。

Here's a quick example: 这是一个简单的示例:

Array.prototype.forEachWithContext(callback, this_in_callback) {
    for(var i = 0; i < this.length; ++i) {
        callback.call(this_in_callback, i, this[i]);
    }
}

And to use it: 并使用它:

PageList.prototype.toHTML = function(){
    //...
    this.elements.forEachWithCallback(function(index, array_value){ ... }, this);
}

My example Array.forEachWithContext is similar to Array.forEach . 我的示例Array.forEachWithContextArray.forEach类似。 However, it takes a callback and a second argument that is used as the value of this during the execution each of those callbacks. 然而,它需要一个回调被用作值的第二个参数this执行过程中每个这些回调。

Try wrapping your $.each function with a $.proxy like this... 尝试像这样用$.proxy包装$.each函数...

$.each(this.elements, $.proxy(function(index, array_value){
    console.log(this.url);
},this));

The $.proxy will ensure that this references your PageList ... $.proxy将确保this引用您的PageList ...

I know that the problem was on the closure not taking this as the value of the instance, but as far as i know a reference to this inside a function that doesn't have an instance bound to it must refer to the window object, instead of undefined, at least that's the case on many of the browsers out there. 我知道问题出在闭包上,而不是将其作为实例的值,但是据我所知,在没有绑定实例的函数内部,对此的引用必须引用window对象,而不是的不确定性,至少在许多浏览器中都是这种情况。

this is window . this window You're printing window.url , which is undefined. 您正在打印window.url ,这是未定义的。 Try console.log(this) , and it should yield window . 尝试console.log(this) ,它应该产生window

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

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