2017-05-06 68 views
1

虽然在https://nodejs.org/api/events.html阅读的NodeJS的文档,我有点困惑this区域的事件监听器处理这样的:的NodeJS:传递参数,这给听众

“这是可以使用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

'此'绑定已被放弃在箭头函数中。它应该让它更容易地休闲一下。 – magreenberg

+1

箭头函数与封闭范围共享相同的上下文。在案件中使用适当的功能。 – shanks

回答

1

做进一步的研究:在模块脚本

thisexports模块范围内。 this在REPL中指的是global对象。

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

来自:Why console.log(this) in node return empty object?作者:T.J. Crowder

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

但你的代码调用IIFE与此指的是全局对象调用它,因为在松散(非严格)模式下,不通过对象属性调用普通函数将其设置为全局对象。 (在严格模式下,这将在此处未定义。)

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

来源:Why is "this" in an anonymous function undefined when using strict?通过jAndy

这是因为,直到EcmaScript的262五门版,有一个很大的困惑,如果谁在那里使用构造格局的人,忘了使用new关键字。如果您在ES3中调用构造函数时忘记使用new,则会引用全局对象(浏览器中的窗口),并且会使用变量来打开全局对象。

这是非常可怕的行为,所以ECMA的人们决定将其设置为undefined。

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

感谢您的回复。当使用“严格模式”时,TypeError被抛出,说'TypeError:不能设置未定义的属性'foo' – decahub

1

直到箭头的功能,每一个新的功能定义自己的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 herehere too

可以绑定this箭头的功能,尝试结合该副

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

感谢您的回应。我了解'this'的背景。我只是想知道为什么它是一个空洞的对象。我一直在想'这个'会引用一个全局对象,但事实并非如此。在香巴兰巴拉给我们的例子中,在IIFE中,这个'未定义'。 – decahub