带有闭包的 Javascript 性能

标签 javascript performance closures

var name = function(n) {
    var digits = ['one','two','three','four'];
    return digits[n];
}

var namenew = (function() {
    digits = ['one','two','three','four'];
    return function(n) {
        return digits[n];
    }
}());

两个版本的输出相同,但据说第二个版本比第一个版本快得多。

据我了解,第一个版本每次都会执行该函数,而第二个版本存储执行结果。这就是让我作为功能性/常规 OOPS 程序员感到困惑的原因。

如何保存一个函数及其内部上下文?幕后发生了什么?有人可以澄清一下吗?

最佳答案

该问题的真正答案大约有 3 页长。但我尽量让它尽可能短。 ECMA-/Javascript 都是关于Execution ContextsObject 的。 ECMAscript 中的上下文分为三种基本类型:全局上下文函数上下文eval 上下文

每次您调用一个函数时,您的引擎都会在它自己的函数上下文中生成它。此外,还创建了一个名为 Activation object 的对象。这个神秘对象是 function context 的一部分,它至少包括:

  • [[作用域链]]
  • 激活对象
  • “这个”上下文值

在不同的引擎上可能会有更多的属性,但这三个是任何ES实现所必需的。不过,回到主题。如果调用函数上下文,所有 父上下文(或更准确地说,父上下文中的 Activation 对象)都被复制到 [[Scope]] 属性。你可以把这个属性想象成一个数组,里面存放着 (Activation-) 对象。现在,任何与函数相关的信息都存储在 Activation 对象中(形式参数、变量、函数声明)。

在您的示例中,digits 变量存储在 namenew 的激活对象中。第二个是在创建内部匿名函数时,将 Activation 对象 添加到它的 [[Scope]] 属性中。当您在那里调用 digits[n] 时,Javascript 首先尝试在其自己的 Activation 对象中找到该变量。如果失败,则搜索进入 Scopechain。瞧,我们在那里找到了变量,因为我们从外部函数复制了 AO。

为了简短的回答我已经写了太多了,但是要真正很好地回答这样的问题你必须在这里解释一些关于 ES 的基础知识。我想这足以让您了解“幕后”到底发生了什么(还有很多东西需要了解,如果您想阅读更多内容,我会给您一些引用资料)。


你要求它,你得到它:

http://dmitrysoshnikov.com/ecmascript/javascript-the-core/

关于带有闭包的 Javascript 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6614572/

相关文章:

javascript - 在 JavaScript 中按类型访问元素

performance - 获取所有 Neo4j 节点和关系的最快方法?

JavaScript 循环;获取当前变量

jquery - 如何将 jquery 自动完成与 var 一起使用?

javascript - Jquery 只更新第一个匹配的 div 中的元素

javascript - expo 文档选择器未显示上传文件

javascript - 在 Node 中本地使用 dynamodb 时出现 "Could not load credentials from any providers"

c# - 关于缓存的线程安全 IEnumerable<T> 实现的性能

MySQL 跟踪慢速更新语句

javascript - TypeScript 闭包——一个 "almost"的解决方案