Javascript中的闭包是否获得对完整外部函数的引用,或者它们是否仅获取对它们实际使用的变量的引用?

时间:2011-02-09 15:48:11

标签: javascript closures

出于好奇,JavaScript中的闭包是否获得对整个“外部环境”的引用,或者分析返回的函数以查看它引用的外部作用域中的哪些变量,然后只获取对这些变量的引用?

2 个答案:

答案 0 :(得分:6)

理论上,JavaScript中的嵌套函数可以访问所有包含范围内的所有变量。遇到标识符时,会根据范围链解析它,该列表包含的对象的属性是变量,每个包含执行上下文的函数参数(即封闭函数),最里面的第一个,加上最后的全球对象。函数对象随身携带它的范围链。

但是,这些Variable对象和作用域链只是规范构造,不能直接访问,因此实现可以自由地进行任何优化,包括分析函数代码,只暴露函数和任何函数访问的变量嵌套在其中,只要规范总是看起来满足。但是,最好假设如果你有一个巨大的对象可以通过一个函数的闭包来访问,那么这个巨大的对象至少会被粘住,直到该函数被垃圾收集。

如果您想了解更多相关信息,请阅读ECMAScript规范。一个很好的起点是第10.1.4节:http://bclary.com/2004/11/07/#a-10.1.4。这不是规范的当前版本,而是所有当前主流浏览器实现的基准。

答案 1 :(得分:5)

答案是“是和否”。当函数“泄漏”函数激活时,整个上下文将保留 * 。但是,由于无法引用上下文本身,函数的代码无法“调查”上下文。因此:

function leaker() {
  var i = 100, j = "hello there";
  return function() {
    i = i - 1;
    return i == 0;
  }
}

返回的函数只能引用“i”。变量“j”可能会存在,但返回的函数中的代码无法“找到”它。

* 我写的是保留了上下文,我认为这是正确的,但从技术上讲,这是解释器/运行时的业务。