在JavaScript中首选命名函数或匿名函数?

可能重复:
JavaScript:var functionName = function(){} vs function functionName(){}

有两种可能的方法在Javascript中提取函数:

var foo = function() { ... } 

(这是有点人为的;另一种常见的模式是:

 var foo = { baz: 43, doSomething:function() { ... } } 

 function foo() { ... } 

有一个明确的理由喜欢一个或另一个?

这一切都归结于你声明你的职能的地方。 吊装。

函数声明和variables声明总是被JavaScript解释器无形地移动(“提升”)到其包含范围的顶部。 显然,函数参数和语言定义的名字已经存在。 这意味着这样的代码:

 function foo() { bar(); var x = 1; } 

实际上是这样解释的:

 function foo() { var x; bar(); x = 1; } 

请注意,声明的分配部分未被悬挂。 只有名字被悬挂。 函数声明并不是这样,整个函数体也会被挂起。

 function test() { foo(); // TypeError "foo is not a function" bar(); // "this will run!" var foo = function () { // function expression assigned to local variable 'foo' alert("this won't run!"); } function bar() { // function declaration, given the name 'bar' alert("this will run!"); } } test(); 

在这种情况下,只有函数声明将其主体悬挂在顶部。 “foo”这个名字被吊起来了,但遗体被遗忘了,在执行过程中被分配。

您可以给函数expression式中定义的函数赋予名称,语法就像函数声明一样。 这不是一个函数声明,这个名字不在范围之内,也没有被挂起。

 foo(); // TypeError "foo is not a function" bar(); // valid baz(); // TypeError "baz is not a function" bin(); // ReferenceError "bin is not defined" var foo = function () {}; // anonymous function expression ('foo' gets hoisted) function bar() {}; // function declaration ('bar' and the function body get hoisted) var baz = function bin() {}; // named function expression (only 'baz' gets hoisted) foo(); // valid bar(); // valid baz(); // valid bin(); // ReferenceError "bin is not defined" 

所以,如果你的首选是提升function的顶部使用function declaration否则使用expression 。 我更喜欢后者,因为我通常使用方法作为function expressions构build对象文字。

命名的function expressions在抛出错误时可以很方便。 控制台会告诉你该函数是什么,而不是陈述anonymous又名堆栈跟踪

你在这里遇到了一些不同的事情,但是我会先尝试打你的主要问题。

一般来说….

function() { ... }是一个函数expression式 。 在语法上,这与2[4,5]级别相同。 这代表了一个价值 。 所以做var foo=function(){ ... }将按照计划进行工作。

function foo() { ... }是一个函数声明。 这可能看起来像var foo=function(){...} ,但是有个小警告。 作为一个声明,它类似于JS中variables提升的概念(基本上,所有variables声明都是在任何expression式被评估之前完成的)。

一个很好的例子是从这里 :

 function test() { foo(); // TypeError "foo is not a function" bar(); // "this will run!" var foo = function () { // function expression assigned to local variable 'foo' alert("this won't run!"); } function bar() { // function declaration, given the name 'bar' alert("this will run!"); } } test(); 

基本上可变的提升已经把价值带到了顶端,所以这个代码在理论上是等价的:

 function test() { var foo;//foo hoisted to top var bar=function(){//this as well alert("this will run!"); } foo(); // TypeError "foo is not a function" bar(); // "this will run!" var foo = function () { // function expression assigned to local variable 'foo' alert("this won't run!"); } } 

注意:我想借此说JS解释者很难遵循理论,因此不build议对他们的某些行为有信任。 在这里,你会发现一个很好的例子,在理论和实践最终不起作用的部分结尾(还有一些关于expression式和声明的更多细节)。

有趣的事实:在括号中包装function foo() {...}将其从一个声明转换为一个expression式,这可能导致一些奇怪的代码

 (function foo() { return 1; })();// 1 foo; //ReferenceError: foo is not defined 

如果您没有理由请不要这样做。


总结 var foo=function(){ ... }是一个类似于函数foo(){ ... }函数,除了前者在你认为应该做的事情上做了什么,而后者却是奇怪的东西除非你把它包装在parens里面,但是弄乱了范围,JS解释器允许你做规范中被认为是语法错误的东西,这样你就可以相信错误的东西实际上是正确的,等等。

请使用函数expression式var f=function(){...} )。 没有什么真正的理由不要这样做,特别是考虑到当你使用点语法的时候你有点被迫这样做。


关于第二件事,你碰到…..

我真的不知道该说些什么,这与其他一切完全不同。

 var foo = { baz: 43, doSomething:function() { ... } } 

这被称为对象文字语法。 基于这种语法的JSON是格式化数据的一种非常简洁的方式, JS中的这种语法经常被用来声明新的对象,比如单例对象(避免了声明一个函数和使用新的一切) 。 它也可以像使用XML一样使用,并且是所有酷的孩子们的首选。

无论如何,基本上对象文字的语法是这样的:

 { name1: val1, .... namek:valk } 

这个expression式是一个具有初始化值的对象。 所以做var obj={ name1: val1, .... namek:valk }意味着:

 obj.name1==val1; obj['name1']==val1;// x['y'] is the same thing as xy ... obj.namek==valk; 

那么这与我们的例子有什么关系呢? 基本上你的expression式经常被用来声明单例对象。 但是它也可以用来声明一个对象的原型,所以稍后有人可以做var newObj = Object.create(foo),newObj将foo作为原型。

仔细研究原型inheritance,如果你想真正得到它是​​多么有用。 道格拉斯·克罗克福德(Douglas Crockford)在他的一次谈话中详细谈到了这一点)。

命名function没有什么优势

  • 名称为元分析。 functionInstance.name会显示你的名字。
  • 更重要的是,这个名字将被打印在堆栈中。
  • 名字也有助于编写自我logging或识字代码。

命名函数expression式有一个缺点

  • IE有NFE的内存泄漏

除了较less的文体控制之外,函数声明没有缺点

你的问题实际上由两部分组成,因为如果你的函数被分配给一个variables或者属性,你不一定非要匿名。

命名vs匿名?

@Raynos清楚地突出了要点。 关于命名函数的最好的部分是它们将显示在堆栈跟踪中。 即使在函数被分配给variables/属性的情况下,给你的函数起一个名字只是为了帮助debugging,但是我不会说匿名函数是邪恶的。 他们确实有一个很好的目的:

匿名函数在JavaScript中是不好的做法吗?

函数声明与函数expression式?

对于问题的这一部分,我会向你提出这个问题,因为它可能比我能深入的讨论更多的话题

var functionName = function(){} vs function functionName(){}