0416 Muki === Muki --- [相關資料」(https://muki.tw/) 簡報連結 --- 目錄 --- [TOC] ## Javascript的全域污染問題 - Js的變數跟函數預設為全域作用域 - 在大型專案中,過多的全域變數會造成命名衝突 - 需要一種方法來避免全域污染 ## 什麼是命名空間 - 是一種將相關的變數函數和物件封裝起來的機制 - 可以幫助我們隔離 ## 全域作用域 vs命名空間 ![image](https://hackmd.io/_uploads/HJnsWkngC.png) 效能上全域的快了一倍 ### 基本的命名空間 - 單一全域變數 - 命名空間物件 - 立即函式執行 IIFE ### 單一全域變數 - 使用一個全域變數做根 - 把方法屬性都掛在全域變數上面 ![image](https://hackmd.io/_uploads/ryRQfy3l0.png) **優點** - 簡單易懂適合小型專案 **缺點** - 仍有全域污染問題 - 不容易擴展 - 其他人容易使用到相同的全域變數名稱 #### 命名空間物件 ![image](https://hackmd.io/_uploads/BJvOM13eR.png) ### 命名空間靈活好擴展 ![image](https://hackmd.io/_uploads/Skr5z13gC.png) **優點** - 較好的組織性跟好擴展 - 降低全域污染(但還是可能發生) **缺點** - 依然有可能造成命名衝突 ### 立即函式執行IIFE - 定義之後立即會執行 - 可以建立一個私有作用域,函式裡面的變數內部韓式不會影響外部作用域,可以防止污染全域 ![image](https://hackmd.io/_uploads/SknxX13lR.png) #### 立即函示可以避免全域污染 ![image](https://hackmd.io/_uploads/rJQmXknxC.png) ![image](https://hackmd.io/_uploads/rydUQ13eC.png) 兩個都叫做 namespace 但很明顯看到不會相互干擾,local跟global的會抓到的資料就會完全分開 #### 立即函式執行IIFE隱私性佳 ![image](https://hackmd.io/_uploads/Sy1qQJngA.png) 若想要把東西在 global 存取,就記得把他 return 回傳出來,就可以在外面使用了 ### 立即函式執行IIFE優劣 **優點** - 完全私有 不會造成全域污染 - 可以引入外部依賴(模組命名空間會提到) **缺點** - 無法動態擴展(但物件可以) #### IIFE復用性 與工廠模式結合 ![image](https://hackmd.io/_uploads/B1OM41hxC.png) ### 進階的命名空間模式 - 巢狀命名空間 - 模組模式 - ES6 模組模式 ### 巢狀命名空間 - 命名空間的延伸 但一層一層進來很方便 但要避免過度使用 ![image](https://hackmd.io/_uploads/r17tVJ3g0.png) **優點** - 更好組織性 - 適合大型專案 - **缺點** - 命名空間管理上更複雜 - 巢狀過多不好管理與閱讀 ### 模組 react 跟 vue 都已經是模組化了 - 可用 IIFE 做到模組化設計模式 - 使用 IIFE 特性 - 將外部依賴項,透過參數方式傳遞進模組內部 - 使用 return 返回公開的方法和屬性,形成一個模組 #### Example ![image](https://hackmd.io/_uploads/ByFxrynxA.png) 只列出重要code,其他用...替代 #### 模組引入依賴 example ![image](https://hackmd.io/_uploads/Bk1SS12eR.png) ##### 模組優劣 **優點** - 更好的封裝性跟可測試性 **缺點** - 需要額外的模組管理工具(ex: CommonJS, AMD, ES6) > 因為現在都支援了,也不是什麼大缺點了 ### ES6 模組 - ES6 原生支援模組化,使用 import 和 export 關鍵字 - 每個模組都有自己的私有作用域 - 可以按需引入所需的方法跟屬性 - vue.js React.js 都適用 **ES6 example:** ![image](https://hackmd.io/_uploads/ryN-813lR.png) **優點** - 語法簡單好懂,原生支持好維護 **缺點** - 需要建構工具支持 ES6 模組化 - webpack, rollup, vite 都支援,已經不用擔心工具不支援的問題,打開檔案寫就對了 #### 最佳實踐跟建議 - 保持命名空間簡單且有意義 - 未命名空間選擇簡單且描述性的名稱 - 避免過度嵌套,保持命名空間扁平化 - 混合使用不同的命名空間 - 根據專案需求,靈活的組合不同的命名空間 EX:外層使用物件模式,內層使用模組模式 ![image](https://hackmd.io/_uploads/r1ud8y2x0.png) - 大型專案使用命名空間 - 在複雜的JS專案中命名空間是必須的 - 持續學習跟運用 命名空間模式會隨著JS的生態系統發展來不斷更新 Happy Learning! Happy Coding! ## 小結