为什么this.name未定义?

时间:2015-01-01 20:15:47

标签: javascript events

this.name为什么返回我未定义?

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的{​​{1}}实例?

3 个答案:

答案 0 :(得分:3)

forEach有自己的上下文。使用3种方法之一绑定新上下文,例如:

events[name].forEach(function(fn) {
  fn.apply(this, args);
}.bind(this));

您还可以传递(作为2 arg到forEach)上下文。回调的参数是(value,index,originalArray,context);

events[name].forEach(function(fn) {
  fn.apply(this, args);
},this);

答案 1 :(得分:2)

没有; this是调用forEach回调的上下文 默认情况下,这是全局对象。

您需要将第二个参数传递给forEach(),以告诉它回调中应该有this

答案 2 :(得分:2)

由于以下代码行:

events[name].forEach(function(fn) {
  fn.apply(this, args);
});

当您致电apply时,您提供了错误的this引用,因为您位于forEach关闭内。

如果要在EventEmitter上提供this实例引用,则需要将其存储在变量中并在闭包内使用它:

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"
    });
  }
}