天天看點

JS - CommonJS、ES2015、AMD、CMD子產品規範對比與介紹

一、CommonJS

1,CommonJS 基本介紹

(1)CommonJS是一種思想,它是為JS的表現來制定規範,由于JS沒有子產品系統、标準庫較少、缺乏包管理工具,是以CommonJS應運而生。

(2)CommonJS 的目标是希望 JS 可以在任何地方運作,不隻是浏覽器中。隻要我們的 JavaScript 是根據 CommonJS API 編寫的,那麼就可以在與 CommonJS 相容的系統上運作。

(3)根據 CommonJS API 編寫的 JavaScript 可以做下面這些事情:

編寫服務端應用

編寫指令行工具

編寫基于 GUI 的桌面應用

(4)CommonJS 規範有很多實作,最有名要數 NodeJS 了。

2,CommonJS 的子產品規範

一個檔案就是一個子產品,擁有單獨的作用域。普通方式定義的變量、函數、對象都屬于該子產品内。

通過 require 來加載子產品。

通過 exports 和 modul.exports 來暴露子產品中的内容。

3,使用樣例1:使用 exports 暴露子產品接口

(1)下面我們在 Node.js 中建立一個子產品,檔案名為:hangge.js

exports.hello = function() {
  console.log('Hello hangge.com');
}
           

(2)建立一個 main.js 檔案,引入這個子產品并調用。

var hangge = require('./hangge');
hangge.hello();
           

4,使用樣例2:使用 modul.exports 暴露子產品對象

(1)下面我們把一個對象封裝到子產品中,檔案名為:hangge.js

//私有變量
var test = ;

//公開方法
function Hangge() {
    var name;
    this.setName = function(thyName) {
        name = thyName;
    };
    this.hello = function() {
        console.log('Hello ' + name);
    };
};

module.exports = Hangge;
           

(2)建立一個 main.js 檔案,引入這個子產品并調用。

var Hangge = require('./hangge');
var hello = new Hangge();
hello.setName('hangge.com');
hello.hello();
           

二、ES2015

1,ES2015 基本介紹

2015 年 6 月, ES2015(即 ECMAScript 6、ES6) 正式釋出。ES2015 是該語言的一個顯著更新,也是自 2009 年 ES5 标準确定後的第一個重大更新。

雖然 ES2015 提出了許多令人激動的新特性,但由于目前 JavaScript 的運作環境衆多,對 ECMAScript 标準的支援程度也不一樣。

2,ES2015 的子產品規範

一個子產品就是一個獨立的檔案。該檔案内部的所有變量,外部無法擷取。

export 指令用于規定子產品的對外接口。

import 指令用于輸入其他子產品提供的功能。

ES6 子產品的設計思想是盡量的靜态化,使得編譯時就能确定子產品的依賴關系,以及輸入和輸出的變量。

3,使用樣例1:使用 export 指令規定對外接口

(1)下面我們在 Node.js 中建立一個子產品,檔案名為:hangge.js

//圓面積計算
export function area(radius) {
  return Math.PI * radius * radius;
}

//圓周長計算
export function circumference(radius) {
  return  * Math.PI * radius;
}
           

(2)建立一個 main.js 檔案,引入這個子產品并調用。這裡 import 指令使用大括号的形式加載子產品對外的接口。

import {area,circumference} from './hangge';
console.log('圓面積:' + area());
console.log('圓周長:' + circumference());
           

當然也可以使用星号(*)指定一個對象,實作子產品的整體加載。

import * as circle from './hangge';
console.log('圓面積:' + circle.area());
console.log('圓周長:' + circle.circumference());
           

4,使用樣例2:使用 export default 指令來輸出子產品

(1)下面我們使用 export default 指令用于指定子產品的預設輸出。子產品檔案名為:hangge.js

//圓面積計算(作為預設接口)
export default function(radius) {
  return Math.PI * radius * radius;
}

//圓周長計算
export function circumference(radius) {
  return  * Math.PI * radius;
}
           

(2)建立一個 main.js 檔案,引入這個子產品并調用。注意:對于 export default 指定子產品的預設輸出,import 語句不需要使用大括号。

import area, {circumference} from './hangge';
console.log('圓面積:' + area());
console.log('圓周長:' + circumference());
           

三、AMD

1,AMD 基本介紹

AMD 全稱為 Asynchromous Module Definition(異步子產品定義)

AMD 是 RequireJS 在推廣過程中對子產品定義的規範化産出,它是一個在浏覽器端子產品化開發的規範。

AMD 模式可以用于浏覽器環境并且允許非同步加載子產品,也可以按需動态加載子產品。

2,AMD 的子產品規範

AMD 通過異步加載子產品。子產品加載不影響後面語句的運作。所有依賴某些子產品的語句均放置在回調函數中。

AMD 規範隻定義了一個函數 define,通過 define 方法定義子產品。該函數的描述如下:

define(id?, dependencies?, factory)

id:指定義中子產品的名字(可選)。如果沒有提供該參數,子產品的名字應該預設為子產品加載器請求的指定腳本的名字。如果提供了該參數,子產品名必須是“頂級”的和絕對的(不允許相對名字)。

dependencies:目前子產品依賴的,已被子產品定義的子產品辨別的數組字面量(可選)。

factory:一個需要進行執行個體化的函數或者一個對象。

AMD 規範允許輸出子產品相容 CommonJS 規範,這時 define 方法如下:

define(function (require, exports, module) {
    var reqModule = require("./someModule");
    requModule.test();

    exports.asplode = function () {
        //someing
    }
});
           

3,使用樣例1:獨立子產品

(1)我們使用 RequireJS 定義一個不依賴其他子產品得獨立子產品,檔案名:hangge.js

define(function(){
    var add = function(x,y) {
        return x + y;
    };
    return {
        add : add
    }
});
           

(2)接着建立一個 html 頁面,其内部加載并調用這個子產品。

<!DOCTYPE html>
<html>
    <head>
        <script type="text/javascript" src="require.js"></script>
        <script type="text/javascript">
          require(['hangge'], function (m){
            console.log(m.add(,));
          });
        </script>
    </head>
    <body>
    </body>
</html>
           

4,使用樣例2:存在依賴的函數式定義

下面定義的子產品又依賴于 cart 和 inventory 這兩個子產品(它們都處在同一個檔案夾下)

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);
            }
        }
    }
);
           

四、CMD

1,CMD 基本介紹

(1)CMD 全稱為 Common Module Definition,它是國内玉伯大神在開發 SeaJS 的時候提出來的。

(2)CMD 與 AMD 挺相近,二者差別如下:

對于依賴的子產品 CMD 是延遲執行,而 AMD 是提前執行(不過 RequireJS 從 2.0 開始,也改成可以延遲執行。 )

CMD 推崇依賴就近,AMD 推崇依賴前置。

AMD 的 api 預設是一個當多個用,CMD 嚴格的區分推崇職責單一,其每個 API 都簡單純粹。例如:AMD 裡 require 分全局的和局部的。CMD 裡面沒有全局的 require,提供 seajs.use() 來實作子產品系統的加載啟動。

2,使用樣例1:使用 exports 暴露子產品接口

(1)下面使用 sea.js 建立一個子產品,檔案名為:hangge.js

define(function(require, exports) {
    // 對外提供name屬性
    exports.name = 'hangge';
    // 對外提供hello方法
    exports.hello = function() {
      console.log('Hello hangge.com');
    };
});
           

(2)接着建立一個 html 頁面,其内部加載并調用這個子產品。

<!DOCTYPE html>
<html>
    <head>
        <script type="text/javascript" src="sea.js"></script>
        <script type="text/javascript">
          //加載一個子產品,在加載完成時,執行回調
          seajs.use('hangge', function(a) {
            a.hello();
          });
        </script>
    </head>
    <body>
    </body>
</html>
           

3,使用樣例2:使用 modul.exports 暴露子產品對象

(1)下面我們把一個對象封裝到子產品中,檔案名為:hangge.js

define(function(require, exports, module) {
    // 對外提供接口
    module.exports = {
        name: 'hangge',
        hello: function() {
          console.log('Hello hangge.com');
        }
    };
});
           

(2)接着建立一個 html 頁面,其内部加載并調用這個子產品。

<!DOCTYPE html>
<html>
    <head>
        <script type="text/javascript" src="sea.js"></script>
        <script type="text/javascript">
          //加載一個子產品,在加載完成時,執行回調
          seajs.use('hangge', function(a) {
            a.hello();
          });
        </script>
    </head>
    <body>
    </body>
</html>