为什么 this.name 未定义?
Why is this.name undefined?
为什么 this.name
returns 我未定义?
function EventEmitter() {
var events = {};
this.name = "Google"
this.on = function(name, fn) {
events[name] = events[name] || [];
events[name].push(fn);
}
this.trigger = function(name, args) {
events[name] = events[name] || [];
args = args || [];
events[name].forEach(function(fn) {
fn.apply(this, args);
});
}
}
var my_event_emitter = new EventEmitter();
my_event_emitter.on('curtain_dropped', function() {
console.log(this.name);
});
my_event_emitter.trigger('curtain_dropped', [true]);
当我调用 fn.apply(this, args)
时 this
不是 EventEmitter
的实例 my_event_emitter
?
否; this
是调用您的 forEach
回调的上下文。
默认情况下,这是全局对象。
您需要将第二个参数传递给 forEach()
以告诉它 this
应该在其回调中是什么。
因为下面的代码行:
events[name].forEach(function(fn) {
fn.apply(this, args);
});
当您调用 apply
时,您给出了错误的 this
引用,因为您在 forEach
闭包中。
如果您想在 this
上提供 EventEmitter
实例引用,您需要将其存储在一个变量中并在闭包中使用它:
function EventEmitter() {
var events = {};
var that = this; // <-- Current instance reference!
this.name = "Google"
this.on = function(name, fn) {
events[name] = events[name] || [];
events[name].push(fn);
}
this.trigger = function(name, args) {
events[name] = events[name] || [];
args = args || [];
events[name].forEach(function(fn) {
fn.apply(that, args); // Provide "that" instead of "this"
});
}
}
forEach 有自己的上下文。使用 3 种方式之一绑定新上下文,例如:
events[name].forEach(function(fn) {
fn.apply(this, args);
}.bind(this));
您还可以传递(作为 forEach 的第 2 个参数)上下文。回调的参数是 (value, index, originalArray, context);
events[name].forEach(function(fn) {
fn.apply(this, args);
},this);
为什么 this.name
returns 我未定义?
function EventEmitter() {
var events = {};
this.name = "Google"
this.on = function(name, fn) {
events[name] = events[name] || [];
events[name].push(fn);
}
this.trigger = function(name, args) {
events[name] = events[name] || [];
args = args || [];
events[name].forEach(function(fn) {
fn.apply(this, args);
});
}
}
var my_event_emitter = new EventEmitter();
my_event_emitter.on('curtain_dropped', function() {
console.log(this.name);
});
my_event_emitter.trigger('curtain_dropped', [true]);
当我调用 fn.apply(this, args)
时 this
不是 EventEmitter
的实例 my_event_emitter
?
否; this
是调用您的 forEach
回调的上下文。
默认情况下,这是全局对象。
您需要将第二个参数传递给 forEach()
以告诉它 this
应该在其回调中是什么。
因为下面的代码行:
events[name].forEach(function(fn) {
fn.apply(this, args);
});
当您调用 apply
时,您给出了错误的 this
引用,因为您在 forEach
闭包中。
如果您想在 this
上提供 EventEmitter
实例引用,您需要将其存储在一个变量中并在闭包中使用它:
function EventEmitter() {
var events = {};
var that = this; // <-- Current instance reference!
this.name = "Google"
this.on = function(name, fn) {
events[name] = events[name] || [];
events[name].push(fn);
}
this.trigger = function(name, args) {
events[name] = events[name] || [];
args = args || [];
events[name].forEach(function(fn) {
fn.apply(that, args); // Provide "that" instead of "this"
});
}
}
forEach 有自己的上下文。使用 3 种方式之一绑定新上下文,例如:
events[name].forEach(function(fn) {
fn.apply(this, args);
}.bind(this));
您还可以传递(作为 forEach 的第 2 个参数)上下文。回调的参数是 (value, index, originalArray, context);
events[name].forEach(function(fn) {
fn.apply(this, args);
},this);