我不明白当我发出一个Web API请求时,闭包变量是如何附加到函数([[Scope]])中的,比如定时器(serTimeout)。
function fun() {
function log() {console.log(callme) };
console.dir(log);
setTimeout( log, 10000);
const callme = "hi iam"
}
fun()
函数 原木 获得访问变量 打电话给我 当const不被吊起时。
我的想法是 fun() 调用,它被推送到调用栈,函数 原木 然后发送到WebAPI定时器函数,在这期间 趣味 运转,并设置 打电话给我 在它的执行上下文中,变量。一旦计时器结束,fn 原木 被推送到回调队列,事件循环在检查调用栈是否为空后推送给你。原木 到callstack执行。我无法理解当 打电话给我 沾染上 [[范围]] 的功能 原木
IMHO, hoisting
是一个非常糟糕的概念,只是恰好有用。它导致了像你这样的误解。解释器真正的工作方式就像我对这个相关问题的回答。JavaScript函数的声明和评估顺序
对于你的具体例子,你提到。
当const不被吊起时
这其实并不正确。当然,葫芦在语言中并不真正存在,它只是程序员为了解释语言的行为而创造的一个概念。让我们看看当我们把解析分为两个阶段:编译和执行时,你的代码是如何被解释的。
function fun() {
function log() {console.log(callme) };
console.dir(log);
setTimeout( log, 10000);
const callme = "hi iam"
}
fun()
编译阶段
fun
,让我们来解析一下它的主体。log
,让我们来解析一下它的主体。callme
. 注意我们使用的变量log
10秒后,注意函数setTimeout使用的是callme
执行阶段
fun()
log
setTimeout()
的变量函数,找到一个叫做 log
- 补上 log
到事件队列callme
到 "hi iam"(注意,在编译阶段不能设置值,因为它可能涉及到执行代码,例如,如果我们做了 const x = (1).toString()
,const只是意味着我们不能在初始化以外的地方设置值)callme
在闭合中使用,将其附加在log()
callme
- 在闭合中发现的,就记录下来。这就是 callme
被卷入 foo
的关闭。如果你坚持使用 hoisting
术语,你可以说,如果有一个闭合,那么const就会被提升。
但是,如果你的心理模型是这种两相解释,你就不需要知道所有的角落情况,什么时候会发生提升,什么时候不会。我强烈建议阅读上面链接的答案,以便更好地理解它的工作原理。