【问题标题】:Difference between IIFE and regular function (example)IIFE 和常规函数的区别(示例)
【发布时间】:2020-05-21 00:03:49
【问题描述】:

了解 IIFE,我知道使用它们可以:

  • 不污染全局范围
  • 保护您的代码不受他人影响。

有人可以帮我更好地理解它,并举一个真实的例子说明我在使用常规函数语句(而不是 od IIFE)时会遇到麻烦吗?

【问题讨论】:

  • 你的意思是 IIFE:立即调用函数表达式?
  • 在模块之外,(几乎)每个脚本都应该在 IIFE 中关闭。

标签: javascript


【解决方案1】:

假设您有一个相当大的代码库(几千行或更多)。将每个函数都放在顶层并不是一个好主意,因为那样很容易不小心将一个函数名写了两次,这会由于名称冲突而导致错误。例如:

// code around validating user registration
function validate(username) {
  return /someValidationRegex/.test(username);
}
// do stuff with validate


// And then, far elsewhere in the code,
// you need to validate an input for sending to the server:
function validate(input) {
  return /someOtherValidationRegex/.test(input);
}
// do stuff with validate

这不起作用,因为最后一个validate 函数将覆盖第一个validate 函数,代码将无法按预期运行。

改为将每个代码段放入 IIFE,以避免名称冲突的可能性:

(() => {
  // code around validating user registration
  function validate(username) {
    return /someValidationRegex/.test(username);
  }
  // do stuff with validate
})();

(() => {
  // code around validating an input for sending to the server:
  function validate(input) {
    return /someOtherValidationRegex/.test(input);
  }
  // do stuff with validate
})();

这是Stack Overflow's Javascript uses 的技术(至少在某些部分)。

即使您小心不要重复函数名称,使用 IIFE 的另一个原因是您可能不小心复制了 窗口属性。例如,以下是人们遇到的一个比较常见的错误:

// name is defined to be a number...
var name = 5;
// but it's actually a string???
console.log(typeof name);

这里的问题是您不小心引用/覆盖了顶层的window.name 属性,而window.name 可能只是一个字符串。在顶层定义了一大堆函数和变量。为避免名称冲突,请将所有内容放入 IIFE:

(() => {
  // name is defined to be a number...
  var name = 5;
  // And it's still a number, good
  console.log(typeof name);
})();

不过,如果您的代码库足够大,名称冲突的可能性很大,而不是手动编写 IIFE,我强烈建议您使用模块系统,例如使用 Webpack。这将允许您在自己的封装范围内编写模块,而不会发生泄漏或名称冲突,并且将更易于维护,因为每个模块只包含它需要运行的代码,仅此而已。这使得识别错误和扩展功能比您必须手动浏览的一大长 <script> 更容易。

【讨论】:

    【解决方案2】:

    IIFE 的共同优点是在IIFE 中定义的任何“函数或变量”都不能在IIFE 块之外访问,从而防止全局范围受到污染。

    IIFE's 用于动态定义和执行函数,并在现场使用它们而无需额外的代码行。

    (function(){
      var firstName = 'Jhon';
      console.log(firstName);
    })(); // will be executed on the fly
    
    function test(){
      var firstName = 'Jhon';
      console.log(firstName);
    }
    test(); // has to call manually

    【讨论】:

      【解决方案3】:

      IIFE 将实际运行(立即调用的函数表达式),它们不需要触发器或函数调用来启动它们,因此变量将设置为其响应。

      这是一个 Fiddle 来证明这一点:

      var iffe = (function() {
          return 'foo';
      })();
      
      var func = function() {
          return 'bar';
      };
      
      console.log('iife = ' + iffe);
      console.log('non-iife = ' + func);

      在您的 JS 控制台中,您会看到类似于以下内容的内容:

      iife = foo 和

      非生命=函数(){ 返回“酒吧”; }

      此外,如果我们需要从外部范围传递 IFFE 范围内的某些内容,我们需要将它们作为参数传递并在 IFFE 包装中定义的函数中接收它,如下所示 -:

      var iffe = (function(doc) {
          return 'foo';
      })(document);
      

      这是更多参考的链接 - http://benalman.com/news/2010/11/immediately-invoked-function-expression/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-16
        • 1970-01-01
        • 2012-08-29
        相关资源
        最近更新 更多