你如何在 JavaScript (ES6) class 上执行自定义事件?

How do you do custom events on a JavaScript (ES6) class?

当我在 JavaScript 类 上搜索自定义事件时,我得到了很多旧的或不完整的结果。 MDN shows a custom event off of a dom element. Whosebug's 最高结果已有近 10 年历史,它使用 ES6 之前的语法。

有没有办法做类似的事情:

class Dog
{
  constructor(name)
  {
    this.name = name;
  }
  
  //something to expose bark event
  
}

const buddy = new Dog('buddy');
buddy.addEventListener("bark", function(e) {
  console.log(`${this.name} barked!`);
});

没有 class 的事件。你可以实现一些注册函数的东西,你可以在方法被触发时调用它们。基本思路:

class Animal {
  #registered = {};
  
  constructor(name)
  {
    this.name = name;
  }  
  
  addEventListener(name, callback) {
    if (!this.#registered[name]) this.#registered[name] = [];
    this.#registered[name].push(callback);
  }
  triggerEvent(name, args) {
     this.#registered[name]?.forEach(fnc => fnc.apply(this, args));
  }
}


class Dog extends Animal
{
  constructor(name)
  {
    super(name);
  }
  
  bark(){
    console.log('bark was called');
    this.triggerEvent('bark');
  }

  eat(what){
    console.log('eat was called', what);
    this.triggerEvent('eat', [what]);
  }

}

const buddy = new Dog('buddy');
buddy.addEventListener("bark", function() {
  console.log(`${this.name} barked!`);
});
buddy.addEventListener("eat", function(item) {
  console.log(`${this.name} ate a ${item}!`);
});
buddy.bark();
buddy.eat('bone');

但是在您的代码片段中,您想要 dog.bark(),在这种情况下请参见下文

class Dog {
  addEventListener(method,callback) {
     this[method] = callback;
  }

  removeEventListener (method) {
      delete this[method];
   }
}

以上将作为

const dog = new Dog();

dog.addEventListener('bark', ()=>console.log("bow"));
dog.bark() // logs => bow

dog.addEventListener('somethingsomething', ()=>{ /*do something*/ })

dog.removeListener('bark');

我们可以将微型 class 实现为 EventEmitter 模式

class Dog {
   constructor() {
      this.listeners = {};
   }

   emit(method, payload = null) {
      const callback = this.listeners[method];
      if(typeof callback === 'function'){
          callback(payload);
      }
  }

  addEventListener(method,callback) {
     this.listeners[method] = callback;
  }

  removeEventListener (method) {
      delete this.listeners[method];
   }
}

我们可以像这样使用 class

const dog = new Dog();

dog.addEventListener('bark',(customSound)=>console.log(customSound || "Bow Bow"));

dog.addEventListener('eat', ()=>console.log("eating yum yum") );

dog.emit('bark') // logs => Bow Bow
dog.emit('bark', 'i can talk humans') // logs => i can talk humans
dog.emit('eat');

dog.removeEventListener('bark');

注意:它是原始实现,不是生产就绪代码。谢谢

扩展 EventTarget class 以获取所有事件函数:

https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/EventTarget