Javascript NodeJS:将参数和它传递给侦听器

Javascript NodeJS:将参数和它传递给侦听器,javascript,node.js,Javascript,Node.js,在阅读NodeJS的文档时,我对事件监听器中处理此问题的区域有点困惑: “可以使用ES6 Arrow函数作为侦听器,但是,执行此操作时,this关键字将不再引用EventEmitter实例:” const myEmitter = new MyEmitter(); myEmitter.on('event', (a, b) => { console.log(a, b, this); // Prints: a b {} }); myEmitter.emit('event', 'a', '

在阅读NodeJS的文档时,我对事件监听器中处理此问题的
区域有点困惑:

“可以使用ES6 Arrow函数作为侦听器,但是,执行此操作时,
this
关键字将不再引用
EventEmitter
实例:”

const myEmitter = new MyEmitter();
myEmitter.on('event', (a, b) => {
  console.log(a, b, this);
  // Prints: a b {}
});
myEmitter.emit('event', 'a', 'b');

表示的对象为空。请说明arrow函数中的此引用是什么?

正如shanks在注释中指出的那样,
arrow函数中的此
表示包含arrow函数的作用域的上下文

下面是一个例子:

const EventEmitter = require('events')
const myEmitter = new EventEmitter();

this.foo = "bar";

myEmitter.on('event', () => {
  console.log(this); // { foo: "bar" }
});

(function() {
  this.foo = "baz";
  myEmitter.emit('event');
})();

在arrow开始工作之前,每个新函数都定义了自己的
值。事实证明,这对于面向对象的编程风格来说很烦人

箭头函数
不会创建自己的此上下文,因此它具有封闭上下文的原始含义。因此,以下代码按预期工作:

function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| properly refers to the person object
  }, 1000);
}

var p = new Person();
有关更多详细信息和

您可以将
绑定到箭头函数,请尝试通过-

myEmitter.on('event', (a, b) => {
  console.log(a, b, this);
  // Prints: a b {}
}.bind(this));

进一步研究:

在模块脚本中指的是模块范围内的
导出
REPL中的此
指的是
全局
对象

看着香巴拉姆巴拉回答<代码>此
在严格模式下的IIFE中是未定义的,在标准模式下是全局对象

发件人:T.J.克劳德

因为NodeJS在模块中运行您的代码,并且它引用它为模块的导出创建的对象(这也是它提供给您的模块变量的exports属性)。(因为他们在模块文档中并没有真正提到这一点,我怀疑使用它可能不是一个好主意——而是使用导出。)

但是调用IIFE的代码调用它时引用全局对象,因为在松散(非严格)模式下,不通过对象属性调用普通函数时,使用此集合调用全局对象。(在严格模式下,这将是未定义的。)

为什么在严格模式下,
在IIFE中变得未定义

发件人:詹迪

这是因为,在ECMAscript 262第5版之前,如果使用构造函数模式的人忘记使用新的关键字,就会产生很大的混乱。如果在ES3中调用构造函数时忘记使用new,则会引用全局对象(浏览器中的窗口),并且会使用变量来关闭全局对象


这是一种可怕的行为,因此ECMA的人员决定将其设置为undefined。

此绑定已在arrow函数中删除。它应该使oop样式的搁置变得更容易。箭头函数与封闭作用域的上下文共享相同的上下文。在机箱中使用适当的功能。感谢您的回复。使用“严格模式”时,会抛出一个TypeError,表示
TypeError:无法设置未定义的属性“foo”
感谢您的响应。我理解
这个
的上下文。我只是想知道为什么它是一个空的物体。我想,
这个
会引用一个全局对象,但事实并非如此。在shambalambala给我们的例子中,在IIFE中,
这个
未定义的