为什么我的接收者的 class 实例方法没有接收到任何数据?
Why does my receiver's class instance method not receive any data?
我创建了一个基本的发射器和接收器。请告诉我为什么当我控制台记录接收者消息时它 returns 是一个空数组?
class Emitter {
constructor(messages = []) {
this.messages = messages;
this.event = () => {};
}
setEvent(fn) {
this.event = fn;
}
trigger() {
this.messages.forEach(message => this.event(message));
}
}
class Reciever {
constructor() {
this.messages = []
}
ping(message) {
console.log(message)
this.messages.push(message)
}
}
const myReciever = new Reciever();
const myEmitter = new Emitter(message = ["A", "B", "C"]);
myEmitter.setEvent(myReciever.ping);
myEmitter.trigger();
console.log(myReciever.messages);
您在 ping
通话中失去了上下文:
myEmitter.setEvent(myReciever.ping);
需要绑定。
myEmitter.setEvent(myReciever.ping.bind(myReciever));
您将所有内容都存储在发射器中,而不是接收器中。如果您打印发射器,条目会重复。
这是因为当您将函数传递给 .setEvent(...)
时,您使用的是 this
- 在这种情况下 - 指的是来自发射器的消息;它丢失了它所属对象的上下文。
如@MinusFour 所示,您需要绑定函数。
查看下面的演示
class Emitter {
constructor(messages = []) {
this.messages = messages;
this.event = () => {};
}
setEvent(fn) {
this.event = fn;
}
trigger() {
this.messages.forEach(message => this.event(message));
}
}
class Reciever {
constructor() {
this.messages = []
}
ping(message) {
console.log(message)
this.messages.push(message)
}
}
const myReciever = new Reciever();
const myEmitter = new Emitter(message = ["A", "B", "C"]);
myEmitter.setEvent(myReciever.ping.bind(myReciever));
myEmitter.trigger();
console.log(myReciever.messages);
从上面的评论...
"At the time of setEvent
the code doesn't care about the this
context of myReciever.ping
. ... ping
gets assigned to an emitters own event
just as function, immediately getting oblivious where it originally did belong to."
除了已经建议的主动 bind
ing thisArg
方法的解决方案之外,还可以以一种可以或必须传递给 setEvent
的方式调整代码方法的 target/context 与 method/function 本身。在 trigger
时间,将在此存储的上下文中调用该方法 ...
class Emitter {
constructor(messages = []) {
this.messages = messages;
this.handler = () => {};
this.target = null;
}
setEvent(handler, target) {
// `setEvent` might be better renamed to
// `setHandler` or `assignHandler`, etc.
this.handler = handler ?? (() => {});
this.target = target ?? null;
}
trigger() {
this.messages.forEach(message =>
this.handler.call(this.target, message)
);
}
}
class Reciever {
constructor() {
this.messages = []
}
ping(message) {
console.log(message)
this.messages.push(message)
}
}
const myReciever = new Reciever();
const myEmitter = new Emitter(message = ["A", "B", "C"]);
myEmitter.setEvent(myReciever.ping, myReciever);
myEmitter.trigger();
console.log(myReciever.messages);
我创建了一个基本的发射器和接收器。请告诉我为什么当我控制台记录接收者消息时它 returns 是一个空数组?
class Emitter {
constructor(messages = []) {
this.messages = messages;
this.event = () => {};
}
setEvent(fn) {
this.event = fn;
}
trigger() {
this.messages.forEach(message => this.event(message));
}
}
class Reciever {
constructor() {
this.messages = []
}
ping(message) {
console.log(message)
this.messages.push(message)
}
}
const myReciever = new Reciever();
const myEmitter = new Emitter(message = ["A", "B", "C"]);
myEmitter.setEvent(myReciever.ping);
myEmitter.trigger();
console.log(myReciever.messages);
您在 ping
通话中失去了上下文:
myEmitter.setEvent(myReciever.ping);
需要绑定。
myEmitter.setEvent(myReciever.ping.bind(myReciever));
您将所有内容都存储在发射器中,而不是接收器中。如果您打印发射器,条目会重复。
这是因为当您将函数传递给 .setEvent(...)
时,您使用的是 this
- 在这种情况下 - 指的是来自发射器的消息;它丢失了它所属对象的上下文。
如@MinusFour 所示,您需要绑定函数。
查看下面的演示
class Emitter {
constructor(messages = []) {
this.messages = messages;
this.event = () => {};
}
setEvent(fn) {
this.event = fn;
}
trigger() {
this.messages.forEach(message => this.event(message));
}
}
class Reciever {
constructor() {
this.messages = []
}
ping(message) {
console.log(message)
this.messages.push(message)
}
}
const myReciever = new Reciever();
const myEmitter = new Emitter(message = ["A", "B", "C"]);
myEmitter.setEvent(myReciever.ping.bind(myReciever));
myEmitter.trigger();
console.log(myReciever.messages);
从上面的评论...
"At the time of
setEvent
the code doesn't care about thethis
context ofmyReciever.ping
. ...ping
gets assigned to an emitters ownevent
just as function, immediately getting oblivious where it originally did belong to."
除了已经建议的主动 bind
ing thisArg
方法的解决方案之外,还可以以一种可以或必须传递给 setEvent
的方式调整代码方法的 target/context 与 method/function 本身。在 trigger
时间,将在此存储的上下文中调用该方法 ...
class Emitter {
constructor(messages = []) {
this.messages = messages;
this.handler = () => {};
this.target = null;
}
setEvent(handler, target) {
// `setEvent` might be better renamed to
// `setHandler` or `assignHandler`, etc.
this.handler = handler ?? (() => {});
this.target = target ?? null;
}
trigger() {
this.messages.forEach(message =>
this.handler.call(this.target, message)
);
}
}
class Reciever {
constructor() {
this.messages = []
}
ping(message) {
console.log(message)
this.messages.push(message)
}
}
const myReciever = new Reciever();
const myEmitter = new Emitter(message = ["A", "B", "C"]);
myEmitter.setEvent(myReciever.ping, myReciever);
myEmitter.trigger();
console.log(myReciever.messages);