JavaScript:内联函数与预定义函数 [英] JavaScript: inline functions vs predefined functions

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

问题描述

有人反对使用内联函数反对将预定义函数名称传递给某些处理程序,因此会给我一些论点。

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

即哪个更好:

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

对比

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



奇怪的问题,但是我们几乎在团队中为此进行斗争。


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

推荐答案

命名函数

有是此页面问答中严重滥用术语的地方。函数是否为内联(函数表达式)表示无法命名。

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.

这是使用函数表达式 >:

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

这是使用功能语句

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

两个示例都使用了命名函数,并且在调试和调试时都获得了相同的好处。配置文件工具!

如果指定了名称( function之后但括号前的文本),则无论它是否为命名功能,它都是一个命名函数内联或单独声明。如果未指定名称,则为匿名。

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".

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

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.

您应该使用哪个?

在回答您的直接问题时,如果函数可以使用,您应该使用命名函数语句可以在代码中的任何其他地方使用。如果该函数仅在一个地方使用,而在其他任何地方都没有关联,那么我将使用一个函数表达式,除非它的长度过长或感觉不合适(出于样式原因)。如果您使用内联函数表达式,则出于调试或代码清晰的目的而对其进行命名通常很有用。

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.

内存泄漏

无论您命名函数,使用函数语句还是使用函数表达式,对内存泄漏问题的影响都很小。让我尝试解释造成这些泄漏的原因。看看下面的代码:

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

在上面的代码中,当 outerFunction完成时, A超出范围并且可能是垃圾

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

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

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.

如果我们将该函数传递给setTimeout以外的其他东西怎么办?

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

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

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

同样的问题!仅当 doStuff不包含对它的引用时,才会清理 myFunction,并且仅在 myFunction被清理时才清理 A。是否使用语句或表达式都无关紧要;重要的是,是否在 doStuff中创建了对该函数的引用!

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天全站免登陆