精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

JavaScript 模塊化及 SeaJs 源碼分析

開發 前端
和后端(比如Java)比較就可以看出明顯的差距。2009年Ryan Dahl創建了node.js項目,將JavaScript用于服務器編程,這標志“JS模塊化編程”正式誕生。

網頁的結構越來越復雜,簡直可以看做一個簡單APP,如果還像以前那樣把所有的代碼都放到一個文件里面會有一些問題:

  • 全局變量互相影響

  • JavaScript文件變大,影響加載速度

  • 結構混亂、很難維護

和后端(比如Java)比較就可以看出明顯的差距。2009年Ryan Dahl創建了node.js項目,將JavaScript用于服務器編程,這標志“JS模塊化編程”正式誕生。

基本原理

模塊就是一些功能的集合,那么可以將一個大文件分割成一些小文件,在各個文件中定義不同的功能,然后在HTML中引入:

  1. var module1 = new Object({ 
  2.     _count : 0
  3.     m1 : function (){ 
  4.         //... 
  5.     }, 
  6.     m2 : function (){ 
  7.         //... 
  8.     } 
  9. }); 

這樣做的壞處是:把模塊中所有的成員都暴露了!我們知道函數的本地變量是沒法從外面進行訪問的,那么可以用立即執行函數來優化:

  1. var module1 = (function(){ 
  2.     var _count = 0
  3.     var m1 = function(){ 
  4.         //... 
  5.     }; 
  6.     var m2 = function(){ 
  7.         //... 
  8.     }; 
  9.     return { 
  10.         m1 : m1, m2 : m2 
  11.     }; 
  12. })(); 

大家定義模塊的方式可能五花八門,如果都能按照一定的規范來,那好處會非常大:可以互相引用!

模塊規范

在node.js中定義math.js模塊如下:

  1. function add(a, b){ 
  2.     return a + b; 
  3. exports.add = add; 

在其他模塊中使用的時候使用全局require函數加載即可:

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

在服務器上同步require是沒有問題的,但是瀏覽器在網絡環境就不能這么玩了,于是有了異步的AMD規范

  1. require(['math'], function (math) {// require([module], callback); 
  2.     math.add(23); 
  3. }); 

模塊的定義方式如下(模塊可以依賴其他的模塊):

  1. define(function (){ // define([module], callback); 
  2.     var add = function (x,y){ 
  3.         return x+y; 
  4.     }; 
  5.     return { add: add }; 
  6. }); 

用RequireJS可以加載很多其他資源(看這里),很好很強大!在工作中用的比較多的是SeaJS,所使用的規范稱為CMD,推崇(應該是指異步模式):

as lazy as possible!

對于依賴的模塊的處理方式和AMD的區別在于:

AMD是提前執行(依賴前置),CMD是延遲執行(依賴就近)。

在CMD中定義模塊的方式如下:

  1. define(function(require, exports, module) { 
  2.     var a = require('./a'); 
  3.     a.doSomething(); 
  4.     var b = require('./b'); 
  5.     b.doSomething(); 
  6. }); 

使用方式直接看文檔,這里就不贅述了!

SeaJS源碼分析

剛接觸模塊化的時候感覺這個太簡單了,不就是:

創建script標簽的時候設置一下onload和src!

事實上是這樣的,但也不完全是!下面來開始看SeaJS的代碼(sea-debug.js)。一個模塊在加載的過程中可能經歷下面幾種狀態:

  1. var STATUS = Module.STATUS = { 
  2.     // 1 - The `module.uri` is being fetched 
  3.     FETCHING: 1
  4.     // 2 - The meta data has been saved to cachedMods 
  5.     SAVED: 2
  6.     // 3 - The `module.dependencies` are being loaded 
  7.     LOADING: 3
  8.     // 4 - The module are ready to execute 
  9.     LOADED: 4
  10.     // 5 - The module is being executed 
  11.     EXECUTING: 5
  12.     // 6 - The `module.exports` is available 
  13.     EXECUTED: 6
  14.     // 7 - 404 
  15.     ERROR: 7 

內存中用Modul對象來維護模塊的信息:

  1. function Module(uri, deps) { 
  2.     this.uri = uri 
  3.     this.dependencies = deps || [] // 依賴模塊ID列表 
  4.     this.deps = {} // 依賴模塊Module對象列表 
  5.     this.status = 0 // 狀態 
  6.     this._entry = [] // 在模塊加載完成之后需要調用callback的模塊 

在頁面上啟動模塊系統需要使用seajs.use方法:

  1. seajs.use(‘./main’, function(main) {// 依賴及回調方法 
  2.     main.init(); 
  3. }); 

加載過程的整體邏輯可以在Module.prototype.load中看到:

  1. Module.prototype.load = function() { 
  2.     var mod = this 
  3.     if (mod.status >= STATUS.LOADING) { 
  4.         return 
  5.     } 
  6.     mod.status = STATUS.LOADING 
  7.     var uris = mod.resolve() // 解析依賴模塊的URL地址 
  8.     emit("load", uris) 
  9.     for (var i = 0, len = uris.length; i < len; i++) { 
  10.         mod.deps[mod.dependencies[i]] = Module.get(uris[i])// 從緩存取或創建 
  11.     } 
  12.     mod.pass(); // 將entry傳遞給依賴的但還沒加載的模塊 
  13.     if (mod._entry.length) {// 本模塊加載完成 
  14.         mod.onload() 
  15.         return 
  16.     } 
  17.     var requestCache = {}; 
  18.     var m; 
  19.     // 加載依賴的模塊 
  20.     for (i = 0; i < len; i++) { 
  21.         m = cachedMods[uris[i]] 
  22.         if (m.status < STATUS.FETCHING) { 
  23.             m.fetch(requestCache) 
  24.         } else if (m.status === STATUS.SAVED) { 
  25.             m.load() 
  26.         } 
  27.     } 
  28.     for (var requestUri in requestCache) { 
  29.         if (requestCache.hasOwnProperty(requestUri)) { 
  30.             requestCache[requestUri]() 
  31.         } 
  32.     } 

總體上邏輯很順就不講了,唯一比較繞的就是_entry數組了。網上沒有找到比較通俗易懂的文章,于是看著代碼連蒙帶猜地大概看懂了,其實只要記住它的目標即可:

當依賴的所有模塊加載完成后執行回調函數!

換種說法:

數組_entry中保存了當前模塊加載完成之后、哪些模塊的依賴可能加載完成的列表(依賴的反向關系)!

舉個例子,模塊A依賴于模塊B、C、D,那么經過pass之后的狀態如下:

此時A中的remain為3,也就是說它還有三個依賴的模塊沒有加載完成!而如果模塊B依賴模塊E、F,那么在它load的時候會將A也傳遞出去:

有幾個細節:

  1. 已經加載完成的模塊不會被傳播;

  2. 已經傳播過一次的模塊不會再次傳播;

  3. 如果依賴的模塊正在加載那么會遞歸傳播;

維護好依賴關系之后就可以通過Module.prototype.fetch來加載模塊,有兩種sendRequest的實現方式:

  1. importScripts

  2. script

然后根據結果執行load或者error方法。依賴的所有模塊都加載完成后就會執行onload方法:

  1. Module.prototype.onload = function() { 
  2.     var mod = this 
  3.     mod.status = STATUS.LOADED 
  4.     for (var i = 0, len = (mod._entry || []).length; i < len; i++) { 
  5.         var entry = mod._entry[i] 
  6.         if (--entry.remain === 0) { 
  7.             entry.callback() 
  8.         } 
  9.     } 
  10.     delete mod._entry 

其中--entry.remain就相當于告訴entry對應的模塊:你的依賴列表里面已經有一個完成了!而entry.remain === 0則說明它所依賴的所有的模塊都已經加載完成了!那么此時將執行回調函數:

  1. for (var i = 0, len = uris.length; i < len; i++) { 
  2.     exports[i] = cachedMods[uris[i]].exec(); 
  3. if (callback) { 
  4.     callback.apply(global, exports)// 執行回調函數 

腳本下載完成之后會馬上執行define方法來維護模塊的信息:

沒有顯式地指定dependencies時會用parseDependencies來用正則匹配方法中的require()片段(指定依賴列表是個好習慣)。

接著執行factory方法來生成模塊的數據:

  1. var exports = isFunction(factory) ? 
  2.     factory.call(mod.exports = {}, require, mod.exports, mod) : 
  3.     factory 

然后執行你在seajs.use中定義的callback方法:

  1. if (callback) { 
  2.     callback.apply(global, exports) 

當你寫的模塊代碼中require時,每次都會執行factory方法:

  1. function require(id) { 
  2.     var m = mod.deps[id] || Module.get(require.resolve(id)) 
  3.     if (m.status == STATUS.ERROR) { 
  4.         throw new Error('module was broken: ' + m.uri) 
  5.     } 
  6.     return m.exec() 

到這里核心的邏輯基本上講完了,補一張狀態的轉換圖:

以后在用的時候就可以解釋一些詭異的問題了!

總結

模塊化非常好用,因此在ECMAScript 6中也開始支持,但是瀏覽器支持還是比較堪憂的~~

責任編輯:王雪燕 來源: WsztRush
相關推薦

2019-08-28 16:18:39

JavaScriptJS前端

2017-04-10 14:23:01

typescriptjavascriptwebpack

2013-08-20 18:39:34

JavaScript模requireJS

2010-05-21 18:26:58

2020-10-09 06:40:53

惡意軟件

2020-05-12 08:39:50

JavaScript工具技術

2020-09-17 10:30:21

前端模塊化組件

2017-05-18 10:23:55

模塊化開發RequireJsJavascript

2013-08-20 15:31:18

前端模塊化

2022-03-11 13:01:27

前端模塊

2015-10-10 11:29:45

Java模塊化系統初探

2020-09-18 09:02:32

前端模塊化

2010-01-12 16:15:02

模塊化交換機

2022-09-05 09:01:13

前端模塊化

2018-03-21 21:31:28

Java9編程Java

2018-06-21 09:36:09

模塊化數據中心集中化

2016-12-21 17:02:35

數據中心MDC模塊化

2019-09-02 10:51:59

Python腳本語言程序員

2017-05-18 11:43:41

Android模塊化軟件

2016-10-09 11:03:41

Javascript模塊化Web
點贊
收藏

51CTO技術棧公眾號

伦xxxx在线| 一区二区美女视频| 久久综合影院| 欧美三级三级三级爽爽爽| 亚洲一区二区三区加勒比| 国产福利免费视频| 亚洲男女自偷自拍| 色yeye香蕉凹凸一区二区av| 能看毛片的网站| 欧美xx视频| 亚洲欧美日韩国产手机在线 | 中文字幕亚洲乱码熟女1区2区| 国产精品探花在线观看| 日韩一区和二区| 无码精品国产一区二区三区免费| 日本美女高清在线观看免费| 成人av午夜影院| 国产在线视频2019最新视频| 日韩熟女精品一区二区三区| 成人黄色小视频| 亚洲国产97在线精品一区| 天天视频天天爽| 国产无遮挡裸体视频在线观看| 欧美国产日韩在线观看| 国产一区二区三区无遮挡| 性色av一区二区三区四区| 影音先锋中文字幕一区二区| 日韩在线视频观看| 泷泽萝拉在线播放| 综合激情久久| 51久久夜色精品国产麻豆| 日本久久久精品视频| 欧美巨大xxxx做受沙滩| 国产精品视频yy9299一区| 久久精品日产第一区二区三区| 国产精品国产av| 日韩av午夜在线观看| 午夜精品一区二区三区在线视 | 国产噜噜噜噜久久久久久久久| 日韩久久久久久久久| 91精品秘密在线观看| 一道本无吗dⅴd在线播放一区| 香蕉视频污视频| 99a精品视频在线观看| 欧美高清视频在线高清观看mv色露露十八 | 成人福利片网站| 国产精品伦一区| 日韩福利视频| 国产区视频在线播放| 久久免费电影网| 久久久久久高清| 午夜成人鲁丝片午夜精品| 国产99精品国产| 成人91免费视频| 亚洲黄色在线观看视频| 国产精品一二三在| 91手机在线视频| 国产激情久久久久久熟女老人av| 国产一区二区不卡在线| 亚洲iv一区二区三区| 国产高清免费观看| 国产成人av一区二区三区在线| 91超碰rencao97精品| 国产99对白在线播放| 国产尤物一区二区| 91久久精品一区二区别| 国内精品国产成人国产三级| 国产精品系列在线播放| 国产精品xxx在线观看www| 国产黄色片免费观看| 成人精品视频一区| 久久艹中文字幕| 国产天堂在线| 国产精品久久毛片a| 一级黄色录像免费看| 黄色精品免费看| 亚洲一区二区偷拍精品| 久久国产精品视频在线观看| 波多野结衣久久精品| 在线观看91精品国产入口| 亚欧激情乱码久久久久久久久| 免费日韩成人| 欧美成人福利视频| 亚洲欧美视频在线播放| 国产九一精品| www国产亚洲精品久久网站| 欧美国产日韩在线观看成人| 在线一区免费| 性色av一区二区三区| 亚洲中文字幕无码爆乳av | 国产精品久久久久久久久| 91中文字幕在线播放| 成人黄色在线网站| 日韩av在线电影观看| 成人免费视屏| 日本韩国一区二区三区| a级大片免费看| 亚洲bt欧美bt精品777| 最近更新的2019中文字幕| 日韩a级片在线观看 | 日韩av日韩在线观看| 国产精品无码久久久久成人app| 丰满少妇久久久久久久| 日韩久久久久久久| 丰满诱人av在线播放| 欧美综合色免费| 精品人妻一区二区免费| 成人婷婷网色偷偷亚洲男人的天堂| 久久久成人的性感天堂| 69av.com| 日韩综合在线视频| 国产精品区一区二区三在线播放| 91在线播放网站| 激情懂色av一区av二区av| 国产精品久久久毛片| 国产乱人伦精品一区| www.日韩欧美| 伊人精品一区二区三区| 99国产精品99久久久久久| 亚洲黄色网址在线观看| 成人在线网站| 日韩精品在线观看网站| 久草视频免费在线播放| 麻豆国产91在线播放| 精品国产乱码久久久久久久软件 | 久久精品青草| 国产精品对白刺激| 天天av综合网| 亚洲国产欧美在线| wwwxxx色| 欧美91福利在线观看| 国产日韩中文字幕| h视频在线观看免费| 欧美性生活大片免费观看网址| 伊人av在线播放| 亚洲激情中文| 91精品久久久久久久久青青| 岛国最新视频免费在线观看| 五月天中文字幕一区二区| 一区二区在线免费观看视频| 亚洲欧美偷拍自拍| 91精品国产自产在线| 福利在线观看| 欧美唯美清纯偷拍| 国产av自拍一区| 日韩中文字幕亚洲一区二区va在线| 久久国产精品 国产精品| 2020国产在线| 亚洲精品美女久久久| 国产真实的和子乱拍在线观看| 国产成人综合在线| www国产免费| 日韩亚洲精品在线观看| 欧美黄色片视频| 噜噜噜久久,亚洲精品国产品| 一卡二卡欧美日韩| 69xxx免费视频| 99热这里只有精品8| 国产综合第一页| 伊人久久综合一区二区| 亚洲欧美日韩中文在线| jizz国产在线| 国产精品乱码人人做人人爱| www.cao超碰| 欧美+日本+国产+在线a∨观看| 99久久久精品免费观看国产| 日韩123区| 日韩精品高清视频| 免费黄色片视频| 亚洲三级免费观看| 精品人妻二区中文字幕| 99亚洲精品| 欧美一区观看| 日韩av懂色| 欧美国产日韩xxxxx| 婷婷五月综合激情| 91福利视频在线| 2025国产精品自拍| aaa欧美色吧激情视频| 欧美变态另类刺激| 日韩成人三级| 国产精品区一区二区三在线播放| 成人教育av| 北条麻妃久久精品| 日韩有码第一页| 欧美又粗又大又爽| 久久久国产精品黄毛片| 91香蕉视频黄| 婷婷激情5月天| 亚洲作爱视频| 宅男在线精品国产免费观看| 草草视频在线一区二区| 国产精品久久激情| 欧美人与性动交α欧美精品济南到| 亚洲乱码av中文一区二区| 一道本无吗一区| 激情成人在线视频| 国产在线一卡二卡| 91视频.com| 中国男女全黄大片| 男人的天堂亚洲一区| 青青青青在线视频| 成人一区二区| 久久香蕉综合色| 视频一区日韩精品| 国产精品久久久| av电影免费在线看| 久久精品久久久久| 奇米影视888狠狠狠777不卡| 日韩一区二区三区高清免费看看| 亚洲欧美偷拍视频| 亚洲国产精品久久人人爱蜜臀| 99久久久无码国产精品不卡| 99久久精品情趣| 超级砰砰砰97免费观看最新一期| 日韩国产欧美在线观看| aa视频在线播放| 亚洲最新av| 一区二区国产日产| 激情五月综合网| 裸模一区二区三区免费| а√中文在线天堂精品| 成人有码视频在线播放| av免费在线一区| 欧美在线激情网| 国产美女精品写真福利视频| 美女扒开尿口让男人操亚洲视频网站| 懂色av中文在线| 亚洲精品色婷婷福利天堂| 黄色小视频免费观看| 欧美一级黄色录像| 亚洲性生活大片| 欧美性视频一区二区三区| 国产www在线| 精品毛片三在线观看| 久久精品国产亚洲AV无码麻豆 | 韩日视频在线观看| 欧美午夜在线| 国产精品一区在线免费观看| 久久人体视频| 永久免费精品视频网站| 久久麻豆精品| 亚洲国产成人不卡| 日本成人小视频| 天堂社区 天堂综合网 天堂资源最新版| 亚洲成在人线免费观看| 久久综合福利| 性欧美lx╳lx╳| 欧美一级片免费观看| 国产99久久久国产精品成人免费| 欧美乱偷一区二区三区在线| 四虎5151久久欧美毛片| 欧美成人蜜桃| 国产一区二区三区站长工具| 欧洲一区二区日韩在线视频观看免费| 免费欧美一区| 先锋在线资源一区二区三区| 成人在线国产| 国产欧美综合一区| 国内视频精品| 尤物av无码色av无码| 午夜在线视频观看日韩17c| 成人免费观看视频在线观看| 美女被久久久| 成人免费在线观看视频网站| 久久99精品国产91久久来源| 国产乱码一区二区三区四区| 国产精品一区二区黑丝| 99久久人妻无码中文字幕系列| 91在线高清观看| 日本xxxxxxxxx18| 亚洲欧美日韩精品久久久久| 久视频在线观看| 欧美性高跟鞋xxxxhd| 国产91av在线播放| 91精品国产入口在线| 日本波多野结衣在线| 亚洲深夜福利视频| av文字幕在线观看| 2019精品视频| 欧美成人aaa| 国产精选在线观看91| 国内精品久久久久久久久电影网| 中文字幕一区二区三区精彩视频| 伊人久久成人| 久久这里只精品| 成人免费毛片a| 一道本在线观看| 一区二区三区欧美| 无码人妻丰满熟妇区五十路| 欧美一区二区三区视频免费播放| 天堂网av在线播放| 日韩在线免费视频| 亚洲小少妇裸体bbw| 国产欧美日韩精品专区| jizz性欧美23| 中文字幕欧美人与畜| 国产美女诱惑一区二区| 国产在线观看中文字幕| av在线播放一区二区三区| 免费91在线观看| 午夜电影一区二区三区| 亚洲系列在线观看| 亚洲色图第三页| 国产羞羞视频在线播放| 国产精品视频yy9099| 男人的天堂久久| 亚洲自拍偷拍一区二区三区| 亚洲免费网站| 伦理片一区二区| 亚洲免费在线视频| 一级黄色av片| 日韩成人中文电影| 2024最新电影在线免费观看| 国产精品九九久久久久久久| 国产一级成人av| www国产免费| 精品一区免费av| 欧美福利第一页| 欧美午夜激情在线| 天天干,夜夜爽| 久久久久成人精品| 看亚洲a级一级毛片| 亚洲日本无吗高清不卡| 国产欧美综合一区二区三区| 精品人妻无码中文字幕18禁| 自拍偷拍国产精品| 中文字幕永久免费视频| 亚洲日韩中文字幕在线播放| 国产精品蜜臀| 丁香五月网久久综合| 中文字幕丰满孑伦无码专区| 大陆精大陆国产国语精品| 久久久久国产精品视频| 黄色av一区| 国产一级免费片| 亚洲制服丝袜av| 亚洲第一大网站| 欧美精品xxx| 99久久香蕉| 亚洲精品久久久久久久蜜桃臀| 国产成人精品网址| 久久久久久久久久久网| 日韩视频免费观看高清完整版| 国产日产一区二区| 91久久夜色精品国产网站| 久久久久美女| 黄色a级三级三级三级| 亚洲欧美日韩国产综合在线 | 国产激情在线播放| 精品一区二区三区免费毛片| 99av国产精品欲麻豆| 精品一区二区视频在线观看| 亚洲成a人v欧美综合天堂| 午夜成人鲁丝片午夜精品| 欧美性一区二区三区| 亚洲a级精品| 三级在线免费看| 亚洲欧洲日韩综合一区二区| 一区二区三区黄| 欧美成人午夜影院| 久久久精品国产**网站| 国产一区二区网| 久久日一线二线三线suv| wwwwww在线观看| 久久精品亚洲国产| 99re8这里有精品热视频8在线| 国产精品50p| 国产精品欧美一区二区三区| 国产精品色综合| 久久免费视频在线| 精品国产一区二区三区久久久樱花 | 成人97人人超碰人人99| 91久久国产综合久久91| 色婷婷综合成人av| 57pao国产一区二区| 欧美亚洲另类色图| 国产精品成人在线观看| 亚洲欧美激情另类| 国产成人短视频| 欧美黄色一区二区| 成人网站免费观看| 91超碰这里只有精品国产| 成人在线免费观看黄色| 日本精品一区二区三区不卡无字幕| 久久精品国产一区二区三区免费看 | 欧美自拍偷拍| 天天爽夜夜爽视频| 欧美日韩中国免费专区在线看| av大全在线免费看| 国产91一区二区三区| 日韩高清不卡一区二区三区| 国产探花在线免费观看| 亚洲欧洲成视频免费观看| 99tv成人影院| 50路60路老熟妇啪啪| 一区二区高清视频在线观看| 国产视频三级在线观看播放| 成人免费在线一区二区三区| 日韩高清不卡一区二区三区|