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

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

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

(function () {

})();
EvaLEY2020/03/11 10:42:14

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

创建IIFE的两种方法

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

要么

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

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

理查德神乐老丝2020/03/11 10:42:14

我认为这两组括号使它有些混乱,但是我在Google的示例中看到了另一种用法,它们使用了类似的用法,希望这可以帮助您更好地理解:

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

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

Object {}
Object {}
泡芙卡卡西2020/03/11 10:42:14

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

樱小胖2020/03/11 10:42:14

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

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

很酷。

L前端2020/03/11 10:42:14

如下代码:

(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的函数括号内这减少了命名冲突的机会,并使您更不小心地命名它们(例如,您不必给它们加上前缀)。

Gil伽罗小宇宙2020/03/11 10:42:14

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

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

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

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

Ss Yy2020/03/11 10:42:14

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

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];
    }
  }
})();
猿米亚2020/03/11 10:42:13

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

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

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

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

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

小胖GO2020/03/11 10:42:13

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

一个有用的简短示例是:

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);

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

Tom伽罗2020/03/11 10:42:13

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

代码

var same_name = 1;

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

console.log(same_name);

产生以下输出:

2
1

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

你的名字2020/03/11 10:42:13

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

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

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

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

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

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

Sam小哥逆天2020/03/11 10:42:13

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

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

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

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

ItachiDavaid2020/03/11 10:42:13

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

(...)();

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

function() {}

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

Jim理查德泡芙2020/03/11 10:42:13
(function () {
})();

This is called IIFE (Immediately Invoked Function Expression). One of the famous JavaScript design patterns, it is the heart and soul of the modern day Module pattern. As the name suggests it executes immediately after it is created. This pattern creates an isolated or private scope of execution.

JavaScript prior to ECMAScript 6 used lexical scoping, so IIFE was used for simulating block scoping. (With ECMAScript 6 block scoping is possible with the introduction of the let and const keywords.) Reference for issue with lexical scoping

Simulate block scoping with IIFE

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

(function (globalObj) {
//Access the globalObj
})(window);
BB2020/03/11 10:42:13

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

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

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

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

$(function(){
});

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

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

但是以上两个构造不是IIFE

古一小胖2020/03/11 10:42:13

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

最常见的用例:

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

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

(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);  // Reference Error: count is not defined

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

我称它为Curly Jail

小哥Stafan2020/03/11 10:42:13

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

(function (local_arg) {
   // anonymous function
   console.log(local_arg);
})(arg);
逆天L2020/03/11 10:42:13

就是说立即执行。

所以如果我这样做:

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