【问题标题】:Is there any difference between var name = function() {} & function name() {} in Javascript? [duplicate]Javascript 中的 var name = function() {} & function name() {} 有什么区别吗? [复制]
【发布时间】:2011-02-25 07:22:36
【问题描述】:

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

假设我们在一个函数内部,而不是在全局命名空间中。

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

  function utilFunction2 () {
  }

  utilFunction1();
  utilFunction2();

}

这些是同义词吗?当someGlobalFunction 返回时,这些功能是否完全不复存在?出于可读性或其他原因,我应该更喜欢其中一个吗?

【问题讨论】:

    标签: javascript


    【解决方案1】:

    它们大部分是一样的。

    utilFunction1 仅在声明后可用。 utilFunction2 被提升到函数的顶部,所以可以在定义之前使用。

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

    除非它们被困在闭包中,否则当someGlobalFunction 返回时,两者都将不复存在。

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

    utilFunction2 形式的声明(称为函数声明)具有在 your-favourite-debuggerTMutilFunction2)的好处/sup>,其中utilFunction1(称为函数表达式)只会显示为匿名函数


    为了完整起见,您也有表格;

    var utilFunction3 = function utilFunction4() {
        // blah
    };
    

    ... 称为 named 函数表达式,它有自己的 weird properties(和 bugs(在旧版本的 IE 中))。

    【讨论】:

    • +1 - 看起来你已经涵盖了所有内容。
    • 还可以注意到,第一个是FunctionExpression,而后一个是FunctionDeclaration。
    【解决方案2】:

    是的,它们完全不同:

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

    例如:

    if (true) {
      function utilFunction() {
        return true;
      }
    } else {
      function utilFunction() {
        return false;
      }
    }
    
    utilFunction(); // returns false in IE, true everywhere else
    

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

    【讨论】:

    • 将函数语句放在if 或其他非函数块中在 ECMAScript 中无效;浏览器行为千差万别。避免!
    【解决方案3】:

    恭喜!您已经发现了函数提升涉及的情况。

    var foo = function() { };
    

    完全不同
    function foo() { };
    

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

    第二个例子将被“提升”——它将在当前闭包内的任何地方可用(通常是当前函数)。甚至在它在所述闭包中声明之前。

    这样的事情会起作用:

    function foo() {
        bar();
        function bar() { alert('baz'); }
    }
    

    而这样的事情绝对不会:

    function foo() {
        bar();
        var bar = function bar() { alert('baz'); };
    }
    

    在第二个例子中你得到一个错误,因为 bar 还没有被定义。如果你交换函数 foo 中的两行,这个例子就可以工作。

    Douglas Crockford 提倡使用第二种方法,因为它不包含像提升这样的隐藏行为 - 您的代码完全按照它所说的去做,不涉及任何技巧。

    【讨论】:

      猜你喜欢
      • 2012-12-27
      • 1970-01-01
      • 2012-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-14
      • 1970-01-01
      相关资源
      最近更新 更多