淺談javascript - 模塊化規範

来源:http://www.cnblogs.com/xiuhongbin/archive/2016/10/24/AMD.html
-Advertisement-
Play Games

一,JS模塊化演變過程 1.普通函數封裝 最初的這種普通函數封裝的缺點很明顯:污染了全局變數,無法避免的會與其他模塊發生變數名衝突,而且自身模塊成員之間沒有任何聯繫,,說白了就是沒有做到“高內聚,低耦合”原則 2.對象 技術一直在進步,這種做法的避免了變數污染,只要保證模塊名唯一即可,自身模塊內的成 ...


一,JS模塊化演變過程

1.普通函數封裝

1 function fn1(){
2 
3 }
4 
5 function fn2(){
6 
7 }

最初的這種普通函數封裝的缺點很明顯:污染了全局變數,無法避免的會與其他模塊發生變數名衝突,而且自身模塊成員之間沒有任何聯繫,,說白了就是沒有做到“高內聚,低耦合”原

2.對象

 1 var myModule = { 
 2     var1: 1,
 3     var2: 2,
 4     fn1: function(){
 5 
 6     },
 7     fn2: function(){
 8 
 9     }
10 }

技術一直在進步,這種做法的避免了變數污染,只要保證模塊名唯一即可,自身模塊內的成員也有了聯繫;

但是新的問題出現了,看似不錯的解決方案,也有缺陷,外部可以隨意修改內部成員;

如:myModel.val = 100;  說白了就是產生了安全問題

3.立即執行函數

 1 var myModule = (function(){ 
 2     var var1 = 1;
 3     var var2 = 2;
 4     function fn1(){
 5 
 6     }
 7     function fn2(){
 8 
 9     }
10     return { 
11         fn1: fn1, fn2: fn2
12     };
13 })();

這種做法就是我們JS模塊化的基礎,技術永無止境,隨著JS模塊化技術提高,產生了不同流派,分支;其中主要有兩種:CommonJS和AMD

二,CommonJS

1.定義模塊:

根據CommonJS規範,一個單獨的文件為一個模塊,每個模塊是一個單獨的作用域,即在自身模塊內部定義的變數,其他模塊無法讀取,除非是定義為global對象的屬性

2.模塊輸出:

每個模塊只有一個出口,即module.exports對象,我們需要把模塊希望輸出的內容放入該對象

3.載入模塊:

載入模塊使用require方法,該方法讀取一個文件並執行,返迴文件內部的module.exports對象

 1 //模塊定義
 2 myModel.js
 3 var name = 'Byron';
 4 function printName(){ 
 5     console.log(name);
 6 }
 7 function printFullName(firstName){ 
 8     console.log(firstName + name);
 9 }
10 module.exports = { 
11     printName: printName,
12     printFullName: printFullName
13 }
14 //載入模塊
15 var nameModule = require('./myModel.js');
16 nameModule.printName();

不同的實現對require時的路徑有不同要求,一般情況可以省略js拓展名,可以使用相對路徑,也可以使用絕對路徑,甚至可以省略路徑直接使用模塊名(前提是該模塊是系統內置模塊) 

問題:

仔細看上面的代碼,會發現require是同步的。模塊系統需要同步讀取模塊文件內容,並編譯執行以得到模塊介面。

這在伺服器端實現很簡單,也很自然,然而, 想在瀏覽器端實現問題卻很多。

瀏覽器端,載入JavaScript最佳、最容易的方式是在document中插入script 標簽。但腳本標簽天生非同步,傳統CommonJS模塊在瀏覽器環境中無法正常載入。

解決思路之一是,開發一個伺服器端組件,對模塊代碼作靜態分析,將模塊與它的依賴列表一起返回給瀏覽器端。 這很好使,但需要伺服器安裝額外的組件,並因此要調整一系列底層架構。

另一種解決思路是,用一套標準模板來封裝模塊定義,但是對於模塊應該怎麼定義和怎麼載入,又產生的分

三,AMD

AMD 即Asynchronous Module Definition,中文名是非同步模塊定義的意思。它是一個在瀏覽器端模塊化開發的規範。

由於不是JavaScript原生支持,使用AMD規範進行頁面開發需要用到對應的庫函數,也就是大名鼎鼎RequireJS,實際上AMD 是 RequireJS 在推廣過程中對模塊定義的規範化的產出。

requireJS主要解決兩個問題

1.多個js文件可能有依賴關係,被依賴的文件需要早於依賴它的文件載入到瀏覽器

2.js載入的時候瀏覽器會停止頁面渲染,載入文件越多,頁面失去響應時間越長

語法

requireJS定義了一個函數 define,它是全局變數,用來定義模塊。

define(id?, dependencies?, factory);

id:可選參數,用來定義模塊的標識,如果沒有提供該參數,腳本文件名(去掉拓展名);

dependencies:是一個當前模塊依賴的模塊名稱數組

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

 1 // 定義模塊 
 2 myModule.js 
 3 define(['dependency'], function(){ 
 4     var name = 'xlw';
 5     function printName(){ 
 6         console.log(name);
 7     }
 8     return {
 9         printName: printName
10     };
11 });
12 // 載入模塊
13 require(['myModule'], function (my){ 
14     my.printName();
15 });

在頁面上使用require函數載入模塊

1 require([dependencies], function(){
2     
3 });

require()函數接受兩個參數

第一個參數是一個數組,表示所依賴的模塊

第二個參數是一個回調函數,當前面指定的模塊都載入成功後,它將被調用。載入的模塊會以參數形式傳入該函數,從而在回調函數內部就可以使用這些模塊

require()函數在載入依賴的函數的時候是非同步載入的,這樣瀏覽器不會失去響應,它指定的回調函數,只有前面的模塊都載入成功後,才會運行,解決了依賴性的問題。

敬請留言指正補充

(完~~)


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <script type="text/javascript"> //substring()方法用於提取字元串中介於兩個指定下標之間的 ...
  • MVC, MVP和MVVM都是用來解決界面呈現和邏輯代碼分離而出現的模式。以前只是對它們有部分的瞭解,沒有深入的研究過,對於一些裡面的概念和區別也是一知半解。現在一邊查資料,並結合自己的理解,來談一下對於這三種模式思想的理解,以及它們的區別。歡迎各位高手拍磚。 閱讀目錄: 一. MVC, MVP, ...
  • 可滾動選日期,並限制哪些日期可選和不可選。 主要用來根據後臺返回生成一個日期選擇器。 具體實現可關註jmslip: https://github.com/jiamao/jmSlip 示例:http://slip.jm47.com/demo/calendar/index.html ...
  • ng-init是給angular執行給定的表達式,初始化變數的值 這樣就初始化了myTest的值,ng-app沒有設值,要是設置的話,就要js啦,要不然就得報錯了 ...
  • 裝飾者模式筆記 在不改變原對象的基礎上, 通過對其進行包裝拓展(添加屬性或方法)使原有對象可以滿足用戶的更複雜要求。 需求不是一成不變的,需求會不斷改進,以增強用戶體驗 demo實例:對輸入框添加focus與blur事件 這個實例中,輸入框只有一兩個時,新添需求不覺得麻煩,當有許多輸入框都要新添需求 ...
  • directive裡面的幾個配置,上代碼就清晰了 這段代碼在瀏覽器上打開是這樣的, 看到嗎,directive裡面的template在標簽的裡面,是標簽的子元素 然後再看,在配置一個replace replace為true的時候可以看到的是原來的自定義標簽被template替代了 要是restric ...
  • 這裡多謝某童鞋的提醒!說我的上篇隨筆jquery插件開發的方式一還還可用於合併參數和深clone,雖然方式二中用了方式一做參數合併,但並未詳細介紹,所以今天在此處做點補充! 一、合併參數 jquery的extend擴展原型: 返回值未arg1,arg2……合併到arg。這裡就有兩種用法。 省略arg ...
  • avalon.js是一款迷你的MVVM框架,設計者將其相容到了IE6。輕巧的體積和良好的相容使它非常適合國內的某些項目(學校、政府、銀行)。然而有時候居然出現了在ie上無法渲染的情況。 例如下列這段簡單的demo: 在chrome上的顯示是: 而在ie8上顯示卻是這樣: 大家不要慌張,可能是你加入了 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...