在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ HTML/ CommonJS
中介者模式
MVVM
亨元模式
設(shè)計模式分類概覽表
ES Harmony
組合模式
CommonJS
jQuery 插件的設(shè)計模式
外觀模式
觀察者模式
建造者模式
構(gòu)造器模式
外觀模式
簡介
AMD
原型模式
設(shè)計模式的分類
觀察者模式
命名空間模式
代理模式
編寫設(shè)計模式
適配器模式
反模式
什么是設(shè)計模式
模塊化模式
MVC
Mixin 模式
裝飾模式
設(shè)計模式的結(jié)構(gòu)
單例模式
迭代器模式
命令模式
工廠模式
MVP
暴露模塊模式
惰性初始模式

CommonJS

為服務(wù)器提供的一種模塊形式的優(yōu)化

CommonJS模塊建議指定一個簡單的用于聲明模塊服務(wù)器端的API,并且不像AMD那樣嘗試去廣泛的操心諸如io,文件系統(tǒng),約定以及更多的一攬子問題。

這種形式為CommonJS所建議--它是一個把目標(biāo)定在設(shè)計,原型化和標(biāo)準(zhǔn)化Javascript API的自愿者工作組。迄今為止,他們已經(jīng)在模塊和包方面做出了批復(fù)標(biāo)準(zhǔn)的嘗試。

入門

從架構(gòu)的角度來看,CommonJS模塊是一個可以復(fù)用的Javascript塊,它出口對任何獨立代碼都起作用的特定對象。不同于AMD,通常沒有針對此模塊的功能封裝(因此打個比方我們并沒有在這里找到定義的相關(guān)語句)。

CommonJS模塊基本上包括兩個基礎(chǔ)的部分:一個取名為exports的自由變量,它包含模塊希望提供給其他模塊的對象,以及模塊所需要的可以用來引入和導(dǎo)出其它模塊的函數(shù)。

理解CommonJS:require()和exports

// package/lib is a dependency we require
var lib = require( "package/lib" );

// behaviour for our module
function foo(){
    lib.log( "hello world!" );
}

// export (expose) foo to other modules
exports.foo = foo;

exports的基礎(chǔ)使用

// define more behaviour we would like to expose
function foobar(){
  this.foo = function(){
    console.log( "Hello foo" );
  }

  this.bar = function(){
    console.log( "Hello bar" );
  }
}

// expose foobar to other modules
exports.foobar = foobar;

// an application consuming "foobar"

// access the module relative to the path
// where both usage and module files exist
// in the same directory

var foobar = require("./foobar").foobar,
    test   = new foobar();

// Outputs: "Hello bar"
test.bar();

等同于AMD的第一個CommonJS示例

define(function(require){
   var lib = require( "package/lib" );

    // some behaviour for our module
    function foo(){
        lib.log( "hello world!" );
    }

    // export (expose) foo for other modules
    return {
        foobar: foo
    };
});

這也可以用AMD支持的簡化了的CommonJS特定做到。

消耗多重依賴

app.js

var modA = require( "./foo" );
var modB = require( "./bar" );

exports.app = function(){
    console.log( "Im an application!" );
}

exports.foo = function(){
    return modA.helloWorld();
}

bar.js

exports.name = "bar";

foo.js

require( "./bar" );
exports.helloWorld = function(){
    return "Hello World!!"
}

加載器和框架對CommonJS提供了什么支持?

在瀏覽器端:

服務(wù)器端:

CommonJS適合瀏覽器么?

有開發(fā)者感覺CommonJS更適合于服務(wù)器端的開發(fā),這是如今應(yīng)該用哪種形式和將要來作為面向未來的備選事實標(biāo)準(zhǔn),在這一問題上存在一定程度分歧的原因之一。一些爭論指摘CommonJS包括許多面向服務(wù)器的特性,這些特性很容易可以看出并不能夠用Javascript在瀏覽器級別中實現(xiàn)--例如,io,系統(tǒng),而且js會被認(rèn)為是借助于它們功能的性質(zhì)無法實現(xiàn)的。

那就是說,無論如何了解如何構(gòu)建CommonJS模塊是有用的,那樣我們就可以更好的理解它們?nèi)绾芜m合于定義可以在任何地方使用的模塊了。模塊在客戶端和服務(wù)器端都有包括驗證,約定和模板引擎的應(yīng)用程序。一些開發(fā)者趨向于選擇那種形式的方式是當(dāng)一個模塊能夠在服務(wù)器端環(huán)境使用時,就選擇CommonJS,而如果不是這種場景,就使用AMD。

由于AMD模塊具有使用插件的能力,并且能夠定義更加精細(xì)的像構(gòu)造器和函數(shù)之類的東西,如此是有道理的。

CommonJS模塊只能夠去定義使用起來會非常繁瑣的對象,如果我們嘗試從它們那里獲取構(gòu)造器的話。

盡管這超出了本節(jié)的討論范疇,也要注意當(dāng)論及AMD和CommonJS時,不同類型的“require”方法會被提到。帶有類似命名空間的問題理所當(dāng)然是令人迷惑的,而社區(qū)當(dāng)前對全局的require功能的優(yōu)點正存在著分歧。這里John Hann的建議是不去叫它“require”,它很可能在告知用戶關(guān)于全局的和內(nèi)部的require之間的差別,這一目標(biāo)上取得失敗,將全局加載器方法重新命名為其它什么東西(例如,庫的名字)可能更加起作用。正式由于這個原因,像curl.js這樣的加載器反對使用require,而使用curl()。

AMD 與 CommonJS 存在競爭,但都是同樣有效的標(biāo)準(zhǔn)

AMD 和 CommonJS 都是有效的模塊形式,它們帶有不同的最終目標(biāo)。

AMD采用瀏覽器先行的方針,它選擇了異步的行為方式,并且簡化了向后兼容性,但是它并沒有任何文件I/O的概念。它支持對象,函數(shù),構(gòu)造器,字符串,JSON以及許多其它類型的模塊,在瀏覽器進(jìn)行本地運行。這是令人難以置信的靈活性。

CommonJS 則在另一個方面采用了服務(wù)器端先行的方針,承載著同步行為,沒有全局的負(fù)擔(dān)并且嘗試去迎合(在服務(wù)器上的)未來。我們的意思是CommonJS支持無封裝的模塊,可以感覺到它跟ES.next/Harmony更接近一點,將我們從AMD強(qiáng)制使用的define()封裝中解放出來。然而CommonJS僅支持對象作為模塊。

UMD:AMD和兼容CommonJS模塊的插件

對于希望創(chuàng)建在瀏覽器和服務(wù)器端環(huán)境都能夠運作的模塊的開發(fā)者而言,現(xiàn)有的解決方案感覺可能少了點。為了有助于緩解這個問題,James Burke , 我以及許許多多其他的開發(fā)者創(chuàng)造了UMD(通用模塊定義)

UMD是一種是實驗性質(zhì)的模塊形式,允許在編寫代碼的時候,所有或者大多數(shù)流行的實用腳本加載技術(shù)對模塊的定義在客戶端和服務(wù)器環(huán)境下都能夠起作用。另外一種模塊格式的想法盡管可能是艱巨的,出于仔細(xì)徹底的考慮,我們將簡要的概括一下UMD。最開始,我們通過簡要的看一看AMD規(guī)范中所支持的對于CommonJS的簡單封裝,來定義UMD。對于希望把模塊當(dāng)做CommonJS模塊來編寫的開發(fā)者,可以應(yīng)用下面的兼容CommonJS的形式:

基礎(chǔ)的AMD混合格式:

define( function ( require, exports, module ){

    var shuffler = require( "lib/shuffle" );

    exports.randomize = function( input ){
        return shuffler.shuffle( input );
    }
});

然而,注意到如果一個模塊并沒有包含一個依賴數(shù)組,并且定義的函數(shù)只包含最少的一個參數(shù),那么它就真的僅僅只是被當(dāng)做CommonJS模塊來對待,這一點是很重要的。這在某些設(shè)備(例如PS3)上面也不會正確的工作。如需進(jìn)一步了解上述的封裝,請看看:http://requirejs.org/docs/api.html#cjsmodule。

進(jìn)一步的考慮,我們想要提供許多不同的模式,那不僅僅只是在AMD和CommonJS上起作用,同樣也能解決開發(fā)者希望使用其它環(huán)境開發(fā)這樣的模塊時普遍遇到的問題。

下面我們可以看到這樣的變化允許我們使用CommonJS,AMD或者瀏覽全局的對象創(chuàng)建一個模塊。

使用 CommonJS,AMD或者瀏覽器全局對象創(chuàng)建模塊

定義一個模塊 commonJsStrict,它依賴于另外一個叫做B的模塊。模塊的名稱暗示了文件的名稱(,就是說一樣的),而讓文件名和導(dǎo)出的全局對象的名字一樣則是一種最佳實踐。

如果模塊同時也在瀏覽器中使用了相同類型的樣板,它就會創(chuàng)建一個global.b備用。如果我們不希望對瀏覽器全局補(bǔ)丁進(jìn)行支持, 我們可以將root移除,并且把this傳遞到頂層函數(shù)作為其第一個參數(shù)。

(function ( root, factory ) {
    if ( typeof exports === 'object' ) {
        // CommonJS
        factory( exports, require('b') );
    } else if ( typeof define === 'function' && define.amd ) {
        // AMD. Register as an anonymous module.
        define( ['exports', 'b'], factory);
    } else {
        // Browser globals
        factory( (root.commonJsStrict = {}), root.b );
    }
}(this, function ( exports, b ) {
    //use b in some fashion.

    // attach properties to the exports object to define
    // the exported module properties.
    exports.action = function () {};
}));

UMD資源庫包含了在瀏覽器中能夠最優(yōu)化運作的涵蓋不同的模塊,那些對于提供導(dǎo)出非常不錯的,那些對于CommonJS的優(yōu)化還有那些對于定義jQuery插件作用良好的,我們會在接下里看得到。

可以在所有環(huán)境下面起作用的jQuery插件

UMD提供了兩種同jQuery一起工作的模式--一種模式定義了能夠同AMD和瀏覽器全局對象一起工作得很好的插件,而另外一種模式也能夠在CommonJS環(huán)境中起作用。jQuery并不像是能夠運行在大多數(shù)CommonJS環(huán)境中的,因此除非我們工作在一個能夠良好同jQuery一起運作的環(huán)境中,那就把這一點牢記于心。

現(xiàn)在我們將定義一個包含一個核心,以及對此核心的一個擴(kuò)展的插件。核心插件被加載到一個$.core命名空間中,它可以簡單的使用借助于命名空間模式的插件擴(kuò)展進(jìn)行擴(kuò)展。通過腳本標(biāo)簽加載的插件會自動填充core下面的一個插件命名空間(比如,$core.plugin.methodName())。

這種模式操作起來相當(dāng)?shù)陌?,因為插件擴(kuò)展可以訪問到底層定義的屬性和方法,或者,做一些小小的調(diào)整就可以重寫行為以便它能夠被擴(kuò)展來做更多的事情。加載器同樣也不在需要面面俱到了。

想要了解更多需要做的詳細(xì)信息,那就請看看下面代碼示例中內(nèi)嵌的注釋吧:

usage.html

<script type="text/javascript" src="jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="pluginCore.js"></script>
<script type="text/javascript" src="pluginExtension.js"></script>

<script type="text/javascript">

$(function(){

    // Our plugin "core" is exposed under a core namespace in
    // this example, which we first cache
    var core = $.core;

    // Then use use some of the built-in core functionality to
    // highlight all divs in the page yellow
    core.highlightAll();

    // Access the plugins (extensions) loaded into the "plugin"
    // namespace of our core module:

    // Set the first div in the page to have a green background.
    core.plugin.setGreen( "div:first");
    // Here we're making use of the core's "highlight" method
    // under the hood from a plugin loaded in after it

    // Set the last div to the "errorColor" property defined in
    // our core module/plugin. If we review the code further down,
    // we can see how easy it is to consume properties and methods
    // between the core and other plugins
    core.plugin.setRed("div:last");
});

</script>

pluginCore.js

// Module/Plugin core
// Note: the wrapper code we see around the module is what enables
// us to support multiple module formats and specifications by
// mapping the arguments defined to what a specific format expects
// to be present. Our actual module functionality is defined lower
// down, where a named module and exports are demonstrated.
//
// Note that dependencies can just as easily be declared if required
// and should work as demonstrated earlier with the AMD module examples.

(function ( name, definition ){
  var theModule = definition(),
      // this is considered "safe":
      hasDefine = typeof define === "function" && define.amd,
      // hasDefine = typeof define === "function",
      hasExports = typeof module !== "undefined" && module.exports;

  if ( hasDefine ){ // AMD Module
    define(theModule);
  } else if ( hasExports ) { // Node.js Module
    module.exports = theModule;
  } else { // Assign to common namespaces or simply the global object (window)
    ( this.jQuery || this.ender || this.$ || this)[name] = theModule;
  }
})( "core", function () {
    var module = this;
    module.plugins = [];
    module.highlightColor = "yellow";
    module.errorColor = "red";

  // define the core module here and return the public API

  // This is the highlight method used by the core highlightAll()
  // method and all of the plugins highlighting elements different
  // colors
  module.highlight = function( el,strColor ){
    if( this.jQuery ){
      jQuery(el).css( "background", strColor );
    }
  }
  return {
      highlightAll:function(){
        module.highlight("div", module.highlightColor);
      }
  };

});

pluginExtension.js

// Extension to module core

(function ( name, definition ) {
    var theModule = definition(),
        hasDefine = typeof define === "function",
        hasExports = typeof module !== "undefined" && module.exports;

    if ( hasDefine ) { // AMD Module
        define(theModule);
    } else if ( hasExports ) { // Node.js Module
        module.exports = theModule;
    } else {

        // Assign to common namespaces or simply the global object (window)
        // account for for flat-file/global module extensions
        var obj = null,
            namespaces,
            scope;

        obj = null;
        namespaces = name.split(".");
        scope = ( this.jQuery || this.ender || this.$ || this );

        for ( var i = 0; i < namespaces.length; i++ ) {
            var packageName = namespaces[i];
            if ( obj && i == namespaces.length - 1 ) {
                obj[packageName] = theModule;
            } else if ( typeof scope[packageName] === "undefined" ) {
                scope[packageName] = {};
            }
            obj = scope[packageName];
        }

    }
})( "core.plugin" , function () {

    // Define our module here and return the public API.
    // This code could be easily adapted with the core to
    // allow for methods that overwrite and extend core functionality
    // in order to expand the highlight method to do more if we wish.
    return {
        setGreen: function ( el ) {
            highlight(el, "green");
        },
        setRed: function ( el ) {
            highlight(el, errorColor);
        }
    };

});

UMD并不企圖取代AMD或者CommonJS,而僅僅只是為如今希望讓其代碼運行在更多的環(huán)境下的開發(fā)者提供一些補(bǔ)充的援助。想要關(guān)于這種實驗性質(zhì)的形式的更多信息或者想要貢獻(xiàn)建議,見:https://github.com/umdjs/umd