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

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

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

var foo = function() { ... }

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

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

function foo() { ... }

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


这一切都取决于你声明你的函数的位置; 吊装。

函数声明和变量声明总是通过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'这个名字被吊起来了,但尸体被留下,在执行过程中被分配。

您可以给函数表达式中定义的函数赋予名称,其语法如函数声明。 这并不是一个函数声明,这个名字也没有被引入范围,也没有被提升。

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 declaration否则使用expression 。 我更喜欢后者,因为我通常使用方法作为function expressions来构建对象文字。

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


你在这里遇到了两件不同的事情,但我会先尝试点击你的主要问题。

一般来说....

function() { ... }是一个函数表达式。 在语法上,这与2[4,5]具有相同的级别。 这代表一个价值 。 因此,每次执行var foo=function(){ ... }都会按计划运行。

function foo() { ... }是一个函数声明。 这看起来可能与var foo=function(){...}做同样的事情,但是有一个小警告。 作为一个声明,它的作用类似于JS中变量提升的概念(基本上,所有变量声明都是在评估任何表达式之前完成的)。

一个很好的例子就是来自这里:

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解释器很难遵循理论,所以不建议相信它们有点不确定的行为。 在这里你会发现一个很好的例子,在理论和实践最终无法工作的部分结尾(还有一些关于表达式与声明主题的更多细节)。

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

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

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


总结 var foo=function(){ ... }是* sorta kinda *与函数foo(){ ... }相同,只不过前者在你认为它应该做的地方做了它,而后者做了一些奇怪的事情除非你把它包装在parens中,但是这会弄乱范围,JS解释器允许你在规范中做一些被认为是语法错误的东西,这样你就会相信错误的东西实际上是正确的,等等......

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


谈到你碰到的第二件事.....

我不太确定该说什么,这与其他所有内容完全不同。

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

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

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

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

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

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

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

详细研究原型继承,如果你想真正得到它的实用性。 道格拉斯克罗克福德在他的一次谈话中详细谈到了这一点)。


命名功能没有什么优势

  • meta分析的名称。 functionInstance.name会显示你的名字。
  • 更重要的是,该名称将被打印在堆栈轨迹中。
  • 名字也有助于编写自我记录或识字代码。
  • 命名函数表达式有一个缺点

  • IE有NFE的内存泄漏
  • 除了较少的文体控制之外,函数声明没有缺点

    链接地址: http://www.djcxy.com/p/2829.html

    上一篇: Are named functions or anonymous functions preferred in JavaScript?

    下一篇: Declaring functions in JavaScript