【问题标题】:TypeScript class and JS scope confusion (again)TypeScript 类和 JS 范围混淆(再次)
【发布时间】:2016-09-12 12:28:16
【问题描述】:

我认为 JS 范围再也不会让我感到惊讶了,但现在我们来了。

我正在使用这个little JQuery plugin for observer like pattern。 这就是我如何订阅取消订阅自定义事件的处理程序(监听器)

$.observer.subscribe('my-event', this.myHandler);
$.observer.unsubscribe('my-event', this.myHandler);

public myHandler() {
    console.log("hello World", this);
}

问题是,如果我使用类方法作为回调 (this.myHandler),则该方法将不会在类范围内而是在观察者对象范围内被调用。

当我像这样使用 JQuery 的代理方法时:

$.observer.subscribe('my-event', $.proxy(this.myHandler, this));
$.observer.unsubscribe('my-event', $.proxy(this.myHandler, this));

处理程序中的范围是正确的,但取消订阅方法停止工作,显然使用代理我正在取消订阅其他东西,而不是处理程序方法。

我不能使用定义局部变量的旧 JS 技巧并使用它来代替这个,比如

var o = this;
public myHandler() {
    console.log("hello World", o);
}

因为这是一个 typescript 类,而 var 有不同的含义。

我该怎么办?

【问题讨论】:

  • 不是this - 没有双关语 - 重复吗?在这种特殊情况下,我会使用一个临时变量来存储$.proxy 调用的结果。
  • @raina77ow 箭头函数和 &.proxy 方法有同样的问题,取消订阅不起作用 - 我不明白为什么。
  • @raina77ow 对不起,你是对的,我只是在我的代码中做错了

标签: javascript typescript this


【解决方案1】:

发生这种情况的原因是因为$.proxy(this.myHandler, this) 在您每次调用它时都会返回一个新函数。为了使unsubscribe 工作,您需要将您传递给subscribe 的函数传递给它(几乎所有侦听器接口都是这种情况,包括DOM 接口)。

const handler = $.proxy(this.myHandler, this);
$.observer.subscribe('my-event', handler);
$.observer.unsubscribe('my-event', handler);

或者,您可以在构造函数中将方法创建为箭头函数属性,或者自动绑定它:

class YourClass {
  constructor() {
    this.myHandler = () => {};
    // or
    this.myHandler = this.myHandler.bind(this);
  }
}

然后您可以将this.myHandler 传递给observer.subscribe,它会做正确的事情。

【讨论】:

    【解决方案2】:

    应该将处理程序声明为属性:

    //public myHandler() {
    public myHandler = () => {
        console.log("hello World", this);
    }
    

    这有一个副作用...myHandler 是属性,不能被覆盖。但是我们可以在我们的处理程序中调用另一个方法 (toBeOverriddenHandler),它具有适当的范围 (this) 并且可以被覆盖

    public myHandler = () => {
        this.toBeOverriddenHandler()
    }
    
    // could be changed in subtypes
    protected toBeOverriddenHandler () {
        console.log("hello World", this);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-22
      • 1970-01-01
      • 2020-02-16
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-01
      相关资源
      最近更新 更多