【问题标题】:javascript closures and function placementjavascript 闭包和函数放置
【发布时间】:2010-09-19 14:57:47
【问题描述】:

函数的放置对作用域内闭包的性能有影响吗?如果是这样,放置这些功能的最佳位置在哪里?如果不是,那么闭包的隐含关联是否足以在逻辑上将函数放在另一个地方?

例如,如果 foo 不依赖于 localState 的值,那么 localState 是否可以从 foo 访问foo 的执行时间、内存使用等有影响吗?

(function(){
    var localState;

    function foo(){
        // code
    }

    function bar(){
        // code
        return localState;
    }
})();

换句话说,这会是一个更好的选择吗?如果是,为什么?

(function(){
    function foo(){
        // code
    }

    var localState;

    function bar(){
        // code
        return localState;
    }
})();

Darius Bacon 建议below 上面的两个示例是相同的,因为 localState 可以从块内的任何位置访问。但是,下面的示例 foo 在块外定义可能是不同的情况。你怎么看?

function foo(){
    // code
}

(function(){

    var localState;

    function bar(){
        // code
        foo();
        return localState;
    }
})();

【问题讨论】:

    标签: javascript performance coding-style structure closures


    【解决方案1】:

    这两个 sn-ps 是等效的,因为它们都是在您正在创建的匿名函数的(相同)环境中定义的。我认为无论哪种方式,您都可以从foo 访问localState

    话虽如此...如果您正在创建的环境中有大量变量,那么foo 的执行时间可能会受到影响,因为变量查找可能需要更长的时间。如果在定义 foo 的函数中不再使用大量变量,并且 foo 也不需要它们,那么 foo 将导致它们不被垃圾收集,这样也可以成为一个问题。

    【讨论】:

    • 事实上,要看到 JS 实际上关闭了未使用的变量,试试这个: (function(){var a=1;return function(x){eval(x)}})( )("alert(a)") 显然,内部函数没有引用a,但它是可用的。
    • 相反,在 Perl 中,sub{my$a=1;sub{eval$_[0]}}->()('print $a') 不打印任何东西,但是sub{my$a=1;sub{$a;eval$_[0]}}->()('$a') 确实:Perl 关心变量是否被引用来判断它是否被关闭。
    【解决方案2】:

    狗,我希望声明的顺序可以被 JavaScript 解释器抽象掉。在任何情况下,如果存在性能差异,那么它就会成为过早优化弊端的典型代表。

    【讨论】:

    • 第二个。让我们不要寻找更多的方法来创建不可读的代码。
    • 告诉我,安德鲁。即使有一些假设的性能提升,我也希望看到它以最简洁和最合乎逻辑的顺序编写。
    【解决方案3】:

    Javascript 中的每个函数都是一个闭包。仅当函数引用该变量时,才会产生解析变量值的运行时。例如,在这个示例中,函数 y 捕获 x 的值,即使 x 没有被 y 直接引用:

    var x = 3;
    function y() eval("x");
    y();
    3
    

    【讨论】:

      【解决方案4】:

      我认为不会有任何性能开销,因为 java 脚本不使用函数堆栈的概念。它支持词法作用域。在闭包调用中执行相同的状态。附带说明一下,在您的示例中,您似乎没有执行任何语句!

      【讨论】:

      • 你是对的!我试图用“”//代码“” cmets 来暗示一些执行,但显然不是很清楚。谢谢你的回答。
      【解决方案5】:

      var 或 function 声明的范围是它出现的整个块,无论声明在块中的哪个位置;所以它影响效率是令人惊讶的。

      也就是说,“function foo()”在这个块中是在“var localState”之前还是之后都没有关系。 可能“function foo()”是在这个块中还是在一个封闭的块中(如果它可以提升到更高的范围,因为它不使用 any local变量);这取决于您的 Javascript 编译器的详细信息。

      【讨论】:

        【解决方案6】:

        在您的示例中,差异并不重要。即使 foo 在全局范围内,您也不会有问题。

        但是,请记住,如果您使用将函数分配给变量的方式来声明函数,那么它们的声明顺序可能会成为一个很大的问题。

        为了更好的主意,请尝试以下两个示例:

        CheckOne();
        function CheckOne() {
            alert('check...check one.');
        }
        
        CheckTwo();
        var CheckTwo = function() {
            alert('check...check two.');
        };
        

        第二个和第一个之间的唯一区别是它们用于声明其函数的样式。第二个会产生参考错误。

        干杯。

        【讨论】:

          猜你喜欢
          • 2015-12-03
          • 2015-05-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-07-06
          • 2013-01-23
          相关资源
          最近更新 更多