如何确定 JavaScript 回调函数的执行上下文
How do I determine the Execution Context for a JavaScript callback function?
当函数作为对象属性调用时,this
设置为父对象。有类似的规则适用于将函数作为构造函数或事件处理程序调用,但是在浏览了更多关于 JS Scope 的文章后,并深入研究了 ECMA5.1 规范,我无法准确理清当函数作为回调传递时如何设置执行上下文。
此代码清楚地表明,作为回调传递给另一个方法的方法(即使在同一对象中)也会恢复到全局执行上下文(在浏览器和 Node.js 中)。
var name = 'global';
var self = function() {
return this.name;
}
var cback = function(ff) {
return ff();
}
var parent = {
name: 'parent',
cback: function(ff) {
return ff();
},
self: function() {
return this.name;
}
}
console.log(parent.cback(parent.self)); // Returns "global"
谁能帮助我理解为什么回调是在全局上下文中而不是在parent
对象的上下文中执行的?我最好的猜测是,任何作为参数传递的函数在分配给局部变量时都会替换其先前的执行上下文(ff
在上面的示例中),这意味着调用它会传递一个未定义的 thisArg 并转移到全局上下文(除非严格模式,或在执行前作为方法附加到新对象), 但我犹豫要不要依赖它,因为它不仅仅是猜测。
当函数作为回调传递时如何设置执行上下文
我认为理解的关键是这些过程是完全独立的。
作为参数传递的任何函数在分配给局部变量时都会替换其先前的执行上下文
没有。函数本身根本没有任何执行上下文。
只有在调用函数时才会创建执行上下文。只有函数的调用方式才能确定执行上下文的属性,例如其this
值。
例如
当函数作为对象属性调用时,
this
设置为父对象。
比如parent.cback(…)
.被调用的函数被属性引用,基引用(parent
)将成为调用的this
上下文。
或者,当函数作为普通函数调用时,this
设置为undefined
(或草率模式下的全局对象) - 例如 ff()
。
对于其他替代方案,请查看 MDN 对 this
关键字的引用。
回调中的this
规则与非方法函数的规则相同。真正重要的是函数调用看起来像f()
(非方法)、x.f()
(方法调用)还是new f()
(构造函数)
谁能帮助我理解为什么回调是在全局上下文中而不是在父对象的上下文中执行的?
可悲的是,这是我们必须忍受的那些大的Javascript疣之一。也就是说,如果您在严格模式下运行,则this
是null
而不是全局对象,这更合理。此外,在 ES6 中,将有 lambda =>
"胖箭头",它们从它们的词法上下文中继承this
(这意味着它从外部函数获取this
,就像常规变量一样)
- 执行上下文和变量对象在 JavaScript 中实际上是一回事吗?
- javascript中的全局和局部变量执行上下文
- 执行上下文和Javascript中的执行上下文对象
- 函数参数的 JavaScript 执行上下文
- 逗号运算符是否会影响 Javascript 中的执行上下文
- 执行上下文和闭包
- Java 脚本 eval() 函数属于哪个对象?此外,在调用 eval() 函数时传递执行上下文
- JavaScript 范围和执行上下文
- 如何在 JavaScript 中动态地向当前执行上下文添加属性
- 任何用于 JavaScript 执行上下文可视化的现有工具
- 为什么此处未创建执行上下文
- 是否可以传递立即调用的函数表达式的执行上下文
- 如何确定 JavaScript 回调函数的执行上下文
- Node.js获取执行上下文的编程模式
- JavaScript中的执行上下文
- 获取javascript函数的绑定执行上下文
- 了解 JavaScript 提升和执行上下文
- 什么是'执行上下文'在JavaScript中
- 全局执行上下文是否可能从执行堆栈中弹出
- d3.js/CoffeeScript:访问mouseover中类和路径的执行上下文(this)