2008-10-28 100 views
3

函数的放置是否影响范围内闭包的性能?如果是这样,放置这些功能的最佳位置在哪里?如果不是的话,隐含的关联是否足够理由将逻辑上的某个功能置于另一个地方?javascript关闭和函数放置

例如,如果不依赖于localState的价值,确实的事实,localState是访问从必须为的执行时间,内存使用的影响,等等。?

(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; 
    } 
})(); 

回答

3

在Javascript中的每个函数是一个闭包。只有当变量被函数引用时才会解析变量值。例如,在这个例子中函数y捕捉即使X不是用y直接引用的x的值:

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

var或function声明的范围是它显示的整个块,而不管声明在块中的哪个位置;所以它会影响效率会令人惊讶。

也就是说,它不应该的问题“函数foo()”是之前还是之后“VAR localState”这个区块内。它可以也罢“函数foo()”是该块或包围一个(如果它可以被提升到一个更高的范围,因为它不使用任何局部变量);这取决于你的Javascript编译器的细节。

2

,我不认为会有任何性能开销,因为Java脚本不使用函数栈的概念。它支持词法范围。在关闭调用中执行相同的状态。在附注中,在你的例子中,你似乎没有执行任何语句!

+0

你说得对!我试图暗示用“”// code“”注释来执行一些执行,但显然不是很清楚。感谢您的回答。 – brad 2008-10-28 17:24:07

5

两个那些片段是等价的,因为他们都在你创建匿名函数(下同)环境中定义。我想你无论如何都可以从foo访问localState

这就是说......如果在创建的环境中存在大量变量,那么foo的执行时间可能会受到影响,因为变量查找可能需要更长的时间。如果在函数中不再使用大量变量,则您定义foofoo也不需要它们,那么foo将导致它们不被垃圾收集,因此这也可能是问题。

+0

事实上,一看就知道JS其实不关过未使用的变量,试试这个:(函数(){VAR一个= 1;复位功能(X){的eval(X)}})()(“警报(一) “)显然,内部函数没有提及`a`,但它是可用的。 – ephemient 2008-10-28 20:12:57

+0

相反,在Perl中,子{我的$ a = 1;子{EVAL $ _ [0]}} - >()( '打印$ a')中,不打印任何东西,但子{我的$ a = 1时;子{$一个; EVAL $ _ [0]}} - >()( '$ A')的作用:Perl的关心该变量是否被引用,以确定它是否被关闭了。 – ephemient 2008-10-28 20:18:22

5

狗,我希望声明的顺序会是这样的JavaScript解释器将抽象掉。无论如何,如果存在性能差异,那么将其作为过早优化弊端的海报孩子是非常小的。

0

在你的例子的差异将没有真正的问题。即使foo在全球范围内,你也不会有问题。

然而,这是非常有用的记住,如果你使用为变量分配功能的风格来声明你的函数中,他们声明会变得非常有问题的顺序。

对于一个更好的主意,请尝试以下两个例子:

CheckOne(); 
function CheckOne() { 
    alert('check...check one.'); 
} 

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

第二和第一之间唯一的区别是他们使用申报功能的风格。第二个生成参考错误。

干杯。