为什么我的javascript函数不执行?错误:无法读取未定义的属性“更改”

时间:2019-10-06 10:55:35

标签: javascript angular typescript ecmascript-6

看来,如果我仅将User类中的public events: Eventing = new Eventing();重命名为events以外的任何其他名称,它将停止工作。我了解,只要该属性的名称与eventing.ts中的属性名称匹配,它就可以工作。为什么呢这就是我要找出的。

stackblitz

index.ts

import { User } from "./user";
const user = new User();
const on = user.on;

user.on("change", () => {
  alert("yo");
});
user.trigger("change");

user.ts

import { Eventing } from "./eventing";

export interface UserProps {
  id?: number;
  name?: string;
  age?: number;
}
export class User {
  public events: Eventing = new Eventing(); //stops working if renamed to anything other than events
  constructor() {}
  get on() {
    return this.events.on;
  }
  get trigger() {
    return this.events.trigger;
  }
}

eventing.ts

type Callback = () => void;

export class Eventing {
  events: { [key: string]: Callback[] } = {};  

  on(eventName: string, callback: Callback): void {
    const handlers = this.events[eventName] || [];  
    handlers.push(callback);  
    this.events[eventName] = handlers;  
  }

  trigger(eventName: string): void {
    const handlers = this.events[eventName];
    if (!handlers || handlers.length === 0) {
      return;
    }
    handlers.forEach(callback => {
      callback();
    });
  }
}

编辑:

用户类内部的

this指用户类本身。但是由于User类具有一个名为event的属性,它是Eventing类的实例,因此当我尝试执行this.event.on()时必须执行它,对吗?为什么不执行?为什么属性名称必须与Eventing类中的属性名称匹配?

1 个答案:

答案 0 :(得分:1)

之所以会这样,是因为您在这里将user this绑定到ontrigger方法上了:

get on() {
    return this.events.on;
}

get trigger() {
  return this.events.trigger;
}

因此在ontrigger方法中,this将是User的实例,而不是Eventing

您可以在lamba函数中打开ontrigger或仅使用bind这样的方法(例如,要将属性更改为foos):

public foos: Eventing = new Eventing();
get on() {
    return this.events.on.bind(this.foos);
}

get trigger() {
    return this.events.trigger.bind(this.foos);
}