成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

RequireJS進(jìn)階:模塊的定義與加載

legendmohe / 1096人閱讀

摘要:將模塊定義為一個函數(shù)對模塊的返回值類型并沒有強(qiáng)制為一定是個,任何函數(shù)的返回值都是允許的。此處是一個返回了函數(shù)的模塊定義點評加載該模塊后,返回值是一個閉包。僅支持返回值類型為的服務(wù),其他返回類型如數(shù)組字串?dāng)?shù)字等都不能支持。

概述

模塊不同于傳統(tǒng)的腳本文件,它良好地定義了一個作用域來避免全局名稱空間污染。它可以顯式地列出其依賴關(guān)系,并以函數(shù)(定義此模塊的那個函數(shù))參數(shù)的形式將這些依賴進(jìn)行注入,而無需引用全局變量。RequireJS的模塊是模塊模式的一個擴(kuò)展,其好處是無需全局地引用其他模塊。

RequireJS的模塊語法允許它盡快地加載多個模塊,雖然加載的順序不定,但依賴的順序最終是正確的。同時因為無需創(chuàng)建全局變量,甚至可以做到在同一個頁面上同時加載同一模塊的不同版本。

(如果你熟悉ConmmonJS,可參看CommonJS的注釋信息以了解RequireJS模塊到CommonJS模塊的映射關(guān)系)。
一個磁盤文件應(yīng)該只定義 1 個模塊。多個模塊可以使用內(nèi)置優(yōu)化工具將其組織打包。

模塊的定義 簡單的鍵值對

如果一個模塊僅含值對,沒有任何依賴,則在define()中定義這些值對就好了:

define({
    name: "john",
    age : 20,
    sex : "femal"
});

點評:這種情況用途不是很大,一般用于簡單的數(shù)據(jù)模擬。加載該模塊后,回調(diào)函數(shù)中注入的參數(shù)是該鍵值對Object對象,即:

 {
    name: "john",
    age : 20,
    sex : "femal"
 }
函數(shù)式定義

如果一個模塊沒有任何依賴,但需要一個做setup工作的函數(shù),則在define()中定義該函數(shù),并將其傳給define():

define(function () {
    //Do setup work here

    return {
        color: "black",
        size: "unisize"
    }
});

點評:這種適合無依賴模塊的編寫,且回調(diào)函數(shù)中注入的參數(shù)是根據(jù)函數(shù)中return的返回值確定的,如果沒有return語句,則默認(rèn)返回undefined。

存在依賴的函數(shù)式定義

如果模塊存在依賴:則第一個參數(shù)是依賴的名稱數(shù)組;第二個參數(shù)是函數(shù),在模塊的所有依賴加載完畢后,該函數(shù)會被調(diào)用來定義該模塊,因此該模塊應(yīng)該返回一個定義了本模塊的object。依賴關(guān)系會以參數(shù)的形式注入到該函數(shù)上,參數(shù)列表與依賴名稱列表一一對應(yīng)。

//my/shirt.js now has some dependencies, a cart and inventory
//module in the same directory as shirt.js
define(["./cart", "./inventory"], function(cart, inventory) {
        //return an object to define the "my/shirt" module.
        return {
            color: "blue",
            size: "large",
            addToCart: function() {
                inventory.decrement(this);
                cart.add(this);
            }
        }
    }
);

本示例創(chuàng)建了一個my/shirt模塊,它依賴于my/cart及my/inventory。磁盤上各文件分布如下:

my/cart.js

my/inventory.js

my/shirt.js

模塊函數(shù)以參數(shù)"cart"及"inventory"使用這兩個以"./cart"及"./inventory"名稱指定的模塊。在這兩個模塊加載完畢之前,模塊函數(shù)不會被調(diào)用

嚴(yán)重不鼓勵模塊定義全局變量。遵循此處的定義模式,可以使得同一模塊的不同版本并存于同一個頁面上(參見 高級用法 )。另外,函參的順序應(yīng)與依賴順序保存一致。

返回的object定義了"my/shirt"模塊。這種定義模式下,"my/shirt"不作為一個全局變量而存在。

點評:這算是模塊中最常見的用法了。注意上面強(qiáng)調(diào)的部分。

將模塊定義為一個函數(shù)

對模塊的返回值類型并沒有強(qiáng)制為一定是個object,任何函數(shù)的返回值都是允許的。此處是一個返回了函數(shù)的模塊定義:

//A module definition inside foo/title.js. It uses
//my/cart and my/inventory modules from before,
//but since foo/title.js is in a different directory than
//the "my" modules, it uses the "my" in the module dependency
//name to find them. The "my" part of the name can be mapped
//to any directory, but by default, it is assumed to be a
//sibling to the "foo" directory.
define(["my/cart", "my/inventory"],
    function(cart, inventory) {
        //return a function to define "foo/title".
        //It gets or sets the window title.
        return function(title) {
            return title ? (window.title = title) :
                   inventory.storeName + " " + cart.name;
        }
    }
);

點評:加載該模塊后,返回值是一個閉包。

簡單包裝CommonJS來定義模塊

如果你現(xiàn)有一些以CommonJS模塊格式編寫的代碼,而這些代碼難于使用上述依賴名稱數(shù)組參數(shù)的形式來重構(gòu),你可以考慮直接將這些依賴對應(yīng)到一些本地變量中進(jìn)行使用。你可以使用一個CommonJS的簡單包裝來實現(xiàn):

define(function(require, exports, module) {
        var a = require("a"),
            b = require("b");

        //Return the module value
        return function () {};
    }
);

該包裝方法依靠Function.prototype.toString()將函數(shù)內(nèi)容賦予一個有意義的字串值,但在一些設(shè)備如PS3及一些老的Opera手機(jī)瀏覽器中不起作用??紤]在這些設(shè)備上使用優(yōu)化器將依賴導(dǎo)出為數(shù)組形式。

更多的信息可參看CommonJS Notes頁面,以及"Why AMD"頁面的"Sugar"段落。

點評:這種用法跟上面說的一樣,首先回調(diào)用Function.prototype.toString()將函數(shù)轉(zhuǎn)換成字符串,然后在進(jìn)行詞法分析,這樣依賴,就比較低耗了,原則上不考慮使用這種方法進(jìn)行模塊封裝。

定義一個命名模塊

你可能會看到一些define()中包含了一個模塊名稱作為首個參數(shù):

    //Explicitly defines the "foo/title" module:
    define("foo/title",
        ["my/cart", "my/inventory"],
        function(cart, inventory) {
            //Define foo/title object in here.
       }
    );

這些常由優(yōu)化工具生成。你也可以自己顯式指定模塊名稱,但這使模塊更不具備移植性——就是說若你將文件移動到其他目錄下,你就得重命名。一般最好避免對模塊硬編碼,而是交給優(yōu)化工具去生成。優(yōu)化工具需要生成模塊名以將多個模塊打成一個包,加快到瀏覽器的載人速度。

點評:define 函數(shù)有三個參數(shù),第一個 id 即模塊名稱,這個名稱的格式是相對于 baseUrl 的路徑除去文件格式,比如 baseUrl 為 js 目錄,一個模塊放在 js/libs/hi.js 里,則如果名稱是這樣定義的:

define("libs/hi", ["jquery"], function($){......});

這樣的定義形式的好處是,模塊不可能沖突,因為同一目錄下不允許同名文件。但也因此 require.js 建議我們不要設(shè)置模塊名稱,因為設(shè)置了 ‘libs/hi’ 的模塊名稱后,模塊就必須放在 js/libs 目錄下的 hi.js 文件中,要移動位置的話,模塊名稱要跟著改變。至于后期利用 r.js 優(yōu)化時生成了模塊名稱,那已經(jīng)是另外一回事。所以定義模塊時,第一參數(shù)常常會忽略。

JSONP服務(wù)依賴

JSONP是在javascript中服務(wù)調(diào)用的一種方式。它僅需簡單地通過一個script標(biāo)簽發(fā)起HTTP GET請求,是實現(xiàn)跨域服務(wù)調(diào)用一種公認(rèn)手段。

為了在RequireJS中使用JSON服務(wù),須要將callback參數(shù)的值指定為"define"。這意味著你可將獲取到的JSONP URL的值看成是一個模塊定義。

下面是一個調(diào)用JSONP API端點的示例。該示例中,JSONP的callback參數(shù)為"callback",因此"callback=define"告訴API將JSON響應(yīng)包裹到一個"define()"中:

require(["http://example.com/api/data.json?callback=define"],
    function (data) {
        //The data object will be the API response for the
        //JSONP data call.
        console.log(data);
    }
);

JSONP的這種用法應(yīng)僅限于應(yīng)用的初始化中。一旦JSONP服務(wù)超時,其他通過define()定義了的模塊也可能得不得執(zhí)行,錯誤處理不是十分健壯。

僅支持返回值類型為JSON object的JSONP服務(wù),其他返回類型如數(shù)組、字串、數(shù)字等都不能支持。

這種功能不該用于long-polling類的JSONP連接——那些用來處理實時流的API。這些API在接收響應(yīng)后一般會做script的清理,而RequireJS則只能獲取該JSONP URL一次——后繼使用require()或define()發(fā)起的的對同一URL的依賴(請求)只會得到一個緩存過的值。

JSONP調(diào)用錯誤一般以服務(wù)超時的形式出現(xiàn),因為簡單加載一個script標(biāo)簽一般不會得到很 詳細(xì)的網(wǎng)絡(luò)錯誤信息。你可以override requirejs.onError()來過去錯誤。更多的信息請參看錯誤處理部分。

點評:跨域腳本調(diào)用。

模塊的加載

常見模塊加載調(diào)用的形式如下:

require(["jquery"],function($){

    //todo

});

第一個參數(shù)指定要加載的模塊名,第二個是相對應(yīng)的注入?yún)?shù)。

幫助文檔

官網(wǎng)API文檔:http://requirejs.org/docs/api.html#define
中文API文檔:http://requirejs.cn/docs/api.html#define
中文API文檔:http://makingmobile.org/docs/tools/requirejs-api-zh/#define
中文文檔:http://www.zfanw.com/blog/require-js.html
中文文檔:http://www.fanli7.net/a/bianchengyuyan/ASP/20130419/300243.html

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/85410.html

相關(guān)文章

  • RequireJS進(jìn)階:配置文件學(xué)習(xí)

    摘要:概述強(qiáng)大靈活的運(yùn)用是通過配置文件決定的。下面通過示例來進(jìn)行深度的探討配置文件的使用。配置文件的位置配置文件的位置和聲明用法是相對于這個腳本文件來決定的。配置文件參數(shù)的介紹所有模塊的查找根路徑。 概述 Requires強(qiáng)大靈活的運(yùn)用是通過配置文件決定的。通過配置文件我們可以給模塊取別名、給模塊加上版本標(biāo)識、設(shè)置模塊依賴、包裝非模塊等強(qiáng)大功能。同時RequireJS的優(yōu)化器也大量使用了配...

    lemon 評論0 收藏0
  • JS進(jìn)階篇--RequireJS模塊化編程詳解

    摘要:所有依賴這個模塊的語句,都定義在一個回調(diào)函數(shù)中,等到加載完成之后,這個回調(diào)函數(shù)才會運(yùn)行。 1.模塊的寫法 模塊化編程一般都有這么幾個過渡過程,如下描述。 原始方法 function m1(){   //... } function m2(){   //... } 上面的函數(shù)m1()和m2(),組成一個模塊。使用的時候,直接調(diào)用就行了。 這種做法的缺點很明顯:污染了全局變量,無法保證不與...

    妤鋒シ 評論0 收藏0
  • 前端資源系列(4)-前端學(xué)習(xí)資源分享&前端面試資源匯總

    摘要:特意對前端學(xué)習(xí)資源做一個匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 特意對前端學(xué)習(xí)資源做一個匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 本以為自己收藏的站點多,可以很快搞定,沒想到一入?yún)R總深似海。還有很多不足&遺漏的地方,歡迎補(bǔ)充。有錯誤的地方,還請斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應(yīng)和斧正,會及時更新,平時業(yè)務(wù)工作時也會不定期更...

    princekin 評論0 收藏0
  • 前端基礎(chǔ)進(jìn)階(十三):透徹掌握Promise使用,讀這篇就夠了

    摘要:在對象的構(gòu)造函數(shù)中,將一個函數(shù)作為第一個參數(shù)。二對象中的方法,可以接收構(gòu)造函數(shù)中處理的狀態(tài)變化,并分別對應(yīng)執(zhí)行。 showImg(https://segmentfault.com/img/remote/1460000008932857); Promise的重要性我認(rèn)為我沒有必要多講,概括起來說就是必須得掌握,而且還要掌握透徹。這篇文章的開頭,主要跟大家分析一下,為什么會有Promise...

    yy736044583 評論0 收藏0
  • RequireJS學(xué)習(xí)筆記

    摘要:如果有疑惑的地方,歡迎討論,我是初學(xué),希望能切磋和得到指點加載會阻塞頁面加載默認(rèn)異步加載文件方法一把放到頁面底部加載方法二支持定義全局相對路徑方法一自定義屬性指定網(wǎng)頁程序的主模塊文件定義整個網(wǎng)頁代碼的入口文件的相對位置,以后此文件 如果有疑惑的地方,歡迎討論,我是初學(xué),希望能切磋和得到指點; js加載會阻塞頁面加載: //requirejs默認(rèn)異步加載js文件; 方法一...

    hersion 評論0 收藏0

發(fā)表評論

0條評論

legendmohe

|高級講師

TA的文章

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