在JavaScript中声明函数

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

这两种声明函数的方式有什么区别?

function someFunc() { ... } var someFunc = function() { ... } 

我不是在技术层面上问的。 我不是问可读性更好,还是更喜欢哪种风格。

我对这里的大多数人抱有不同的看法。 从技术上来说,这个语法对于声明函数的方式可能是一样的我在最后一条语句上是不正确的,我在差异文件中读到了为什么它们在技术上是不同的,为什么我会添加 )。 但是他们在不断演变的模式中发挥作用的方式是巨大的。 我会强烈推荐Doughlas Crockford的“Javascript:The Good Parts”。

但要以微妙而简单的方式来certificate我的观点。 这是一个小例子。

 //Global function existing to serve everyone function swearOutLoud(swearWord) { alert("You "+ swearWord); } //global functions' territory ends here //here is mr. spongebob. He is very passionate about his objects; but he's a bit rude. var spongeBob = { name : "squarePants", swear : function(swearWord) { name = "spongy"; alert("You "+ swearWord); return this; } } //finally spongebob learns good manners too. EVOLUTION! spongeBob.apologize = function() { alert("Hey " + this.name + ", I'm sorry man!"); return this; } //Ask spongebob to swear and then apologize in one go (CASCADING EFFECT!!) alert(spongeBob.swear("twit").apologize()); 

如果你看看上面的代码,我宣布了一个名为swearOutLoud的函数。 哪一个会从任何对象或通话中发出一个粗言秽语,并且会给你输出。 它可以使用传递给它的“this”参数和参数对任何对象进行操作。

然而,第二个声明被声明为一个名为“spongeBob”的对象的属性。 这一点很重要, 因为在这里我正朝着一个对象驱动的行为迈进。 虽然我还保持“级联效应”,如果我没有别的东西可以返回,我会返回“这个”。

类似的东西在jQuery中完成; 如果你正在编写框架或者其他东西,这个级联模式是很重要的。 你也可以把它链接到Builder的devise模式。

但是通过将函数声明为对象的属性,我能够实现以对象为中心的行为,从而导致更好的编程范式。 除非devise得好 在全局访问之外声明的个别函数导致非面向对象的编码方式。 我不知何故更喜欢后者。

要看到级联的效果,看看最后一个声明,你可以让海绵发誓和立即道歉; 即使道歉后来被添加为属性。

我希望我明确我的观点。 从技术angular度来看可能不大; 但从devise和代码演进的angular度来看,这是巨大的,并使世界有所不同。

但那只是我! 要么接受,要么离开它。 🙂

编辑:

所以这两个电话在技术上是不同的; 因为命名声明与全局命名空间绑定,并在parsing时定义。 所以甚至可以在函数声明之前调用。

  //success swearOutLoud("Damn"); function swearOutLoud(swearWord) { alert("You " + swearWord) } 

上面的代码将正常工作。 但是下面的代码不会。

 swear("Damn!"); var swear = function(swearWord) { console.log(swearWord); } 

使用function someFunc() { ... }一个优点是函数名称出现在Firebugdebugging器中。 以另一种方式声明的var someFunc = function() { ... }var someFunc = function() { ... } )是匿名的

风格明智的第二个例子是更一致的其他常见的方式来声明函数,因此可以认为它更可读

 this.someFunc = function() { ... } ... someFunc: function() { ... }, 

但是,也提到它是匿名的,因此分析时不会显示该名称。 另一种声明函数的方法如下,它使你两全其美

 var someFunc = function someFunc() { ... } 

实际上,区别在于第二个声明使我们能够声明像这样的函数,使得可以将函数作为对象的属性:

 var myObject=new Object(); myObject.someFunc=function() { ... }; 

另一个区别是,在大多数浏览器上,后者允许你根据情况定义不同的实现,而前者不会。 假设你想跨浏览器事件订阅。 如果你试图这样定义一个addEventListenerTo函数:

 if (document.addEventListener) { function addEventListenerTo(target, event, listener) { .... } } else if (document.attachEvent) { function addEventListenerTo(target, event, listener) { .... } } else { function addEventListenerTo(target, event, listener) { .... } } 

在一些浏览器上,所有的函数都被parsing,最后一个优先。 结果:以上只是不起作用。 然而,将匿名函数分配给variables是可行的。 您还可以使用分配给variables的匿名函数来应用function性和基本的面向方面编程技术。

 var fib = memoize(function (n) { if (n < 0) return 0; if (n < 2) return 1; return fib(n-1) + fib(n-2); }); ... // patch the $ library function if (...) { $ = around($, fixArg, fixResult); } 

第一种forms是对的:

 function test() { } 

是一种更为公认的语法,第二种forms是:

 var test = function() { ... } 

允许你控制函数的范围(通过使用var;没有它,它将是全球无论如何)。

而且你甚至可以同时做两个:

 var test = function test() { ... test(); ... } 

这允许你以第二种forms定义一个recursion函数。

为了可读性,我会说第一个显然更好。 一个未来的维护程序员,即使假设他们熟悉javascript并且知道在这个线程中出现的许多细节,他们也会采用第一种格式。

例如,如果他们有一天想要按Ctrl-f来search你的函数的定义来看看里面发生了什么,他们是要先searchsomeFunc = function()还是function someFunc()

而且,为了得到彻底的印刷(因为我们正在谈论可读性)读者经常快速地扫描文本,并且如果他们正在寻找函数定义,则更倾向于跳过以“var”开头的行。

我知道这是一个非技术性的答案,但人类阅读代码比计算机更难。

当你写

 function Test() { } 

JavaScript实际上正在创build一个属性,它为其分配一次调用的函数对象将执行函数定义中报告的代码。 该属性附加到对象window或包含函数定义的对象。