javascript - 当 JavaScript 函数作为变量关闭时会发生什么?

标签 javascript function closures

我读过很多关于 SO 上的闭包和 JavaScript 的问题,但是我找不到有关函数闭包时会发生什么的信息。通常示例是字符串文字或简单对象。请参阅下面的示例。当您在函数中关闭时,即使您稍后更改原始函数,也会保留原始函数。

从技术上来说,闭包中保存的函数会发生什么?它是如何存储在内存中的?如何保存?

请参阅以下代码作为示例:

var makeFunc = function () {
  var fn = document.getElementById;  //Preserving this, I will change it later

  function getOriginal() {
    return fn;  //Closure it in
  }

  return getOriginal;
};

var myFunc = makeFunc();
var oldGetElementById = myFunc();  //Get my preserved function

document.getElementById = function () {  //Change the original function
  return "foo"
};

console.log(oldGetElementById.call(document, "myDiv"));  //Calls the original!
console.log(document.getElementById("myDiv"));   //Returns "foo"

最佳答案

感谢您的评论和讨论。根据您的建议,我发现了以下内容。

What technically happens to the function preserved in a closure?

将函数视为对象与将任何其他简单对象视为闭包变量(例如字符串或对象)没有什么不同。

How is it stored in memory? How is it preserved?

为了回答这个问题,我不得不深入研究一些有关编程语言的文本。 John C. Mitchell's Concepts in Programming Languages解释了闭包变量通常最终出现在程序堆中。

Therefore, the variables defined in nesting subprograms may need lifetimes that are of the entire program, rather than just the time during which the subprogram in which they were defined is active. A variable whose lifetime is that of the whole program is said to have unlimited extent. This usually means they must be heap-dynamic, rather than stack-dynamic.

更具体地针对 JavaScript 运行时,Dmitry Soshnikov describes

As to implementations, for storing local variables after the context is destroyed, the stack-based implementation is not fit any more (because it contradicts the definition of stack-based structure). Therefore in this case closured data of the parent context are saved in the dynamic memory allocation (in the “heap”, i.e. heap-based implementations), with using a garbage collector (GC) and references counting. Such systems are less effective by speed than stack-based systems. However, implementations may always optimize it: at parsing stage to find out, whether free variables are used in function, and depending on this decide — to place the data in the stack or in the “heap”.

此外,Dmitry 展示了函数闭包中父作用域的各种实现:

As we mentioned, for optimization purpose, when a function does not use free variables, implementations may not to save a parent scope chain. However, in ECMA-262-3 specification nothing is said about it; therefore, formally (and by the technical algorithm) — all functions save scope chain in the [[Scope]] property at creation moment.

Some implementations allow access to the closured scope directly. For example in Rhino, the [[Scope]] property of a function corresponds to a non-standard property __parent__.

关于javascript - 当 JavaScript 函数作为变量关闭时会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30629415/

相关文章:

C++:处理不同大小数组的函数

function - 为什么追加函数调用时函数执行顺序似乎颠倒了?

javascript - 如何清除所有 javascript 超时?

c - 使用函数指针设置函数参数

JavaScript 循环;获取当前变量

javascript - 如何在 Tampermonkey 中获取 cookie?

javascript - insidehtml 中的警报按钮

javascript - 我的 javascript 闭包写得正确吗?

javascript - 如何读取 VueJs 中元素的 data-*?

javascript - Meteor JS 全局函数