JavaScript 和 jQuery,“this”在匿名函数中

JavaScript and jQuery, "this" inside an anonymos function

本文关键字:函数 this jQuery JavaScript      更新时间:2023-09-26

我有这个代码:

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);
          ...
    }
}

它按预期工作。

问题是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);
        }
}

我知道问题在于闭包没有将this作为实例的值,但据我所知,在没有绑定实例的函数中对this的引用必须引用窗口对象,而不是undefined,至少在许多浏览器上都是这种情况。

那么我的代码到底发生了什么。

注意:我正在使用jQuery,并且已经定义了this.elements

编辑:现在我弄清楚$.each是一个非实例函数,所以我的回调是从$.each调用的,但它必须windowthis的引用,仍在考虑它。

根据 jQuery 文档 for $.each

[当前元素]的值也可以通过this关键字访问...

在 JavaScript 中,当您将回调函数交给高阶函数(在本例中为 $.each(时,高阶函数可以决定回调运行时this的值。您无法控制此行为 - 只需不要使用this(例如,在您的示例中使用像instance这样的引用或通过闭包(。

查看上下文设置函数Function.callFunction.apply,以了解像$.each这样的高阶函数如何设置回调的this上下文。 一旦你阅读了这些MDN页面,它可能会清除一些事情。

下面是一个快速示例:

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

并使用它:

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

我的示例Array.forEachWithContext类似于Array.forEach。 但是,它需要一个回调第二个参数,该参数在执行每个回调期间用作this的值。

尝试用这样的$.proxy包装您的$.each函数...

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

$.proxy将确保this引用您的PageList...

我知道问题在于闭包没有将其作为实例的值,但据我所知,在没有绑定实例的函数中对此的引用必须引用窗口对象,而不是未定义,至少在许多浏览器上都是这种情况。

this window.您正在打印未定义的window.url。尝试console.log(this),它应该会产生window