摘要:前言很久沒寫文章總結了,這次主要粗略的總結一下中的模塊化模塊模塊的職責封裝實現,暴露接口,聲明依賴。
前言:很久沒寫文章總結了,這次主要粗略的總結一下 js中的模塊化
1.模塊模塊的職責:封裝實現,暴露接口,聲明依賴。先來一個對比,下面代碼沒有應用任何模塊系統
math.js:(1)沒有封裝性(2)接口不明顯
function add(a,b){ return a+ b } function sub(a,b){ return a - b }
caculator.js:(1)依賴math.js但是沒有依賴聲明 (2)使用全局狀態
var action = "add"; function compute(a,b){ switch (action){ case "add": return add(a,b) case "sub": return add(a,b) } }(2)字面量
math.js:(1)結構性好(2)訪問控制沒有
var math = { add:function add(a,b){ return a+ b }, sub:function sub(a,b){ return a - b } }
caculator.js:(1)依賴math.js但是沒有依賴聲明 (2)無法標明屬性是私有,無封裝
var caculator = { action:"add"; compute:function compute(a,b){ switch (action){ case "add": return math.add(a,b) case "sub": return math.add(a,b) } } }(3)IIFE:字值型的函數表達式
可以創建一個局部作用域,封裝內部成員變量,通過return輸出需要輸出的接口
版本一:caculator-1.js:(1)實現了訪問控制(2)依然沒有依賴聲明
var caculator = (function(){ var action = "add"; return{ compute:function compute(a,b){ switch (action){ case "add": return math.add(a,b) case "sub": return math.add(a,b) } } } })()
版本二:caculator-2.js:(1)顯示依賴聲明(2)仍然污染了全局變量(3)必須手動進行依賴管理
揭露模塊模式:return部分與版本一不太一樣,把方法定義在函數體里面,return的只是方法。具體可參考這位童鞋的文章:Javascript 設計模式 -- Revealing Module(揭示模塊)模式
var caculator = (function(m){ var action = "add"; function compute(a,b(){ switch (action){ case "add": return m.add(a,b) case "sub": return m.add(a,b) } } return{ compute:compute } })(math)(4)命名空間
解決暴露全局變量的問題,只暴露一個類似namespace的全局變量就實現所有模塊的聲明
math.js:(1)第一個參數是模塊聲明;(2)第二個參數是聲明依賴,目前是沒有依賴的;(3)第三個參數是模塊的構成
namespace("math",[],function(){ function add(a,b){ return a+ b } function sub(a,b){ return a - b } return{ add:add, sub:sub } })
caculator.js:(1)有依賴生命(2)依賴math被當做參數傳入
namespace("caculator",["math"],function(m){ var action = "add" function compute(a,b){ return m[action](a,b) } return{ compute:compute } })
namespace的代碼:還是沒有解決依賴管理的問題,如果各個模塊分散在不同的文件中,就要對腳本加載順序進行手動的排序
var namespace = (function(){ //緩存所有的模塊 var cache = {} function createModule(name,deps,definition){ //參數是:模塊名,依賴列表,定義 //先對參數進行判斷,如果只有一個參數,就返回 if(arguments.length === 1){ return cache[name] } //必須取得所有依賴的模塊,要保證前面的模塊已經被定義好了 deps = deps.map(function(depName){ return ns(depName) }) //初始化模塊并返回 cache[name] = definition.apply(null,deps) return cache[name]; } return createModule })()2.模塊系統
職責:(1)依賴管理:加載/分析/注入/初始化 (2)決定模塊的寫法
下面總結三種典型的模塊系統的寫法
優點:
依賴管理成熟可靠
社區活躍,規范接受度高
運行時支持,模塊定義非常簡單
文件級別的模塊作用域隔離
可以處理循環依賴
缺點:
不是標準組織的規范
同步的require,沒有考慮瀏覽器異步加載的過程
但是還是有辦法使用的,目前有很多工具可以把多個模塊的文件打包成一個文件:browserify,webpack,component
看下面用commonjs寫就的代碼:
math.js:
function add(a,b){ return a+ b } function sub(a,b){ return a - b } exports.add = add exports.sub = sub
caculator.js:
var math = require("./math"); //依賴聲明 function Caculator(container){ this.left = container.querySelector(".j-left" ); this.right = container.querySelector(".j-right" ); this.add = container.querySelector(".j-add" ); this.result = container.querySelector(".j-result"); this.add.addEventListener("click",this.compute.bind(this)); } Caculator.prototype.compute = function(){ this.result.textContent = math.add(+this.left.value, +this.right.value) } exports.Caculator = Caculator; //暴露接口
用前端打包工具進行打包math.js 和caculator.js
首先安裝browserify,在命令行輸入命令:browserify caculator.js > caculator-bundle.js
打包成形如命名空間的文件形式
天然的作用于異步環境
AMD代碼寫法:
math.js:第一個參數是依賴列表
define([],function(){ function add(a,b){ return a+ b } function sub(a,b){ return a - b } return{ //接口暴露 add:add, sub:sub } })
caculator.js:參數一是依賴聲明,參數二是依賴注入
define(["./math"],function(math){ function Caculator(container){ this.left = container.querySelector(".j-left" ); this.right = container.querySelector(".j-right" ); this.add = container.querySelector(".j-add" ); this.result = container.querySelector(".j-result"); this.add.addEventListener("click",this.compute.bind(this)); } Caculator.prototype.compute = function(){} return{ Caculator:Caculator } })
AMD還支持一個叫Simplified CommonJS wrapping
define(function(require,exports){ var math = require("./math"); function Caculator(container){ this.left = container.querySelector(".j-left" ); this.right = container.querySelector(".j-right" ); this.add = container.querySelector(".j-add" ); this.result = container.querySelector(".j-result"); this.add.addEventListener("click",this.compute.bind(this)); } Caculator.prototype.compute = function(){} exports.Caculator = Caculator; })
上述如何獲取依賴列表呢?
函數通過toString可以打印出它的函數體,然后用正則表達式提取出來
factory.toString()
/require([""]([^""]*)[""])/.exec(factory.toString())[1]
優點:
依賴管理成熟可靠
社區活躍,規范接受度高
專為異步IO打造,適合瀏覽器環境
支持類似Commonjs的書寫方式
通過插件api可支持加載非js資源
成熟的打包構建工具,并可結合插件
缺點:
模塊定義繁瑣,需要額外嵌套
只是庫級別的支持,需要引入額外的庫
無法處理循環依賴
無法實現條件加載
(3)ES6/module語言級別的支持,未來的模塊化
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/79894.html
摘要:進入傳入地址出來一個復雜對象把掛載到對象上太復雜我們先看可以緩存輸入的文件系統輸入文件系統輸出文件系統,掛載到對象傳入輸入文件,監視文件系統,掛載到對象添加事件流打開插件讀取目錄下文件對文件名進行格式化異步讀取目錄下文件同步方法就 進入webpack.js //傳入地址,new Compiler出來一個復雜對象 compiler = new Compiler(options.conte...
摘要:每次都信誓旦旦的給自己立下要好好學習源碼的,結果都是因為某個地方卡住了,或是其他原因沒看多少就放棄了。這次又給自己立個堅持看完源碼。我看的源碼版本是。本篇文章是官方文檔里邊的一篇文章的翻譯,原文地址。 每次都信誓旦旦的給自己立下要好好學習react源碼的flag,結果都是因為某個地方卡住了,或是其他原因沒看多少就放棄了。這次又給自己立個flag-堅持看完react源碼。為了敦促自己,特...
摘要:布局定位浮動外邊距操縱的好處之一是,它能夠控制頁面布局而不需要使用表現性標記。但是布局被誤認為是難以理解的,在初學者當中,這種想法相當普遍。是一個標準的行內元素,行內元素可以在段落中包裹文字而不打亂段落的布局。 css 布局 定位 浮動 外邊距操縱 display flex CSS的好處之一是,它能夠控制頁面布局而不需要使用表現性標記。但是CSS布局被誤認為是難以理解的,在初學者當...
摘要:縮進縮進用于表示不同的代碼塊,如函數條件語句循環和類的主主體。標識符和保留字標識符是用來識別變量函數類模塊和其他對象的名稱。標識符可以包含字母數字和下劃線,但必須以非數字字符開始。由于標識符是區分大小寫的,所以和是兩個不同的標識符。 上一篇文章:Python詞法約定和語法專題:總覽下一篇文章:Python詞法約定和語法專題:總覽Python詞法約定和語法專題:總覽 行結構 Pytho...
摘要:原文鏈接翻譯于今天我們興奮的發布了的嘗鮮版,一個新的靜態類型檢查器。為添加了靜態類型檢查,以提高開發效率和代碼質量。這最終形成一個高度并行增量式的檢查架構,類似。知道縮小類型范圍時做動態檢查的影響。 原文鏈接:https://code.facebook.com/posts/1505962329687926/flow-a-new-static-type-checker-for-java...
閱讀 2458·2021-09-28 09:36
閱讀 3597·2021-09-22 15:41
閱讀 4388·2021-09-04 16:45
閱讀 1957·2019-08-30 15:55
閱讀 2847·2019-08-30 13:49
閱讀 825·2019-08-29 16:34
閱讀 2370·2019-08-29 12:57
閱讀 1679·2019-08-26 18:42