3

js中的立即执行函数

( function(){…} )()和( function (){…} () )是两种javascript立即执行函数的常见写法

问题:

为什么会出现上面的两种不一样的写法,上面的写法难道不是简单的就是一个括号包裹匿名函数对象,再在后面加个括号调用函数,最后达到函数定义后立即执行的目的????然而并不是我想的那么简单

除了这两种常用的方式:
(function(){ //do something here;  })();
( function (){//do something here; }}());

还有一种方式为:
!function(){  // do something  }();

在这里开头要加上 ! 或者 ~ , - 和 +。(都是英文符号)
为什么这里要这样子,为什么要在前面加上()、!、+、-、=等运算符????

因为 JavaScript 文法明确规定表达式语句不得以 function 或者 {
为开头(http://es5.github.io/#x12.4

ExpressionStatement → [lookahead ∉ {{, function}] Expression;

好的现在带来更多的困惑了......

首先想要明白这个问题需要弄清函数表达式(function expression)和函数声明(function declaration)的区别:

函数表达式:

函数表达式中的函数可以为匿名函数,也可以有函数名,但是该函数实际上不能直接使用,只能通过表达式左边的变量 a 来调用。

var a = function(){
alert('Function expression');
};
var b = new a();

函数声明:

// 函数声明时必须有函数名

function a(){
alert('Function declaration');
}
a();

下面来看一下这段代码:

~function() { 
console.log("hi"); 
} (); 

实际上可以分为两个部分(~function() { console.log("hi")} 和()部分)前面部分的匿名函数通过一元操作符变成了函数表达式,因而可以通过在表达式的后面使用 () 来执行 。

因此,执行匿名函数可以通过+,-,!,() 这里的括号也是一种运算符,称为分组运算符
这样的形式来转化为函数表达式,就可以通过表达式的后面使用 () 来执行

一些其他的写法:

( function() {}() );
( function() {} )();
[ function() {}() ];

~ function() {}();
! function() {}();
+ function() {}();
- function() {}();

delete function() {}();
typeof function() {}();
void function() {}();
new function() {}();
new function() {};

var f = function() {}();

1, function() {}();
1 ^ function() {}();
1 > function() {}();

下面看一个组错误的的现象:

function (){console.log("hi")}();
VM354:1 Uncaught SyntaxError: Unexpected token )

function g(){ console.log("hi")}();
VM519:1 Uncaught SyntaxError: Unexpected token )

(1) function (){ }()

期望是立即调用一个匿名函数表达式,结果是进行了函数声明,函数声明必须要有标识符做为函数名称,而这里用()来做为标识符是非法的.

(2) function g(){ }()

期望是立即调用一个具名函数表达式,结果是声明了函数 g。末尾的括号作为分组运算符,必须要提供表达式做为参数。

function g(){ console.log("hi")}(1);
>1

所以那些匿名函数附近使用括号或一些一元运算符的惯用法,就是来引导解析器,指明运算符附近是一个表达式。

匿名函数的好处在于:可以减少局部变量,以免污染现有的运行环境。jQuery等库都用到了这样的原理。
另外:通过+,-!这三个符号运行的匿名函数比()运行的匿名函数可以减少一个字符的使用,但是我们通常使用加(),因为其他的操作符可能会带来其他的影响

更多可以参考
ECMA-262-3 in detail. Chapter 5. Functions.


outshineamaze
264 声望23 粉丝

一个想成为全栈工程师的码农