你是怎麼理解ES6中Module的?使用場景?

来源:https://www.cnblogs.com/smileZAZ/p/18068900
-Advertisement-
Play Games

這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 一、介紹 模塊,(Module),是能夠單獨命名並獨立地完成一定功能的程式語句的集合(即程式代碼和數據結構的集合體)。 兩個基本的特征:外部特征和內部特征 外部特征是指模塊跟外部環境聯繫的介面(即其他模塊或程式調用該模塊的方式,包括有輸入 ...


這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助

一、介紹

模塊,(Module),是能夠單獨命名並獨立地完成一定功能的程式語句的集合(即程式代碼和數據結構的集合體)。

兩個基本的特征:外部特征和內部特征

  • 外部特征是指模塊跟外部環境聯繫的介面(即其他模塊或程式調用該模塊的方式,包括有輸入輸出參數、引用的全局變數)和模塊的功能

  • 內部特征是指模塊的內部環境具有的特點(即該模塊的局部數據和程式代碼)

為什麼需要模塊化

  • 代碼抽象
  • 代碼封裝
  • 代碼復用
  • 依賴管理

如果沒有模塊化,我們代碼會怎樣?

  • 變數和方法不容易維護,容易污染全局作用域
  • 載入資源的方式通過script標簽從上到下。
  • 依賴的環境主觀邏輯偏重,代碼較多就會比較複雜。
  • 大型項目資源難以維護,特別是多人合作的情況下,資源的引入會讓人奔潰

因此,需要一種將JavaScript程式模塊化的機制,如

  • CommonJs (典型代表:node.js早期)
  • AMD (典型代表:require.js)
  • CMD (典型代表:sea.js)

AMD

Asynchronous ModuleDefinition(AMD),非同步模塊定義,採用非同步方式載入模塊。所有依賴模塊的語句,都定義在一個回調函數中,等到模塊載入完成之後,這個回調函數才會運行

代表庫為require.js

/** main.js 入口文件/主模塊 **/
// 首先用config()指定各模塊路徑和引用名
require.config({
  baseUrl: "js/lib",
  paths: {
    "jquery": "jquery.min",  //實際路徑為js/lib/jquery.min.js
    "underscore": "underscore.min",
  }
});
// 執行基本操作
require(["jquery","underscore"],function($,_){
  // some code here
});

CommonJs

CommonJS 是一套 Javascript 模塊規範,用於服務端

// a.js
module.exports={ foo , bar}

// b.js
const { foo,bar } = require('./a.js')

其有如下特點:

  • 所有代碼都運行在模塊作用域,不會污染全局作用域
  • 模塊是同步載入的,即只有載入完成,才能執行後面的操作
  • 模塊在首次執行後就會緩存,再次載入只返回緩存結果,如果想要再次執行,可清除緩存
  • require返回的值是被輸出的值的拷貝,模塊內部的變化也不會影響這個值

既然存在了AMD以及CommonJs機制,ES6Module又有什麼不一樣?

ES6 在語言標準的層面上,實現了Module,即模塊功能,完全可以取代 CommonJS和 AMD規範,成為瀏覽器和伺服器通用的模塊解決方案

CommonJS 和AMD 模塊,都只能在運行時確定這些東西。比如,CommonJS模塊就是對象,輸入時必須查找對象屬性

// CommonJS模塊
let { stat, exists, readfile } = require('fs');

// 等同於
let _fs = require('fs');
let stat = _fs.stat;
let exists = _fs.exists;
let readfile = _fs.readfile;

ES6設計思想是儘量的靜態化,使得編譯時就能確定模塊的依賴關係,以及輸入和輸出的變數

// ES6模塊
import { stat, exists, readFile } from 'fs';

述代碼,只載入3個方法,其他方法不載入,即 ES6 可以在編譯時就完成模塊載入

由於編譯載入,使得靜態分析成為可能。包括現在流行的typeScript也是依靠靜態分析實現功能

二、使用

ES6模塊內部自動採用了嚴格模式,這裡就不展開嚴格模式的限制,畢竟這是ES5之前就已經規定好

模塊功能主要由兩個命令構成:

  • export:用於規定模塊的對外介面
  • import:用於輸入其他模塊提供的功能

export

一個模塊就是一個獨立的文件,該文件內部的所有變數,外部無法獲取。如果你希望外部能夠讀取模塊內部的某個變數,就必須使用export關鍵字輸出該變數

// profile.js
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;

或 
// 建議使用下麵寫法,這樣能瞬間確定輸出了哪些變數
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;

export { firstName, lastName, year };

輸出函數或類

export function multiply(x, y) {
  return x * y;
};

通過as可以進行輸出變數的重命名

function v1() { ... }
function v2() { ... }

export {
  v1 as streamV1,
  v2 as streamV2,
  v2 as streamLatestVersion
};

import

使用export命令定義了模塊的對外介面以後,其他 JS 文件就可以通過import命令載入這個模塊

// main.js
import { firstName, lastName, year } from './profile.js';

function setName(element) {
  element.textContent = firstName + ' ' + lastName;
}

同樣如果想要輸入變數起別名,通過as關鍵字

import { lastName as surname } from './profile.js';

當載入整個模塊的時候,需要用到星號*

// circle.js
export function area(radius) {
  return Math.PI * radius * radius;
}

export function circumference(radius) {
  return 2 * Math.PI * radius;
}

// main.js
import * as circle from './circle';
console.log(circle)   // {area:area,circumference:circumference}

輸入的變數都是只讀的,不允許修改,但是如果是對象,允許修改屬性

import {a} from './xxx.js'

a.foo = 'hello'; // 合法操作
a = {}; // Syntax Error : 'a' is read-only;

不過建議即使能修改,但我們不建議。因為修改之後,我們很難差錯

import後面我們常接著from關鍵字,from指定模塊文件的位置,可以是相對路徑,也可以是絕對路徑

import { a } from './a';

如果只有一個模塊名,需要有配置文件,告訴引擎模塊的位置

import { myMethod } from 'util';

在編譯階段,import會提升到整個模塊的頭部,首先執行

foo();

import { foo } from 'my_module';

多次重覆執行同樣的導入,只會執行一次

import 'lodash';
import 'lodash';

上面的情況,大家都能看到用戶在導入模塊的時候,需要知道載入的變數名和函數,否則無法載入

如果不需要知道變數名或函數就完成載入,就要用到export default命令,為模塊指定預設輸出

// export-default.js
export default function () {
    console.log('foo');
}

載入該模塊的時候,import命令可以為該函數指定任意名字

// import-default.js
import customName from './export-default';
customName(); // 'foo'

動態載入

允許您僅在需要時動態載入模塊,而不必預先載入所有模塊,這存在明顯的性能優勢

這個新功能允許您將import()作為函數調用,將其作為參數傳遞給模塊的路徑。 它返回一個 promise,它用一個模塊對象來實現,讓你可以訪問該對象的導出

import('/modules/myModule.mjs')
  .then((module) => {
    // Do something with the module.
  });

複合寫法

如果在一個模塊之中,先輸入後輸出同一個模塊,import語句可以與export語句寫在一起

export { foo, bar } from 'my_module';

// 可以簡單理解為
import { foo, bar } from 'my_module';
export { foo, bar };

同理能夠搭配as*搭配使用

三、使用場景

如今,ES6模塊化已經深入我們日常項目開發中,像vuereact項目搭建項目,組件化開發處處可見,其也是依賴模塊化實現

vue組件

<template>
  <div class="App">
      組件化開發 ---- 模塊化
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  }
}
</script>

react組件

function App() {
  return (
    <div className="App">
		組件化開發 ---- 模塊化
    </div>
  );
}

export default App;

包括完成一些複雜應用的時候,我們也可以拆分成各個模塊

參考文獻

  • https://macsalvation.net/the-history-of-js-module/
  • https://es6.ruanyifeng.com/#docs/module

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Prometheus是一個開源的監控和告警工具包,其常用的組件主要包括以下幾個部分: Prometheus Server 功能:Prometheus Server是Prometheus的核心組件,負責定時從被監控組件(如Kubernetes、Docker、主機等)中拉取(pull)數據,並將其存儲在 ...
  • 本文主要學習FreeRTOS任務管理的相關知識,包括FreeRTOS創建/刪除任務、任務狀態、任務優先順序、延時函數、空閑任務和任務調度方法等知識 ...
  • Windows從零安裝WordPress 在Linux中,可以用Linux運維工具配合docker很便捷的安裝並配置MySQL、nginx、php、WordPress,但是Windows伺服器中,我還沒有發現類似的面板,就嘗試學慣用最原始的方法進行安裝。 教程環境:Windows Server 20 ...
  • 概述:樂觀併發控制是處理數據訪問併發的一種策略,通過在更新前檢查版本號或時間戳,確保數據在事務間保持一致性。在MySQL示例中,通過比對版本號,如果發現其他事務已更新數據,則拒絕當前事務的修改,避免潛在的併發衝突。這種機制提高了數據一致性,典型應用包括樂觀鎖的實現。 數據訪問併發是指多個事務或用戶同 ...
  • RDS for MariaDB的實例狀態概覽功能,幫助客戶快速感知資料庫實例的整體健康度,並迅速定位異常,極大簡化了運維操作。 ...
  • 轉載至我的博客 https://www.infrastack.cn ,公眾號:架構成長指南 在併發一致性控制場景中,我們常常用for update悲觀鎖來進行一致性的保證,但是如果不瞭解它的機制,就進行使用,很容易出現事故,比如for update進行了鎖表導致其他請求只能等待,從而拖垮系統,因此了 ...
  • 本文詳細介紹了Libcomm通信庫及其原理,讓我們更好的理解GaussDB(DWS)集群通信中的具體邏輯,對於GaussDB(DWS)通信運維也具備一定的參考意義。 ...
  • 本文主要講解了 Compose 中狀態的概念。最後做個小結, - Compose UI 依賴狀態變化,觸發重組,驅動界面更新。 - 使用 remember 和 rememberSaveable 進行狀態持久化。remember 保證在 recompose 過程中狀態穩定,rememberSaveab... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...