91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript的CommonJS、AMD、CMD、ES6實例分析

發布時間:2022-03-02 09:33:24 來源:億速云 閱讀:115 作者:iii 欄目:web開發

本篇內容主要講解“JavaScript的CommonJS、AMD、CMD、ES6實例分析”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“JavaScript的CommonJS、AMD、CMD、ES6實例分析”吧!

JavaScript的CommonJS、AMD、CMD、ES6實例分析

一、前言

AMD、CMD、CommonJsES5中提供的模塊化編程方案,import/exportES6中新增的模塊化編程方案。

那么,究竟什么什么是AMD、CMD、CommonJs?他們之間又存在什么區別呢?項目開發應該選用哪種模塊化編程規范,又是如何使用?本篇博文將一一解答以上疑問。

二、AMD-異步模塊定義

AMD是”Asynchronous Module Definition”的縮寫,即”異步模塊定義”。它采用異步方式加載模塊,模塊的加載不影響它后面語句的運行。

這里異步指的是不堵塞瀏覽器其他任務(dom構建,css渲染等),而加載內部是同步的(加載完模塊后立即執行回調)。

RequireJS:是一個AMD框架,可以異步加載JS文件,按照模塊加載方法,通過define()函數定義,第一個參數是一個數組,里面定義一些需要依賴的包,第二個參數是一個回調函數,通過變量來引用模塊里面的方法,最后通過return來輸出。

AMDRequireJS在推廣過程中對模塊定義的規范化產出,它是一個概念,RequireJS是對這個概念的實現,就好比JavaScript語言是對ECMAScript規范的實現。AMD是一個組織,RequireJS是在這個組織下自定義的一套腳本語言。

不同于CommonJS,它要求兩個參數:

require([module], callback);

第一個參數[module],是一個數組,里面的成員是要加載的模塊,callback是加載完成后的回調函數。如果將上述的代碼改成AMD方式:

require(['math'], function(math) {
  math.add(2, 3);})

其中,回調函數中參數對應數組中的成員(模塊)。

requireJS加載模塊,采用的是AMD規范。也就是說,模塊必須按照AMD規定的方式來寫。

具體來說,就是模塊書寫必須使用特定的define()函數來定義。如果一個模塊不依賴其他模塊,那么可以直接寫在define()函數之中。

define(id, dependencies, factory);
  • id:模塊的名字,如果沒有提供該參數,模塊的名字應該默認為模塊加載器請求的指定腳本名字;

  • dependencies:模塊的依賴,已被模塊定義的模塊標識的數組字面量。依賴參數是可選的,如果忽略此參數,它應該默認為 ["require", "exports", "module"]。然而,如果工廠方法的長度屬性小于3,加載器會選擇以函數的長度屬性指定的參數個數調用工廠方法。

  • factory:模塊的工廠函數,模塊初始化要執行的函數或對象。如果為函數,它應該只被執行一次。如果是對象,此對象應該為模塊的輸出值。

假定現在有一個math.js文件,定義了一個math模塊。那么,math.js書寫方式如下:

// math.jsdefine(function() {
  var add = function(x, y) {
    return x + y;
  }

  return  {
    add: add  }})

加載方法如下:

// main.jsrequire(['math'], function(math) {
  alert(math.add(1, 1));})

如果math模塊還依賴其他模塊,寫法如下:

// math.jsdefine(['dependenceModule'], function(dependenceModule) {
    // ...})

require()函數加載math模塊的時候,就會先加載dependenceModule模塊。當有多個依賴時,就將所有的依賴都寫在define()函數第一個參數數組中,所以說AMD是依賴前置的。這不同于CMD規范,它是依賴就近的。
CMD

三、CMD-同步模塊定義

CMDCommon Module Definition通用模塊定義,是SeaJS在推廣過程中對模塊定義的規范化產出,是一個同步模塊定義,是SeaJS的一個標準,SeaJSCMD概念的一個實現,SeaJS是淘寶團隊玉伯提供的一個模塊開發的js框架。CMD規范是國內發展出來的,就像AMD有個requireJSCMD有個瀏覽器的實現SeaJSSeaJS要解決的問題和requireJS一樣,只不過在模塊定義方式和模塊加載(可以說運行、解析)時機上有所不同。

CMD 通過define()定義,沒有依賴前置,通過require加載jQuery插件,CMD是依賴就近,在什么地方使用到插件就在什么地方require該插件,即用即返,這是一個同步的概念。

CMD 規范中,一個模塊就是一個文件。代碼的書寫格式如下:

define(function(require, exports, module) {
  // 模塊代碼});

其中,

  • require是可以把其他模塊導入進來的一個參數;

  • exports是可以把模塊內的一些屬性和方法導出的;

  • module 是一個對象,上面存儲了與當前模塊相關聯的一些屬性和方法。

AMD是依賴關系前置,在定義模塊的時候就要聲明其依賴的模塊;
CMD是按需加載依賴就近,只有在用到某個模塊的時候再去require,示例代碼如下:

// CMDdefine(function(require, exports, module) {
  var a = require('./a')
  a.doSomething()
  // 此處略去 100 行
  var b = require('./b') // 依賴可以就近書寫
  b.doSomething()
  // ... })// AMD 默認推薦的是define(['./a', './b'], function(a, b) { // 依賴必須一開始就寫好
  a.doSomething()
  // 此處略去 100 行
  b.doSomething()
  ...})

四、CommonJS 規范

CommonJS規范是通過module.exports定義的,在前端瀏覽器里面并不支持module.exports,通過node.js后端使用。Nodejs端使用CommonJS規范,前端瀏覽器一般使用AMDCMDES6等定義模塊化開發規范。

CommonJS的終極目標是提供一個類似PythonRubyJava的標準庫。這樣的話,開發者可以使用CommonJS API編寫應用程序,然后這些應用就可以運行在不同的JavaScript解釋器和不同的主機環境中。

在兼容CommonJS的系統中,你可以使用JavaScript開發以下程序:

  1. 服務器JavaScript應用程序;

  2. 命令行工具;

  3. 圖形界面應用程序;

  4. 混合應用程序(如,Titanium或Adobe AIR);

2009年,美國程序員Ryan Dahl創造了node.js項目,將javascript語言用于服務器端編程。這標志"Javascript模塊化編程"正式誕生。NodeJSCommonJS規范的實現,webpack 也是以CommonJS的形式來書寫。

node.js的模塊系統,就是參照CommonJS規范實現的。在CommonJS中,有一個全局性方法require(),用于加載模塊。假定有一個數學模塊math.js,就可以像下面這樣加載。

var math = require('math');

然后,就可以調用模塊提供的方法:

var math = require('math');math.add(2,3); // 5

CommonJS定義的模塊分為:模塊引用(require)模塊定義(exports)模塊標識(module)
其中,

  • require()用來引入外部模塊;

  • exports對象用于導出當前模塊的方法或變量,唯一的導出口;

  • module對象就代表模塊本身。

雖說NodeJS遵循CommonJS的規范,但是相比也是做了一些取舍,添了一些新東西的。

NPM作為Node包管理器,同樣遵循CommonJS規范。

下面講講commonJS的原理以及簡易實現:

1、原理
瀏覽器不兼容CommonJS的根本原因,在于缺少四個Node.js環境變量。

module
exports
require
global

只要能夠提供這四個變量,瀏覽器就能加載 CommonJS 模塊。

下面是一個簡單的示例。

var module = {
  exports: {}};(function(module, exports) {
  exports.multiply = function (n) { return n * 1000 };
  }(module, module.exports))var f = module.exports.multiply;
  f(5) // 5000

上面代碼向一個立即執行函數提供 module 和 exports 兩個外部變量,模塊就放在這個立即執行函數里面。模塊的輸出值放在 module.exports 之中,這樣就實現了模塊的加載。

2、Browserify 的實現
Browserify 是目前最常用的 CommonJS 格式轉換工具。

請看一個例子,main.js 模塊加載 foo.js 模塊。

// foo.jsmodule.exports = function(x) {
  console.log(x);};// main.jsvar foo = require("./foo");foo("Hi");

使用下面的命令,就能將main.js轉為瀏覽器可用的格式。

$ browserify main.js > compiled.js

其中,Browserify到底做了什么?安裝一下browser-unpack,就清楚了。

$ npm install browser-unpack -g

然后,將前面生成的compile.js解包。

$ browser-unpack < compiled.js
[
  {
    "id":1,
    "source":"module.exports = function(x) {\n  console.log(x);\n};",
    "deps":{}
  },
  {
    "id":2,
    "source":"var foo = require(\"./foo\");\nfoo(\"Hi\");",
    "deps":{"./foo":1},
    "entry":true
  }]

可以看到,browerify 將所有模塊放入一個數組,id 屬性是模塊的編號,source 屬性是模塊的源碼,deps 屬性是模塊的依賴。

因為 main.js 里面加載了 foo.js,所以 deps 屬性就指定 ./foo 對應1號模塊。執行的時候,瀏覽器遇到 require('./foo') 語句,就自動執行1號模塊的 source 屬性,并將執行后的 module.exports 屬性值輸出。

五、ES6

有關es6模塊特性,強烈推薦阮一峰老師的:ECMAScript 6 入門 - Module 的語法專欄。

要說 ES6 模塊特性,那么就先說說 ES6 模塊跟 CommonJS 模塊的不同之處。

  • ES6 模塊輸出的是值的引用,輸出接口動態綁定,而 CommonJS 輸出的是值的拷貝;

  • ES6 模塊編譯時執行,而 CommonJS 模塊總是在運行時加載。

CommonJS 模塊輸出的是值的拷貝(原始值的拷貝),也就是說,一旦輸出一個值,模塊內部的變化就影響不到這個值。

// a.jsvar b = require('./b');console.log(b.foo);setTimeout(() => {
  console.log(b.foo);
  console.log(require('./b').foo);}, 1000);// b.jslet foo = 1;setTimeout(() => {
  foo = 2;}, 500);module.exports = {
  foo: foo,};// 執行:node a.js// 執行結果:// 1// 1// 1

上面代碼說明,b 模塊加載以后,它的內部 foo 變化就影響不到輸出的 exports.foo 了。這是因為 foo 是一個原始類型的值,會被緩存。所以如果你想要在 CommonJS 中動態獲取模塊中的值,那么就需要借助于函數延時執行的特性。

// a.jsvar b = require('./b');console.log(b.foo);setTimeout(() => {
  console.log(b.foo);
  console.log(require('./b').foo);}, 1000);// b.jsmodule.exports.foo = 1;   // 同 exports.foo = 1 setTimeout(() => {
  module.exports.foo = 2;}, 500);// 執行:node a.js// 執行結果:// 1// 2// 2

所以我們可以總結一下:

  • CommonJS 模塊重復引入的模塊并不會重復執行,再次獲取模塊直接獲得暴露的module.exports 對象。

  • 如果你需要處處獲取到模塊內的最新值的話,也可以每次更新數據的時候每次都要去更新 module.exports 上的值

  • 如果暴露的 module.exports 的屬性是個對象,那就不存在這個問題了。

到此,相信大家對“JavaScript的CommonJS、AMD、CMD、ES6實例分析”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

纳雍县| 巍山| 抚宁县| 鲁山县| 浙江省| 南漳县| 太康县| 宜昌市| 张家口市| 钟山县| 鄂托克旗| 布拖县| 郑州市| 凤冈县| 从化市| 博客| 海原县| 城固县| 招远市| 余江县| 安丘市| 内丘县| 株洲县| 卓尼县| 霍邱县| 宾阳县| 镇平县| 分宜县| 武城县| 外汇| 措勤县| 祁阳县| 海淀区| 社旗县| 翁牛特旗| 肇东市| 宣汉县| 甘德县| 屯留县| 衡南县| 谷城县|