學習js函數--自執行函數

來源:互聯網
上載者:User

標籤:err   div   java   turn   val   開頭   nts   ...   作者   

我在寫代碼時候經常會在tpl的<script>裡寫類似的代碼:

$(function(){    alert("我好餓");});

剛開始的時候只知道寫了它不需要調用,直接執行,就這樣依葫蘆畫瓢,我寫了很多代碼。說道這,還要說說這貨的載入順序,如果把代碼直接寫到script標籤裡,當頁面載入完這個script標籤就會執行裡邊的代碼了。如果在這代碼裡用到了未載入的dom或者調用了未載入的方法,是會報錯的。言歸正傳,這個函數其實就是自執行函數,很多人會比較專業地稱為“立即調用的函數運算式”。

在這裡,我引用下limlimlim的部落格,感覺比較專業...原址http://blog.csdn.net/limlimlim/article/details/9198111

當你聲明類似function foo(){}或var foo = function(){}函數的時候,通過在後面加個括弧就可以實現自執行,例如foo(),看代碼:

// 因為想下面第一個聲明的function可以在後面加一個括弧()就可以自己執行了,比如foo(),// 因為foo僅僅是function() { /* code */ }這個運算式的一個引用 var foo = function(){ /* code */ } // ...是不是意味著後面加個括弧都可以自動執行? function(){ /* code */ }(); // SyntaxError: Unexpected token (//

上述代碼,如果甚至運行,第2個代碼會出錯,因為在解析器解析全域的function或者function內部function關鍵字的時候,預設是認為function聲明,而不是function運算式,如果你不顯示告訴編譯器,它預設會聲明成一個缺少名字的function,並且拋出一個語法錯誤資訊,因為function聲明需要一個名字。

有趣的是,即便你為上面那個錯誤的代碼加上一個名字,他也會提示法錯誤,只不過和上面的原因不一樣。在一個運算式後面加上括弧(),該運算式會立即執行,但是在一個語句後面加上括弧(),是完全不一樣的意思,他的只是分組操作符。

// 下面這個function在文法上是沒問題的,但是依然只是一個語句// 加上括弧()以後依然會報錯,因為分組操作符需要包含運算式 function foo(){ /* code */ }(); // SyntaxError: Unexpected token ) // 但是如果你在括弧()裡傳入一個運算式,將不會有異常拋出// 但是foo函數依然不會執行function foo(){ /* code */ }( 1 ); // 因為它完全等價於下面這個代碼,一個function聲明後面,又聲明了一個毫無關係的運算式: function foo(){ /* code */ } ( 1 );

要解決上述問題,非常簡單,我們只需要用大括弧將代碼的代碼全部括住就行了,因為JavaScript裡括弧()裡面不能包含語句,所以在這一點上,解析器在解析function關鍵字的時候,會將相應的代碼解析成function運算式,而不是function聲明。

// 下面2個括弧()都會立即執行(function () { /* code */ } ()); // 推薦使用這個(function () { /* code */ })(); // 但是這個也是可以用的// 由於括弧()和JS的&&,異或,逗號等操作符是在函數運算式和函式宣告上消除歧義的// 所以一旦解析器知道其中一個已經是運算式了,其它的也都預設為運算式了// 不過,請注意下一章節的內容解釋var i = function () { return 10; } ();true && function () { /* code */ } ();0, function () { /* code */ } ();// 如果你不在意傳回值,或者不怕難以閱讀// 你甚至可以在function前面加一元操作符號!function () { /* code */ } ();~function () { /* code */ } ();-function () { /* code */ } ();+function () { /* code */ } ();// 還有一個情況,使用new關鍵字,也可以用,但我不確定它的效率// http://twitter.com/kuvos/status/18209252090847232new function () { /* code */ }new function () { /* code */ } () // 如果需要傳遞參數,只需要加上括弧()

上面所說的括弧是消除歧義的,其實壓根就沒必要,因為括弧本來內部本來期望的就是函數運算式,但是我們依然用它,主要是為了方便開發人員閱讀,當你讓這些已經自動執行的運算式賦值給一個變數的時候,我們看到開頭有括弧(,很快就能明白,而不需要將代碼拉到最後看看到底有沒有加括弧。

 

在這篇文章裡,我們一直叫自執行函數,確切的說是自執行匿名函數(Self-executing anonymous function),但英文原文作者一直倡議使用立即調用的函數運算式(Immediately-Invoked Function Expression)這一名稱,作者又舉了一堆例子來解釋,好吧,我們來看看:

// 這是一個自執行的函數,函數內部執行自身,遞迴function foo() { foo(); }// 這是一個自執行的匿名函數,因為沒有標示名稱// 必須使用arguments.callee屬性來執行自己var foo = function () { arguments.callee(); };// 這可能也是一個自執行的匿名函數,僅僅是foo標示名稱引用它自身// 如果你將foo改變成其它的,你將得到一個used-to-self-execute匿名函數var foo = function () { foo(); };// 有些人叫這個是自執行的匿名函數(即便它不是),因為它沒有調用自身,它只是立即執行而已。(function () { /* code */ } ());// 為函數運算式添加一個標示名稱,可以方便Debug// 但一定命名了,這個函數就不再是匿名的了(function foo() { /* code */ } ());// 立即調用的函數運算式(IIFE)也可以自執行,不過可能不常用罷了(function () { arguments.callee(); } ());(function foo() { foo(); } ());// 另外,下面的代碼在黑莓5裡執行會出錯,因為在一個命名的函數運算式裡,他的名稱是undefined// 呵呵,奇怪(function foo() { foo(); } ());

希望這裡的一些例子,可以讓大家明白,什麼叫自執行,什麼叫立即調用。(我到這也才理解了一點,理論萬歲)

下面 limlimlim還講了Module模式,這是我之後要學習的重要東西,當然在這之前還有閉包(頭大)

給各位看看例子吧

// 建立一個立即調用的匿名函數運算式// return一個變數,其中這個變數裡包含你要暴露的東西// 返回的這個變數將賦值給counter,而不是外面聲明的function自身var counter = (function () {    var i = 0;    return {        get: function () {            return i;        },        set: function (val) {            i = val;        },        increment: function () {            return ++i;        }    };} ());// counter是一個帶有多個屬性的對象,上面的代碼對於屬性的體現其實是方法counter.get(); // 0counter.set(3);counter.increment(); // 4counter.increment(); // 5counter.i; // undefined 因為i不是返回對象的屬性i; // 引用錯誤: i 沒有定義(因為i只存在於閉包)

 

學習js函數--自執行函數

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.