我想知道这是什么意思:

(function () {

})();

这是在说document。onload吗?


当前回答

TL;DR:表达式可以括在圆括号中,如果函数的表达式和块形式组合在一起,则会与函数调用冲突。

我喜欢反例,因为它们描绘了一幅伟大的逻辑图景,而其他人没有列出任何反例。你可能会问,“为什么浏览器不能看到function(){}(),而只是假设它是一个表达式?”让我们用三个例子来比较这个问题。

var x; //这里fibonacci是一个block函数 函数fibonacci(x) { Var值= x < 2 ?X: fibonacci(X -1) + fibonacci(X -2); if (x === 9) console.log("The " + x + "th fibonacci is: " + value); 返回值; } (x = 9); console.log(" x的值:" + x); Console.log ("fibonacci is a(n) ")+ typeof fibonacci);

当我们将函数转换为表达式时,观察事情是如何变化的。

var x; //这里fibonacci是一个函数表达式 函数fibonacci(x) { Var值= x < 2 ?X: fibonacci(X -1) + fibonacci(X -2); if (x === 9) console.log("The " + x + "th fibonacci is: " + value); 返回值; }) (x = 9); console.log(" x的值:" + x); Console.log ("fibonacci is a(n) ")+ typeof fibonacci);

当你使用not-operator而不是圆括号时,也会发生同样的事情,因为这两个操作符都将语句转换为表达式:

var x; //这里fibonacci是一个函数表达式 ! 函数fibonacci(x) { Var值= x < 2 ?X: fibonacci(X -1) + fibonacci(X -2); if (x === 9) console.log("The " + x + "th fibonacci is: " + value); 返回值; } (x = 9); console.log(" x的值:" + x); Console.log ("fibonacci is a(n) ")+ typeof fibonacci);

通过将函数转换为表达式,它由它下面的两行(x = 9)执行。由于表达式函数和块函数的行为是分开的,所以这两个例子都运行得很好,没有歧义(规范方面)。

名字的作用域

另一个重要的观察是,命名块函数对整个作用域可见,而函数表达式只对其本身可见。换句话说,fibonacci只对第一个示例中的最后一个console.log是块时可见。在这三个例子中,fibonacci对自身是可见的,允许fibonacci调用自身,这是递归。

箭头功能

逻辑的另一个方面是箭头函数。如果块函数和表达式函数的定义合并在一起,规范将不得不包括箭头函数的任意规则和例外:

函数hello() {console.log(" hello World")} (x) => console.log("hello " + x) console.log("如果你正在阅读,没有发生错误");

虽然函数块工作正常,但函数表达式后面跟着箭头函数会产生语法错误:

! 函数hello() {console.log(" hello World")} (x) => console.log("hello " + x) console.log("如果你正在阅读,没有发生错误");

这里,第二行的(x)是调用前一行的函数还是箭头函数的函数参数是不明确的。

请注意,箭头函数多年来确实符合ECMAScript标准,在语言的初始设计中并不是一个因素;我的观点是,表达式函数和块函数之间的区别有助于JavaScript语法更有逻辑性和连贯性。

其他回答

自执行函数通常用于封装上下文和避免名称混淆。在(function(){..})()中定义的任何变量都不是全局变量。

的代码

var same_name = 1;

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

console.log(same_name);

产生如下输出:

2
1

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

也就是说立即执行。

所以如果我这样做:

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

立即调用的函数表达式(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

还有一个用例是内存,缓存对象不是全局的:

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

这是一个更深入的解释,为什么你会使用这个:

“使用IIFE的主要原因是确保数据隐私。因为JavaScript的var将变量限定在包含变量的函数内,所以任何在IIFE中声明的变量都不能被外部世界访问。”

http://adripofjavascript.com/blog/drips/an-introduction-to-iffes-immediately-invoked-function-expressions.html