在JavaScript中声明函数

时间:2009-12-18 02:50:06

标签: javascript syntax function

  

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

这两种声明功能的方式之间有什么区别?

function someFunc() { ... }

var someFunc = function() { ... }

我不是在技术意义上问。我不是问哪个更易于阅读,或者哪种风格更受欢迎。

8 个答案:

答案 0 :(得分:48)

我和大多数人在这里有不同的看法。 从技术上讲,这种语法对于双向声明函数意味着相同我在上一次声明中表示不正确。我读了一篇差异文章,为什么它们在技术上是差异的,我最后会添加,为什么) ;但他们在不断发展的模式中发挥作用的方式是巨大的。我强烈推荐Doughlas Crockford的“Javascript:The Good Parts”。

但要以微妙和简单的方式证明我的观点;这是一个小例子。

//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设计模式。

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

要查看级联效果,请查看最后一条声明,您可以让海绵宝宝立刻发誓并道歉;即使后来道歉被添加为属性。

我希望我明确指出。从技术角度来看,差异可能很小;但从设计和代码演变的角度来看,它是巨大的,并创造了一个与众不同的世界。

但那就是我!要么接受,要么离开它。 :)

修改

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

 //success
 swearOutLoud("Damn");

function swearOutLoud(swearWord) {
    alert("You " + swearWord)
}

以上代码将正常运行。但是下面的代码不会。

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

答案 1 :(得分:14)

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

答案 2 :(得分:5)

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

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

答案 3 :(得分:5)

样式方面,第二个例子与声明函数的其他常用方法更加一致,因此可以认为它更具可读性

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

但是,正如前面提到的那样它是匿名的,因此在分析时不会出现名称。 宣布该功能的另一种方式如下,它可以让你充分利用这两个世界

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

答案 4 :(得分:2)

另一个不同之处在于,在大多数浏览器中,后者允许您根据环境定义不同的实现,而前者则不允许。假设您想要跨浏览器事件订阅。如果您试图定义addEventListenerTo函数:

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

在某些浏览器上,所有函数最终都被解析,最后一个函数优先。结果:以上情况不起作用。但是,将匿名函数分配给变量将起作用。您还可以使用分配给变量的匿名函数来应用函数和基本aspect oriented programming技术。

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

答案 5 :(得分:2)

第一种形式都是如此:

function test() { }

是一种更公认的语法,第二种形式是:

var test = function() { ... }

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

你甚至可以做到这两点:

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

这允许您以第二种形式定义递归函数。

答案 6 :(得分:1)

写作时

function Test() {
}

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

答案 7 :(得分:1)

为了便于阅读,我会说第一个显然更好。未来的维护程序员,即使假设他们已经熟悉javascript以了解该线程中出现的许多细节,也将采用第一种格式。

例如,如果有一天他们想要ctrl-f来搜索你的函数的定义以查看那里发生了什么,他们是否会首先搜索someFunc = function()function someFunc()

另外,为了获得关于它的完整印刷(因为我们说的是可读性),读者经常快速扫描文本,并且如果他们正在寻找的话,更倾向于跳过以“var”开头的行。功能定义。

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