Почему моя функция JavaScript не выполняется? Ошибка: невозможно прочитать свойство 'change' из неопределенного - PullRequest
2 голосов
/ 06 октября 2019

Похоже, что если я просто переименую public events: Eventing = new Eventing(); в своем классе User во что-либо, кроме 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 Ответ

1 голос
/ 06 октября 2019

Это происходит потому, что вы привязываете user this к on и trigger методам здесь:

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

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

Так что внутри on и trigger методов this будетбыть экземпляром User, а не Eventing.

Вы можете включить on и trigger в функции lamba или просто 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...