Javascript:内联函数与预定义函数 [英] Javascript: Inline function vs predefined functions

查看:208
本文介绍了Javascript:内联函数与预定义函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

任何正文都可以使用内联函数来传递预定义的函数名到一些处理程序。



这更好:

 (function(){
setTimeout(function(){/ * some code here * },5);
})();

 (function(){
function invokeMe(){
/ * code * /
}
setTimeout(invokeMe,5);
}) );


奇怪的问题,

解决方案

命名的函数



问题和答案。



这是使用函数表达式

  setTimeout(function doSomethingLater(){alert('In a named function。');},5); 

这是使用函数语句

  function doSomethingLater(){alert('In a named function。'); } 
setTimeout(doSomethingLater,5);

两个例子都使用命名函数, profiling tools!



如果指定了名称(function之后但在括号前面的文本),那么它是一个命名函数,内联或单独声明。如果未指定名称,则为匿名。



注意:T.J.指出IE以不平凡的方式命名函数表达式(请参阅: http://kangax.github.com/ nf /#jscript-bugs ),这一点很重要,我只是想说明一下这个术语。



您应该使用哪个?



为了回应您的直接问题,您应该使用命名的函数语句其他地方的代码。如果函数正好在一个地方使用,并且没有任何其他相关性,那么我会使用一个函数表达式,除非它是过长的,否则感觉不合适(因为风格的原因)。如果使用内联函数表达式,那么为了调试或代码清晰度的目的,它通常很有用。



内存泄漏 / p>

无论是命名函数,使用函数语句还是使用函数表达式,都不会对内存泄漏问题产生影响。让我尝试解释什么导致这些泄漏。看看这段代码:

 (function outerFunction(){
var A ='some variable';

doStuff();
})();

在上面的代码中,当outerFunction完成A超出范围,



如果我们在其中添加一个函数怎么办?

 <$> c $ c>(function outerFunction(){
var A ='some variable';

setTimeout(function(){alert('我有权访问A是否使用');},5);
})();

在上面的代码中,我们传递给setTimeout的函数表达式引用了A (通过闭包的魔力),甚至在outerFunction完成之后A将保留在内存中,直到触发超时并取消引用函数



如果我们将该函数传递给setTimeout以外的内容,该怎么办?

 (function outerFunction(){
var A ='some variable';

doStuff(function(){alert('我有权访问A是否使用');});
} ;

function doStuff(fn){
someElement.onclick = fn;
}



现在我们传递给doStuff的函数表达式可以访问A ,甚至在outerFunction完成之后,A将保留在内存中,只要存在对我们传递给doStuff 的函数的引用。在这种情况下,我们正在创建对该函数的引用(作为事件处理程序),因此A将保留在内存中,直到该事件处理程序被清除。 (例如有人调用 someElement.onclick = null



现在看看当我们使用函数语句时会发生什么:

 (function outerFunction(){
var A ='some variable';

function myFunction(){alert('我也可以访问A');};
doStuff(myFunction);
})();

同样的问题! myFunction将被清除,只有当doStuff没有保存它的引用,A将只有清理,当myFunction被清理。不管我们使用语句还是表达式都没关系;重要的是如果在doStuff中创建对该函数的引用!


Can any body throw me some arguments for using inline functions against passing predefined function name to some handler.

I.e. which is better:

(function(){
  setTimeout(function(){ /*some code here*/ }, 5);
})();

versus

(function(){
  function invokeMe() {
    /*code*/
  }
  setTimeout(invokeMe, 5);
})();

Strange question, but we are almost fighting in the team about this

解决方案

Named functions

There is some serious misuse of terminology in the question and answers on this page. There is nothing about whether or not a function is inline (a function expression) that says you cannot name it.

This is using a function expression:

setTimeout(function doSomethingLater() { alert('In a named function.'); }, 5);

and this is using a function statement:

function doSomethingLater() { alert('In a named function.'); }
setTimeout(doSomethingLater, 5);

Both examples are using named functions and both get the same benefits when it comes to debugging and profiling tools!

If the name is specified (the text after "function" but before the parenthesis) then it is a named function regardless of whether it is inline or declared separately. If the name is not specified then it is "anonymous".

Note: T.J. points out that IE mishandles named function expressions in a non-trivial way (See: http://kangax.github.com/nfe/#jscript-bugs) and this is important to note, I'm simply trying to make a point about the terminology.

Which should you use?

In response to your direct question, you should use a named function statement if the function could ever be used from any other place in your code. If the function is being used in exactly one place and has no relevance anywhere else then I would use a function expression unless it is prohibitively long or otherwise feels out of place (for style reasons). If you use an inline function expression then it is often useful to name it anyway for the purposes of debugging or code clarity.

Memory leaks

Whether you name your function, use a function statement, or use a function expression has little impact on the memory leak issue. Let me try to explain what causes these leaks. Take a look at this code:

(function outerFunction() {
    var A = 'some variable';

   doStuff();
})();

In the code above, when "outerFunction" finishes "A" goes out of scope and can be garbage collected, freeing that memory.

What if we add a function in there?

(function outerFunction() {
    var A = 'some variable';

   setTimeout(function(){ alert('I have access to A whether I use it or not'); }, 5);
})();

In this code (above) the function expression we are passing to setTimeout has a reference to "A" (through the magic of closure) and even after "outerFunction" finishes "A" will remain in memory until the timeout is triggered and the function is dereferenced.

What if we pass that function to something other than setTimeout?

(function outerFunction() {
    var A = 'some variable';

   doStuff(function(){ alert('I have access to A whether I use it or not'); });
})();

function doStuff(fn) {
    someElement.onclick = fn;
}

Now the function expression we are passing to "doStuff" has access to "A" and even after "outerFunction" finishes "A" will remain in memory for as long as there is a reference to the function we passed into doStuff. In this case, we are creating a reference to that function (as an event handler) and therefore "A" will remain in memory until that event handler is cleared. (e.g. someone calls someElement.onclick = null)

Now look at what happens when we use a function statement:

(function outerFunction() {
    var A = 'some variable';

    function myFunction() { alert('I have also have access to A'); };
    doStuff(myFunction);
})();

The same problem! "myFunction" will be cleaned up only if "doStuff" does not hold a reference to it and "A" will only be cleaned up when "myFunction" is cleaned up. It does not matter whether we used a statement or an expression; what matters is if a reference to that function is created in "doStuff"!

这篇关于Javascript:内联函数与预定义函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆