我想知道这是什么意思:

(function () {

})();

这是在说document。onload吗?


当前回答

它是一个立即调用的函数表达式,简称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的箭头函数来编写(就像Gajus在评论中指出的那样):

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

其他回答

它是一个函数表达式,它代表立即调用函数表达式(IIFE)。IIFE只是一个在创建后立即执行的函数。因此,函数不必等到调用它才能执行,而是立即执行IIFE。让我们通过示例来构造IIFE。假设我们有一个add函数,它接受两个整数作为参数并返回和 让我们把add函数放到IIFE中,

步骤1:定义函数

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

Step2:通过将整个函数声明包装到圆括号中来调用函数

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

步骤3:要立即调用函数,只需从调用中删除'add'文本。

(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:重新声明不可配置的全局属性文档。

但是如果你想要声明一个名为documentmet的变量,你可以使用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>

输出:

让我们尝试另一个例子,假设我们有一个计算器对象像bellow-

<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:计算器。Mul不是if .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>

输出:

从这里开始:

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

不需要比这更复杂了。

这个函数称为自调用函数。自调用(也称为自执行)函数是在定义之后立即调用(已调用)的无名(匿名)函数。点击这里阅读更多

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

这里有一个例子:

(函数(){ Var x = 5 + 4; console.log (x); }) ();

这是一个自调用匿名函数。

查看W3Schools对自调用函数的解释。

函数表达式可以“自调用”。 自动调用(启动)自调用表达式,无需 被称为。 函数表达式将自动执行 后面跟着()。 不能自调用函数声明。

自执行匿名函数。它在创建时立即执行。

举个简单的例子,说明这个方法很有用:

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

因此,不是每次都创建一个列表,而是只创建一次(开销更少)。