如果我像这样在JavaScript中创建函数构造函数:
function Emitter() {
this.events={}
}
然后我向其原型添加一个方法,如下所示:
Emitter.prototype.on = function(type,listener) {
this.event[type] = this.events[type] | [];
this.event[type].push(listener);
}
当我在Emitter的一个实例上两次调用方法时,为什么它不只是覆盖称为greet的原始属性并将其分配给第二个函数?我想我不了解发生的事情的局限性:
this.event[type] = this.events[type] | [];
var emtr = new Emitter();
emtr.on('greet',function(){
console.log('Hello once');
});
emtr.on('greet', function(){
console.log('Hello twice');
});
答案 0 :(得分:2)
您应该为||
使用OR
而不是|
,这是无效的:
this.event[type] = this.events[type] | [];
此外,您正在呼叫event
而不是events
。您应该具有:
this.events[type] = this.events[type] || [];
这样,如果this.events[type]
不是undefined
,它将保持原样。但是,如果为undefined
,则会被分配为空数组:[]
下面的代码将成功地将两个函数添加到emtr.events['greet']
(函数数组)中:
function Emitter() {
this.events = {}
}
Emitter.prototype.on = function(type, listener) {
this.events[type] = this.events[type] || [];
this.events[type].push(listener);
}
var emtr = new Emitter();
emtr.on('greet', function() {
console.log('Hello once');
});
emtr.on('greet', function(){
console.log('Hello twice');
});
console.log(emtr.events['greet'])
所以您可以这样称呼他们:
emtr.events['greet'][0]();
还有
emtr.events['greet'][1]()
如果相反,您想替换侦听器,则不应该使用数组。指向一个函数而不是一个函数数组就足够了:
function Emitter() {
this.events = {}
}
Emitter.prototype.on = function(type, listener) {
this.events[type] = listener;
}
var emtr = new Emitter();
emtr.on('greet', function() {
console.log('Hello once');
});
emtr.on('greet', function(){
console.log('Hello twice');
});
emtr.events['greet'](); // notice how the first listener was replaced by the new one
通过这种方式,您可以使用emtr.events['greet']()
来调用监听器。
答案 1 :(得分:1)
@Ivan完全正确的同时,他错过了您的主要问题“为什么?”
答案是,JS中的逻辑OR运算符用作赋值语句的一部分时,还充当空合并运算符。
基本上是这种情况
let x = y || “default”;
右侧将求出第一个“真实”值并将其返回。在JS中,大多数事情都在逻辑运算中评估为true,除了false,0,null和其他与该问题无关的值。
因此,按照您的语法(由Ivan纠正),您要告诉JS将第一个正确的东西分配给events [type]属性。本身(如果不为null,未分配,0等,则为true),否则为空数组。
第一次添加事件时,该事件不会被分配,因此会添加一个空数组。随后,将数组eval设置为true,因此您只需继续将属性重新分配给它本身就没有效果。
有道理吗?
答案 2 :(得分:0)
function Emitter() {
this.events = []
}
Emitter.prototype.on = function (type, listener) {
this.events[type] = this.events[type]||[]
this.events[type].push(listener);
}
Emitter.prototype.emit = function(type){
var listener = this.events[type].pop()
if(this.events[type].length>=0)
listener()
else
console.log('Nothing to emit')
}
var emtr = new Emitter();
emtr.on('greet',function(){
console.log('Hello once');
});
emtr.emit('greet')