( function(){…} )()和( function (){…} () )是兩種javascript當即執行函數的常見寫法javascript
爲何會出現上面的兩種不同的寫法,上面的寫法難道不是簡單的就是一個括號包裹匿名函數對象,再在後面加個括號調用函數,最後達到函數定義後當即執行的目的????然而並非我想的那麼簡單java
除了這兩種經常使用的方式: (function(){ //do something here; })(); ( function (){//do something here; }}()); 還有一種方式爲: !function(){ // do something }();
在這裏開頭要加上 ! 或者 ~ , - 和 +。(都是英文符號)
爲何這裏要這樣子,爲何要在前面加上()、!、+、-、=等運算符????git
由於 JavaScript 文法明確規定表達式語句不得以 function 或者 {
爲開頭(http://es5.github.io/#x12.4)github
ExpressionStatement → [lookahead ∉ {{, function}] Expression;
首先想要明白這個問題須要弄清函數表達式(function expression)和函數聲明(function declaration)的區別:express
函數表達式中的函數能夠爲匿名函數,也能夠有函數名,可是該函數實際上不能直接使用,只能經過表達式左邊的變量 a 來調用。ecmascript
var a = function(){ alert('Function expression'); }; var b = new a();
// 函數聲明時必須有函數名函數
function a(){ alert('Function declaration'); } a();
~function() { console.log("hi"); } ();
實際上能夠分爲兩個部分(~function() { console.log("hi")} 和()部分)前面部分的匿名函數經過一元操做符變成了函數表達式,於是能夠經過在表達式的後面使用 () 來執行 。es5
所以,執行匿名函數能夠經過+,-,!,() 這裏的括號也是一種運算符,稱爲分組運算符
這樣的形式來轉化爲函數表達式,就能夠經過表達式的後面使用 () 來執行code
( 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 )
指望是當即調用一個匿名函數表達式,結果是進行了函數聲明,函數聲明必需要有標識符作爲函數名稱,而這裏用()來作爲標識符是非法的.對象
指望是當即調用一個具名函數表達式,結果是聲明瞭函數 g。末尾的括號做爲分組運算符,必需要提供表達式作爲參數。
function g(){ console.log("hi")}(1); >1
因此那些匿名函數附近使用括號或一些一元運算符的慣用法,就是來引導解析器,指明運算符附近是一個表達式。
匿名函數的好處在於:能夠減小局部變量,以避免污染現有的運行環境。jQuery等庫都用到了這樣的原理。
另外:經過+,-!這三個符號運行的匿名函數比()運行的匿名函數能夠減小一個字符的使用,可是咱們一般使用加(),由於其餘的操做符可能會帶來其餘的影響