JavaScript中的高阶函数并在EventEmitter的类中引用'this'关键字[重复]
Posted
技术标签:
【中文标题】JavaScript中的高阶函数并在EventEmitter的类中引用\'this\'关键字[重复]【英文标题】:Higher Order Functions in JavaScript and referring to the 'this' keyword within a class for an EventEmitter [duplicate]JavaScript中的高阶函数并在EventEmitter的类中引用'this'关键字[重复] 【发布时间】:2021-03-08 00:21:13 【问题描述】:我已经在这个问题上停留了两天,并且在其他堆栈溢出帖子上没有骰子。我真的需要一些帮助。
我的目标是创建一个允许三个功能的事件发射器。订阅、取消订阅和 Emit - 其中,emit 将传递的参数发送到所有订阅函数。
我遇到的问题是我似乎无法将一个函数传递给订阅。我必须传递一个匿名函数来调用另一个函数。
subscribe(() => entities[1].eventEmitter.emit())
与 subscribe(entities[1].eventEmitter.emit)
。我似乎不明白这里的实际区别是什么,以及为什么他们会引用不同的“this”值。我认为第二个示例是第一个示例的简化版本?任何人都可以解释为什么两个版本引用不同的“this”值?
好吧,这一切都很好,因为传入匿名函数有效,但是当我尝试取消订阅时,我不再有对匿名函数的引用,因此无法从数组中删除它。我知道您可以将匿名函数存储在变量中,但这不可行,因为我动态生成这些实体并且可能存在“无限”实体。 IE。大小未知。
所以我一定是在这里做错了什么。要么我做错了,那里有一个更简单的解决方案,要么我只是错过了一些可以解决我的问题的东西。 Welcome 解决方案可以是完全不同的解决方案,也可以是成功订阅、取消订阅和发出的一种方式。谢谢!如果我可以提供更多说明,请告诉我。
class EventEmitter
constructor()
this.subscriptions = [];
subscribe(fn)
this.subscriptions.push(fn);
unsubscribe(fn)
this.subscriptions = this.subscriptions.filter(subscription => subscription !== fn);
emit(args)
// upon subscribing, you should get an error when doing trigger that amounts to
// "message": "Uncaught TypeError: Cannot read property 'subscriptions' of undefined"
// this happens because the line entities[0].eventEmitter.subscribe(entities[1].eventEmitter.emit);
// with argument passed in entities[1].eventEmitter.emit refers to the window?
// so this.subscriptions is not defined
// console.log(this);
console.log('emitting');
this.subscriptions.forEach(subscription => subscription(args));
class Entity
constructor()
this.eventEmitter = new EventEmitter();
const entities = [
new Entity(),
new Entity(),
];
document.getElementById('add').addEventListener('click', () =>
// works, but requires an anonymous function that can't be removed
entities[0].eventEmitter.subscribe(() => entities[1].eventEmitter.emit());
// doesn't work because 'this' in the emit funciton refers to the window
entities[0].eventEmitter.subscribe(entities[1].eventEmitter.emit);
, false);
document.getElementById('trigger').addEventListener('click', () =>
entities[0].eventEmitter.emit();
, false);
document.getElementById('remove').addEventListener('click', () =>
// how? ...
// entities[0].eventEmitter.unsubscribe(entities[1].eventEmitter.emit);
, false);
<button id='add'>add event listener</button>
<button id='trigger'>trigger emit on element 0</button>
<button id='remove'>remove event listener</button>
【问题讨论】:
您可以将this.emit = this.emit.bind(this);
放入Entity
构造函数中,然后您可以在任何地方引用每个实体的方法并在其他地方订阅/取消订阅。
亲爱的主,它成功了!这是完美的,感谢您的帮助!
【参考方案1】:
嗯,您可以使用.bind()
并将其绑定到您的事件发射器类
我创建了一个存储方法的数组。
class EventEmitter
constructor()
this.subscriptions = [];
subscribe(fn)
this.subscriptions.push(fn);
unsubscribe(fn)
this.subscriptions = this.subscriptions.filter(subscription => subscription !== fn);
emit(args)
// upon subscribing, you should get an error when doing trigger that amounts to
// "message": "Uncaught TypeError: Cannot read property 'subscriptions' of undefined"
// this happens because the line entities[0].eventEmitter.subscribe(entities[1].eventEmitter.emit);
// with argument passed in entities[1].eventEmitter.emit refers to the window?
// so this.subscriptions is not defined
// console.log(this);
this.subscriptions.forEach(subscription =>
console.log("emit");
subscription(args)
);
class Entity
constructor()
this.eventEmitter = new EventEmitter();
const entities = [
new Entity(),
new Entity(),
];
let methods = [];
document.getElementById('add').addEventListener('click', () =>
let method = entities[1].eventEmitter.emit.bind(entities[1].eventEmitter)
methods.push(method);
entities[0].eventEmitter.subscribe(method);
, false);
document.getElementById('trigger').addEventListener('click', () =>
entities[0].eventEmitter.emit();
, false);
document.getElementById('remove').addEventListener('click', () =>
entities[0].eventEmitter.unsubscribe(methods.pop())
, false);
<button id='add'>add event listener</button>
<button id='trigger'>trigger emit on element 0</button>
<button id='remove'>remove event listener</button>
【讨论】:
我会在早上跟进!凌晨 1 点在这里哈哈 感谢您的帮助!上面评论中的@Bergi 解决了我想要实现的目标!以上是关于JavaScript中的高阶函数并在EventEmitter的类中引用'this'关键字[重复]的主要内容,如果未能解决你的问题,请参考以下文章
前端面试 JavaScript— 什么是高阶函数?数组中的高阶函数有哪些?