用'this`混淆回调 [英] callback with `this` confusion

查看:58
本文介绍了用'this`混淆回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个时钟对象:

var Clock = {
    start: function () {
      $('#btnScrollPause').show();
      $('#btnScrollResume').hide();

      advance();
      this.interval = setInterval(function () {
        advance();
      }, 5000);
    },

    pause: function () {
      $('#btnScrollPause').hide();
      $('#btnScrollResume').show();
      this.reset();
    },

    resume: function () {
      if (!this.interval) {
        this.start();
      }
    },

    reset: function () {
      clearInterval(this.interval);
      delete this.interval;
    }
  };

我有两个按钮可以暂停和恢复元素的自动滚动,但我的困惑在于点击我附加给他们的处理程序。

I have two buttons that pause and resume automatic scrolling of an element, but my confusion is on the click handlers that I've attached to them.

如果我像这样调用暂停函数:

If I call the pause function like this:

// 1
$('#btnScrollPause').click(function () {
  Clock.pause();
});

它可以正常工作,但是如果我尝试减少这样的代码:

It works correctly, however if I try to reduce the code like so:

// 2
$('#btnScrollPause').click(Clock.pause);

它不再有效,我收到错误this.reset未定义。另外,如果我创建一个函数并在click处理程序中使用它:

It no longer works and I get the error "this.reset is not defined". Also, if I make a function and use that in the click handler instead:

// 3
$('#btnScrollPause').click(scrollPause);

function scrollPause() {
  Clock.pause();
}

它有效!有人可以解释为什么1和3有效,但2有没有?

It works! Can someone explain why 1 and 3 work, but 2 doesn't?

推荐答案

this 对象绑定在JavaScript中是易失性的...也就是说,它并不总是指向同一个对象,并且它的绑定可以从一行代码更改为下一行代码。如何调用包含单词的代码确定它将绑定到哪个对象。

The this object binding is volatile in JavaScript...that is, it doesn't always point to the same object and its binding can change from one line of code to the very next. How you invoke the code that contains the word this determines what object it will bind to.

你做了什么时钟的实例(即 var c = new Clock())然后说:

Had you made an instance of Clock (i.e. var c = new Clock()) and then said:

$('#btnScrollPause').click(c.pause);

它会有效,因为这个会是绑定到 c 变量引用的 Clock 的实例。

It would have worked because this would be bound to the instance of the Clock referenced by the c variable.

但是因为它代表你的代码,这个绑定到你的按钮,因为这是启动代码的对象。

But as it stands with your code, this is bound to your button because that is the object that initiated the code.

这是一个清单,你可以按照这个清单知道这个将绑定到...

Here's a checklist that you can follow to know what this will bind to...

如果调用包含的代码:


  1. 作为对象实例的方法或属性(通过实例变量):

  1. As a method or property of an object instance (through an instance variable):

var o = new Object(); 

// "this" will be bound to the "o" object instance
// while "someProperty" and "someMethod" code executes
o.someProperty = someValue;
o.someMethod();


  • 通过 .call() .apply() .bind() Array.prototype.fn 调用:

    // "this" will be bound to the object suppled as the "thisObjectBinding"
    someFunction.call(thisObjectBinding, arg, arg);
    someFunction.apply(thisObjectBinding, [arg, arg]);
    var newFunc = someFunction.bind(thisObjectBinding, arg, arg);
    

    此外,有几个 Array.prototype 方法允许对于要传递的 thisObject ,它将在方法调用的持续时间内改变绑定:

    Additionally, several Array.prototype methods allow for a thisObject to be passed which will alter the binding for the duration of the method call:

    Array.prototype.every( callbackfn [ , thisArg ] )
    Array.prototype.some( callbackfn [ , thisArg ] )
    Array.prototype.forEach( callbackfn [ , thisArg ] )
    Array.prototype.map( callbackfn [ , thisArg ] )
    Array.prototype.filter( callbackfn [ , thisArg ] )
    


  • 如果没有其他方案适用,则会发生默认绑定。

  • If none of the other scenarios apply, Default binding occurs.

    3a。使用use strict undefined

    3b。没有use strict生效:绑定到Global对象

    3b. Without "use strict" in effect: this binds to the Global object

    **注意:绑定也会受到使用 eval的影响( ),但作为一般的最佳做法,应避免使用 eval()

    ** NOTE: this binding can also be affected by using eval(), but as a general best practice, the use of eval() should be avoided.

    这篇关于用'this`混淆回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆