如何在Web API调用中设置Closure?

问题描述 投票:0回答:1

我不明白当我发出一个Web API请求时,闭包变量是如何附加到函数([[Scope]])中的,比如定时器(serTimeout)。

function fun() {   
    function log() {console.log(callme) }; 
    console.dir(log); 
    setTimeout( log, 10000);
    const callme = "hi iam"
  }
fun()

enter image description here函数 原木 获得访问变量 打电话给我 当const不被吊起时。

我的想法是 fun() 调用,它被推送到调用栈,函数 原木 然后发送到WebAPI定时器函数,在这期间 趣味 运转,并设置 打电话给我 在它的执行上下文中,变量。一旦计时器结束,fn 原木 被推送到回调队列,事件循环在检查调用栈是否为空后推送给你。原木 到callstack执行。我无法理解当 打电话给我 沾染上 [[范围]] 的功能 原木

javascript closures
1个回答
1
投票

IMHO, hoisting 是一个非常糟糕的概念,只是恰好有用。它导致了像你这样的误解。解释器真正的工作方式就像我对这个相关问题的回答。JavaScript函数的声明和评估顺序

对于你的具体例子,你提到。

当const不被吊起时

这其实并不正确。当然,葫芦在语言中并不真正存在,它只是程序员为了解释语言的行为而创造的一个概念。让我们看看当我们把解析分为两个阶段:编译和执行时,你的代码是如何被解释的。

function fun() {   
    function log() {console.log(callme) }; 
    console.dir(log); 
    setTimeout( log, 10000);
    const callme = "hi iam"
  }
fun()

编译阶段

  1. 好了,我们有一个函数定义 fun,让我们来解析一下它的主体。
  2. 好了,我们有一个函数定义 log,让我们来解析一下它的主体。
    1. 好了,我们要记录一个变量 callme. 注意我们使用的变量
  3. 我们想叫 log 10秒后,注意函数setTimeout使用的是
  4. 我们定义一个常数 callme

执行阶段

  1. 好了,我们正在打电话 fun()
    1. 我们正在声明一个函数log(),创建一个它的实例。
    2. 我们输出的定义是 log
    3. 我们叫 setTimeout()的变量函数,找到一个叫做 log - 补上 log 到事件队列
    4. 设置 callme 到 "hi iam"(注意,在编译阶段不能设置值,因为它可能涉及到执行代码,例如,如果我们做了 const x = (1).toString(),const只是意味着我们不能在初始化以外的地方设置值)
    5. 函数调用结束后,我们检测到 callme 在闭合中使用,将其附加在
  2. 10秒过后,OK事件循环检测超时,调用 log()
    1. 我们需要登录 callme - 在闭合中发现的,就记录下来。

这就是 callme 被卷入 foo的关闭。如果你坚持使用 hoisting 术语,你可以说,如果有一个闭合,那么const就会被提升。

但是,如果你的心理模型是这种两相解释,你就不需要知道所有的角落情况,什么时候会发生提升,什么时候不会。我强烈建议阅读上面链接的答案,以便更好地理解它的工作原理。

© www.soinside.com 2019 - 2024. All rights reserved.