成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

詳解 JavaScript 中的模塊、Import和Export

開發 前端
在互聯網的洪荒時代,網站主要用 HTML和 CSS 開發的。如果將 JavaScript 加載到頁面中,通常是以小片段的形式提供效果和交互,一般會把所有的 JavaScript 代碼全都寫在一個文件中,并加載到一個 script 標簽中。盡管可以把 JavaScript 拆分為多個文件,但是所有的變量和函數仍然會被添加到全局作用域中。

 在互聯網的洪荒時代,網站主要用 HTML和 CSS 開發的。如果將 JavaScript 加載到頁面中,通常是以小片段的形式提供效果和交互,一般會把所有的 JavaScript 代碼全都寫在一個文件中,并加載到一個 script 標簽中。盡管可以把 JavaScript 拆分為多個文件,但是所有的變量和函數仍然會被添加到全局作用域中。

但是后來 JavaScript 在瀏覽器中發揮著重要的作用,迫切需要使用第三方代碼來完成常見任務,并且需要把代碼分解為模塊化的文件,避免污染全局命名空間。

ECMAScript 2015 規范在 JavaScript 語言中引入了 module,也有了 import 和 export 語句。在本文中,我們一起來學習 JavaScript 模塊,以及怎樣用 import 和 export 來組織代碼。

模塊化編程

在 JavaScript 中出現模塊的概念之前,當我們想要把自己的代碼組織為多個塊時,一般會創建多個文件,并且將它們鏈接為單獨的腳本。下面先舉例說明,首先創建一個 index.html 文件和兩個JavaScript文件“ functions.js 和 script.js。

index.html 文件用來顯示兩個數字的和、差、乘積和商,并鏈接到 script 標簽中的兩個 JavaScript 文件。打開 index.html 并添加以下代碼:

index.html

 

 

  1. <!DOCTYPE html> 
  2. <html lang="en"
  3.   <head> 
  4.     <meta charset="utf-8" /> 
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 
  6.  
  7.     <title>JavaScript Modules</title> 
  8.   </head> 
  9.  
  10.   <body> 
  11.     <h1>Answers</h1> 
  12.     <h2><strong id="x"></strong> and <strong id="y"></strong></h2> 
  13.  
  14.     <h3>Addition</h3> 
  15.     <p id="addition"></p> 
  16.  
  17.     <h3>Subtraction</h3> 
  18.     <p id="subtraction"></p> 
  19.  
  20.     <h3>Multiplication</h3> 
  21.     <p id="multiplication"></p> 
  22.  
  23.     <h3>Division</h3> 
  24.     <p id="division"></p> 
  25.  
  26.     <script src="functions.js"></script> 
  27.     <script src="script.js"></script> 
  28.   </body> 
  29. </html> 

 

 

 

這個頁面很簡單,就不詳細說明了。

functions.js 文件中包含將會在第二個腳本中用到的數學函數。打開文件并添加以下內容:

functions.js

 

  1. function sum(x, y) { 
  2.   return x + y 
  3.  
  4. function difference(x, y) { 
  5.   return x - y 
  6.  
  7. function product(x, y) { 
  8.   return x * y 
  9.  
  10. function quotient(x, y) { 
  11.   return x / y 

最后,script.js 文件用來確定 x 和 y 的值,以及調用前面那些函數并顯示結果:

script.js

 

  1. const x = 10 
  2. const y = 5 
  3.  
  4. document.getElementById('x').textContent = x 
  5. document.getElementById('y').textContent = y 
  6.  
  7. document.getElementById('addition').textContent = sum(x, y) 
  8. document.getElementById('subtraction').textContent = difference(x, y) 
  9. document.getElementById('multiplication').textContent = product(x, y) 
  10. document.getElementById('division').textContent = quotient(x, y) 

保存之后在瀏覽器中打開 index.html 可以看到所有結果:

 

 

 

 

對于只需要一些小腳本的網站,這不失為一種有效的組織代碼的方法。但是這種方法存在一些問題:

  • 污染全局命名空間:你在腳本中創建的所有變量(sum、 difference 等)現在都存在于 window 對象中。如果你打算在另一個文件中使用另一個名為 sum 的變量,會很難知道在腳本的其它位置到底用的是哪一個值變量,因為它們用的都是相同的 window.sum 變量。唯一可以使變量私有的方法是將其放在函數的作用域中。甚至在 DOM 中名為 x 的 id 可能會和 var x 存在沖突。
  • 依賴管理:必須從上到下依次加載腳本來確保可以使用正確的變量。將腳本分別保存存為不同文件會產生分離的錯覺,但本質上與放在頁面中的單個 <script> 中相同。

在 ES6 把原生模塊添加到 JavaScript 語言之前,社區曾經嘗試著提供了幾種解決方案。第一個解決方案是用原生 JavaScript 編寫的,例如將所有代碼都寫在 objects 或立即調用的函數表達式(IIFE)中,并將它們放在全局命名空間中的單個對象上。這是對多腳本方法的一種改進,但是仍然存在將至少一個對象放入全局命名空間的問題,并沒有使在第三方之間一致地共享代碼的問題變得更加容易。

之后又出現了一些模塊解決方案:CommonJS 是一種在 Node.js 實現的同步方法,異步模塊定義(AMD)是一種異步方法,還有支持前面兩種樣式的通用方法——通用模塊定義(UMD)。

這些解決方案的出現使我們可以更輕松地以包的形式共享和重用代碼,也就是可以分發和共享的模塊,例如 npm。但是由于存在許多解決方案,并且都不是 JavaScript 原生的,所以需要依靠 Babel、Webpack 或 Browserify之類的工具才能在瀏覽器中使用。

由于多文件方法存在許多問題,并且解決方案很復雜,所以開發人員對把模塊化開發的方法引入 JavaScript 語言非常感興趣。于是 ECMAScript 2015 開始支持 JavaScript module。

module 是一組代碼,用來提供其他模塊所使用的功能,并能使用其他模塊的功能。export 模塊提供代碼,import 模塊使用其他代碼。模塊之所以有用,是因為它們允許我們重用代碼,它們提供了許多可用的穩定、一致的接口,并且不會污染全局命名空間。

模塊(有時稱為 ES 模塊)現在可以在原生 JavaScript 中使用,在本文中,我們一起來探索怎樣在代碼中使用及實現。

原生 JavaScript 模塊

JavaScript 中的模塊使用import 和 export 關鍵字:

  • import:用于讀取從另一個模塊導出的代碼。
  • export:用于向其他模塊提供代碼。

接下來把前面的的 functions.js 文件更新為模塊并導出函數。在每個函數的前面添加 export 。

functions.js

 

  1. export function sum(x, y) { 
  2.   return x + y 
  3.  
  4. export function difference(x, y) { 
  5.   return x - y 
  6.  
  7. export function product(x, y) { 
  8.   return x * y 
  9.  
  10. export function quotient(x, y) { 
  11.   return x / y 

在 script.js 中用 import 從前面的 functions.js 模塊中檢索代碼。

注意:import 必須始終位于文件的頂部,然后再寫其他代碼,并且還必須包括相對路徑(在這個例子里為 ./)。

把 script.js 中的代碼改成下面的樣子:

script.js

 

  1. import { sum, difference, product, quotient } from './functions.js' 
  2.  
  3. const x = 10 
  4. const y = 5 
  5.  
  6. document.getElementById('x').textContent = x 
  7. document.getElementById('y').textContent = y 
  8.  
  9. document.getElementById('addition').textContent = sum(x, y) 
  10. document.getElementById('subtraction').textContent = difference(x, y) 
  11. document.getElementById('multiplication').textContent = product(x, y) 
  12. document.getElementById('division').textContent = quotient(x, y) 

注意:要通過在花括號中命名單個函數來導入。

為了確保代碼作為模塊導入,而不是作為常規腳本加載,要在 index.html 中的 script 標簽中添加type="module"。任何使用 import 或 export 的代碼都必須使用這個屬性:

index.html

  1. <script  
  2.   type="module" src="functions.js"
  3. </script> 
  4. <script  
  5.   type="module" src="script.js"
  6. </script> 

 

由于受限于 CORS 策略,必須在服務器環境中使用模塊,否則會出現下面的錯誤:

  1. Access to script at 'file:///Users/your_file_path/script.js' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https. 

模塊與常規腳本不一樣的地方:

  • 模塊不會向全局(window)作用域添加任何內容。
  • 模塊始終處于嚴格模式。
  • 在同一文件中把同一模塊加載兩次不會出問題,因為模塊僅執行一次
  • 模塊需要服務器環境。

模塊仍然經常與打包程序(如 Webpack)一起配合使用,用來增加對瀏覽器的支持和附加功能,但它們也可以直接用在瀏覽器中。

接下來探索更多使用 import 和 export 語法的方式。

命名導出

如前所述,使用 export 語法允許你分別導入按名稱導出的值。以這個 function.js 的簡化版本為例:

functions.js

 

  1. export function sum() {} 
  2. export function difference() {} 

這樣允許你用花括號按名稱導入 sum 和 difference:

script.js

 

  1. import {sum, difference} from './functions.js' 

也可以用別名來重命名該函數。這樣可以避免在同一模塊中產生命名沖突。在這個例子中,sum 將重命名為 add,而 difference 將重命名為 subtract。

script.js

 

  1. import { 
  2.   sum as add
  3.   difference as subtract 
  4. from './functions.js' 
  5.  
  6. add(1, 2) // 3 

在這里調用 add() 將產生 sum() 函數的結果。

使用 * 語法可以將整個模塊的內容導入到一個對象中。在這種情況下,sum 和 difference 將成為 mathFunctions 對象上的方法。

script.js

 

  1. import * as mathFunctions from './functions.js' 
  2.  
  3. mathFunctions.sum(1, 2) // 3 
  4. mathFunctions.difference(10, 3) // 7 

原始值、函數表達式和定義、異步函數、類和實例化的類都可以導出,只要它們有標識符就行:

 

  1. // 原始值 
  2. export const number = 100 
  3. export const string = 'string' 
  4. export const undef = undefined 
  5. export const empty = null 
  6. export const obj = {name'Homer'
  7. export const array = ['Bart''Lisa''Maggie'
  8.  
  9. // 函數表達式 
  10. export const sum = (x, y) => x + y 
  11.  
  12. // 函數定義 
  13. export function difference(x, y) { 
  14.   return x - y 
  15.  
  16. // 匿名函數 
  17. export async function getBooks() {} 
  18.  
  19. // 類 
  20. export class Book { 
  21.   constructor(name, author) { 
  22.     this.name = name 
  23.     this.author = author 
  24.   } 
  25.  
  26. // 實例化類 
  27. export const book = new Book('Lord of the Rings''J. R. R. Tolkein'

所有這些導出都可以成功被導入。接下來要探討的另一種導出類型稱為默認導出。

默認導出在前面的例子中我們導出了多個命名的導出,并分別或作為一個對象導入了每個導出,將每個導出作為對象上的方法。模塊也可以用關鍵字 default 包含默認導出。默認導出不使用大括號導入,而是直接導入到命名標識符中。

以 functions.js 文件為例:

functions.js

 

  1. export default function sum(x, y) { 
  2.   return x + y 

在 script.js 文件中,可以用以下命令將默認函數導入為 sum:

script.js

 

  1. import difference from './functions.js' 
  2.  
  3. difference(1, 2) // 3 

不過這樣做很危險,因為在導入過程中對默認導出的命名沒有做任何限制。在這個例子中,默認函數被導入為 difference,盡管它實際上是 sum 函數:

script.js

 

  1. import difference from './functions.js' 
  2.  
  3. difference(1, 2) // 3 

所以一般首選使用命名導出。與命名導出不同,默認導出不需要標識符——原始值本身或匿名函數都可以用作默認導出。以下是用作默認導出的對象的示例:

functions.js

 

  1. export default { 
  2.   name'Lord of the Rings'
  3.   author: 'J. R. R. Tolkein'

可以用以下命令將其作為 book 導入:

functions.js

 

  1. import book from './functions.js' 

同樣,下面的例子演示了如何將匿名箭頭函數導出為默認導出:

functions.js

 

  1. export default () => 'This function is anonymous' 

可以這樣導入:

script.js

 

  1. import anonymousFunction from './functions.js' 

命名導出和默認導出可以彼此并用,例如在這個模塊中,導出兩個命名值和一個默認值:

functions.js

 

  1. export const length = 10 
  2. export const width = 5 
  3.  
  4. export default function perimeter(x, y) { 
  5.   return 2 * (x + y) 

可以用以下命令導入這些變量和默認函數:

script.js

 

  1. import calculatePerimeter, {length, width} from './functions.js' 
  2.  
  3. calculatePerimeter(length, width) // 30 

現在默認值和命名值都可用于腳本了。

 

總結

模塊化編程設計允許我們把代碼分成單個組件,這有助于代碼重用,同時還可以保護全局命名空間。一個模塊接口可以在原生 JavaScript 中用關鍵字 import 和 export 來實現。

責任編輯:華軒 來源: 前端先鋒
相關推薦

2020-12-23 14:18:43

JavaScript模塊導出

2013-05-08 10:36:07

JavaScriptJS詳解JavaScrip

2021-05-08 07:51:07

Vue框架前端

2015-12-24 10:05:39

JavaScripttypeofinstanceof

2017-03-20 14:45:42

JavaScript詳解

2020-07-09 08:01:48

JavaScriptES模塊

2010-09-01 15:11:09

linkimportCSS

2010-09-08 09:33:09

CSSlink@import

2009-09-21 16:59:29

Array擴展

2016-10-11 20:33:17

JavaScriptThisWeb

2009-06-10 22:07:59

JavaScriptdocument對象window對象

2016-12-27 10:19:42

JavaScriptindexOf

2010-09-08 15:13:09

Node節點Node屬性

2009-10-26 15:07:12

checkbox樹

2020-04-15 15:48:03

Node.jsstream前端

2024-04-26 08:27:15

JavaScriptCSSHTML元素

2016-08-12 11:04:17

JavaScript物聯網應用

2009-11-06 13:28:19

Javascript框

2020-11-19 10:50:43

ImportPython代碼

2010-05-21 10:13:30

Svn import子
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美亚洲在线 | 国产三级大片 | 黄色一级电影在线观看 | 国产剧情一区二区三区 | 99精品亚洲国产精品久久不卡 | 国产成人福利 | 亚洲国产激情 | 欧美人成在线视频 | 国产亚洲一区二区三区在线观看 | 国产高清视频一区二区 | 中文字幕第十五页 | 伊人艹 | 2018国产精品 | 黄色网址在线播放 | 国产成人午夜电影网 | 欧美一区二区三区视频 | 欧美日韩中文字幕 | 国产一区二区三区在线免费观看 | 国产小视频自拍 | 亚洲国产一区二区三区 | 人人玩人人添人人澡欧美 | 色综合天天天天做夜夜夜夜做 | 国产一级电影在线观看 | 免费视频一区二区 | 成人国产精品久久 | 91精品国产综合久久久动漫日韩 | 久久久久一区二区三区 | 人人色视频 | 成人精品视频免费 | 欧美精品久久久久 | 亚州无限乱码 | 欧美一级免费看 | 日韩有码一区 | 国产一区二区三区在线看 | 日韩视频一区 | 国产高清久久 | 日韩在线一区二区三区 | 一级片在线播放 | 色999日韩 | 亚洲一区二区三区在线 | 国产在线观看一区 |