首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JavaScript:内联函数与预定义函数

JavaScript:内联函数与预定义函数
EN

Stack Overflow用户
提问于 2010-03-29 15:38:20
回答 13查看 94.6K关注 0票数 45

有人可以抛出一些参数,用于使用内联函数将预定义的函数名称传递给某个处理程序。

即哪一种更好:

代码语言:javascript
复制
(function() {
  setTimeout(function() { /*some code here*/ }, 5);
})();

对比

代码语言:javascript
复制
(function() {
  function invokeMe() {
    /*code*/
  }
  setTimeout(invokeMe, 5);
})();

奇怪的问题,但我们几乎是在为这个而战。

EN

回答 13

Stack Overflow用户

回答已采纳

发布于 2012-01-06 23:55:56

命名函数

在本页的问题和答案中存在一些严重的术语滥用。一个函数是否是内联的(一个函数表达式)并不表示你不能命名它。

这是使用函数表达式

代码语言:javascript
复制
setTimeout(function doSomethingLater() { alert('In a named function.'); }, 5);

这是使用函数语句

代码语言:javascript
复制
function doSomethingLater() { alert('In a named function.'); }
setTimeout(doSomethingLater, 5);

这两个示例都在使用命名函数,而且在调试和分析工具方面都有相同的好处!

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

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

你应该使用哪一个

在回答您的直接问题时,如果函数可以从代码中的任何其他位置使用,则应该使用命名函数语句。如果该函数仅在一个地方使用,并且在任何其他地方都没有关联,那么我将使用一个函数表达式,除非它长得令人望而却步,或者感觉不合适(出于风格原因)。如果您使用内联函数表达式,那么为了调试或代码清晰的目的,给它命名通常是有用的。

内存泄漏

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

代码语言:javascript
复制
(function outerFunction() {
    var A = 'some variable';

   doStuff();
})();

在上面的代码中,当"outerFunction“完成"A”超出作用域时,可以被垃圾收集,从而释放该内存。

如果我们在里面增加一个函数呢?

代码语言:javascript
复制
(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“之后,”A“仍将留在内存中,直到触发超时和取消引用为止。

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

代码语言:javascript
复制
(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“完成"A”之后,只要有对传递到doStuff的函数的引用,也将保留在内存中。在本例中,我们将创建对该函数的引用(作为事件处理程序),因此"A“将保留在内存中,直到清除该事件处理程序。(例如有人叫someElement.onclick = null)

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

代码语言:javascript
复制
(function outerFunction() {
    var A = 'some variable';

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

同样的问题!"myFunction“只有在"doStuff”不包含对它的引用时才会被清除,而"A“只有在"myFunction”被清除时才会被清除。不管我们是使用语句还是表达式,重要的是是否在"doStuff“中创建了对该函数的引用!

票数 57
EN

Stack Overflow用户

发布于 2010-03-29 15:45:17

两者之间有一个显著的区别:后者有一个名字。

我喜欢帮助我的工具帮助我,所以我主要是避免匿名函数,因为我的工具不能给我关于它们的有意义的信息(例如,在调试器的调用堆栈列表中,等等)。所以我会用

代码语言:javascript
复制
(function(){
  function invokeMe() {
    /*code*/
  }
  setTimeout(invokeMe, 5);
})();

一般为...form。然而,规则是要被打破的,而不是屈从于奴隶。:-)

注意,根据规范,还有第三种选择:您可以有一个内联函数,它也有一个名称:

代码语言:javascript
复制
(function(){
  setTimeout(function invokeMe(){ /*some code here*/ }, 5);
})();

但问题是,到目前为止,微软的每个版本的JavaScript解释器("JScript"),包括(令人惊讶地) IE9中的一个版本,都不正确地命名函数表达式,并在不同的时间创建2完全不同的函数。(证明,可以在IE9或更早的浏览器中尝试,也可以在其他浏览器中使用。)IE有两种错误: 1.它创建两个独立的函数对象;2.由于其中一个函数对象,它将名称符号“流”到表达式的包围范围中(这明显违反了规范的第13条 )。详细信息:http://blog.niftysnippets.org/2010/09/double-take.html

票数 11
EN

Stack Overflow用户

发布于 2010-03-29 15:42:52

海事组织,声明一个函数只有在你打算以后以其他方式重复使用它的时候才是有用的。

我个人对setTimeout处理程序使用函数表达式(第一种方式)。

但是,您可能想知道函数声明和函数表达式之间的区别,我建议您阅读以下文章:

  • 命名函数表达式
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2539205

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档