国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

詳解 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-08 09:33:09

CSSlink@import

2010-09-01 15:11:09

linkimportCSS

2009-09-21 16:59:29

Array擴展

2016-10-11 20:33:17

JavaScriptThisWeb

2009-06-10 22:07:59

JavaScriptdocument對象window對象

2009-10-26 15:07:12

checkbox樹

2010-09-08 15:13:09

Node節點Node屬性

2016-12-27 10:19:42

JavaScriptindexOf

2020-04-15 15:48:03

Node.jsstream前端

2009-11-06 13:28:19

Javascript框

2016-08-12 11:04:17

JavaScript物聯網應用

2024-04-26 08:27:15

JavaScriptCSSHTML元素

2020-11-19 10:50:43

ImportPython代碼

2011-06-09 15:27:01

JavaScript
點贊
收藏

51CTO技術棧公眾號

1024视频在线| www.欧美视频| 国产精品你懂的在线欣赏| 日本一区二区三区视频免费看| 超碰97久久国产精品牛牛| 亚洲欧美精品伊人久久| 亚洲奶水xxxx哺乳期| 色哟哟一区二区在线观看| 人人做人人爽| 欧美激情中文不卡| 久久无码高潮喷水| 国产成人aaa| www插插插无码免费视频网站| 美女脱光内衣内裤视频久久网站 | 欧美婷婷精品激情| 国产一区二区三区不卡在线观看 | 国产欧美激情| 久久久久久久有限公司| 免费在线播放第一区高清av| 精品久久久久久中文字幕动漫 | 91精品91久久久久久| 午夜精品在线| 亚洲91av视频| 欧美a一欧美| 庆余年2免费日韩剧观看大牛| 欧美影院天天5g天天爽| 欧美一级电影在线| 精品国产123区| 91色精品视频在线| 蜜桃伊人久久| 国产成人一区二区三区别| 26uuu精品一区二区三区四区在线| 亚洲成年人影院| 中文字幕视频免费在线观看| 欧美性xxxxxx少妇| 97人人在线视频| 色久欧美在线视频观看| 欧美片网站免费| 国产精品久久久久久久久久久久久| 最新精品国产| 中文字幕综合在线观看| 91在线观看地址| 黄网站色大毛片| 91精品婷婷国产综合久久性色| 欧美13videosex性极品| 欧美高清无遮挡| 在线中文一区| 久久av秘一区二区三区| 久久精品一区二区三区四区| 四虎永久在线| 日韩精品视频在线免费观看| 欧美黑白配在线| 国产一区精品在线| 国产精品亚洲专一区二区三区| 91小视频网站| 91精品国产一区二区三区| a屁视频一区二区三区四区| 91国偷自产一区二区三区的观看方式| 欧美91大片| 激情五月婷婷六月| 大伊人狠狠躁夜夜躁av一区| 国产精品电影| 国产日韩欧美日韩大片| 老司机精品视频导航| 国产a国产a国产a| 日韩视频一区二区三区 | 午夜久久福利| 欧美做暖暖视频| 亚洲成人自拍偷拍| 成人av观看| 1卡2卡3卡精品视频| 成人美女在线视频| 日韩黄色影片| 久久99热精品这里久久精品| 亚洲人成毛片在线播放女女| 韩国视频一区二区三区| 欧美一区二区在线播放| 日韩一级电影| 国产xxxx振车| 欧美日韩国产影片| 美女久久久久| 国产精品久久中文字幕| 欧美精品xxxxbbbb| 亚洲精品无吗| 国产一区二区三区小说| 欧美色网一区| 成人黄色午夜影院| 久久久久久综合| 538在线视频| 成人av资源| 亚洲精品国产a| 伊人久久一区| 四虎免费在线观看视频| 欧美久久久久久久久| 精品72久久久久中文字幕| 无罩大乳的熟妇正在播放| 日韩免费在线观看| 亚洲h色精品| www.大网伊人| 不卡av电影院| 成人不卡免费av| 国产精品xx| 欧洲精品码一区二区三区免费看| 午夜精品久久久久久久久久久| 亚洲成人精品综合在线| 四虎影院一区二区三区| 色综合天天综合给合国产| aaa国产精品| 好吊妞无缓冲视频观看| 亚洲欧洲偷拍精品| 日本一区二区三区在线观看视频| 亚洲国产一区二区三区在线 | 欧美孕妇毛茸茸xxxx| av高清久久久| 日本免费久久| 国产免费一区二区三区四在线播放| 欧美亚洲动漫另类| 香蕉国产精品| 天堂v视频永久在线播放| 日韩av不卡在线| 综合分类小说区另类春色亚洲小说欧美| 未满十八勿进黄网站一区不卡| 国产成人永久免费视频| 亚洲福利在线看| 久久精品久久久精品美女| 亚洲精品白浆| 亚洲天堂av免费在线观看| 亚洲国产古装精品网站| 麻豆91精品91久久久的内涵| 国产资源在线观看入口av| 做爰高潮hd色即是空| 日韩精品www| 国产精品综合在线视频| 日韩电影免费观| 久久久性生活视频| 日韩在线不卡视频| 91亚洲精品久久久蜜桃网站| 625成人欧美午夜电影| 欧美大黑帍在线播放| 日韩性xxxx爱| 国产精品天干天干在观线| 神马日本精品| 日韩在线免费播放| 日韩一区在线免费观看| 日韩一级二级| 能在线观看的av网站| 2020久久国产精品| 欧美日韩一区二区在线| 亚洲欧洲美洲在线综合| 国产精品亚洲欧美| 岛国片av在线| 欧美精品自拍视频| 欧美精品videosex极品1| 亚洲欧美日韩国产手机在线| 日韩成人综合| 麻豆传媒在线观看| 欧美日韩dvd| 性欧美xxxx视频在线观看| 亚洲乱码日产精品bd| 天天综合精品| 日本高清在线观看视频| 久久亚洲中文字幕无码| 2019av中文字幕| 欧美日韩免费高清一区色橹橹| 麻豆成人91精品二区三区| av综合网址| 午夜免费视频在线国产| 日韩av在线播放不卡| 国产精品久久久久久久久借妻| 欧美日韩久久不卡| 成人黄色一级视频| 97久久夜色精品国产| 黄色在线观看www| 国产夫妻视频| 日本一区二区在线视频| 久久91亚洲精品中文字幕奶水| 欧美日韩一区二区在线| 韩国精品一区二区| 国产精品一线天粉嫩av| 久久www人成免费看片中文| 国产精品视频黄色| 激情伦成人综合小说| 久久天堂电影网| 色欧美乱欧美15图片| 国产成人综合在线观看| 国产探花一区| 中文字幕乱码在线播放| 淫视频在线观看| 国产成人生活片| 91传媒视频在线观看| 久久国产精品偷| 欧美一区二区三区视频免费| 成人欧美一区二区三区小说| 国模娜娜一区二区三区| 久久精品青草| 精品中文在线| 黄色大片在线| 黄色在线网站| 国产字幕中文| 三级4级全黄60分钟|