关闭的Javascript性能(Javascript closures performance)

2019-07-20 05:31发布

我已经是JavaScript中工作一段时间,通常这样做只是为了缓存,在一个深层结构内声明的功能属性的值或“命名空间”

//global scope
(function ($, lib) {
  //function scope 1
  var format = lib.format, // instead of calling lib.format all the time just call format
    touch = lib.pointer.touch, //instead of calling lib.pointer.touch each time just touch
    $doc = $(document),
    log = logger.log; //not console log...


  $doc.on('app:ready', function () {
    //function scope 2
    $doc.on('some:event', function (e) {
      //function scope 3
      //use the cached variables
      log(format('{0} was triggered on the $doc object', e.type);
    });

    $doc.on(touch, function (e) {
      //function scope 3
      log(format('this should be {1} and is... {0} ', e.type, touch);
    });
  }); 
}(jQuery, lib));

我这样做的原因是:

  • 懒惰,因为我,写触摸似乎更吸引人,写lib.pointer.touch,即使与花哨的自动完成功能强大的集成开发环境可以帮助这一点,触摸较短。
  • 一个极小可能是单一的私有变量转换为一个单个字母变化,所以对我来说也是有意义(我知道,我知道,从来没有太早优化,但这似乎是安全的我猜)

所有书面这样的代码似乎在移动设备和桌面浏览器执行体面,所以这似乎是一个安全的做法(在“实践”,双关语意)。 但我因为这依赖于封闭和内部函数必须创建一个封闭保存它被宣布我不知道的情况下...

  • 如果一个函数不使用来自外部的环境变量(自由变量)......被关闭情况下仍保存? (或者,如果IA树倒在树林,没有人是那里听到,那么它仍然使飞机坠毁的声音?嘿嘿)我知道,这可能JavaScript引擎之间变化,因为关于它是否需要保存ECMA提什么当来自外部的变量没有访问上下文与否。

  • 如果上述表达式为真...将这个代码块是更有效?

     //global scope (function ($, lib) { //function scope 1 var format = lib.format, touch = lib.pointer.touch, $doc = $(document), log = console.log; $doc.on('app:ready', function () { (function ($doc, touch, lib, format) { // since all the variables are provided as arguments in this function // there is no need to save them to the [[scope]] of this function // because they are local to this self invoking function now $doc.on('some:event', function (e) { //function scope 3 //use the cached variables log(format('{0} was triggered on the $doc object', e.type); }); $doc.on(touch, function (e) { //function scope 3 log(format('this should be {1} and is... {0} ', e.type, touch); }); }($doc, touch, lib, format)); }); }(jQuery, lib)); 

是不是更有效,因为它通过这些变量自我立即调用函数? 将创建新的函数代码中的任何影响,(正或负)的成本是多少?

  • 我如何正确衡量我的JavaScript库以可靠的方式内存消耗? 我有100X一些JavaScript模块内所有直接的自我调用的功能主要是为了避免泄漏到全球范围内的变量。 所以他们都被包裹在模块非常类似的代码上面提到的块。

  • 将它有更好的效果缓存变量接近,即使这将意味着我将不得不重复变量的声明更接近他们要去哪里使用?

  • 我有一个在目前当地环境寻找一个不变量的感觉,发动机会先寻找到父范围,并在该水平遍历所有的变量...每级的更多的变数,更糟糕的可能会是表现看一个变量。

  • 试着从内部关闭未定义的变量将是最昂贵的,因为根据定义变量将在父范围内第一次搜索,直到全球范围内,并没有找到这将迫使发动机,最终达到全局范围。 真的吗? 在引擎优化这种查询的?

到底......我知道,我不会想实现我的代码作为第二个例子,主要是因为它会使代码难以阅读,我用第一种方法最终输出的最小尺寸还挺舒适。 我的问题是由好奇心和尝试了解一个好一点的JavaScript的这个非常好的功能的动机。

因此这个测试...

http://jsperf.com/closures-js

这似乎第二种方法是更快。 但是当迭代的次数一个疯狂的数字......现在我的代码没有做到这一点的迭代数......但可能是因为我的编码方式消耗更多的内存只有明显...

更新:它已经被指出,我认为这个问题太大。 我很抱歉将尝试在小零件断裂。 这个问题主要是受好奇心就像我说的动机,甚至表现在移动设备中,似乎可以忽略不计。 感谢您对所有您的反馈意见。

Answer 1:

我认为这是过早的优化。 你已经知道的表现并不在多数情况下一个问题。 即使是在紧密循环,性能不会下降那么糟糕。 让JavaScript引擎优化这种自身作为浏览器已经开始做,从关闭删除不需要的变量。

一个重要的事情是,不要使你的代码难以阅读不必要的优化。 你的榜样需要相当多的代码,阻碍发展。 在某些情况下,我们被迫使代码难以阅读,因为我们知道该应用程序的特定部分是更多的内存/性能密集型,但只有在这一点上,我们应该做的。

如果添加断点下面的代码(在Chrome),你会看到world变量进行了优化,走出封闭的,看下面变量的作用域的“封闭”节点http://jsfiddle.net/4J6JP / 1 /

(function(){
   var hello = "hello", world="world";
    setTimeout(function(){
        debugger;
        console.log(hello);
    });
})()

请注意,如果你在一个内部函数添加一个eval,那么所有的赌注都关闭,关闭不能优化。



文章来源: Javascript closures performance