什么是JavaScript中的(function(){})()构造?


790

我曾经知道这是什么意思,但是我现在正在努力...

这基本上是在说document.onload什么吗?

(function () {

})();

20
顺便说一句,尽管您会看到有人称此功能为“自我调用”,但这显然是不正确的。术语“ ifef”具有准确性的优点。
AakashM 2011年

6
这很好地解释了这种结构。这也是“ IIFE”一词的起源。benalman.com/news/2010/11/...
jeremysawesome


2
对于此结构的命名,也请在此处查看。阅读有关此构造目的技术说明(也在此处)。对于语法,请看一下为什么必须加上括号,以及括号应该放在哪里
Bergi 2014年

Answers:


854

它是立即调用的函数表达式,简称IIFE。它在创建后立即执行。

与任何事件(例如document.onload)的事件处理程序无关。
考虑第一对括号中的部分:....它是一个正则函数表达式。然后查看最后一对,通常将其添加到表达式中以调用函数;在这种情况下,我们的先前表达。(function(){})();(function(){})();

当试图避免污染全局名称空间时,通常使用此模式,因为IIFE内部使用的所有变量(如在任何其他常规函数中一样)在其范围之外不可见。
这就是为什么您可能将此结构与的事件处理程序混淆的window.onload原因,因为它经常被这样使用:

(function(){
  // all your code here
  var foo = function() {};
  window.onload = foo;
  // ...
})();
// foo is unreachable here (it’s undefined)

Guffa建议的更正

该函数在创建后立即执行,而不是在解析之后执行。在执行脚本块中的任何代码之前,都将对其进行分析。同样,解析代码并不会自动意味着它已被执行,例如,如果IIFE在函数内部,那么直到调用该函数后,它才会被执行。

更新 由于这是一个非常受欢迎的话题,值得一提的是,IIFE也可以使用ES6的arrow函数编写(就像Gajus 在评论中指出的那样):

((foo) => {
 // do something with foo here foo
})('foo value')

@ gion_13创建阶段和解析阶段之间有什么区别?
akantoword

1
以我看来,@ jlei是一个js程序的生命周期,包括以下几个阶段:解析,创建/编译,执行。尽管实际的实现(和命名:))可能因浏览器而异,但我们可以通过注意解析错误,提升和运行时错误来确定代码中的这些阶段。我个人没有为此找到很多资源,因为它的级别太低,而且程序员无法控制。您可以在此SO帖子中找到某种解释:stackoverflow.com/a/34562772/491075
gion_13,2016年

@sam firat就是所有的变量声明和new关键字。这意味着在您的示例中,您将实例化由其构造函数(匿名函数表达式)定义的新对象,并通过new运算符调用该对象,而不是像IIFE示例中那样调用函数。当然,该函数的作用类似于其内容的闭包,但到目前为止,它是一个不同的用例。
gion_13 '17

这如何污染全局名称空间?无论如何,foo在函数外部不可用。 function(){ var foo = '5'; }
Pankaj

1
@Pankaj —单独使用,即使在语法上也不是有效的JS(它是一个函数表达式,但不在表达式上下文中,因此被视为语法错误)。
昆汀

109

它只是创建后立即执行的匿名函数。

就像您将其分配给变量,然后在没有变量的情况下立即使用它:

var f = function () {
};
f();

在jQuery中,您可能会想到类似的构造:

$(function(){
});

这是绑定ready事件的简短形式:

$(document).ready(function(){
});

但是以上两个构造不是IIFE


83
最后两个并不是真正的IIFE,因为它们是在DOM准备就绪时立即
svvac 2014年

15
@swordofpain:是的,这是正确的,它们不是IIFE。
古法

@swordofpain考虑第二个片段;将add()转换为IIFE会在函数的末尾添加任何值吗?
timebandit 2015年

最后是否需要使用分号?
FrenkyB

@FrenkyB不必要,不需要,但是应该鼓励使用(分号在Javascript中实际上并不是必需的,但这是一个好习惯)。这些语句中的每一个都是碰巧包含匿名函数的语句,而不是函数声明。
Ledivin

52

立即调用的函数表达式(IIFE)立即调用一个函数。这仅表示该函数在定义完成后立即执行。

另外三种常用的措词:

// Crockford's preference - parens on the inside
(function() {
  console.log('Welcome to the Internet. Please follow me.');
}());

//The OPs example, parentheses on the outside
(function() {
  console.log('Welcome to the Internet. Please follow me.');
})();

//Using the exclamation mark operator
//https://stackoverflow.com/a/5654929/1175496
!function() {
  console.log('Welcome to the Internet. Please follow me.');
}();

如果对其返回值没有特殊要求,那么我们可以这样写:

!function(){}();  // => true
~function(){}(); // => -1
+function(){}(); // => NaN
-function(){}();  // => NaN

或者,它可以是:

~(function(){})();
void function(){}();
true && function(){ /* code */ }();
15.0, function(){ /* code */ }();

您甚至可以写:

new function(){ /* code */ }
31.new function(){ /* code */ }() //If no parameters, the last () is not required

4
最后一个31.new“无效语法

9
为什么有这么多方法可以写相同的东西?> _ <我不喜欢这种语言
Awesome_girl

6
获奖者是;(function(){}());
Roko C. Buljan

Crockford首选项说明非常有用-解释了我在野外看到的差异,例如jQuery tiny-pubsub gist从一个版本切换到另一个版本(您可以在文件末尾看到更改),而我无法找出原因。
icc97

1
@Awesome_girl:并不是有很多方法可以写同样的东西。这是因为JS拥有一个松散的类型系统,该系统具有可以对任何值类型进行操作的运算符。您可以做1 - 1,也可以轻松地做true - function(){}。它只是一件事(中缀减法运算符),但是具有不同的甚至荒谬的操作数。

31

它声明一个匿名函数,然后调用它:

(function (local_arg) {
   // anonymous function
   console.log(local_arg);
})(arg);

我猜“参数”是在函数内的局部上下文中引用为“ arg”的外部变量吗?
达利博

@Dalibor arguments特别;我的猜测是答案刚好在名字的开头
Cat

29

就是说立即执行。

所以如果我这样做:

var val = (function(){
     var a = 0;  // in the scope of this function
     return function(x){
         a += x;
         return a;
     };
})();

alert(val(10)); //10
alert(val(11)); //21

小提琴:http//jsfiddle.net/maniator/LqvpQ/


第二个例子:

var val = (function(){
     return 13 + 5;
})();

alert(val); //18

1
我不明白这证明了它的自我调用能力?
Exitos

1
@Exitos,因为它返回了该函数。我再举一个例子。
Naftali又名Neal

非常容易理解的+1
Adiii

24

该构造称为立即调用函数表达式(IIFE),表示立即执行。可以将其视为当解释器到达该函数时自动调用的函数。

最常见的用例:

它最常见的用例之一是限制通过进行的变量的范围var。通过创建的变量var的作用域仅限于函数,因此此构造(某些代码的函数包装)将确保变量范围不会从该函数中泄漏出来。

在下面的示例中,count在立即调用的函数之外将不可用,即,范围count不会泄漏出该函数。ReferenceError无论如何,如果您尝试在立即调用的函数之外访问它,则应该获得一个。

(function () { 
    var count = 10;
})();
console.log(count);  // Reference Error: count is not defined

ES6替代品(推荐)

在ES6中,我们现在可以通过let和创建变量const。它们都是块作用域的(不同于var功能作用域的)。

因此,您现在可以编写更简单的代码来确保变量的作用域不会泄漏出所需的块,而不必为上面提到的用例使用IIFE的那种复杂结构。

{ 
    let count = 10;
}
console.log(count);  // ReferenceError: count is not defined

在此示例中,我们用来let定义count变量,该变量count限于使用大括号创建的代码块{...}

我称它为“监狱监狱”。


10
我喜欢卷曲监狱的命名。也许会坚持下去:)
gion_13

15
(function () {
})();

这称为IIFE(立即调用函数表达式)。这是著名的JavaScript设计模式之一,它是现代Module模式的核心和灵魂。顾名思义,它在创建后立即执行。这种模式创建了隔离的或私有的执行范围。

ECMAScript 6之前的JavaScript使用词法作用域,因此IIFE用于模拟块作用域。(通过引入letconst关键字,可以使用ECMAScript 6进行块作用域定义。) 有关词法作用域的问题的参考

使用IIFE模拟块作用域

使用IIFE的的性能优势是通过像常用的全局对象的能力windowdocument通过减少范围查找等作为参数。(请记住,JavaScript在本地范围内查找属性,并在整个范围内一直查找直到全局范围)。因此,在本地范围内访问全局对象可以减少如下所示的查找时间。

(function (globalObj) {
//Access the globalObj
})(window);

感谢您提供要点来理解IIFE中的第二个括号。还用于通过定义定义来澄清全局变量的查找时间收益
Arsal

11

不,此构造仅创建命名范围。如果您将它分成几部分,则可以看到您有一个外部

(...)();

那是一个函数调用。在括号内,您具有:

function() {}

那是一个匿名函数。在构造内部用var声明的所有内容仅在同一构造内部可见,并且不会污染全局名称空间。


11

这是Javascript中立即调用的函数表达式:

要了解JS中的IIFE,让我们分解一下:

  1. 表达式:返回值的
    示例:在chrome控制台中尝试以下操作。这些是JS中的表达式。
a = 10 
output = 10 
(1+3) 
output = 4
  1. 函数表达式
    示例:
// Function Expression 
var greet = function(name){
   return 'Namaste' + ' ' + name;
}

greet('Santosh');

函数表达式的工作原理:
-JS引擎首次运行时(执行上下文-创建阶段),该函数(在上面=的右侧)不会执行或存储在内存中。JS引擎为变量“ greet”分配了“ undefined”值。
-在执行过程中(执行上下文-执行阶段),将动态创建功能对象(尚未执行),将其分配给'greet'变量,并且可以使用'greet('somename')'进行调用。

3.立即调用功能表达式:

例:

// IIFE
var greeting = function(name) {
    return 'Namaste' + ' ' + name;
}('Santosh')

console.log(greeting)  // Namaste Santosh. 

IIFE的工作方式
-在函数声明后立即注意'()'。每个功能对象都具有可调用的“ CODE”属性。我们可以使用()大括号来调用它(或调用它)。
-因此,在执行过程中(执行上下文-执行阶段),将同时创建并执行功能对象 -因此,现在,问候变量(而不具有funtion对象)具有其返回值(字符串)

JS中IIFE的典型用例:

以下IIFE模式是非常常用的。

// IIFE 
// Spelling of Function was not correct , result into error
(function (name) {
   var greeting = 'Namaste';
   console.log(greeting + ' ' + name);
})('Santosh');
  • 我们在这里做两件事。a)将函数表达式包装在大括号()中。这将告诉语法解析器()内的内容是一个表达式(在这种情况下为函数表达式),并且是有效的代码。
    b)我们正在同时使用末尾的()调用此函数。

因此,该函数可以同时创建和执行(IIFE)。

IIFE的重要用例:

IIFE使我们的代码安全。
-IIFE是一个函数,具有其自己的执行上下文,这意味着在其中创建的所有变量都在此函数本地,并且不与全局执行上下文共享。

假设我在应用程序中使用了另一个JS文件(test1.js)以及iife.js(请参见下文)。

// test1.js

var greeting = 'Hello';

// iife.js
// Spelling of Function was not correct , result into error
(function (name) { 
   var greeting = 'Namaste';
   console.log(greeting + ' ' + name);
})('Santosh');

console.log(greeting)   // No collision happens here. It prints 'Hello'.

因此,IIFE可以帮助我们编写安全的代码,而不会在无意间与全局对象发生冲突。


如果我们在IIFE中创建函数,我们如何在其他js或jsx文件(即react组件)中访问它们。
石岩石

即使我们没有使用IIFE,greeting变量也不会在全局greeting变量上发生冲突。那么那里有什么优势呢?
威利·大卫(Willy David Jr)'18年

6

那是一个自调用的匿名函数

查看W3Schools关于自调用功能的说明

可以使函数表达式“自调用”。

自调用表达式将自动调用(启动),而不被调用。

如果函数表达式后跟(),则函数表达式将自动执行。

您不能自行调用函数声明。


3
(function named(){console.log("Hello");}());<-自执行命名函数
bryc

@bryc为什么要命名不需要名称的函数。
RicardoGonzales

2
我猜@RicardoGonzales递归
bryc

5

这是自调用匿名功能。它在定义时执行。这意味着已定义此函数,并在定义后立即调用自身。

语法的解释是:第一个()括号内的函数是没有名称的函数,通过下一个();括号,您可以理解它在定义时被调用。您可以在第二个()括号中传递任何参数,该参数将在第一个括号中的函数中获取。请参阅以下示例:

(function(obj){
    // Do something with this obj
})(object);

在这里,您正在传递的“对象”将通过“ obj”在函数内访问,就像您在函数签名中获取它一样。


2
这个问题已经有一个可以接受的答案,并且您的答案没有添加任何未被该接受的答案涵盖的内容。因此,绝对没有必要写这个答案。
Aadit M Shah 2015年

3
我喜欢阅读多个答案,有时一个或另一个的措辞会有所不同。

我认为它是增加的,因为它让我知道第二组括号的用途。至少我在这里更清楚了。
约翰尼

我的最爱。样本IIFE的两端都有参数,并且两者之间的映射很简单。
Stephen W. Wright

4

从这里开始:

var b = 'bee';
console.log(b);  // global

将其放在函数中,它不再是全局的,而是您的主要目标。

function a() {
  var b = 'bee';
  console.log(b);
}
a();
console.log(b);  // ReferenceError: b is not defined -- *as desired*

立即调用该函数-哎呀:

function a() {
  var b = 'bee';
  console.log(b);
}();             // SyntaxError: Expected () to start arrow function, but got ';' instead of '=>'

使用括号可以避免语法错误:

(function a() {
  var b = 'bee';
  console.log(b);
})(); // OK now

您可以省略函数名称:

(function () {    // no name required
  var b = 'bee';
  console.log(b);
})();

并不需要比这更复杂。


2
语法错误是指箭头功能。据我了解,它是js的新功能,几年前还不存在,但IIFE确实存在。因此,括号可能最初是用来避免语法错误的,但是有所不同吗?
JCarlosR

您能回答@JCarlos问题吗?正如他非常正确地指出的那样,IIFE在箭头功能之前出现了很多,这将有助于理解为什么需要包装。
Script47

@ Script47我在评论中没有回答JCarlos的问题。您可以提出一个新问题并将其发布,我相信您会得到一些好的答案。
Jim Flood

@JCarlos执行抛出错误的代码时,实际上得到的Uncaught SyntaxError: Unexpected token )是箭头函数,而不是任何提及。您能否与它一起抛出箭头功能错误?
Script47

2

自执行匿名功能。它在创建后立即执行。

一个有用的简短示例是:

function prepareList(el){
  var list = (function(){
    var l = []; 
    for(var i = 0; i < 9; i++){
     l.push(i);
    }
    return l;
  })();

  return function (el){
    for(var i = 0, l = list.length; i < l; i++){
      if(list[i] == el) return list[i];
    }
    return null;
  }; 
} 

var search = prepareList();
search(2);
search(3);

因此,您不必一次创建一个列表,而只需创建一次(减少开销)。


1
按照书面说明,您的搜索将在每次调用时重建列表。为了避免这种情况,您需要(1)创建列表,并且(2)以可以访问刚刚创建的列表的闭包形式返回搜索功能。您可以使用匿名自调用表格轻松完成此操作。参见jsfiddle.net/BV4bT
乔治

您能解释一下吗……少些开销..i一点都不明白这部分
HIRA THAKUR

2
开销是指不必要执行的任何工作。不必在每次函数调用时填充数组,这就是为什么示例中的数组由self-exec填充的原因。仅首次使用匿名功能。但是,我似乎在自己的答案中犯了一个错误,请参见乔治评论中的链接以获取适当的示例。
usoban 2013年

2

自我执行功能通常用于封装上下文并避免名称冲突。您在(function(){..})()内部定义的任何变量都不是全局变量。

编码

var same_name = 1;

var myVar = (function() {
    var same_name = 2;
    console.log(same_name);
})();

console.log(same_name);

产生以下输出:

2
1

通过使用此语法,可以避免与JavaScript代码中其他地方声明的全局变量冲突。


1
正确,输出将是2,然后1,因为myVar的将被首先运行
DALIBOR

1
您的解释在解释函数范围方面做得很好,但在解释为什么立即执行它方面就不够。将其分配给变量是自失败的,并且还可能打算多次执行它。 var same_name = 1; var myVar = function() { var same_name = 2; console.log(same_name); }; myVar(); console.log(same_name); 会有相同的结果。
domenicr '16

2

它称为IIFE-立即调用函数表达式。这是显示其语法和用法的示例。它仅在函数之前而不是在函数之前限制变量的使用。

(function () {
  function Question(q,a,c) {
    this.q = q;
    this.a = a;
    this.c = c;
  }

  Question.prototype.displayQuestion = function() {
    console.log(this.q);
    for (var i = 0; i < this.a.length; i++) {
      console.log(i+": "+this.a[i]);
    }
  }

  Question.prototype.checkAnswer = function(ans) {
    if (ans===this.c) {
      console.log("correct");
    } else {
      console.log("incorrect");
    }
  }

  var q1 = new Question('Is Javascript the coolest?', ['yes', 'no'], 0);
  var q2 = new Question('Is python better than Javascript?', ['yes', 'no', 'both are same'], 2);
  var q3 = new Question('Is Javascript the worst?', ['yes', 'no'], 1);

  var questions = [q1, q2, q3];

  var n = Math.floor(Math.random() * questions.length)

  var answer = parseInt(prompt(questions[n].displayQuestion()));
  questions[n].checkAnswer(answer);
})();

1

IIFE(立即调用的函数表达式)是一个在脚本加载并消失后立即执行的函数。

考虑下面的函数,该函数写在名为iife.js的文件中

(function(){
       console.log("Hello Stackoverflow!");
   })();

上面的代码将在您加载iife.js后立即执行,并显示“ Hello Stackoverflow!在开发人员工具的控制台上。

有关详细说明,请参见立即调用函数表达式(IIFE)。


1

另一个用例是记忆,其中缓存对象不是全局的:

var calculate = (function() {
  var cache = {};
  return function(a) {

    if (cache[a]) {
      return cache[a];
    } else {
      // Calculate heavy operation
      cache[a] = heavyOperation(a);
      return cache[a];
    }
  }
})();

0

立即调用的函数表达式(IIFE)是创建后立即执行的函数。它与任何事件或异步执行都没有关系。您可以定义一个IIFE,如下所示:

(function() {
     // all your code here
     // ...
})();

第一对括号function(){...}将括号内的代码转换为表达式。第二对括号调用由表达式产生的函数。

An IIFE也可以描述为自调用匿名函数。它最常见的用法是限制通过var生成的变量的范围,或封装上下文以避免名称冲突。


0

使用自唤匿名函数的原因是,它们不应被其他代码调用,因为它们“设置”了要调用的代码(以及赋予函数和变量的范围)。

换句话说,它们就像是在程序开始时“创建类”的程序。(自动)实例化它们之后,唯一可用的函数是匿名函数返回的函数。但是,其他所有“隐藏”功能以及任何状态(在作用域创建期间设置的变量)仍然存在。

很酷。


0

如下代码:

(function () {

})();

被称为立即调用函数表达式(IIFE)。

之所以称为函数表达式,是因为( yourcode )Javascript中的运算符将其强制为表达式。函数表达式函数声明之间的区别如下:

// declaration:
function declaredFunction () {}

// expressions:

// storing function into variable
const expressedFunction = function () {}

// Using () operator, which transforms the function into an expression
(function () {})

表达式只是一堆可以评估为单个值的代码。对于上述示例中的表达式,此值为单个函数对象

在获得一个计算结果为函数对象的表达式之后,我们可以立即使用运算符调用该函数对象()。例如:

(function() {

  const foo = 10;        // all variables inside here are scoped to the function block
  console.log(foo);

})();

console.log(foo);  // referenceError foo is scoped to the IIFE

为什么这有用?

当我们处理大型代码库和/或导入各种库时,命名冲突的可能性会增加。当我们在IIFE内编写代码的某些相关部分(并因此使用相同的变量)时,所有变量和函数名的作用域都在IIFE的函数括号内。这减少了命名冲突的机会,并使您更不小心地命名它们(例如,您不必给它们加上前缀)。


0

使用ES6语法(亲自张贴,我继续登陆此页面寻找快速示例):

// simple
const simpleNumber = (() => {
  return true ? 1 : 2
})()

// with param
const isPositiveNumber = ((number) => {
  return number > 0 ? true : false
})(4)

0

此功能称为自调用功能。自调用(也称为自执行)函数是无名(匿名)函数,在其定义后立即被调用(调用)。在这里阅读更多

这些函数的作用是在定义函数时立即调用该函数,从而节省了时间和额外的代码行(与在单独的行中调用相比)。

这是一个例子:

(function() {
    var x = 5 + 4;
    console.log(x);
})();



0

它是一个函数表达式,代表立即调用函数表达式(IIFE)。IIFE只是创建后立即执行的功能。因此,在必须等待该函数被调用才能执行该函数的情况下,会立即执行IIFE。让我们以示例的方式构造IIFE。假设我们有一个add函数,该函数将两个整数作为args并返回总和,使add函数成为IIFE,

步骤1:定义功能

function add (a, b){
    return a+b;
}
add(5,5);

步骤2:通过将整个函数声明包装在括号中来调用函数

(function add (a, b){
    return a+b;
})
//add(5,5);

步骤3:立即调用该函数,只需从调用中删除“添加”文本即可。

(function add (a, b){
    return a+b;
})(5,5);

使用IFFE的主要原因是要在函数内保留私有范围。在您的JavaScript代码中,您要确保没有覆盖任何全局变量。有时您可能会意外地定义一个覆盖全局变量的变量。让我们以身作则。假设我们有一个名为iffe.html的html文件,并且body标签内的代码是-

<body>
    <div id = 'demo'></div>
    <script>
        document.getElementById("demo").innerHTML = "Hello JavaScript!";
    </script> 
</body>

好了,上面的代码将毫无疑问地执行,现在假定您意外或故意清除了一个名为document的变量。

<body>
    <div id = 'demo'></div>
    <script>
        document.getElementById("demo").innerHTML = "Hello JavaScript!";
        const document = "hi there";
        console.log(document);
    </script> 
</body>

您将最终遇到SyntaxError:重新声明不可配置的全局属性文档。

但是,如果您希望清除变量名documet,则可以使用IFFE。

<body>
    <div id = 'demo'></div>
    <script>
        (function(){
            const document = "hi there";
            this.document.getElementById("demo").innerHTML = "Hello JavaScript!";
            console.log(document);
        })();
        document.getElementById("demo").innerHTML = "Hello JavaScript!";
    </script> 
</body>

输出:

在此处输入图片说明

让我们再举一个例子,假设我们有一个像下面这样的计算器对象:

<body>
    <script>
        var calculator = {
            add:function(a,b){
                return a+b;
            },
            mul:function(a,b){
                return a*b;
            }
        }
        console.log(calculator.add(5,10));
    </script> 
</body>

好吧,它的工作就像一种魅力,如果我们不小心重新分配了计算器对象的值,该怎么办。

<body>
    <script>
        var calculator = {
            add:function(a,b){
                return a+b;
            },
            mul:function(a,b){
                return a*b;
            }
        }
        console.log(calculator.add(5,10));
        calculator = "scientific calculator";
        console.log(calculator.mul(5,5));
    </script> 
</body>

是的,您最终会遇到TypeError:Calculator.mul不是iffe.html函数

但是在IFFE的帮助下,我们可以创建一个私有范围,在其中可以创建另一个变量名计算器并使用它。

<body>
    <script>
        var calculator = {
            add:function(a,b){
                return a+b;
            },
            mul:function(a,b){
                return a*b;
            }
        }
        var cal = (function(){
            var calculator = {
                sub:function(a,b){
                    return a-b;
                },
                div:function(a,b){
                    return a/b;
                }
            }
            console.log(this.calculator.mul(5,10));
            console.log(calculator.sub(10,5));
            return calculator;
        })();
        console.log(calculator.add(5,10));
        console.log(cal.div(10,5));
    </script> 
</body>

输出: 在此处输入图片说明


-1

我认为这2套方括号有些令人困惑,但是我在Google的示例中看到了另一种用法,它们使用了类似的用法,希望这可以帮助您更好地理解:

var app = window.app || (window.app = {});
console.log(app);
console.log(window.app);

因此,如果windows.app未定义,则window.app = {}立即执行,因此在条件评估期间将其window.app分配给它{},因此结果既是appwindow.app现在变为{},因此控制台输出为:

Object {}
Object {}

-1

通常,在程序中编写函数后,我们不会立即调用该函数。用非常简单的术语来说,当您在函数创建后立即调用它时,它被称为IIFE-一个花哨的名字。


-1

通常,JavaScript代码在应用程序中具有全局作用域。当我们在其中声明全局变量时,就有可能在开发的其他区域中将相同的重复变量用于其他目的。由于此重复,可能会发生一些错误。因此我们可以通过立即调用函数expression来避免使用该全局变量,该表达式是自执行表达式。当我们在该IIFE表达式中编写代码时,全局变量将类似于局部作用域和局部变量。

创建IIFE的两种方法

(function () {
    "use strict";
    var app = angular.module("myModule", []);
}());

要么

(function () {
    "use strict";
    var app = angular.module("myModule", []);
})();

在上面的代码片段中,“ var app ”现在是一个局部变量。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.