欧美精产国品一二三区,国产成人一区二区三区A片免费,特级毛片www免费版,成人做爰A片免费看黄冈宾馆,日韩精品人妻中文字幕有码

深入淺出(chu) ES Module

概述

在 JavaScript 模塊化發展歷程中,為解決全局變量污染,代碼依賴管理等(deng)問題,先后出現了 CommonJS(CJS)、AMD、CMD、UMD、ES6 Module(ESM)五大主流方(fang)案(an)。不同方(fang)案(an)因設計目(mu)標、運行環境(瀏覽器 / Node)的差異,形成了各自的語法特性(xing)與生(sheng)態(tai)定(ding)位。

其中ES6 Module是 ES6 官方定義的標準化模塊化方案,旨在統一瀏覽器與服務(wu)器端(duan)的模塊化語法,解決傳統模塊化方案(如 CommonJS、AMD)的碎片(pian)化問題。

核心特性

  • 靜態化設計:模塊的導入(import)與導出(export)聲明必須在模塊頂層,且導入導出的模塊標識符(如文件路徑)需是靜態字符串,不能動態拼接(如 ·import('./' + path)· 是不允許的)。這一特性讓 JavaScript 引擎在編譯階段就能分析模塊依賴關系,實現 Tree-Shaking(搖樹優化,剔除未使用的代碼)。
  • 獨立模塊作用域:每個 ESM 模塊都是一個獨立的作用域,模塊內聲明的變量、函數、類默認不對外暴露,需通過export顯式導出后,其他模塊才能通過import導入使用,這樣可以避免全局變量污染。
  • 值引用特性:ESM 導入的模塊成員是 “值的引用”(而非 CommonJS 的值的拷貝),若導出模塊修改了導出的變量(如導出一個 let 聲明的變量并后續修改),導入模塊會同步感知到變化(需注意:基礎類型值若用const聲明,因不可修改,不會有此特性)。
  • 異步加載:在瀏覽器環境中,ESM 默認通過 <script type="module"> 標簽異步加載(相當于給 <script> 加了defer屬性),不會阻塞 HTML 解析,且模塊加載完成后會按依賴順序執行。

基礎語法

導出(export)

  • 命名導出:導出多個獨立的模塊成員,導入時需用相同的名稱接收(可通過as重命名);
  • 默認導出:每個模塊最多只能有一個默認導出,導入時可自定義接收名稱(無需加大括號)。
// 模塊A:moduleA.js
// 1. 命名導出(方式1:聲明時導出)
export const name = 'ES6 Module';
export function add(a, b) {
  return a + b;
}

// 2. 命名導出(方式2:集中導出)
const age = 6;
const multiply = (a, b) => a * b;
export { age, multiply as multiplyFn }; // as重命名導出

// 3. 默認導出(方式1:直接導出)
export default class ModuleClass {
  constructor() {
    this.version = '1.0.0';
  }
}

// 4. 默認導出(方式2:先聲明后導出)
const defaultObj = { type: 'module' };
export default defaultObj;

導入語法(import)

  • 導入命名成員:需用大括號包裹導入的成員名稱,與導出名稱一致(可通過as重命名);
  • 導入默認成員:無需大括號,可自定義接收名稱;
  • 整體導入:用 * as 模塊名 導入整個模塊的所有導出成員,訪問時需通過 模塊名.成員名 的方式;
  • 導入執行:若導入模塊僅需執行其代碼(如執行初始化邏輯,無需使用其導出成員),可直接使用 import './moduleA.js'。'
// 模塊B:moduleB.js
// 1. 導入命名成員(原樣接收)
import { name, add } from './moduleA.js';
console.log(name); // 輸出:ES6 Module
console.log(add(2, 3)); // 輸出:5

// 2. 導入命名成員(重命名接收)
import { age, multiplyFn as multiply } from './moduleA.js';
console.log(age); // 輸出:6
console.log(multiply(2, 3)); // 輸出:6

// 3. 導入默認成員(自定義名稱)
import ModuleClass from './moduleA.js'; // 無需大括號
const instance = new ModuleClass();
console.log(instance.version); // 輸出:1.0.0

// 4. 混合導入(命名成員+默認成員)
import ModuleClass, { name as moduleName } from './moduleA.js';
console.log(moduleName); // 輸出:ES6 Module

// 5. 整體導入
import * as ModuleA from './moduleA.js';
console.log(ModuleA.name); // 輸出:ES6 Module
console.log(ModuleA.add(2, 3)); // 輸出:5
console.log(new ModuleA.default().version); // 輸出:1.0.0(默認成員需通過.default訪問)

// 6. 導入執行
import './moduleA.js'; // 僅執行moduleA.js的代碼,不使用其導出成員

模塊方案對比

CJS(CommonJS)

Node.js 原生支持的模塊化方案,面向服務端,采用運行時動態加載,通過(guo)require導(dao)(dao)入、module.exports導(dao)(dao)出;

  • 設計目標
    ? 解決 Node.js 服務端模塊依賴管理問題,避免全局變量污染;
    ? 基于文件即模塊理念,每個文件是獨立模塊,通過module.exports暴露成員,require加載模塊。
  • 特點
    • 運行時加載:運行時動態加載,代碼執行到require語句時,才會讀取目標文件、執行模塊代碼、返回module.exports對象;
    • 值傳遞:基礎類型是值的拷貝, 對象類型則是引用傳遞,require時會將module.exports的屬性值拷貝,后續導出模塊修改基礎類型值,導入模塊不會同步變化;
    • 緩存模塊:模塊首次加載后,會緩存module.exports對象,后續require同一模塊時,直接返回緩存結果,避免重復執行模塊代碼;
    • 運行環境:主要用于 Node.js,瀏覽器端需通過 Browserify、Webpack 等工具轉換為全局變量或 ESM。

AMD(Asynchronous Module Definition)

面(mian)向瀏覽器端的異(yi)步模(mo)塊(kuai)化方案,解決瀏覽器加載模(mo)塊(kuai)時 “阻塞頁面(mian)渲染” 問題,代表實現為 RequireJS;

  • 設計目標
    • 解決瀏覽器端同步加載模塊阻塞頁面渲染問題,通過異步方式加載模塊,加載完成后執行回調函數;
    • 支持依賴前置(提前聲明所有依賴),確保模塊執行時依賴已加載完成。
  • 特點
    • 異步加載: 通過 <script> 標簽動態創建請求加載模塊,加載完成后觸發回調函數,不阻塞 HTML 解析與頁面渲染;
    • 依賴前置:模塊定義時需提前聲明所有依賴,如define(['jquery'], ...),RequireJS 會先加載依賴模塊,所有依賴加載完成后,再執行當前模塊的工廠函數;
    • 運行環境:僅支持瀏覽器端,Node 端需通過amd-loader等工具轉換;
    • 支持多種路徑寫法:支持相對路徑(如./moduleA)、絕對路徑(如/js/moduleA)、模塊別名(如jquery)。

UMD(Universal Module Definition)

通用(yong)(yong)模塊定義,兼容(rong) ESM、CJS、AMD 三種方案,可在瀏覽器與(yu) Node 端通用(yong)(yong),主要用(yong)(yong)于(yu)第(di)三方庫發布。

  • 設計目標
    ? 解決第三方庫需適配多模塊方案的問題,使用一套代碼就能夠同時兼容 ESM、CJS、AMD 三種方案,可在瀏覽器與 Node 端通用,避免為不同模塊方案單獨發布代碼,降低維護成本。
  • 特點
    • 多環境適配:可在Node和瀏覽器端使用,檢測方式為 typeof define === 'function' && define.amd 檢測 AMD 環境,typeof module === 'object' && module.exports 檢測 CJS 環境,否則降級為全局變量;

ESM(ES6 Module)

ES6 官方標準化方案,兼顧瀏覽器與 Node 端,采用編譯時靜態加載,支持 Tree-Shaking,通過 import/export 語法實現。

  • 設計目標
    • ES6 官方統一瀏覽器與 Node 端的模塊化方案,解決傳統方案碎片化問題;
    • 基于編譯時靜態加載設計,支持 Tree-Shaking。
  • 特點
    • 編譯時靜態加載:JavaScript 引擎在編譯階段分析模塊依賴,構建依賴樹,不執行模塊代碼,因為是靜態編譯的時候做了分析,所以很自然的支持 Tree Shaking。
    • 值的引用傳遞:導入的成員是對導出模塊成員的引用,若導出模塊修改非const變量,導入模塊會同步變化。
    • 默認啟用嚴格模式:禁止未聲明的變量使用。
posted @ 2025-10-31 12:20  Achieve前端實驗室  閱讀(85)  評論(0)    收藏  舉報