国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【前端模塊化】JS模塊化思想以及相關規(guī)范(CommonJS、ES module)

這篇具有很好參考價值的文章主要介紹了【前端模塊化】JS模塊化思想以及相關規(guī)范(CommonJS、ES module)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

JS模塊化以及相關規(guī)范

1.模塊化概念

隨著前端應用日趨復雜,項目代碼也大量膨脹,模塊化就是一種最主流的代碼組織方式,一個模塊就是一個實現(xiàn)特定功能的文件,它通過把我們的復雜代碼按照功能的不同,劃分為不同的模塊單獨維護的這種方式,去提高我們的開發(fā)效率,降低維護成本。要用什么功能就加載什么模塊,模塊化開發(fā)是當下最重要的前端開發(fā)范式之一,其只是思想,不包含具體實現(xiàn)。

2.模塊化開發(fā)的優(yōu)點

  • 避免變量污染、命名沖突等問題
  • 提高代碼復用率
  • 提高可維護性
  • 能夠進行依賴關系的管理

3.模塊化演變過程

1.文件劃分方式

將每個功能和相關的一些狀態(tài)數(shù)據(jù)單獨存放在不同的文件當中,此時一個文件就是一個獨立的模塊。

然后將這個模塊引入頁面當中,直接調(diào)用模塊中的成員(變量/函數(shù)),一個script標簽就對應一個模塊,所有模塊都在全局范圍內(nèi)工作。

例:

html文件:

 <script type='text/javascript' src='module1.js'></script>	<!-- 模塊1 -->
 <script type='text/javascript' src='module2.js'></script>	<!-- 模塊2 -->
 <script type='text/javascript' src='module3.js'></script>	<!-- 模塊3 -->
  <script type='text/javascript'>
    foo();
    bar();
    msg='NBA';   //會污染全局變量
    foo();
  </script>

js文件:

/**
 * 全局函數(shù)模式: 將不同的功能封裝成不同的全局函數(shù)
 * 問題: Global被污染了, 很容易引起命名沖突
 */

let msg = 'modulel'
function foo() {
    console.log('foo()', msg);
}

function bar() {
    console.log('bar()', msg);
}

這種方式的缺點很明顯,即:

  • 各模塊內(nèi)部的成員都處在全局作用域中,即任意位置均可進行訪問和修改,這樣就會污染全局作用域。
  • 容易出現(xiàn)命名沖突。
  • 無法很好地管理各模塊之間的依賴關系。
2.命名空間(namespace)方式

命名空間方式是指:在文件劃分方式的基礎上,約定每個模塊只暴露一個對象,并將該模塊中的所有成員封裝在該對象中。當需要使用的時候,就調(diào)用這個對象的屬性即可。

例如:

module_a.js

let moduleA = {
  name: '一碗周',
  handle() {
    console.log(this.name)
  },
}

module_b.js

let moduleB = {
  name: '一碗粥',
  handle() {
    console.log(this.name)
  },
}

html文件:

<body>
  <script src="./component/module_a.js"></script>
  <script src="./component/module_b.js"></script>
  <script>
    console.log(moduleA.name);
    console.log(moduleB.name);	//仍然可以訪問到模塊中的所有屬性
    moduleA.handle()
    moduleB.handle()
  </script>
</body>

所以,這種方法實際上就是簡單的對象封裝。

這種方式減少了命名沖突的可能,但是各模塊中仍然沒有私有空間,而且也沒有解決管理模塊依賴關系的問題。

3.IIFE(立即執(zhí)行函數(shù))

所謂的IIFE模式就是使用立即執(zhí)行函數(shù)去創(chuàng)建閉包,這種方式為模塊提供了私有空間

具體的做法就是:

將模塊中每一個成員都放在一個函數(shù)提供的私有作用域當中,對于需要暴露給外部的成員可以通過掛載到全局對象上的方式去實現(xiàn)。

這種方式實現(xiàn)了私有成員的概念,就是說模塊的私有成員只能在模塊內(nèi)部通過閉包的方式去訪問。而在外部,是沒有辦法去使用的。這樣就確保了私有成員的安全。

例:

module_a.js

(function () {
  let name = '一碗周'
  function handle() {
    console.log(name)
  }
  window.moduleA = { handle }	//向window暴露handle對象,從而形成閉包
})()

module_b.js

(function () {
  let name = '一碗粥'
  function handle() {
    console.log(name)
  }
  window.moduleB = { handle }
})()

html文件如下:

<body>
  <script src="./component/module_a.js"></script>
  <script src="./component/module_b.js"></script>
  <script>
    console.log(moduleA.name) // undefined
    console.log(moduleB.name) // undefined,說明無法訪問到這個屬性,即實現(xiàn)了私有變量的效果
    moduleA.handle()
    moduleB.handle()
  </script>
</body>

在這一階段,實現(xiàn)了私有成員的概念,但仍未解決模塊間的依賴關系問題。

4.IIFE模式增強

這一階段,在 IIFE 模式的基礎上,通過為立即執(zhí)行函數(shù)添加參數(shù)的形式,實現(xiàn)模塊間的依賴。

例如:

module_a.js

(function () {
  function printName(name) {
    console.log(name)
  }
  // 暴露一個打印的方法
  window.moduleA = { printName }
})()

module_b.js

(function (m) /* 形參 */ {
  let name = '一碗周'
  function sayName() {
    // 使用其他模塊的成員
    m.printName(name)
  }
  window.moduleB = { sayName }
})(moduleA) // 實參

html文件:

<body>
  <script src="./component/module_a.js"></script>
  <script src="./component/module_b.js"></script>
  <script>
    moduleB.sayName() // 一碗周,即實現(xiàn)了模塊之間的依賴
  </script>
</body>

但這種方式仍然存在問題:

  • 引入了過多 <script> 標簽,就需要發(fā)送多個請求,請求數(shù)量太多
  • 依賴關系模糊
  • 難以維護

下面來介紹兩種現(xiàn)在開發(fā)過程中常使用的模塊化規(guī)范:

4.常用模塊化規(guī)范 — CommonJS

CommonJS在Node.js中廣泛應用,Node.js是CommonJS的實踐者。

CommonJS規(guī)范指出一個單獨的文件就是一個模塊,它采用的是同步加載模塊,也就是說模塊加載的順序就是代碼中編寫的順序是一致的,而加載的文件資源大多數(shù)都存儲在服務器中,所以說加載速度沒有什么問題。

但是這種方案不適用與瀏覽器端,由于網(wǎng)絡原因,更合理的方案是采用異步加載(CMD、AMD和ESmodule)

4.1 CommonJS的基本語法

暴露模塊使用module.exports,或者直接使用exports,引入模塊直接使用require()方法,示例代碼如下:

module_c.js

let name = '一碗周'
module.exports = {
  name,
  getName() {
    return name
  },
  setName(n) {
    name = n
  },
}

index.js

// 引入自定義的模塊
const person = require('./module_c')
// 引入 Node.js 提供的模塊
const fs = require('fs')

console.log(person.getName()) // 一碗周
person.setName('一碗粥')
console.log(person.name) // 一碗周

console.log(person.getName()) // 一碗粥
4.2 CommonJS的模塊加載機制

在上面的代碼中,首先通過 module.exports 導出一個對象,其中包含一個屬性兩個方法。然后在index.js中引入該模塊,通過require()方法引入模塊并定義一個變量來接收這個模塊。

但需要注意的是,CommonJS的模塊加載機制是被輸出值的拷貝 ,也就是說一旦輸出了某個值,即使模塊內(nèi)的數(shù)據(jù)變化,也不會影響這個值了!

上面的代碼中通過setName()重新為name進行賦值,在賦值后拿到的結(jié)果還是初始值,這是因為name是一個原始類型的值,它的值會被緩存。

當我們通過getName()方法來方法name的值才可以獲取到?jīng)]有緩存的那個結(jié)果。

5.AMD和CMD

AMD是"Asynchronous Module Definition "的縮寫。AMD規(guī)范的最佳實踐者是require.js。

CMD規(guī)范是在sea.js推廣中形成的,與AMD類似,不同點在于:AMD 推崇依賴前置、提前執(zhí)行,CMD推崇依賴就近、延遲執(zhí)行。

這里不對這兩者做介紹…

6.ES Module

6.1 ES Module 的語法特性

如果想要在HTML中使用使用ES Module的話,需要為<script>標簽添加一個type="module"的屬性,然后就可以執(zhí)行其中的JS代碼。

ES Module有主要以下幾個特性:

  • 自動全部采用嚴格模式,自動忽略'use strict'
  • 每個ES Module都會運行在單獨的私有作用域
  • ES Module是通過CORS的方式請求外部JavaScript模塊的
  • ES Module的<script>標簽會自動延遲執(zhí)行腳本,相當于加了defer屬性,網(wǎng)頁對默認的<script>標簽采用的是立即執(zhí)行的機制,頁面的渲染會等待這個腳本執(zhí)行完成才會往下渲染
6.2 ES Module 的導入和導出

導出成員可以通過export導出具體成員,也可以通過export default導出默認成員,示例代碼如下:

module_e.js

// 導出單個成員
export let name = '一碗周'
// 導出默認成員
export default function sayMe() {
  console.log('一碗周')
}
// 批量導出成員
// export { name, sayMe }

值得注意的是,批量導出成員的寫法并不是導出為一個對象,而是固定的語法,導出得到的是多個成員,導出多個成員必須使用花括號包裹!

想要導出對象,可以使用默認語法,示例代碼如下:

export default { name, sayMe }

這樣獲得的就是一個對象,其中有兩個屬性。

要注意的是:使用ES Module導出成員,導出的是值的引用 ,也就是說如果模塊內(nèi)部的成員發(fā)生改變,所有引用該模塊的地方都會發(fā)生改變。

導入成員使用import關鍵字導入,如下代碼展示了如何導入一個ES Module模塊,示例代碼如下:

// 導入默認成員
// import sayMe from './module_e.js'
// 或者通過 as 關鍵字對導入的默認成員進行重命名
// import { default as sayMe } from './module_e.js'
// 導入指定成員
// import { name } from './module_e.js'

// 也可以將上面兩行合并為1行,示例代碼如下:
// import { default as sayMe, name } from './module_e.js'
// 或者簡寫如下:
import sayMe, { name } from './module_e.js'

sayMe()
console.log(name)

但是,我們無法修改導入的成員的值,如果修改則會拋出異常!

import sayMe, { name } from './module_e.js'

name = '1'

異常信息為Uncaught TypeError: Assignment to constant variable.

如果我們只想要執(zhí)行某個模塊,并不需要模塊內(nèi)部的成員,可以直接通過import關鍵字引入即可。

如果我們想要動態(tài)的引入某個成員,可以將import()當做一個函數(shù)來使用,示例代碼如下:

import('./module.js').then(res=>{
  // res 表示模塊的默認導出成員
})

我們可以將導入的模塊直接導出,示例代碼如下:

export { name } from './module.js'

總結(jié)

總的來說,如今模塊化已經(jīng)成為了前端開發(fā)者的必備技能了。文章來源地址http://www.zghlxwxcb.cn/news/detail-790809.html

到了這里,關于【前端模塊化】JS模塊化思想以及相關規(guī)范(CommonJS、ES module)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 模塊化規(guī)范

    模塊化規(guī)范

    常用模塊化有兩種規(guī)范,commonJS和ES6 我們常遇到的使用場景是,在commonJS的模塊里需要引入ES6規(guī)范的模塊。這時就需要把ES6模塊轉(zhuǎn)譯為commonJS規(guī)范的模塊,否則報錯 轉(zhuǎn)義工具有: Babel:Babel 是一個流行的 JavaScript 編譯器,它可以將 ES6 模塊轉(zhuǎn)譯為 CommonJS 模塊。你可以使用 Bab

    2024年02月15日
    瀏覽(26)
  • 前端框架前置課Node.js學習(1) fs,path,模塊化,CommonJS標準,ECMAScript標準,包

    前端框架前置課Node.js學習(1) fs,path,模塊化,CommonJS標準,ECMAScript標準,包

    目錄 什么是Node.js 定義 作用: 什么是前端工程化 Node.js為何能執(zhí)行Js fs模塊-讀寫文件 模塊 語法: 1.加載fs模塊對象 2.寫入文件內(nèi)容 3.讀取文件內(nèi)容 Path模塊-路徑處理 為什么要使用path模塊 語法 URL中的端口號 http模塊-創(chuàng)建Web服務 需求 步驟: 案例:瀏覽時鐘 步驟: 什么是模塊化 定

    2024年01月16日
    瀏覽(54)
  • PCB模塊化設計05——晶體晶振PCB布局布線設計規(guī)范

    PCB模塊化設計05——晶體晶振PCB布局布線設計規(guī)范

    1、布局整體緊湊,一般放置在主控的同一側(cè),靠近主控IC。 2、布局是盡量使電容分支要短(目的:減小寄生電容,) 3、晶振電路一般采用π型濾波形式,放置在晶振的前面。 1)走線采取類差分走線; 2)晶體走線需加粗處理:8-12mil,晶振按照普通單端阻抗線走線即可;

    2024年02月12日
    瀏覽(97)
  • 前端10年進化 Node.js、模塊化、CommonJS、AMD、CMD、Webpack、Vue-cli、Electron-vue

    模塊化的概念在軟件開發(fā)領域已經(jīng)存在很長時間,但在?JavaScript?中的模塊化發(fā)展相對較晚。以下是對您提出的問題的回答: 提出時間:JavaScript?中的模塊化概念相對較早地提出于?CommonJS?規(guī)范。CommonJS?是一種?JavaScript?模塊化規(guī)范,最早在?2009?年由?Ryan?Dahl?和其他社區(qū)成

    2024年02月11日
    瀏覽(25)
  • TS編譯器選項——指定編譯ES版本和模塊化使用規(guī)范

    TS編譯器選項——指定編譯ES版本和模塊化使用規(guī)范

    compilerOptions是TS的編譯器選項,主要在tsconfig.json文件中用于對ts編譯為js文件時進行配置 \\\"compilerOptions\\\" : { 配置項 } 版本可以為如下版本:\\\'es3\\\', \\\'es5\\\', \\\'es6\\\', \\\'es2015\\\', \\\'es2016\\\', \\\'es2017\\\', \\\'es2018\\\', \\\'es2019\\\', \\\'es2020\\\', \\\'es2021\\\', \\\'es2022\\\', \\\'esnext\\\'. 版本可以為如下版本:\\\'none\\\', \\\'commonjs\\\', \\\'amd\\\', \\\'system\\\', \\\'u

    2024年02月04日
    瀏覽(32)
  • PCB模塊化設計09——RJ45-以太網(wǎng)口PCB布局布線設計規(guī)范

    PCB模塊化設計09——RJ45-以太網(wǎng)口PCB布局布線設計規(guī)范

    以太網(wǎng)(Ethernet)是一種計算機局域網(wǎng)組網(wǎng)技術,該技術基于IEEE制定的IEEE 802.3標準,它規(guī)定了包括物理層的連線、電信號和介質(zhì)訪問層協(xié)議的內(nèi)容。 以太網(wǎng)是當前應用最普遍的局域網(wǎng)技術。Ethernet的接口是實質(zhì)是MAC通過MII總線控制PHY的過程。 以太網(wǎng)接口電路主要由MAC控制器

    2024年02月10日
    瀏覽(21)
  • js 模塊化

    模塊化主要是用來抽離公共代碼,隔離作用域,避免變量沖突等。 模塊化的整個發(fā)展歷史如下: IIFE :使用自執(zhí)行函數(shù)來編寫模塊化,特點:在一個單獨的函數(shù)作用域中執(zhí)行代碼,避免代碼沖突。 AMD :使用 require 來編寫模塊化,特點:依賴必須提前聲明好。 CMD :使用 seaJS

    2024年02月14日
    瀏覽(19)
  • JS模塊化系統(tǒng)

    隨著 JavaScript 開發(fā)變得越來越廣泛,命名空間和依賴關系變得越來越難以處理。人們已經(jīng)開發(fā)出不同的解決方案以模塊系統(tǒng)的形式來解決這個問題。 CommonJS 是一種同步加載模塊的規(guī)范,主要用于服務器端的 Node.js 環(huán)境。 top:CommonJS 加載的是一個對象(即 module.exports 屬性),

    2024年02月19日
    瀏覽(26)
  • js模塊化開發(fā)

    js模塊化開發(fā)

    ? 到底什么是模塊化、模塊化開發(fā)呢? ? 事實上模塊化開發(fā)最終的目的是將程序劃分成一個個小的結(jié)構(gòu); ? 這個結(jié)構(gòu)中編寫屬于自己的邏輯代碼,有自己的作用域,定義變量名詞時不會影響到其他的結(jié)構(gòu); ? 這個結(jié)構(gòu)可以將自己希望暴露的變量、函數(shù)、對象等導出給其結(jié)

    2024年02月13日
    瀏覽(28)
  • 前端進階之——模塊化

    前端進階之——模塊化

    ? ? ? ? 在做項目的時候越來越發(fā)現(xiàn)模塊化的重要性,做好模塊化開發(fā)不僅給后期的維護帶來不少好處而且大大提升項目開發(fā)效率,接下來整理一下模塊化相關知識吧。 封裝方法、提高代碼的復用性、可維護性和可讀性 隔離作用域,避免污染全局作用域 避免變量沖突 立即執(zhí)

    2024年02月10日
    瀏覽(93)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包