JavaScript:函数引用存储在数组中时的执行上下文
JavaScript: Execution context when a function reference is stored in an array
考虑以下代码:
var obj = {
name: 'Hans',
print: function(p) {
console.log(this.name)
}
};
obj.print(); // prints 'Hans'
我们知道 print
函数是在对象 obj
上调用的。换句话说,obj
是 print
的(部分)执行上下文。简单吧?
现在,这就是我正在努力理解的:
考虑将函数引用存储在数组中:
var funcs = [function(p) {
console.log(this.length, this)
}];
funcs[0](); // prints 1 which is the length of the array 'func' and also [ [Function] ]
表示数组第一个元素运行时的执行上下文就是数组本身!!我的假设是数组中存储的只是对函数的引用,所以它等同于:
var f = function(p) {
console.log(this)
};
var funcs = [f];
f(); // prints Window
事实证明这是错误的。
我在这里错过了什么?
您看到的结果是因为数组实际上是对象,而数组索引是恰好具有数字名称的属性。当 属性 包含一个函数,并且您调用 object.property()
或 object["property"]()
时,this
上下文就是对象。
但这只会在您使用 属性 访问器或数组索引语法调用函数时发生。如果将函数分配给某个其他变量并通过它调用函数,则与对象的关联将丢失。这就是为什么您会在最后一个片段中看到 window
对象。
如果将 obj.print()
更改为
,您会在第一个片段中看到相同的效果
var foo = obj.print;
foo();
考虑以下代码:
var obj = {
name: 'Hans',
print: function(p) {
console.log(this.name)
}
};
obj.print(); // prints 'Hans'
我们知道 print
函数是在对象 obj
上调用的。换句话说,obj
是 print
的(部分)执行上下文。简单吧?
现在,这就是我正在努力理解的: 考虑将函数引用存储在数组中:
var funcs = [function(p) {
console.log(this.length, this)
}];
funcs[0](); // prints 1 which is the length of the array 'func' and also [ [Function] ]
表示数组第一个元素运行时的执行上下文就是数组本身!!我的假设是数组中存储的只是对函数的引用,所以它等同于:
var f = function(p) {
console.log(this)
};
var funcs = [f];
f(); // prints Window
事实证明这是错误的。 我在这里错过了什么?
您看到的结果是因为数组实际上是对象,而数组索引是恰好具有数字名称的属性。当 属性 包含一个函数,并且您调用 object.property()
或 object["property"]()
时,this
上下文就是对象。
但这只会在您使用 属性 访问器或数组索引语法调用函数时发生。如果将函数分配给某个其他变量并通过它调用函数,则与对象的关联将丢失。这就是为什么您会在最后一个片段中看到 window
对象。
如果将 obj.print()
更改为
var foo = obj.print;
foo();