小编典典

将整个 Javascript 文件包装在匿名函数中的目的是什么?

all

我最近读了很多 Javascript,我注意到整个文件在要导入的 .js 文件中如下所示。

(function() {
    ... 
    code
    ...
})();

这样做的原因是什么而不是一组简单的构造函数?


阅读 184

收藏
2022-03-04

共1个答案

小编典典

它通常用于命名空间(见下文)并控制成员函数和/或变量的可见性。把它想象成一个对象定义。它的技术名称是 立即调用函数表达式 (IIFE)。jQuery
插件通常是这样写的。

在 Javascript 中,您可以嵌套函数。因此,以下内容是合法的:

function outerFunction() {
   function innerFunction() {
      // code
   }
}

现在你可以调用outerFunction()了,但是可见性innerFunction()仅限于范围outerFunction(),也就是说它是私有的outerFunction()。它基本上遵循与
Javascript 中的变量相同的原则:

var globalVariable;

function someFunction() {
   var localVariable;
}

相应地:

function globalFunction() {

   var localFunction1 = function() {
       //I'm anonymous! But localFunction1 is a reference to me!
   };

   function localFunction2() {
      //I'm named!
   }
}

在上述场景中,您可以globalFunction()从任何地方拨打电话,但您不能拨打localFunction1localFunction2

当你写的时候(function() { ... })(),你正在做的是你在第一组括号内的代码是一个函数字面量(意味着整个“对象”实际上是一个函数)。之后,您将自行调用()刚刚定义的函数(final)。因此,正如我之前提到的,它的主要优点是您可以拥有私有方法/函数和属性:

(function() {
   var private_var;

   function private_function() {
     //code
   }
})();

在第一个示例中,您将globalFunction通过名称显式调用来运行它。也就是说,您只需globalFunction()运行它即可。但是在上面的例子中,你不只是定义一个函数;您正在一次定义
调用它。这意味着当你的 JavaScript 文件被加载时,它会立即被执行。当然,你可以这样做:

function globalFunction() {
    // code
}
globalFunction();

除了一个显着的区别外,行为基本上是相同的:当您使用 IIFE
时避免污染全局范围(因此这也意味着您不能多次调用该函数,因为它没有名称,但是因为此功能仅在真正不成问题时才执行)。

IIFE 的巧妙之处在于,您还可以在内部定义事物,并且只向外界公开您想要的部分(命名空间的示例,因此您基本上可以创建自己的库/插件):

var myPlugin = (function() {
 var private_var;

 function private_function() {
 }

 return {
    public_function1: function() {
    },
    public_function2: function() {
    }
 }
})()

现在你可以打电话myPlugin.public_function1(),但你不能访问private_function()!非常类似于类定义。为了更好地理解这一点,我推荐以下链接以供进一步阅读:

编辑

我忘了提。在决赛中(),你可以通过任何你想要的东西。例如,当您创建 jQuery 插件时,您传入jQuery$类似这样:

(function(jQ) { ... code ... })(jQuery)

因此,您在这里所做的是定义一个接受一个参数的函数(称为jQ,一个局部变量,并且 只有
该函数知道)。然后,您将自行调用该函数并传入一个参数(也称为jQuery,但 这个 参数来自外部世界,是对实际 jQuery
本身的引用)。没有迫切需要这样做,但有一些优点:

  • 您可以重新定义全局参数并为其命名在本地范围内有意义。
  • 有一点性能优势,因为在本地范围内查找内容更快,而不必沿着范围链向上进入全局范围。
  • 压缩(缩小)有好处。

前面我描述了这些函数如何在启动时自动运行,但如果它们自动运行,谁在传递参数?该技术假定您需要的所有参数都已定义为全局变量。因此,如果 jQuery
尚未定义为全局变量,则此示例将不起作用。正如您可能猜到的,jquery.js
在其初始化期间所做的一件事是定义一个“jQuery”全局变量,以及它更著名的“$”全局变量,它允许此代码在包含 jQuery 后工作。

2022-03-04