Javascript: 为什么具有全局执行上下文的回调函数可以访问作用域变量?
Javascript: why do callback functions with global execution context have access to scoped variables?
在下面的代码中:
function test() {
var x = 5 // scoped to test function
console.log(this); // global object
logCb(function(){
console.log(this); // global object
console.log(x);
})
}
function logCb (cb) {
console.log(this); // global object
cb() // This still seems to execute within the test function scope? why...
}
test()
x 用于测试,这是定义回调函数的地方。我本以为 cb()
行会抛出错误,因为 logCb() 函数无法访问 x 变量。
然而事实并非如此。为什么?回调中的引用似乎是在赋值期间创建的,而不是在执行期间创建的——如果你考虑提升,我想这是有道理的——即在编译期间,回调函数是否被提升到 'test' 的顶部,然后赋值发生在测试范围内?
我读到执行与作用域不同。在这篇文章中:http://ryanmorr.com/understanding-scope-and-context-in-javascript/,这句话scope pertains to the variable access of a function when it is invoked and is unique to each invocation
似乎暗示回调是从测试函数内部调用的。
因为在我看来,无论在哪里调用回调函数,它仍然会被限定为测试范围。
我想我的问题是:
在考虑作用域和执行上下文时,回调函数是如何定义和调用的?
How is the callback function handled in terms of definition and then
invocation when thinking about scope and execution context?
函数作用域基于它在词法环境中的物理位置
解释:回调在函数test()中按词法出现,所以它总是会尝试找到[的值=30=]this 在自身内部(如果存在)否则它将在外部环境中看到它的值(在这种情况下是 function test)
测试函数和LogCb函数将遵循相同的做法。在这种情况下,外部环境将是 global
how does the engine keep track of scope separately to execution
context?
词法环境:您编写的代码中物理位置。
执行上下文: 帮助管理 运行.
代码的包装器
现在你的代码中有很多词法环境。当前 运行 是哪一个是通过执行上下文管理的。它可以包含超出您在代码中编写的内容。
无论何时创建执行上下文,我们都可以使用三样东西:
- 全局对象(window):全局范围内的任何变量或函数链接到window对象
- 'this'
- 外部环境
因此,根据当前 运行 的执行上下文,这些内容会根据它在代码中的物理位置或词法位置而有所不同。例如 cb
的外部环境是 function test()
作用域由创建函数的位置决定,而不是由调用它的位置决定。
您传递给 logCb
的函数是在 test
中创建的,因此它可以访问 test
的范围。
在 javascript 中调用函数时,会向其传递一个上下文。
上下文可以是以下方式之一
使用 new 创建一个临时对象,并将其作为上下文传递给函数
通过对象 a.getValue() 调用函数。 getValue 获取上下文 a
如果上面2个的none传递全局对象即window
在下面的代码中:
function test() {
var x = 5 // scoped to test function
console.log(this); // global object
logCb(function(){
console.log(this); // global object
console.log(x);
})
}
function logCb (cb) {
console.log(this); // global object
cb() // This still seems to execute within the test function scope? why...
}
test()
x 用于测试,这是定义回调函数的地方。我本以为 cb()
行会抛出错误,因为 logCb() 函数无法访问 x 变量。
然而事实并非如此。为什么?回调中的引用似乎是在赋值期间创建的,而不是在执行期间创建的——如果你考虑提升,我想这是有道理的——即在编译期间,回调函数是否被提升到 'test' 的顶部,然后赋值发生在测试范围内?
我读到执行与作用域不同。在这篇文章中:http://ryanmorr.com/understanding-scope-and-context-in-javascript/,这句话scope pertains to the variable access of a function when it is invoked and is unique to each invocation
似乎暗示回调是从测试函数内部调用的。
因为在我看来,无论在哪里调用回调函数,它仍然会被限定为测试范围。
我想我的问题是:
在考虑作用域和执行上下文时,回调函数是如何定义和调用的?
How is the callback function handled in terms of definition and then invocation when thinking about scope and execution context?
函数作用域基于它在词法环境中的物理位置
解释:回调在函数test()中按词法出现,所以它总是会尝试找到[的值=30=]this 在自身内部(如果存在)否则它将在外部环境中看到它的值(在这种情况下是 function test)
测试函数和LogCb函数将遵循相同的做法。在这种情况下,外部环境将是 global
how does the engine keep track of scope separately to execution context?
词法环境:您编写的代码中物理位置。
执行上下文: 帮助管理 运行.
代码的包装器现在你的代码中有很多词法环境。当前 运行 是哪一个是通过执行上下文管理的。它可以包含超出您在代码中编写的内容。
无论何时创建执行上下文,我们都可以使用三样东西:
- 全局对象(window):全局范围内的任何变量或函数链接到window对象
- 'this'
- 外部环境
因此,根据当前 运行 的执行上下文,这些内容会根据它在代码中的物理位置或词法位置而有所不同。例如 cb
的外部环境是 function test()
作用域由创建函数的位置决定,而不是由调用它的位置决定。
您传递给 logCb
的函数是在 test
中创建的,因此它可以访问 test
的范围。
在 javascript 中调用函数时,会向其传递一个上下文。
上下文可以是以下方式之一
使用 new 创建一个临时对象,并将其作为上下文传递给函数
通过对象 a.getValue() 调用函数。 getValue 获取上下文 a
如果上面2个的none传递全局对象即window