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