国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

自調用匿名函數(匿名閉包)解析與調用

Scorpion / 642人閱讀

摘要:打開源碼,首先你會看到這樣的代碼結構這是一個自調用匿名函數。模式,是自執行函數的高級模式,可以非常方便的在各個匿名閉包中以全局對象調用閉包函數。

打開jQuery源碼,首先你會看到這樣的代碼結構:

(function(window,undefined ){

//

})();

這是一個自調用匿名函數。什么東東呢?在第一個括號內,創建一個匿名函數;第二個括號,立即執行

為什么要創建這樣一個“自調用匿名函數”呢?
通過定義一個匿名函數,創建了一個“私有”的命名空間,該命名空間的變量和方法,不會破壞全局的命名空間。這點非常有用也是一個JS框架必須支持的功能,jQuery被應用在成千上萬的JavaScript程序中,必須確保jQuery創建的變量不能和導入他的程序所使用的變量發生沖突。
接下來看看在 自調用匿名函數 中都實現了什么功能,按照代碼順序排列:

(function( window, undefined ) {

// 構造jQuery對象
var jQuery = function( selector, context ) {
    return new jQuery.fn.init( selector, context, rootjQuery );
}
// 工具函數 Utilities
// 異步隊列 Deferred
// 瀏覽器測試 Support
// 數據緩存 Data
// 隊列 queue
// 屬性操作 Attribute
// 事件處理 Event
// 選擇器 Sizzle
// DOM遍歷
// DOM操作
// CSS操作
// 異步請求 Ajax
// 動畫 FX
// 坐標和大小
window.jQuery = window.$ = jQuery;

})(window);

匿名函數從語法上叫函數直接量,JavaScript語法需要包圍匿名函數的括號,事實上自調用匿名函數有兩種寫法:

(function() {

console.info( this );
console.info( arguments );

}( window ) );

(function() {

console.info( this );
console.info( arguments );

})( window );

為什么要傳入window呢?

通過傳入window變量,使得window由全局變量變為局部變量,當在jQuery代碼塊中訪問window時,不需要將作用域鏈回退到頂層作用域,這樣可以更快的訪問window;這還不是關鍵所在,更重要的是,將window作為參數傳入,可以在壓縮代碼時進行優化,看看jquery-1.6.1.min.js: (function(a,b){})(window); // window 被優化為 a
通過以上的介紹,我們大概了解通過()可以使得一個函數表達式立即執行。

匿名函數作為一個“容器”,“容器”內部可以訪問外部的變量,而外部環境不能訪問“容器”內部的變量,
所以 ( function(){…} )() 內部定義的變量不會和外部的變量發生沖突,俗稱“匿名包裹器”或“命名空間”。

(function () {

// ... 所有的變量和function都在這里聲明,并且作用域也只能在這個匿名閉包里
// ...但是這里的代碼依然可以訪問外部全局的對象

}());
同下面
(function () {/ 內部代碼 /})();

通俗的講,()就是用來求值的,因此這個()任何時候都不能為空,因為它是要計算的。函數解析它只會解析到 {}為止,不會解析到 ()的。

    把表達式放在()中會返回表達式的值;
    把函數放在()中會返回函數本身;(function(){}());
    如果()緊跟在函數后面,就是表示在調用函數,即對函數求值:(function(){})();

(function() {

//自執行函數中的內部變量,外部是無法訪問的
var name = "kevin";

})( window );
name //undefined,無法獲取name的值

代碼在運行過程中,會優先解析 【巳聲明的函數】;

           而函數表達式是當執行到它時,才會解析;
           匿名函數是不會多帶帶寫的,因此它的執行是需要其它函數的調用,通常看到的匿名函數,都是當作參數被傳遞的。而立即執行函數它本身就是個匿名函數,
           js代碼執行的順序:
            //巳聲明的函數 function test(){}
            //匿名函數  function (){}
            //函數表達式 var test = function(){}
            //立即執行函數  (function(){})();

立即執行函數配合閉包,在模塊化中的應用,其中要明白幾個點:

1、要在函數體后面加括號就能立即調用,則這個函數必須是函數表達式,不能是函數聲明;
2、立即執行函數可以當作是一個私有作用域,作用域內部可以訪問外部的變量,而外部環境是不能訪問作用域內部的變量的,因此,立即執行函數是一個封閉的作用域,不會和外部作用域起沖突。
   JQuery使用的就是這種方法,將JQuery代碼包裹在( function (window,undefined){…jquery代碼…} (window)中,在全局作用域中調用JQuery代碼時,可以達到保護JQuery內部變量的作用。
3、Module模式,是自執行函數的高級模式,可以非常方便的在各個匿名閉包中以全局對象調用閉包函數。有興趣可以查看:http://www.cnblogs.com/TomXu/archive/2011/12/15/2288411.html                                Module 模式為:
   a.創建一個立即調用的匿名函數表達式
   b.return一個變量,其中這個變量里包含你要暴露的東西
      c.返回的這個變量將賦值給window

(function () {

var i = 0;
return {
    get: function () {
        return i;
    },
    set: function (val) {
        i = val;
    },
    increment: function () {
        return ++i;
    }
};

} (window));

    // window作為一個帶有多個屬性的全局對象,上面的代碼對于屬性的體現其實是方法,它可以這樣調用:
    window.get(); // 0
    window.set(3);
    window.increment(); // 4
    window.increment(); // 5

    window.i; // undefined 因為i不是返回對象的屬性
    i; // 引用錯誤: i 沒有定義(因為i只存在于閉包)

/上面就是關于自調用匿名函數的解析,那么這樣的函數它是怎么被調用的呢?*/
/下面是關于全局變量的調用,也就是匿名閉包函數的調用*/

再次搬出Module模式,有興趣可以查看:http://www.cnblogs.com/TomXu/...
Module 模式,也就是匿名閉包的創建與調用:

   a.創建一個立即調用的匿名函數表達式
   b.return一個變量,其中這個變量里包含你要暴露的東西
      c.返回的這個變量將賦值給window

window(或者是任意一個全局對象)作為一個帶有多個屬性的全局對象,也可以把window當成一個參數,以對象的方式,在其它函數中實現調用。用下面的例子說明:

(function ($, YAHOO) {

// 這里,我們的代碼就可以使用全局的jQuery對象了,YAHOO也是一樣
$.aa = function(){
    //code
}

} (jQuery, YAHOO));
//調用 jQuery.aa();

下面是一個標準的Module模式,通過匿名函數的返回值來返回這個全局變量:

var blogModule = (function () {

var my = {}, privateName = "博客園";

function privateAddTopic(data) {
    // 這里是內部處理代碼
}

my.Name = privateName;
my.AddTopic = function (data) {
    privateAddTopic(data);
};

return my;

} ());
//調用 blogModule.my();

在一些大型項目里,將一個功能分離成多個文件是非常重要的,因為可以多人合作易于開發。再回頭看看上面的全局參數導入例子,我們能否把blogModule自身傳進去呢?答案是肯定的,我們先將blogModule傳進去,添加一個函數屬性,然后再返回就達到了我們所說的目的:

var blogModule = (function (my) {

my.AddPhoto = function () {
    //添加內部代碼  
};
return my;

} (blogModule || {}));

(function (my){

my.AddPhoto = function () {
    //添加內部代碼  
};
return my;

})(blogModule || {}));
//調用 blogModule.AddPhoto();

那么,多個自執行函數間是怎么調用的呢?

(function(owner) {

//第一個匿名閉包
owner.debug = true;
//Ajax相關參數配置
owner.ajax = {
    timeout: 10000,
    type: "post",
    dataType: "json",
};

})(window.C = {}));

如果第二個函數想調用 全局變量為C中的 對象呢?要怎么寫?

(function($, owner) {

//這里調用上面全局變量為C 中的對象呢
if(!C.debug) return false;
var url = "aaa.html";
mui.ajax({
    url: url,
    dataType: C.ajax.dataType,
    type: C.ajax.type,
});

})(mui, window.app = {});

再舉個例子,同樣的,不同自執行閉包函數間的調用方法:

(function($, owner) {

//獲取語言閉包
owner.getLanguage = function() {
    var language = localStorage.getItem(C.state.field.language);
    if(typeof language == "undefined" || language === null || language == "") {
        var currentLang = navigator.language;
        if(!currentLang)
            currentLang = navigator.browserLanguage;
        language = currentLang.toLowerCase();
        language = language.replace(/-/g, "_");

        if(language != "en_us" && language != "zh_cn")
            language = "en_us";

        localStorage.setItem(C.state.field.language, language);
    }

    //在上面的解析中有說過,Module模式,return 一個變量,這個變量就是要爆露的東西。通過這個函數的全局變量,這個  language  可以在任何地方調用   
    //return一個變量,其中這個變量里包含你要暴露的東西 
    //全局調用  storage.language                                  
    return language;
};

})(mui, window.storage = {}));

(function($, owner) {

owner.language = {};
owner.preload = function(settings){
    var defaults = {
        name: "i18n",
        language: "",
        path: "/",
        cache: true,
        encoding: "UTF-8",
        autoReplace: true,
        success: null,
        error: null,
    };
    
    settings = $.extend(defaults, settings);
    if(settings.language === null || settings.language == "") {
        //全局調用  storage.language                                                                            
        settings.language = storage.getLanguage();
    }
}                                        

})(mui, window.i18n = {});

所以 匿名閉包的調用規則是這樣的,立即執行(最后一個括號) (window),如果把window作為一個參數進行傳遞,那么就把它以對象的方式,在其它函數中實現全局調用。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/96487.html

相關文章

  • javascript基礎-函數

    摘要:在函數內部定義的匿名函數的作用域鏈中,不包含外部函數的活動對象。在執行完畢以后,其執行環境的作用域鏈被銷毀,但是其活動對象不會被銷毀,因為匿名函數的作用域鏈中仍然引用著這個活動對象,直到匿名函數執行完畢后,才一起被銷毀。 函數表達式和函數聲明 函數聲明:function 函數名稱 (參數:可選){ 函數體 } 函數表達式:function 函數名稱(可選)(參數:可選){ 函數體 }...

    QLQ 評論0 收藏0
  • 深入理解JavaScript系列4:立即調用函數表達式

    摘要:前言大家學的時候,經常遇到自執行匿名函數的代碼,今天我們主要就來想想說一下自執行。其實,前面兩個例子里的變量,也可以換成,因為和外面的不在一個作用于,所以不會出現問題,這也是匿名函數閉包的威力。 前言 大家學JavaScript的時候,經常遇到自執行匿名函數的代碼,今天我們主要就來想想說一下自執行。 在詳細了解這個之前,我們來談了解一下自執行這個叫法,本文對這個功能的叫法也不一定完全對...

    roadtogeek 評論0 收藏0
  • 深入理解JavaScript系列3:全面解析Module模式

    摘要:總結上面的大部分方式都可以互相組合使用的,一般來說如果要設計系統,可能會用到松耦合擴展,私有狀態和子模塊這樣的方式。 簡介 Module模式是JavaScript編程中一個非常通用的模式,一般情況下,大家都知道基本用法,本文嘗試著給大家更多該模式的高級使用方式。 首先我們來看看Module模式的基本特征: 模塊化,可重用 封裝了變量和function,和全局的namaspace不接觸...

    付倫 評論0 收藏0
  • 閉包的學習總結

    摘要:第一部分執行代碼之后,返回了一個新的匿名函數,此時在全局作用域調用匿名函數它不在是的屬性或者方法,此時調用者是因此輸出是。總結關于中的,記住誰調用,就指向誰要訪問閉包的,要定義個變量緩存下來。 前言: 這是一篇關于閉包函數的總結和筆記 希望對大家有點幫助 寫的不好的地方,也請大家多多指教 一: js中的命名函數,匿名函數,自調用函數和回調函數 1.命名函數: 函數如果有名字,就...

    YanceyOfficial 評論0 收藏0
  • 進擊的 JavaScript(五) 之 立即執行函數閉包

    摘要:匿名函數是不能單獨寫的,所以就提不上立即執行了。六立即執行函數在閉包中的應用立即執行函數能配合閉包保存狀態。來看下上節內容中閉包的例子現在,我們來利用立即執行函數來簡化它第一個匿名函數執行完畢后,返回了第二個匿名函數。 前面的閉包中,提到與閉包相似的立即執行函數,感覺兩者還是比較容易弄混吧,嚴格來說(因為犀牛書和高程對閉包的定義不同),立即執行函數并不屬于閉包,它不滿足閉包的三個條件。...

    vincent_xyb 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<