摘要:模塊什么是模塊什么是模塊化玩過游戲的朋友應該知道,一把裝配完整的步槍,一般是槍身消音器倍鏡握把槍托。更重要的是,其它大部分語言都支持模塊化。這一點與規范完全不同。模塊輸出的是值的緩存,不存在動態更新。
1.模塊 1.1 什么是模塊?什么是模塊化?
玩過FPS游戲的朋友應該知道,一把裝配完整的M4步槍,一般是槍身+消音器+倍鏡+握把+槍托。
如果把M4步槍看成是一個頁面的話,那么我們可以做如下類比
槍身 ->
消音器 ->
倍鏡 ->
握把 ->
槍托 ->
OK,你剛才做了一件事情,就是把m4步槍拆成了五個部分,你拆分的每一個部分就是一個模塊【module】,你拆分的這個過程就是模塊化【modularization】。
模塊化是一種編程思想,其核心就是拆分任務,把復雜問題簡單化,這樣一來既方便多人分工協作,又可以幫助我們迅速定位問題
方便多人分工協作 —— 可以不同的人開發不同的模塊,再組合,大大增加團隊效率
幫助我們迅速定位問題 —— 后坐力太大,那八成是槍托或握把的問題;聲音過大,那八成是消音器的問題。
1.2 模塊化的血淚史下面用一個小栗子講一講模塊化的發展史
龔先生和棚先生一起接了一個項目,他們倆需要分別實現一些功能,很簡單,就是Console出來自己的變量a
于是他們倆一合計,安排龔先生的代碼多帶帶放在script1.js里寫,棚先生的代碼多帶帶放在script2.js里寫,然后用script標簽分別引入
// script1.js文件 var a = 1 console.log(a)
// script2.js文件 var a = 2 console.log(a)
很快他們遇到了第一個問題 —— 變量命名沖突
尤其是包含了異步的時候,會出現如下情況
// script1.js文件 var a = 1 setTimeout(()=>{ console.log(a) // 我們想console出來1,卻console出了2 },1000)
// script2.js文件 var a = 2 console.log(a)
上面的問題明顯是由于a是一個全局變量導致的,所以解決思路也很明確——造一個局部變量唄
局部變量ES5時代使用立即執行函數制造局部變量
// script1.js文件 !function(){ var a = 1 setTimeout(()=>{ console.log(a) // 這下是2了 },1000) }() // 下面有5000行代碼
// script2.js文件 console.log(2)
ES6時代直接使用塊級作用域+let
// script1.js文件 { let a = 1 setTimeout(()=>{ console.log(a) // 這下是2了 },1000) }
// script2.js文件 { let a = 2 console.log(a) }通過window連接各個模塊
后來公司招了一個前端大佬,說現在只能由他來控制什么時候console變量,于是他新建了一個control.js文件
并通過window對象連接script1.js和scirpt2.js
// script1.js文件 { let a = 1 window.module1 = function() { console.log(a) } }
// script2.js文件 { let a = 2 window.module2 = function() { console.log(a) } }
// control.js文件 setTimeout(()=>{ window.module1() },1000) window.module2()
這個時候,非常重要的一點就是window是一個全局變量并且充當了一個公用倉庫,這個倉庫有兩個關鍵作用,存【導出】和取【依賴】
// script1.js文件 { let a = 1 // 把這個函數存放進window,就是導出到window window.module1 = function() { console.log(a) } }
// control.js文件 setTimeout(()=>{ // 我們從window里取出module1函數進行調用,就是依賴了script1.js文件 window.module1() },1000) window.module2()依賴加載的順序
煩人的產品對需求又進行了更改,給了一個name.js文件
// name.js文件 window.names = ["gongxiansheng","pengxiansheng"]
要求現在龔先生和棚先生需要Console出自己的名字
這還不簡單?幾秒鐘寫好
// script1.js文件 { window.module1 = function() { console.log(window.names[0]) } }
// script2.js文件 { window.module2 = function() { console.log(window.names[1]) } }
// control.js文件 setTimeout(()=>{ window.module1() },1000) window.module2()
但很快他們發現,console出來的都是undefined
前端大佬一眼看出了問題,對他們倆說
你們依賴的代碼一定要在你們自己的代碼前引入,不然是取不到值的;你看我的control.js是不是在你們倆的代碼后面引入的,因為我用到了你們倆的代碼了呀
噢噢,原來是js文件加載順序問題,改一下吧
但是在人多了以后,我們到時候會搞不清楚到底誰依賴了誰,保險起見只能全部都加載,性能浪費了太多,前端大佬搖頭嘆息道
2. ES6的模塊 2.1 ES6之前模塊化的痛點變量沖突
要用window連接各個模塊
依賴需要全部加載
還要TMD注意加載順序
模塊化是ES6的最大的亮點之一,因為在ES6之前的語法里從未有過模塊化的體系,這對開發大型的、復雜的項目形成了巨大障礙。因為我們無法對項目進行拆分,無法更好地進行多人協作開發。更重要的是,其它大部分語言都支持模塊化。
既然語言不支持,那么如何將模塊化引入JS呢?
前端社區就自己制定了一些模塊加載方案——這也是CommonJS【服務器】和AMD、CMD【瀏覽器】的由來。
但是現在ES6引入了模塊化的功能,實現起來非常簡單,完全可以取代 CommonJS 和 AMD 規范,成為瀏覽器和服務器通用的模塊解決方案。2.2 import和export的用法
import和export語法較為簡單,大家去MDN可以看非常詳細的講解,筆者在這里知識用注釋簡單介紹一下export語法
// 命名導出 export { name1, name2, …, nameN }; export { variable1 as name1, variable2 as name2, …, nameN }; export let name1, name2, …, nameN; // also var export let name1 = …, name2 = …, …, nameN; // also var, const export function FunctionName() {...} export class ClassName {...} // 默認導出 export default expression; export default function (…) { … } // also class, function* export default function name1(…) { … } // also class, function* export { name1 as default, … }; // 將其它模塊內的導出作為當前文件的導出 export * from …; export { name1, name2, …, nameN } from …; export { import1 as name1, import2 as name2, …, nameN } from …;import用法
import defaultExport from "module-name"; // 導入默認默認變量 import * as name from "module-name"; // 將模塊內所有變量導出,并掛載到name下【name是一個module對象】。什么要有as——為了防止export出來的變量命名沖突 import { export } from "module-name"; // 導入某一個變量 import { export as alias } from "module-name"; // 導入某一個變量并重命名 import { export1 , export2 } from "module-name"; // 導入兩個變量 import { export1 , export2 as alias2 , [...] } from "module-name"; // 導入多個變量,同時可以給導入的變量重命名 import defaultExport, { export [ , [...] ] } from "module-name"; // 導入默認變量和多個其它變量 import defaultExport, * as name from "module-name"; // 導入默認變量并重新命名 import "module-name"; // 導入并加載該文件【注意文件內的變量必須要通過export才能被使用】 var promise = import(module-name); // 異步的導入使用import和export改寫第一節的代碼
// name.js文件 let names = ["gongxiansheng","pengxiansheng"] export default names
// script1.js import names from "./name.js" let module1 = function () { console.log(names[0]) } export default module1
// script2.js import names from "./name.js" let module2 = function() { console.log(names[1]) } export default module2
// control.js import module1 from "./script1.js" import module2 from "./script2.js" setTimeout(() => { module1() }, 1000) module2()
2.3 拓展:import和export的一些運行原理 2.3.1 ES6 模塊輸出的是值的引用,輸出接口會動態綁定
其實就是按照數據類型里的引用類型的概念去理解。
這一點與 CommonJS 規范完全不同。
CommonJS 模塊輸出的是值的緩存,不存在動態更新。
// module1.js export var foo = "bar"; setTimeout(() => foo = "baz", 500);
// module2.js import {foo} from "./module1.js" console.log(foo) setTimeout(() => console.log(foo), 1000); // console的結果 // bar // baz2.3.2 export可以出現在模塊內的任何位置,但不能處于塊級作用域內
// 報錯 { export let foo = "bar"; }2.3.3 import具有提升效果(類似于var),會提升到整個模塊的頭部,首先執行
console.log(foo) import {foo} from "./script1.js"
參考資料:ECMAScript 6 入門
本文純屬原創,為了方便大家理解,小故事,小栗子都是筆者自己想的。如果您覺得對你有幫助,麻煩給個贊,給作者灰暗的生活揮灑揮灑積極向上的正能量,謝謝啦^_^。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/96770.html
摘要:在單核系統之上我們采用單進程單線程的模式來開發。由進程來管理所有的子進程,主進程不負責具體的任務處理,主要工作是負責調度和管理。模塊與模塊總結無論是模塊還是模塊,為了解決實例單線程運行,無法利用多核的問題而出現的。 前言 進程與線程是一個程序員的必知概念,面試經常被問及,但是一些文章內容只是講講理論知識,可能一些小伙伴并沒有真的理解,在實際開發中應用也比較少。本篇文章除了介紹概念,通過...
摘要:忍者級別的函數操作對于什么是匿名函數,這里就不做過多介紹了。我們需要知道的是,對于而言,匿名函數是一個很重要且具有邏輯性的特性。通常,匿名函數的使用情況是創建一個供以后使用的函數。 JS 中的遞歸 遞歸, 遞歸基礎, 斐波那契數列, 使用遞歸方式深拷貝, 自定義事件添加 這一次,徹底弄懂 JavaScript 執行機制 本文的目的就是要保證你徹底弄懂javascript的執行機制,如果...
摘要:模塊化是隨著前端技術的發展,前端代碼爆炸式增長后,工程化所采取的必然措施。目前模塊化的思想分為和。特別指出,事件不等同于異步,回調也不等同于異步。將會討論安全的類型檢測惰性載入函數凍結對象定時器等話題。 Vue.js 前后端同構方案之準備篇——代碼優化 目前 Vue.js 的火爆不亞于當初的 React,本人對寫代碼有潔癖,代碼也是藝術。此篇是準備篇,工欲善其事,必先利其器。我們先在代...
摘要:的四種綁定規則的種綁定規則分別是默認綁定隱式綁定顯示綁定綁定。綁定中的操作符,和其他語言中如的機制是不一樣的。規則例外在顯示綁定中,對于和的綁定將不會生效。它也是作為機制的一種替換,解決之前綁定過程各種規則帶來的復雜性。 徹底搞懂 JS 中 this 機制 摘要:本文屬于原創,歡迎轉載,轉載請保留出處:https://github.com/jasonGeng88/blog 目錄 t...
摘要:圖數據類型圖引用類型深淺拷貝問題不知道什么是深拷貝和淺拷貝的請先去并在調試臺自己操作一下,這篇文章只會說明為何中會有這種問題。所以有的時候我們為了避免淺拷貝,會用一些方式實現深拷貝。 首先要了解的js基礎 基本數據類型:Object、undefined、null、Boolean、Number、String、Symbol (ES6新加) Object包括: Array 、Date 、R...
閱讀 3735·2023-04-25 18:41
閱讀 1169·2021-11-11 16:55
閱讀 1823·2021-09-22 15:54
閱讀 3069·2021-09-22 15:51
閱讀 3545·2019-08-30 15:55
閱讀 1937·2019-08-30 14:19
閱讀 1277·2019-08-29 10:57
閱讀 1699·2019-08-29 10:56