为什么在实现事件处理模式时未定义`this`?

时间:2020-07-26 21:05:56

标签: javascript typescript prototype-programming

我正在创建一个库,我需要实现的模式之一是事件处理。我正在用TypeScript编写,但是这个问题基本上是Javascript。考虑以下代码:

class MessageRelayer {
    private readonly listeners: Array<(args: string) => void> = [];

    public addListener(listener: (args: string) => void): void {
        this.listeners.push(listener);
    }

    public relayMessage(msg: string): void {
        for (const listener of this.listeners) listener(msg);
    }
}

class TestClass {
    private el: string;

    constructor(private readonly relay: MessageRelayer) {
        this.el = "example";
    }

    public initialize(): void {
        this.relay.addListener(this.onRelayed);
    }

    private onRelayed(e: string): void {
        console.log("EL is:", this.el);
    }
}

const relay = new MessageRelayer();
const stuff = new TestClass(relay);
stuff.initialize();

relay.relayMessage("Hello world"); // Error here

运行此代码时,它在onRelayed中给我错误:

无法读取未定义的属性“ el”

如果initialize的写法是:

public initialize(): void {
    this.relay.addListener((e: string) => { console.log("EL is:", this.el); });
}

有效。

问题

我了解这与著名的this绑定问题有关。但是发生的事情我无法在这里解释。我认为应该发生的是:

  1. 调用initialize()时,功能TestClass.onRelayed传递给MessageRelayer。这意味着在那一刻,this的{​​{1}}将绑定到TestClass.onRelayed
  2. 一旦调用MessageRelayerrelayMessage将获取MessageRelayer的保存实例,该实例的TestClass.onRelayed现在指向this,并执行该实例。
  3. 我应该得到一个错误,提示MessageRelayer不包含this

相反,我发现el实际上是this。这是怎么回事?

0 个答案:

没有答案