在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
表示的对象为空。请问箭头函数中的这个参考是什么?
答案 0 :(得分:2)
在箭头函数之前,每个新函数都定义了自己的this
值。事实证明,这是一种面向对象的编程风格。
An arrow function
没有创建自己的这个上下文,所以这从封闭的上下文中有其原始含义。因此,以下代码按预期工作:
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));
答案 1 :(得分:1)
正如评论中提到的那样,箭头函数中的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');
})();
答案 2 :(得分:1)
进一步研究:
模块脚本中的 this
引用模块范围内的exports
。
REPL中的this
引用global
对象。
看着shambalambala的答案。严格模式下的IIFE内的this
未定义,在标准模式下,它是全局对象。
来自:Why console.log(this) in node return empty object?由T.J.克劳德
因为NodeJS在一个模块中运行你的代码,并且这引用了它为你的模块导出创建的对象(它也是它为你提供的模块变量的exports属性)。 (因为他们并没有真正提到模块文档,我怀疑使用它可能不是一个好主意 - 而是使用导出。)
但是你的代码调用IIFE会调用它来引用全局对象,因为在松散(非严格)模式下,不通过对象属性调用普通函数会将其设置为全局对象。 (在严格模式下,这将是未定义的。)
为什么this
在严格模式下的IIFE中未定义?
来自:jAndy的Why is "this" in an anonymous function undefined when using strict?
这是因为,在ECMAscript 262第5版之前,如果使用构造函数模式的人忘记使用new关键字,那么会出现很大的混乱。如果在ES3中调用构造函数时忘记使用new,则会引用全局对象(浏览器中的窗口),并且您将使用变量来破坏全局对象。
这是一种可怕的行为,因此ECMA的人决定,只是将其设置为未定义。