【问题标题】:JavaScript function declaration or expression in conjunction with returning a nested function结合返回嵌套函数的 JavaScript 函数声明或表达式
【发布时间】:2019-05-19 08:02:42
【问题描述】:

这段代码出现在一个非常流行的 JS 教程中:

const sum = (function() {
  "use strict";
  return function sum(...args) {
    return args.reduce((a, b) => a + b, 0);
  };
})();
console.log(sum(1, 2, 3)); // 6
  1. 我试图弄明白他们从函数返回函数的原因(不幸的是,那里没有提供解释)。如果使用参数声明外部函数,执行计算,然后简单地返回值,那将更简单直接。为什么有必要(在这种情况下;似乎可以找到一般情况的答案here)以这种方式表达函数?

  2. 是否有理由表达一个函数而不是声明它?即,将函数表示为varletconst,而不是简单地用function 关键字声明它?每种方式的优点是什么?我读到here,除了提升之外,这完全是一个风格决定。那么,总是声明函数而不是表达函数不是更安全吗?我一定在这里遗漏了一些基本的东西。

【问题讨论】:

  • 似乎只需要对内部函数应用严格模式才需要用IIFE包装。
  • @AndrewL,谢谢。我更新了问题以参考一般情况。不过,在具体示例中这样做有什么好处吗?
  • 听起来像一个糟糕的教程,tbh。除非您认为严格模​​式有好处,否则没有任何好处。 const sum = (...xs) => xs.reduce((a,b) => a + b, 0) 真的是你所需要的。
  • @hindmost 当然这根本没有必要,他们可以将指令放在内部函数中。

标签: javascript function ecmascript-6 declaration


【解决方案1】:

使用像您的示例中那样立即调用的匿名函数通常只是为了隔离代码范围。特别是在这种情况下,"use strict" 的使用将严格模式仅限于顶级函数内的代码。

正如你所说,你可以只拥有一个函数而不是两个,但结果不一样:

const sum = (function() {
  "use strict";
  var x = something(); // strict mode enforced here
  return function sum(...args) {
    return args.reduce((a, b) => a + b, 0);
  };
})();

这里:

var x = something(); // strict mode not enforced here
function sum() {
    "use strict";
    return arguments.reduce((a, b) => a + b, 0);
};

此外,虽然在第二种方法中,函数必须在全局范围内声明,但在第一种方法中,您可以在顶级函数中声明许多函数,而不会污染全局范围。

【讨论】:

    【解决方案2】:

    在对第 2 点的部分回答中,命名函数将在堆栈跟踪中报告其名称,而分配给变量或常量的匿名函数则不会。所以,这稍微有利于声明函数。

    但是,您可以命名一个函数并将其分配给一个变量或常量,而不会出现这样的问题:

    let sum = function sum(...args) {
      return args.reduce((a, b) => a + b, 0)
    }
    

    如果您更喜欢分配的功能,这可以为您提供两全其美的功能。

    【讨论】:

      【解决方案3】:

      这是您的第一个问题:当函数用于打包模块并模拟命名空间(或包)范围时,上面使用的构造是有意义的。所有顶级功能的本地变量都将自动成为“包”范围。在上面的示例中,没有使用它,所以我也认为它是过度设计的

      第二个问题 — 匿名 fn、var 和 let 具有显着不同的可见性。这在设计中通常很重要,可以帮助您更好地控制需要暴露的内容。这是我能想到的唯一原因。

      【讨论】:

        【解决方案4】:

        1-这就是所谓的IIFE。立即调用的函数表达式。它有几个优点:首先,它是一种创建类似于 OOP 的功能(如私有和公共函数)的方法,然后它是一种封装事物的方法,因此它们不会污染全局命名空间。如果您声明一个全局函数,并且您使用的某些库标有相同的函数名称,会发生什么?最后一个获胜,这会造成难以发现的错误。这也是一种创建模块的方式(阅读更多关于模块的信息here)。

        2-取决于代码作者使用的逻辑以及事物的组织方式。使用 vars 而不是函数往往更简洁。在数组函数出现之后,这变得越来越普遍。但这仍然是您的选择。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-05-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-10-10
          • 2014-06-23
          • 1970-01-01
          相关资源
          最近更新 更多