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

Posted

技术标签:

【中文标题】NodeJS:将参数和 this 传递给侦听器【英文标题】:NodeJS: Passing arguments and this to listeners 【发布时间】:2017-10-05 02:15:25 【问题描述】:

在阅读 https://nodejs.org/api/events.html 的 NodeJS 文档时,我对 this 在事件侦听器中处理此问题的区域有点困惑:

“可以将 ES6 箭头函数用作侦听器,但是,这样做时,this 关键字将不再引用 EventEmitter 实例:”

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

this 代表的对象是空的。请问这个箭头函数中的引用是什么?

【问题讨论】:

this 绑定已在箭头函数中删除。它应该更容易放松 oop 风格。 箭头函数与封闭范围共享相同的上下文。在案例中使用适当的功能。 【参考方案1】:

正如 cmets 中提到的 shanks,箭头函数中的 this 表示包含箭头函数的范围的上下文。

这是一个例子:

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');
)();

【讨论】:

感谢您的回复。当使用“严格模式”时,会抛出一个 TypeError 说 TypeError: Cannot set property 'foo' of undefined【参考方案2】:

直到箭头函数,每个新函数都定义了自己的this 值。事实证明,这种面向对象的编程风格很烦人。

An arrow function 不会创建自己的 this 上下文,因此 this 有其从封闭上下文中的原始含义。因此,以下代码按预期工作:

function Person()
  this.age = 0;

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


var p = new Person();

更多详情check here和here too。

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

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

【讨论】:

感谢您的回复。我了解this 的上下文。我只是想知道为什么它是一个空对象。我在想this 会引用一个全局对象,但事实并非如此。在 shambalambala 给我们的示例中,在 IIFE 中,thisundefined【参考方案3】:

做进一步的研究:

模块脚本中的this 指的是模块范围内的exports。 REPL 中的this 指的是global 对象。

看着香巴拉巴拉的答案。 this 在严格模式下的 IIFE 中是未定义的,在标准模式下它是全局对象。

发件人:Why console.log(this) in node return empty object? T.J.克劳德

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

但是您调用 IIFE 的代码使用 this 引用全局对象来调用它,因为在松散(非严格)模式下,不通过对象属性调用普通函数会使用 this 设置为全局对象调用它。 (在严格模式下,这将在那里未定义。)

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

发件人:Why is "this" in an anonymous function undefined when using strict? by jAndy

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

这是很糟糕的行为,因此 ECMA 的人们决定将其设置为未定义。

【讨论】:

以上是关于NodeJS:将参数和 this 传递给侦听器的主要内容,如果未能解决你的问题,请参考以下文章

将参数传递给 pynput 侦听器

将动作侦听器方法作为标记文件属性传递

使用多个 onclick 侦听器将多个 url 传递给 recyclerview 中的 itemview

如何将相同的事件侦听器分配给 Vue.js 中动态创建的按钮并将对象的值作为参数传递给它?

在事件侦听器函数中传递参数 [重复]

Nodejs EventEmitter - 定义侦听器函数的范围