首页 > 解决方案 > 为什么在实现事件处理模式时 `this` 未定义?

问题描述

我正在创建一个库,我需要实现的模式之一是事件处理。我正在用 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. 这意味着在那一刻,thisforTestClass.onRelayed将绑定到MessageRelayer
  2. 一旦relayMessage被调用,MessageRelayer将获取TestClass.onRelayedthis现在指向的已保存实例MessageRelayer,并执行它。
  3. 我应该得到一个this不包含的错误el

相反,我发现this实际上是undefined. 这里发生了什么?

标签: javascripttypescriptprototype-programming

解决方案


推荐阅读