【问题标题】:what will remain of scope of a function after it has been called?一个函数被调用后的作用域是什么?
【发布时间】:2015-08-21 14:01:01
【问题描述】:

我正在使用闭包,我来到了这段代码:

doit = true;
aww = function() {
    if(doit) {var foo; doit = false;} else {}
    foo = 0; foo += 1; return foo;
}

doit 是一个变量,aww 函数使用它只定义/删除foo 一次。
当我第一次执行aww 时,它将foo 作为一个局部变量(并设置为在以后的调用中不声明它)然后将foo 分配给0 并将其增加1。然后返回它(1)

我希望,下次我调用aww 时,foo 变量不会首先声明,因此aww 函数应该首先创建foo 并使其全局,因为它还没有被声明,它被分配给 0 之前没有任何 var。但真正发生的事情与我的预期不同。
foo 不会成为全球性的,它仍然是本地的。

假设函数执行结束后函数的作用域仍然存在,这是真的吗?
或者,如果不是,是否只有 本地声明的变量列表 保存在某处?
我读过关于闭包的文章,但并不完全理解它们。这个问题的答案让我比以前更清楚了。谢谢。

【问题讨论】:

  • 假设即使这样的列表也会存储在某个地方是不安全的,在某些情况下它可能是过早的优化。总的来说,每次调用函数时,函数体都是独立执行的。如果您想使用一些静态属性,请将其放在上层范围内(或扩充函数本身 - 毕竟它是一个对象)。

标签: javascript closures


【解决方案1】:

你的功能:

aww = function() {
    if(doit) {var foo; doit = false;} else {}
    foo = 0; foo += 1; return foo;
}

被解释为好像是这样写的:

aww = function() {
    var foo;
    if(doit) {doit = false;} else {}
    foo = 0; foo += 1; return foo;
}

该函数将始终返回 1,因为该函数始终将 foo 设置为 0,然后设置为 1。变量声明被视为出现在函数顶部。

doit 的引用是与闭包有关的部分。因为该变量在函数外部,所以函数将在第一次调用时将其值切换为 false,然后不会再次更改它。它可以访问doit并依赖其值在两次调用之间保持不变,除非其他东西可以访问doit并进行更改。

另一方面,变量foo 是函数的简单局部变量。对该函数的每次调用都会创建一个全新的foo,并且它与之前的任何foo 都没有关系。

【讨论】:

  • 说得好。 OP,请查看 javascript 变量提升以获取有关此行为的更多信息。
  • 谢谢,学到了一些东西,但仍然没有得到一些部分。您的意思是函数的范围在执行后会丢失吗?但我看到了与闭包(函数调用)不同的行为,例如页面末尾的示例Here。我看到该函数表达式的范围仍然存在,并且被内部函数add 使用。真的吗?
  • @TechJS 范围(闭包)没有丢失,但 foo 不是闭包的一部分 - 它是一个局部变量。 (如果aww 做了一些事情来暴露其本地上下文,它成为闭包的一部分,但它没有。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-19
  • 2020-10-10
相关资源
最近更新 更多