在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作为原型。
详细研究原型继承,如果你想真正得到它的实用性。 道格拉斯克罗克福德在他的一次谈话中详细谈到了这一点)。
命名功能没有什么优势
functionInstance.name
会显示你的名字。 命名函数表达式有一个缺点
除了较少的文体控制之外,函数声明没有缺点
链接地址: http://www.djcxy.com/p/2829.html上一篇: Are named functions or anonymous functions preferred in JavaScript?