Are named functions preferred over anonymous functions in JavaScript?
Possible Duplicate:
JavaScript: var functionName = function() {} vs function functionName() {}
在javascript中,有两种可能的方法来提取函数:
1 | var foo = function() { ... } |
这有点做作;另一个常见的模式是:
1 2 3 4 5 6 | var foo = { baz: 43, doSomething: function() { // ... } } |
对战
1 2 3 | function foo() { // ... } |
是否有明确的理由选择其中一个?
所有这些都取决于你在哪里声明你的功能;提升。
函数声明和变量声明总是被javascript解释器无形地移动("提升")到其包含范围的顶部。显然,函数参数和语言定义的名称已经存在。这意味着这样的代码:
1 2 3 4 | function foo() { bar(); var x = 1; } |
实际解释如下:
1 2 3 4 5 | function foo() { var x; bar(); x = 1; } |
注意声明的分配部分没有被提升。只有名字被提升。这与函数声明不同,整个函数体也将被提升。
1 2 3 4 5 6 7 8 9 10 11 | 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"这个名字被提升了,但是尸体被留在后面,在执行过程中被分配。
您可以为函数表达式中定义的函数命名,语法类似于函数声明。这不会使其成为函数声明,也不会将名称纳入范围,也不会提升主体。
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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" |
因此,如果您的偏好是让功能提升到顶部,则使用
当抛出错误时,名为
你在这里碰到了几个不同的问题,但我会先回答你的主要问题。
一般来说。。。。
这里有一个很好的例子:
1 2 3 4 5 6 7 8 9 10 11 | 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(); |
基本上,可变起重已经将该值提升到顶部,因此该代码(理论上)相当于:
1 2 3 4 5 6 7 8 9 10 11 12 | 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解释器很难遵循理论,因此不建议将它们信任于有些不确定的行为。在这里,您将在一节的末尾找到一个很好的例子,理论和实践最终都不起作用(还有一些关于表达式与声明主题的更多细节)。
有趣的事实:将
1 2 | (function foo() { return 1; })();// 1 foo; //ReferenceError: foo is not defined |
如果你没有理由,请不要这样做。
摘要
请使用函数表达式(
在你接触到的第二件事上……
我真的不知道该说什么,这有点完全不同于其他一切。
1 2 3 4 5 6 | var foo = { baz: 43, doSomething:function() { ... } } |
这被称为对象文本语法。基于这种语法的JSON是格式化数据的一种非常好的方法,而JS中的这种语法通常用于声明新对象,例如,使用singleton对象(避免在声明函数和使用new时出现所有混乱)。它也可以用同样的方式使用XML,并且是所有酷孩子的首选…
总之,基本上,对象文本语法的工作方式如下:
1 | { name1: val1, .... namek:valk } |
此表达式是一个对象,其上初始化了某些值。这样做意味着:
1 2 3 4 | 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作为原型。
如果您真的想了解原型继承有多有用,请详细研究它。道格拉斯·克罗克福德在他的一次多次会谈中详细谈到了这一点)。
命名函数没有什么优势
- 元分析的名称。
functionInstance.name 会告诉你名字。 - 更重要的是,名称将打印在堆栈跟踪中。
- 名字也有助于编写自我记录或识字代码。
命名函数表达式有一个缺点
- IE有NFE的内存泄漏
除了较少的风格控制之外,函数声明没有缺点
您的问题实际上由两部分组成,因为如果将函数分配给变量或属性,则不必使函数匿名。
命名vs匿名?
@雷诺斯清楚地强调了要点。关于命名函数最好的部分是它们将在堆栈跟踪中显示自己。即使在将函数分配给变量/属性的情况下,最好为函数命名以帮助调试,但是我不会说匿名函数是邪恶的。它们确实有很好的用途:
匿名函数在JavaScript中是一个坏习惯吗?
函数声明与函数表达式?
关于这个问题的那一部分,我建议你参考这个问题,因为它可能比我所能涵盖的更深入地涵盖了这个主题。
var functionname=function()vs function functionname()