5

与我阅读的文章一样多,我仍然有一些问题。

我已经知道(并理解)闭包的用法,例如:

  1. 臭名昭著的循环问题(链接循环,每个链接都带有警报,并保持编号)

  2. 增加的计数器(继续调用一个函数 -> 提醒增加的数字)

这里

引用其外部函数的局部变量的内部函数创建闭包

这里

闭包是函数的局部变量 - 在函数返回后保持活动状态,或者闭包是在函数返回时未释放的堆栈帧。(好像“堆栈帧”被分配而不是在堆栈上!)

请教3个问题:

问题 #1

有人告诉我,JS 中的所有函数都会创建闭包。

什么???如果我创建一个带有私有变量的普通函数,它只会创建一个范围。不关闭。

我认为关闭是这样的:(从这里开始

  1. 制作一个外部的“功能制造商”功能。
  2. 在其中声明一个局部变量。
  3. 在外部函数内部声明一个内部函数。
  4. 在内部函数中使用外部函数的变量。
  5. 让外部函数返回内部函数
  6. 运行该函数,并将其返回值分配给一个变量

示例:

function functionMaker(){
   var x = 1;
   function innerFunction(){
     alert(x);
     x++;
   }
   return innerFunction;
}

那么为什么他们说每个 js 函数都会创建闭包呢?

问题2

又名IEFA Self-Invoking Functions-Immediately Invoked Function Expression创建一个闭包吗?

看着

(function (a) {
    alert(a);
})(4);

我看不到上面的6 条规则这样的模式:这里到底在哪里Have the outer function return the inner function?我没有看到这个词return

问题 #3

function myFunction() {
  var myVar = 1;
  var alertMyVar = function () {
    alert('My variable has the value ' + myVar);
  };
  setTimeout(alertMyVar, 1000 * 3600 * 24);
}
myFunction();

难道myFunction在这里活了一整天?或者它在之后就结束了setTimeout?如果是这样,如何SetTimeOut 记住该值?

请帮我把它做对。

4

1 回答 1

8

所有函数调用都会创建一个闭包。需要注意的重要一点是闭包是否持续超过函数调用的生命周期。

如果我执行立即执行的功能:

var value = (function() {
  return 4;
})();

然后创建一个闭包,但在函数返回时丢弃。为什么?因为没有对闭包中定义的符号的幸存引用。但在这儿:

var value = function() {
  var counter = 0;
  return function() {
    return counter++;
  };
}();

闭包在立即执行的函数之后继续存在,因为它返回另一个函数,该函数又包含对原始函数中定义的“计数器”符号的引用。因为返回的函数仍然是“活动的”,所以闭包必须由运行时系统保留。

注意这里:

var value = function() {
  return function(a) {
    return "hello " + a;
  };
}();

即使外部立即执行的函数返回一个函数,该函数也不会引用外部函数的任何符号,因此无需保留闭包。

我想我想说的是,将闭包视为执行函数效果的一部分是有帮助的,而不是严格地作为静态的、结构性的东西。可能有一个函数有时会创建一个持久闭包,但并非总是如此。

于 2012-11-21T15:05:01.940 回答