在这个post中,有很多答案在讨论JavaScript中的this
关键字。但是,我仍然将this
中的anonymous function
混淆为
// MyModule.js
'use strict';
(function(handler) {
// export methods
handler.B = B;
handler.A = A;
function A() {
console.log(this);
console.log('function A is invoked...');
}
function B() {
console.log(this);
console.log('function B is invoked...');
try {
A();
this.A();
} catch (err) {
console.log('Exception is ' + err);
}
}
})(module.exports);
// test.js
var myModule = require('MyModule.js');
myModule.B();
输出:(在Node.js下运行)
{ B: [Function: B], A: [Function: A] }
function B is invoked...
undefined
function A is invoked...
{ B: [Function: B], A: [Function: A] }
function A is invoked...
输出表明函数A
位于两个不同的范围内。我对吗?为什么函数A
有两个范围?
众所周知,this
与范围有关。 this
的匿名函数中的MyModule
为undefined
。根据输出,函数A
的一个范围是undefined
,另一个是{ B: [Function: B], A: [Function: A] }
。他们之间有什么区别?
答案 0 :(得分:4)
this
和范围几乎没有任何关系。在JavaScript中,this
通常由函数调用的方式设置,而不是在其定义的位置。 (该规则有两个例外,我将在下面提到它们。)
因此,当您拨打A
时,您正在设置呼叫期间this
的内容(主要是隐式)。当你这样做时:
A();
...你正在调用A
而没有做任何明确的事情来设置this
应该是什么;因此,您隐式调用this
设置为undefined
,因为您的代码处于严格模式。 (如果它处于松散模式,你将调用它,并将this
设置为对全局对象的引用。)同样值得注意的是,您正在通过创建的上下文解析标识符A
通过调用您的匿名函数,其中包含A
和B
作为(有效)变量。
但是在这里:
this.A();
...您正在调用A
作为从对象属性(A
获取函数引用的表达式的一部分;请注意,这是不同的含义A
,但属性和上下文变量都引用相同的函数)。执行该操作的行为将A
调用this
设置为对您获取属性的对象的引用。
这就是为什么您在this
中看到A
的两个不同值。
“this
的例外情况由您调用它的方式设置”规则为:
ES6的“箭头”功能,它从上下文(非范围)继承this
。
ES5的“绑定”函数(在函数引用上调用.bind
的结果),this
调用将.bind
括起来,所以总是看到this
的值相同。
答案 1 :(得分:0)
通常,函数中的this
绑定到您调用该函数的对象。
在你的例子中:
myModule.B()
,this
等于myModule
,{ B: [Function: B], A: [Function: A] }
try
块内,您在没有对象的情况下调用A()
,此处this
为undefined
,因为您在严格模式下运行 < / strong>,否则会指向全局对象,即浏览器中的window
或节点中的global
this.A()
,此处您基本上将当前this
(myModule
)传递给该函数,因此它将是myModule
整个this
绑定仅受您调用函数的方式的影响。