JavaScript模塊化開發(fā)流程分步講解
接觸了Vue模塊化開發(fā)才發(fā)現(xiàn)JavaScript組件化開發(fā)的演變一直在繼續(xù),以前也沒有特別在意這一塊內(nèi)容,寫著代碼能調(diào)試運行不報錯就可以了,主要編程語言標準就是ECMAScript5和ECMAScript6(2015年發(fā)布),使用ECMAScript6規(guī)范編寫的程序需要轉(zhuǎn)譯器將代碼編譯為ECMAScript5才能為瀏覽器支持。作為前度開發(fā)者了解這些以及ECMAScript5和ECMAScript6的寫法區(qū)別即可。
比如,ECMAScript5的寫法:
var MyModuleName = { Property1: "", Property2: "", Config: { SetName1:"", SetName2:"" }, Method1: function() {}, Method2: function() {} };
對應的ECMAScript6的寫法:
export const MyModuleName = { Property1: "", Property2: "", Config: { SetName1: "", SetName2: "" }, myMethod1() {}, myMethod2() {} };
其實學習前端開發(fā)僅僅知道大概是不行的,現(xiàn)在把這一塊的內(nèi)容詳細梳理一下。
1、使用傳統(tǒng)的全局命名空間
這樣情況下的缺點顯而易見:
⑴全局變量無法控制是否沖突;
⑵成員函數(shù)之間看不出直接關系。
示例代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>最原始的模式</title> </head> <body> <div id="view"></div> <script> var a=1,b=2; const viewId=document.getElementById('view'); const contentId=document.createElement('div'); contentId.innerHTML="a+b="+add(a,b); viewId.appendChild(contentId); function add(a,b){ return a+b; } function subtract(a,b){ return a-b; } </script> </body> </html>
可以出正確結(jié)果,如果進行所謂的模塊化開發(fā),就是將代碼不同文件化來進行。
主文件:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>最原始的模式</title> </head> <body> <div id="view"></div> <script> var a=1,b=2; </script> <script src="module2.js"></script> <script src="module1.js"></script> </body> </html>
module1.js代碼:
const viewId=document.getElementById('view'); const contentId=document.createElement('div'); contentId.innerHTML="a+b="+add(a,b); viewId.appendChild(contentId);
module2.js代碼:
var add=function(a,b){ return a+b; } var subtract=function(a,b){ return a-b; }
但是這導致可能因為文件引入順序而出現(xiàn)運行錯誤,如果文件多了,依賴不容易檢查,那么糾錯就是一件讓人頭疼的事情了。
2、使用對象的寫法
缺點:
⑴暴露所有模塊成員;
⑵內(nèi)部狀態(tài)可以被外部改寫;
⑶多文件化后依賴關系不好處理。
示例代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>使用對象寫法</title> </head> <body> <div id="view"></div> <script> var a=1,b=2; var MyUtils=new Object({ Property1: "as", add:function(a,b){ return a+b; }, subtract:function(a,b){ return a-b; } }); const viewId=document.getElementById('view'); const contentId=document.createElement('div'); var result=MyUtils.add(a,b); contentId.innerHTML="a+b="+result; viewId.appendChild(contentId); </script> </body> </html>
3、使用命名空間的寫法
前端開發(fā)者基本上都使用過JQuery.js來進行前端開發(fā),JQuery.js主要使用率命名空間模式來組織代碼,定義了一個全局變量 $ 或 jQuery,該變量是一個對象,包含了所有 jQuery 提供的功能。當使用 $或者jQuery 時,實際上就是訪問這個全局變量。而 jQuery 庫中所有的方法和屬性都是在這個全局變量上定義的。
缺點:
⑴無法解決相互依賴問題特別是多文件化后;
⑵代碼組織形式逐漸復雜化;
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>使用命名空間的寫法</title> </head> <body> <div id="view"></div> <script> var a=1,b=2; var MyApp = { UI: { //定義UI操作內(nèi)容 }, Data: { //定義Data內(nèi)容 }, Service: { //定義Service的內(nèi)容 }, Utils: { //定義工具類內(nèi)容 add:function(a,b){ return a+b; }, subtract:function(a,b){ return a-b; } } }; const viewId=document.getElementById('view'); const contentId=document.createElement('div'); var result=MyApp.Utils.add(a,b); contentId.innerHTML="a+b="+result; viewId.appendChild(contentId); </script> </body> </html>
最開始常見的寫法也可以是這樣的:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>使用IIFE(立即執(zhí)行函數(shù))寫法</title> </head> <body> <div id="view"></div> <script> var a=1,b=2; //定義全局變量 var MyUtils={}; //定義子命名空間 var MyUtils.UI={}; var MyUtils.Data={}; var MyUtils.Service={}; var MyUtils.Utils={}; //在子命名空間中定義內(nèi)容 var MyUtils.Utils.add=function(a,b){ return a+b; }; const viewId=document.getElementById('view'); const contentId=document.createElement('div'); var result=MyUtils.add(a,b); contentId.innerHTML="a+b="+result; viewId.appendChild(contentId); </script> </body> </html>
4、使用IIFE的寫法
缺點:
⑴外部代碼無法讀取內(nèi)部的變量;
⑵無法徹底解決模塊間的相互依賴問題。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>使用IIFE(立即執(zhí)行函數(shù))寫法</title> </head> <body> <div id="view"></div> <script> var a=1,b=2; var MyUtils=(function(){ Property1: "as"; var add=function(a,b){ return a+b; }; var subtract=function(a,b){ return a-b; } return { add:add, subtract:subtract } })(); const viewId=document.getElementById('view'); const contentId=document.createElement('div'); var result=MyUtils.add(a,b); contentId.innerHTML="a+b="+result; viewId.appendChild(contentId); //外部代碼無法讀取內(nèi)部的變量。 </script> </body> </html>
要解決外部訪問對象內(nèi)部數(shù)據(jù),可以對外暴露方法:
var a=1,b=2; var MyUtils=(function(){ Property1: "as"; var add=function(a,b){ return a+b; }; var subtract=function(a,b){ return a-b; }; var setProperty=function(str){ this.Property1=str; }; return { add:add, subtract:subtract, setProperty } })(); const viewId=document.getElementById('view'); const contentId=document.createElement('div'); var result=MyUtils.add(a,b); contentId.innerHTML="a+b="+result; viewId.appendChild(contentId); MyUtils.setProperty("123"); console.log(MyUtils.Property1);
上面的代碼暴露了setProperty方法,可以操作對象的內(nèi)部屬性值。
遵循IIFE(立即執(zhí)行函數(shù))規(guī)范很好地使用了閉包的特點,可以進行多模塊的開發(fā):
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>使用IIFE(立即執(zhí)行函數(shù))寫法</title> </head> <body> <div id="view"></div> <script> var a=1,b=2; var MyUtils1=(function(){ Property1: "as"; var add=function(a,b){ return a+b; }; var setProperty=function(str){ this.Property1=str; }; return { add:add, setProperty } })(); var MyUtils2=(function(){ Property1: "untils2"; var add=function(a,b){ return a+b; }; var setProperty=function(str){ this.Property1=str; }; return { add:add, setProperty } })(); //"繼承"前面兩個模塊 var MyUtils=(function(MyUtils1,MyUtils2){ MyProperty: "MyUntils"; function add(a,b){ return MyUtils1.add(a,b); }; function subtract(a,b){ return MyUtils1.subtract(a,b); }; return { add:add, subtract:subtract } })(MyUtils1,MyUtils2); const viewId=document.getElementById('view'); const contentId=document.createElement('div'); var result=MyUtils.add(a,b); contentId.innerHTML="a+b="+result; viewId.appendChild(contentId); </script> </body> </html>
但是最終的模塊嚴格意義上并不是真正地繼承前面的兩個模塊,只是依賴這兩個模塊的注入。
本想在這一篇把所有的演變模式總結(jié)完畢,可是后續(xù)的內(nèi)容太多了并且后面的內(nèi)容才是重點,寫到這里文字已經(jīng)有點多了,還是先寫到這里。
到此這篇關于JavaScript模塊化開發(fā)流程分步講解的文章就介紹到這了,更多相關JS模塊化開發(fā)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
火狐和ie下獲取javascript 獲取event的方法(推薦)
下面小編就為大家?guī)硪黄鸷蚷e下獲取javascript 獲取event的方法(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-11-11js實現(xiàn)addClass,removeClass,hasClass的函數(shù)代碼
js實現(xiàn)addClass,removeClass,hasClass的函數(shù)代碼,需要的朋友可以參考下。2011-07-07arcgis for js柵格圖層疊加(Raster Layer)問題
這篇文章主要介紹了arcgis for js柵格圖層疊加(Raster Layer)的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-11-11你不知道的 TypeScript 高級類型(小結(jié))
這篇文章主要介紹了你不知道的 TypeScript 高級類型(小結(jié)),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-08-08layer實現(xiàn)登錄彈框,登錄成功后關閉彈框并調(diào)用父窗口的例子
今天小編就為大家分享一篇layer實現(xiàn)登錄彈框,登錄成功后關閉彈框并調(diào)用父窗口的例子,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09