Javascript中var name = function(){}&function name(){}之间有什么区别吗?

Fle*_*ore 29 javascript

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

假设我们在函数内部而不是在全局命名空间中.

function someGlobalFunction() {
  var utilFunction1 = function() {
  }

  function utilFunction2 () {
  }

  utilFunction1();
  utilFunction2();

}
Run Code Online (Sandbox Code Playgroud)

这些是同义词吗?这些功能在someGlobalFunction返回时是否完全不存在?为了便于阅读或其他原因,我应该更喜欢其中一种吗?

Mat*_*att 48

他们大多是一样的.

utilFunction1只有在声明后才可用.utilFunction2被提升到函数的顶部,因此可以在定义之前使用.

function someGlobalFunction() {
  utilFunction1(); // Error: untilFunction1 is undefined :(
  utilFunction2(); // Works

  var utilFunction1 = function() {
  }

  function utilFunction2 () {
  }
}
Run Code Online (Sandbox Code Playgroud)

除非它们被困在封闭物中,否则两者在someGlobalFunction返回时都将不复存在.

我更喜欢使用用于声明的方法utilFunction2,但这取决于你.

表单的声明utilFunction2(称为函数声明)具有utilFunction2您最喜欢的调试器TM中被命名(即显示为)的好处,其中as utilFunction1(称为函数表达式)将仅显示为匿名函数.


为了完整,你也有表格;

var utilFunction3 = function utilFunction4() {
    // blah
};
Run Code Online (Sandbox Code Playgroud)

...它被称为命名函数表达式,它有自己的奇怪属性(和错误(在旧版本的IE中)).

  • 还可以注意到,第一个是FunctionExpression,而后一个是FunctionDeclaration. (3认同)

jim*_*mbo 10

是的,它们完全不同:

  • utilFunction1没有名称,所以如果它抛出异常,你的调试工具只会告诉你一个匿名函数吐了
  • 即使在达到该行之前,utilFunction2也将在函数范围内可用(如fletcher所述)
  • 使用utilFunction2表示法可能会在IE中的某些情况下导致奇怪的行为.

例如:

if (true) {
  function utilFunction() {
    return true;
  }
} else {
  function utilFunction() {
    return false;
  }
}

utilFunction(); // returns false in IE, true everywhere else
Run Code Online (Sandbox Code Playgroud)

IE将函数范围问题发挥到极致,有效地评估函数,即使它们没有代码路径!

  • 将函数语句放在`if`或其他非函数块中在ECMAScript中无效; 浏览器行为变化很大.避免! (7认同)

war*_*gle 8

恭喜!您已经找到了涉及功能提升的情况.

var foo = function() { };
Run Code Online (Sandbox Code Playgroud)

与...完全不同

function foo() { };
Run Code Online (Sandbox Code Playgroud)

由于其他地方提到的所有原因,加上一个.

第二个例子将被"提升" - 它将在当前闭包内的任何地方可用(通常是当前函数).甚至在关闭之前宣布它.

像这样的东西会起作用:

function foo() {
    bar();
    function bar() { alert('baz'); }
}
Run Code Online (Sandbox Code Playgroud)

虽然这样的事情绝对不会:

function foo() {
    bar();
    var bar = function bar() { alert('baz'); };
}
Run Code Online (Sandbox Code Playgroud)

在第二个示例中出现错误,因为尚未定义bar.如果在函数foo中交换两行,该示例将起作用.

道格拉斯克罗克福德提倡使用第二种方法,因为它不包含像吊装这样的隐藏行为 - 你的代码完全按照它所说的做,不涉及任何技巧.