Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 什么';当我使用;传统的;C风格的函数声明?_Javascript_Function - Fatal编程技术网

Javascript 什么';当我使用;传统的;C风格的函数声明?

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是一个全局变量)。但是如果我用(

我知道有几种方法可以在JavaScript中定义函数。最常见的两种是:

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