Javascript 什么';当我使用;传统的;C风格的函数声明?
我知道有几种方法可以在JavaScript中定义函数。最常见的两种是:Javascript 什么';当我使用;传统的;C风格的函数声明?,javascript,function,Javascript,Function,我知道有几种方法可以在JavaScript中定义函数。最常见的两种是: (1) function add (a, b) { return a + b; } (2) var add = function (a, b) { return a + b; } 我认为函数是一个可以像其他变量一样传递的对象。所以我完全理解(2)在做什么。它正在创建一个函数并将所述函数分配给add(假设这是在全局范围内,因此add是一个全局变量)。但是如果我用(
(1) function add (a, b) {
return a + b;
}
(2) var add = function (a, b) {
return a + b;
}
我认为函数是一个可以像其他变量一样传递的对象。所以我完全理解(2)
在做什么。它正在创建一个函数并将所述函数分配给add
(假设这是在全局范围内,因此add
是一个全局变量)。但是如果我用(1)
来代替,会发生什么呢?我已经知道它对执行顺序有影响:如果我使用(1)
,那么我可以在代码中定义add()
的点之前引用add()
,但是如果我使用(2)
,那么我必须将我的函数分配给add
,然后才能开始引用add()
(1)
仅仅是(2)
的一个快捷方式吗,尽管它的行为与其他C风格语言一样,允许我们在使用它的点“下方”定义函数?或者它在内部是一种不同类型的功能?哪一个更符合JavaScript的“精神”(如果这个术语不太模糊的话)?你会把自己局限于其中一个还是另一个,如果是的话,是哪一个?看起来你已经意识到了1(1)和(2)的主要特征。还要注意,在(1)中仍然有一个名为add
的局部变量包含函数值,就像(2)中一样:
另一点值得一提的是,函数声明(1)不应用于有条件地定义函数(例如在if
语句中),因为正如您所提到的,JavaScript解释器2会自动将它们移动到包含范围的顶部。这通常被称为
至于哪种方法更符合JavaScript的精神,我更喜欢使用函数表达式(2)。为了获得更权威的意见,在他流行的2中的“坏部分”一章中列出了函数声明(1)
1也称为函数语句(参见下面的注释)。
2实际上,一些浏览器能够处理
if
语句中的函数声明(再次参考下面的注释)。3-附录B:第113页
function foo() {};
foo.toString() //-> "function foo() {}"
var bar = foo;
bar.toString() //-> "function foo() {}"
因此它声明了一个命名函数。无论哪个变量指向它,它的名称都会保留。使用另一种语法的是匿名函数,它是匿名的,只有在被变量引用时才能访问
var foo = function() {};
foo.toString() //-> "function () {}"
var bar = foo;
bar.toString() //-> "function () {}"
至于使用哪种风格,没有主要的规则。虽然我个人喜欢匿名语法,因为它提醒我函数确实是可以传递的对象。我也倾向于支持“它都在一个大的主对象中”的方法,它要求函数以这种方式声明
var MyThingy = {
foo: function() { alert('foo') },
bar: function() { MyThingy.foo() }
}
但是,在创建函数之后,这些差异实际上并不重要,它们的行为是相同的。但是匿名语法没有你提到的那种提前扫描的魔力,在复杂的代码和奇怪的作用域情况下也没有那么多bug。根据ECMAScript规范,如果
语句块中的函数声明是语法错误,那么语句块中的函数声明就不会出错,可能是因为IE和Mozilla开创了先例。Mozilla通过在ECMAScript中添加一个名为FunctionStatement
(,)的扩展来解决这个问题。JScript不太尊重规范,在内部做了什么,天知道。编辑评论:函数声明也被称为函数语句,但这是错误的。comp.lang.javascript常见问题解答(在我之前的评论中链接到)非常雄辩地说明了这一点:“函数语句一词被广泛错误地用于描述函数声明
。这是一种误导,因为在ECMAScript中,函数声明
不是语句
;程序中有些地方允许使用语句
,但不允许使用函数声明
。@Tim:谢谢你有趣的评论。我不知道“语句”的命名问题。
var MyThingy = {
foo: function() { alert('foo') },
bar: function() { MyThingy.foo() }
}