1.自執行函式表示式
當我要寫一個外掛了,首先就會敲這樣一段程式碼:
(function(){
}());
對,就是這個自執行函式,有的人叫它立即呼叫函式,還有更高大的叫法:立即呼叫的函式表示式。不管怎麼樣,他是自己會執行的。
為什麼要這樣寫呢?
因為這樣子寫有一個好處,減少全域性變數的汙染。那好吧!我們就多幾一點程式碼來試一下。
(function(){
var a = 1;
}());
alert(a); //ReferenceError: a is not defined
很明顯,我們定義的變數a,在外面已經訪問不到了。a就是一個私有的變數,所以不管裡面定義多少變數,也不會外面的變數衝突了,那就放心大膽的寫吧!
為什麼這樣子就私有了呢?
1.因為在JavaScript裡,任何function在執行的時候都會建立一個執行上下文;
2.function裡面宣告的變數和function有可能只在該function內部訪問;
所以我們就利用了這個執行上下文,來建立私有變數或私有子function。
為什麼會是這樣子寫呢? 首先我們將就最簡單的例子看起:
//定義個function
var foo = function () {
//code
};
//使用小括號,即可以執行
foo();
這樣子,我們就發現,原來加小括號,在javascript裡,還有一個意思,就是執行一個function。那麼我們會不會很自然的去改一下程式碼,變成下面這樣子呢?
var foo = function () {
console.log(1);
}();
不錯,還是可以執行的,接著改造如下:
function () {
console.log(1);
}();
經過改造之後,徹底的不能玩耍了,原因何在?
因為在解析器解析全域性的function或者function內部function關鍵字的時候,預設是認為function宣告,而不是function表示式,如果你不顯示告訴編譯器,它預設會宣告成一個缺少名字的function,並且丟擲一個語法錯誤資訊,因為function宣告需要一個名字。
不是說加一個名字就好的嗎?
function foo() {
console.log(1);
}();
結果還是玩不了,因為他只是一個語句,分組操作符需要包含表示式,所以還是報錯。什麼是語句什麼是表示式這裡就細講了。有興趣的同學請參考:http://www.cnblogs.com/slowsoul/archive/2013/01/21/2870310.html
也許我是亂敲的程式碼嗎,不小心在括號裡面多敲了一個1,程式碼變成這樣子了。
function foo() {
console.log(1);
}(1);
我們神奇的發現,程式碼不報錯了,雖然不報錯了,但是並不是我們想要的結果,實際上他真面目是這樣子的。
//宣告一個函式
function foo() {
console.log(1);
}
//一個表示式
(1);
他是兩段程式碼,相互沒有什麼關係。迴歸語句和表示式,我們是不想到,只要把語名變成表示式,他就不會報錯了呢?是的,變成表示式就不會報錯。所以我們在function外面加一個()他就變成了一個表示式了。程式碼就變成下面這樣子了。
(function foo() {
console.log(1);
});
好的,終於不報錯了,接下來也細說一下這段程式碼。
1.因為JavaScript裡括弧()裡面不能包含語句,程式碼解析成function表示式,而不是function宣告。
2.()裡面的值,就是一個function,就像(1)一樣,把1想像成function吧。
終於看到了曙光,我們就來完成最後一步吧!
(function foo() {
console.log(1);
}());
加上一個括號,就變成了我開始寫的那樣子的一段程式碼。現在我們應該最知道他叫什麼了吧!他叫自執行函式表示式或是立即呼叫的函式表示式。
當找到一個方法之後,人們總是會探索別外的方法,我們只能這樣子寫嗎?不是的,我們還可以這樣子寫。
(function foo() {
console.log(1);
})();
有人會問,哪種方法更好,事實上沒有多大的區別,而我個人偏好把小括號放裡面的那種方式,還有更多的玩法,只要把他變成表示式就行了。
// 由於括弧()和JS的&&,異或,逗號等操作符是在函式表示式和函式宣告上消除歧義的
// 所以一旦解析器知道其中一個已經是表示式了,其它的也都預設為表示式了
// 不過,請注意下一章節的內容解釋
var i = function () { return 10; } ();
true && function () { /* code */ } ();
0, function () { /* code */ } ();
// 如果你不在意返回值,或者不怕難以閱讀
// 你甚至可以在function前面加一元操作符號
!function () { /* code */ } ();
~function () { /* code */ } ();
-function () { /* code */ } ();
+function () { /* code */ } ();
// 還有一個情況,使用new關鍵字,也可以用,但我不確定它的效率
new function () { /* code */ }
new function () { /* code */ } () // 如果需要傳遞引數,只需要加上括弧()
事實有這麼多的方案可以讓一個function自執行,為何所有開發都要用()呢?原因也是很簡單,這樣子寫,可以讓程式碼更容易閱讀。
相關文章
- 自執行函式函式
- 深入理解 函式、匿名函式、自執行匿名函式函式
- JavaScript 匿名立即自執行函式JavaScript函式
- 塊級作用域替代“匿名立即執行函式表示式(匿名IIFE)”函式
- 立即執行函式函式
- Python函式與lambda 表示式(匿名函式)Python函式
- javascript-函式表示式JavaScript函式
- 函式表示式–遞迴函式遞迴
- python函式每日一講 - exec執行函式Python函式
- 胡扯JS系列-匿名函式的自動執行JS函式
- JavaScript函式宣告和函式表示式區別JavaScript函式
- JS函式表示式——函式遞迴、閉包JS函式遞迴
- 何時使用函式表示式與函式宣告函式
- matlab表示函式Matlab函式
- js中自執行函式的怪異行為研究JS函式
- MySQL 對window函式執行sum函式疑似BugMySql函式
- kotlin 函式和 Lambda 表示式Kotlin函式
- 1. 輔助函式 dd()函式
- Java公式:如何執行字串表示式?!Java公式字串
- await會阻塞其所在表示式中後續表示式的執行AI
- JavaScript 匿名函式與具名函式執行效率比較JavaScript函式
- (未完成)APC函式的執行,分析 KiDeliverApc 函式函式IDE
- js立即執行函式原理JS函式
- 多執行緒常用函式執行緒函式
- 03-立即執行函式函式
- 函式宣告與函式表示式有什麼區別?函式
- jdk1.8-Lambda函式表示式JDK函式
- 課時21:函式:lambda表示式函式
- 5.函式和lambda表示式函式
- jdk1.8Lambda函式表示式JDK函式
- 初識Lambda表示式(匿名函式)函式
- 1. PHP 函式學習 strpos ()PHP函式
- 【Python】python map()函式和lambda表示式Python函式
- 前端進階-執行時函式前端函式
- js解惑-函式執行順序JS函式
- 立即執行函式(IIFE)&&閉包函式
- JS 中的函式表示式和函式宣告你混淆了嗎?JS函式
- Golang時間函式及測試函式執行時間案例Golang函式
- php之正規表示式函式總結PHP函式