JavaScript 模块化方法中 IIFE 和非 IIFE 之间的区别

Difference between an IIFE and non-IIFE in JavaScript Modular approach

本文关键字:IIFE 区别 之间 和非 JavaScript 模块化方法      更新时间:2023-09-26

最近,当我试图了解更多关于 JavaScript 中的 IIFE 和模块时我想到了一个问题,IIFE如何在不立即的情况下制作模块调用该函数不会使其成为模块。

任何人都可以与我分享此代码之间的区别

var MODULE = (function () {
var my = {},
    privateVariable = 1;
function privateMethod() {
    // ...
}
my.moduleProperty = 1;
my.moduleMethod = function () {
    // ...
};
return my;
}());

以及此代码,其中函数未立即调用。.

var MODULE = function () {
var my = {},
    privateVariable = 1;
function privateMethod() {
    // ...
}
my.moduleProperty = 1;
my.moduleMethod = function () {
    // ...
};
return my;
};

第二个代码块是否意味着模块只是一个本身返回对象的函数?

如果我像这样使用第二个变量

var ModuleObj = Module();

这是否与我像 IIFE 一样共享的第一个代码块相同。有点困惑...

是的,你几乎已经知道两者之间的区别,让我们看看为什么你可能想要一个而不是另一个。

IIFE 可用于隔离范围。它允许您将定义的变量保持在 IIFE 内的私有状态,而不会污染其周围的全局空间。这是编写函数的好方法,该函数包含一些您不需要潜伏的变量。让我们稍微缩小此示例。

var Counter = (function () {
  var count = 0;
  var counter = {
    add: function () {
      count++;
    },
    subtract: function () {
      count--;
    },
    getCount: function () {
      return count;
    }
  }
  return counter;
})();
Counter.add();
Counter.add();
Counter.getCount(); // 2
Counter.subtract();
Counter.getCount(); // 1

上面发生的事情是,我们能够在不泄露私人信息的情况下编写此"计数器"功能,例如 count .如果其他事情可以意外地覆盖它,那就太糟糕了。另外发生的情况是,我们可以立即将Counter分配给IFFE的结果 - counter函数集。 Counter现在等于此,并且counter能够保留对count的访问权限,因为它是在同一范围内定义的。

这样做的好处是,我们能够为这种功能组合分配一个变量。IIFE 基本上允许我们立即返回我们在其中return的内容。由于我们将Counter分配给 IIFE,并且 IIFE 返回其中的功能,因此Counter现在是一个功能齐全的组件。

我们并不总是必须使用IIFE。当您想要"隐藏"实现细节并返回 API 时,它非常方便。


那么,如果我们有同样的东西,但它不是一个IIFE - 只是一个函数呢?

就像您的示例一样,我们必须调用它才能获得"实例"。

var CounterFactory = function () {
  var count = 0;
  var counter = {
    add: //...
    subtract: //...
    getCount: //...
  };
  return counter;
};
var CounterA = CounterFactory();
var CounterB = CounterFactory();
CounterA.add();
CounterA.add();
CounterA.getCount(); // 2
CounterB.add();
CounterB.getCount(); // 1

看到区别了吗?这完全取决于函数返回的内容。在第一个例子中,我们只得到一个Counter实例,这可能完全没问题。在第二个例子中,它更像是一个"工厂"——它生成一个counter实例,我们可以多次调用它并获得它的多个实例。

好的,

IIFE运行其中的函数,并定义变量MODULE以返回该函数。另一个向函数本身声明 MODULE 变量。

可以这样想(也可以在控制台中尝试以查看结果(。

此代码不运行控制台.log方法。

(function(){
    console.log('ran')
});

此代码执行

(function(){
    console.log('ran')
})();

因此,IIFE的全部意义是在做任何事情之前运行函数,最后((会这样做。

如果我们采用未运行的代码并将其分配给一个值,会发生什么?

var foo = (function(){
    console.log('ran')
});
foo();

我们有一个可以执行的函数 foo。

那么,

如果我们可以分配它并在以后运行它,那么 IIFE 的意义何在?答案是局部变量,您可以稍后将其用于闭包。

console.log(num); //get undefined
(function(){
    var num = 'ran';
    console.log(num) //get 'ran'
})();
console.log(num); //get undefined

我们得到未定义的运行然后未定义,所以我们在函数中声明的值保留在函数中,没有其他任何东西可以到达它们。这是 JavaScript 运行的词法范围。

只是为了好玩,让我们用它做一个结束。

var add = (function(){
    var num = 0;
    return function(){
        console.log(num++);
    }
})();
console.log(num) //get undefined
add() //get 1
add() //get 2
console.log(num) //still undefined