简体   繁体   English

在此示例中,jQuery对“ this”做了什么?

[英]What is jQuery doing to “this” in this example?

I know that a jQuery event handler usually binds this to the object that emitted the event. 我知道jQuery事件处理程序通常this绑定到发出事件的对象。 And I also know that in vanilla JS, this is the object that invoked the function. 而且我也知道在香草JS中, this是调用函数的对象。

However, I'm having trouble making sense of why the following code works. 但是,我很难理解以下代码为何起作用。 this appears to reference the tour object defined in the code, yet going by the jQuery event handler binding, this should be the clicked button or going by JS, it should be the $("#tour") object since it invoked on. this似乎引用tour中的代码定义的对象,通过jQuery的事件处理程序结合还不打算, this应该是点击按钮或JS去,它应该是$("#tour")的对象,因为它调用上。

Where am I going wrong? 我要去哪里错了?

var tour = {
  init: function() {
    $("#tour").on("click", "button", this.fetchPhotos);
  },

  fetchPhotos: function() { 
    $.ajax('/photos.html', {
      data: {location: $("#tour").data('location')},
      success: function(response) {
        $('.photos').html(response).fadeIn();
      },
      error: function() {
        $('.photos').html('<li>There was a problem fetching the latest photos. Please try again.</li>');
      },
      timeout: 3000,
      beforeSend: function() {
        $('#tour').addClass('is-fetching');
      },
      complete: function() {
        $('#tour').removeClass('is-fetching');
      }
    });
  }
}

$(document).ready(function() { 
  tour.init();
});

The only use of this in that code is: 唯一使用this在代码是:

$("#tour").on("click", "button", this.fetchPhotos);

It is used in the following function: 它用于以下功能:

  init: function() {
    $("#tour").on("click", "button", this.fetchPhotos);
  },

How that function is called will determine the value of this . 该函数的调用方式将确定this的值。 It is called like this: 它的名称如下:

$(document).ready(function() { 
  tour.init();
});

So this is tour . 所以thistour


yet going by the jQuery event handler binding, this should be the clicked button 尚未经过jQuery事件处理程序绑定,这应该是clicked按钮

No. this isn't used inside the event handler function. 不。在事件处理函数中未使用this函数。 It is used to get a reference to the function that is passed as an argument and eventually used as that function. 它用于获取对该函数的引用,该引用作为参数传递并最终用作该函数。

or going by JS, it should be the $("#tour") object since it invoked on. 或通过JS调用,它应该是$(“#tour”)对象,因为它被调用了。

No. It isn't used inside the on function, it is used to get a reference to the function that is passed as an argument to that function. 不。它不在on函数内部使用,它用于获取对该函数的引用,该引用作为该函数的参数传递。

function a(argument) {
    this; // Value depends on how a is called
}

function b(argument) {
    a(this); // Value depends on how b is called
}

fetchPhotos (the event handler function) doesn't use this at all, but if it did, it would be the object on which the event fired (since that is how jQuery.on would bind it). fetchPhotos (事件处理函数)根本不使用this ,但是如果使用了它,它将是触发事件的对象(因为jQuery.on会绑定该对象)。

The functions invoked are tour.init and tour.fetchPhotos . 调用的函数是tour.inittour.fetchPhotos


tour.init is invoked on this line: 在此行上调用tour.init

tour.init();

so inside its body, this will point to tour (meaning that this.fetchPhotos will be tour.fetchPhotos ). 因此在其主体内, this将指向游览(这意味着this.fetchPhotos将是tour.fetchPhotos )。


tour.fetchPhotos is invoked by the jQuery event system, when the button is clicked. 单击按钮时,jQuery事件系统将调用tour.fetchPhotos Inside its body, this will point to #tour , the HTMLElement that fired the event. 在其主体内, this将指向#tour事件的HTMLElement #tour You can log it to make sure: 您可以登录以确保:

fetchPhotos: function() { console.log(this) }

I'm not certain whats being asked here. 我不确定在这里问什么。 But I assume you're calling 但是我想你是在打电话

tour.init();

which makes this a reference to your tour object, within the execution context of init() . 这使得this对你的一个参考tour对象,的执行上下文内init() Thats why you can reference this.fetchPhoto within there and passing over the function reference to .on . 这就是为什么您可以在其中引用this.fetchPhoto并将函数引用传递给.on

Within the event handler , this will be a reference to the node with the id of #tour . 事件处理程序中this 将是对ID为#tour的节点的#tour

Your confusion is understandable. 您的困惑是可以理解的。 When you do 当你做

$("#tour").on("click", "button", function() {
 // inner scope
});

The inner scope this will refer to the invoked objected, because the third parameter, the annonymous function, will be run on that. 内范围this将是指被调用的反对,因为第三参数,所述annonymous功能,将该运行。

In your example, however, this.fetchPhotos isn't being run on an anonymous function, instead it's the function itself. 但是,在您的示例中, this.fetchPhotos不是匿名函数上运行,而是函数本身。 So this.fetchPhotos refers to the function tour.fetchPhotos . 因此this.fetchPhotos引用了tour.fetchPhotos函数。

fetchPhotos: function() { 
  // inner scope
});

Inside the inner scope here, however, this will refer to the invoked object again. 但是,在此内部作用域内, this将再次引用被调用的对象。

Had you instead done: 如果您改为:

$("#tour").on("click", "button", function() {
  this.fetchPhotos();
});

Then you would run into trouble as this would no longer be referring to the tour object, but instead the object that triggered the event, ie the DOM element with ID tour . 然后,你会遇到麻烦,因为this将不再是指tour对象,而是触发事件的对象,即具有ID的DOM元素tour

By default, this refers to the object which owns the method : 默认情况下, this是指拥有方法的对象:

var o = {};
o.m = function () {
    return this;
};
o.m(); // returns o
// since "return this" equals "return o"

But you can "redirect" this to another object like so : 但是你可以“重定向” this对像这样另一个对象:

var p = {};
o.m.call(p); // returns p
// since "return this" equals "return p"

Getting closer to your own scenario : 接近您自己的情况:

p.n = function (fn) {
    return fn.call(this);
};
p.n(o.m); // returns p
// since "return fn.call(this)" equals "return o.m.call(p)"

A bit twisted : 有点扭曲:

p.n.call(o, o.m); // returns o
// since "return fn.call(this)" equals "return o.m.call(o)"

Concretely, when you write tour.init() , this line : 具体来说,当您编写tour.init() ,此行:

$('#tour').on('click', 'button', this.fetchPhotos);
                                 ^

Is the same as this line : 与此行相同:

$('#tour').on('click', 'button', tour.fetchPhotos);
                                 ^

Then (very (very!) roughly), #tour is bound to fetchPhotos by jQuery through the call function, which will result in something like fetchPhotos.call($('#tour')[0]) . 然后(非常非常(非常!)),jQuery通过call函数将#tour绑定到fetchPhotos ,这将导致类似fetchPhotos.call($('#tour')[0])事情。

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

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