如果我将一个函数包装在另一个函数中有什么区别吗?

Is there any difference if I wrap a function inside another?

这两者有什么区别? 我在 browserify 中都导入了它们,它们似乎给出了相同的结果。 它们之间以及它们的工作方式有什么区别吗?

var App = (function () {
   var Foo = function (name) {
     this.name = name;
   };

   Foo.prototype.logout = function () {
     console.log();
   }

   return Foo;
})();

module.exports = App;

VS

var Foo = function (name) {
  this.name = name;
};

Foo.prototype.logout = function () {
  console.log();
}

module.exports = Foo;

在这种特殊情况下,唯一的区别是,在第一个代码示例中,您最终得到一个名为 "App" 的变量,而在第二个代码示例中,您最终得到一个名为 "Foo" 的变量。除了对命名空间的影响外,两者做同样的事情。

更一般地说,代码如下所示:

var x = function() {
  // lots of stuff
  return something;
}();

允许 "lots of stuff" 在与周围上下文隔离的上下文中完成。这意味着在该匿名函数内部定义的函数和变量不会 "leak out" 进入周围的上下文,除非这是 return 语句的明确目标(或其他以某种方式影响某些外部上下文的代码,最典型的是通过直接修改 window 或类似 jQuery 原型)。

在您的示例中,第二个示例中的 "lots of stuff" 不涉及更改除该函数原型之外的任何命名空间,第一个代码也是如此。

是的,这两者是有区别的。第一个示例可以防止 Foo 变量污染全局范围,因为它被包装在 IFEE(立即调用的函数表达式)中并分配给变量 App。由于 Foo 在 IFEE 内部,因此它属于 IFEE 的范围。 第二个示例中的 Foo 变量在全局范围内,如果您在其他代码中导入此文件,如果还存在具有该名称的变量,Foo 将覆盖该文件中的变量。因此,为确保不会发生这种情况,最好将导入的代码包装到 IFEE 中。 此外,访问变量 Foo 是不同的,在第一个示例中,您将使用 App.Foo 访问它(因为它在 App 下命名空间),而在第二个示例中,您将使用 Foo.

访问它