为什么 this.name 未定义

Why is this.name undefined?

本文关键字:未定义 name this 为什么      更新时间:2023-09-26

为什么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不是my_event_emitter EventEmitter的实例?

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

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

您还可以传递(作为 forEach 的 2 个参数)上下文。回调的参数是(值、索引、原始数组、上下文);

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

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