溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

ES6中Modules的示例分析

發布時間:2021-12-28 11:28:49 來源:億速云 閱讀:144 作者:小新 欄目:開發技術

這篇文章主要為大家展示了“ES6中Modules的示例分析”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“ES6中Modules的示例分析”這篇文章吧。

一些簡單的背景

隨用隨取, 是一種我們都希望實現的機制。

在 Javascript 中也一樣,把一個大的 Javascript 程序分割成不同的部分, 哪個部分要被用到,就取那一部分。

在很長一段時間內, NodeJS 擁有這樣的能力, 后來, 越來越多的庫和框架也擁有了模塊化的能力, 比如 CommonJS, 或者基于AMD模型的實現(比如RequireJs),還有后續的Webpack, Babel等。

到2015年,一個標準的模塊化系統誕生了,這就是我們今天要說的主角 - ES6 模型系統。

一眼看上去, 我們不難發現, ES6的模型系統和CommonJS語法非常的相似,畢竟ES6 的模型系統是從CommonJS時代走過來的, 深受CommonJS 影響。

看個簡單的例子,比如在CommonJs中: (https://flaviocopes.com/commonjs/)

//file.jsmodule.exports = value;// 引入valueconst value = require('file.js')

而在ES6中:

// const.jsexport const value = 'xxx';import { value } from 'const.js'

語法是非常相似的。

下面我們就主要看 import 和 export,和幾個相關的特性,了解ES6 Modules的更多方面。

模塊化的好處

模塊化的好處主要是兩點:

1. 避免全局變量污染2. 有效的處理依賴關系

隨著時代的演進, 瀏覽器原生也開始支持es6 import 和 export 語法了。

先看個簡單的例子:

<script type="module">  import { addTextToBody } from '/util.js';  addTextToBody('Modules are pretty cool.');</script>// util.js export function addTextToBody(text) {  const p = document.createElement('p');  p.textContent = text;  document.body.appendChild(p);}

如果要處理事件,也是一樣, 看個簡單的例子:

<button id="test">Show Message</button><script type="module" crossorigin src="/showImport.js"></script>// showImport.jsimport { showMessage } from '/show.js'document.getElementById('test').onclick = function() {  showMessage();}// show.jsexport function showMessage() {  alert("Hello World!")}

如果你想跑這個demo, 注意要起個簡單的服務:

$ http-server

否則,你會看到一個CORS拋錯。

至于拋錯的具體原因和其他細節,不是本文討論的重點, 感興趣的可以閱讀如下鏈接了解詳情。

https://jakearchibald.com/2017/es-modules-in-browsers/

嚴格模式

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

'use strict' 聲明我們都不陌生, 在es5 時代我們也經常使用, 一般是在文件頂部加這個聲明,目的就是禁用Javascript中不太友好的一部分,有助于我們寫更嚴謹的代碼。

這個特性,在es6語法中是默認開啟的, 如果代碼里面有不太嚴格的代碼,則會報錯,例如:

下面是我從MDN中摘取的一些在嚴格模式中被禁用的部分:

Variables can’t be left undeclaredFunction parameters must have unique names (or are considered syntax errors)with is forbiddenErrors are thrown on assignment to read-only propertiesOctal numbers like 00840 are syntax errorsAttempts to delete undeletable properties throw an errordelete prop is a syntax error, instead of assuming delete global[prop]eval doesn’t introduce new variables into its surrounding scopeeval and arguments can’t be bound or assigned toarguments doesn’t magically track changes to method parametersarguments.callee throws a TypeError, no longer supportedarguments.caller throws a TypeError, no longer supportedContext passed as this in method invocations is not “boxed” (forced) into becoming an ObjectNo longer able to use fn.caller and fn.arguments to access the JavaScript stackReserved words (e.g protected, static, interface, etc) cannot be bound

exports 的幾種用法

ES6模塊只支持靜態導出,你只可以在模塊的最外層作用域使用export,不可在條件語句中使用,也不能在函數作用域中使用。

從分類上級講, exports 主要有三種:

1、Named Exports (Zero or more exports per module)

2、Default Exports (One per module)

3、Hybrid Exports

exports 總覽:

// Exporting inpidual featuresexport let name1, name2, …, nameN; // also var, constexport let name1 = …, name2 = …, …, nameN; // also var, constexport function functionName(){...}export class ClassName {...}// Export listexport { name1, name2, …, nameN };// Renaming exportsexport { variable1 as name1, variable2 as name2, …, nameN };// Exporting destructured assignments with renamingexport const { name1, name2: bar } = o;// Default exportsexport default expression;export default function (…) { … } // also class, function*export default function name1(…) { … } // also class, function*export { name1 as default, … };// Aggregating modulesexport * from …; // does not set the default exportexport * as name1 from …;export { name1, name2, …, nameN } from …;export { import1 as name1, import2 as name2, …, nameN } from …;export { default } from …;

下面我就介紹一下常見的 exports用法。

1. Named exports (導出每個函數/變量)

具名導出,這種方式導出多個函數,一般使用場景比如 utils、tools、common 之類的工具類函數集,或者全站統一變量等。

只需要在變量或函數前面加 export 關鍵字即可。

//------ lib.js ------export const sqrt = Math.sqrt;export function square(x) {    return x * x;}export function diag(x, y) {    return sqrt(square(x) + square(y));}//------ main.js 使用方式1 ------import { square, diag } from 'lib';console.log(square(11)); // 121console.log(diag(4, 3)); // 5//------ main.js 使用方式2 ------import * as lib from 'lib';console.log(lib.square(11)); // 121console.log(lib.diag(4, 3)); // 5

我們也可以直接導出一個列表,例如上面的lib.js可以改寫成:

//------ lib.js ------const sqrt = Math.sqrt;function square(x) {    return x * x;}function add (x, y) {    return x + y;}export { sqrt, square, add }

2. Default exports (導出一個默認 函數/類)

這種方式比較簡單,一般用于一個類文件,或者功能比較單一的函數文件使用。

一個模塊中只能有一個export default默認輸出。

export default與export的主要區別有兩個:

不需要知道導出的具體變量名, 導入(import)時不需要{}.

//------ myFunc.js ------export default function () {};//------ main.js ------import myFunc from 'myFunc';myFunc();

導出一個類

//------ MyClass.js ------class MyClass{}export default MyClass;//------ Main.js ------import MyClass from 'MyClass';

注意這里默認導出不需要用{}。

3. Mixed exports (混合導出)

混合導出,也就是 上面第一點和第二點結合在一起的情況。比較常見的比如 Lodash,都是這種組合方式。

//------ lib.js ------export var myVar = ...;export let myVar = ...;export const MY_CONST = ...;export function myFunc() {  // ...}export function* myGeneratorFunc() {  // ...}export default class MyClass {  // ...}// ------ main.js ------import MyClass, { myFunc } from 'lib';

再比如lodash例子:

//------ lodash.js ------export default function (obj) {  // ...};export function each(obj, iterator, context) {  // ...}export { each as forEach };//------ main.js ------import _, { forEach } from 'lodash';

4. Re-exporting (別名導出)

一般情況下,export輸出的變量就是在原文件中定義的名字,但也可以用 as 關鍵字來指定別名,這樣做一般是為了簡化或者語義化export的函數名。

//------ lib.js ------export function getUserName(){  // ...};export function setName(){  // ...};//輸出別名,在import的時候可以同時使用原始函數名和別名export {  getName as get, //允許使用不同名字輸出兩次  getName as getNameV2,  setName as set}

5. Module Redirects (中轉模塊導出)

有時候為了避免上層模塊導入太多的模塊,我們可能使用底層模塊作為中轉,直接導出另一個模塊的內容如下:

//------ myFunc.js ------export default function() {...}; //------ lib.js ------export * from 'myFunc';export function each() {...}; //------ main.js ------import myFunc, { each } from 'lib';export 只支持在最外層靜態導出、只支持導出變量、函數、類,如下的幾種用法都是錯誤的。`錯誤`的export用法://直接輸出變量的值export 'Mark';// 未使用中括號 或 未加default// 當只有一個導出數,需加default,或者使用中括號var name = 'Mark';export name;//export不要輸出塊作用域內的變量function () {  var name = 'Mark';  export  { name };}

import的幾種用法

import的用法和export是一一對應的,但是import支持靜態導入和動態導入兩種方式,動態import支持晚一些,兼容性要差一些。

下面我就總結下import的基本用法:

1. Import All things

當export有多個函數或變量時,如文中export的第一點,可以使用 * as 關鍵字來導出所有函數及變量,同時 as 后面跟著的名稱做為 該模塊的命名空間。

//導出lib的所有函數及變量import * as lib from 'lib';//以 lib 做為命名空間進行調用,類似于object的方式console.log(lib.square(11)); // 121

2. Import a single/multiple export from a module

從模塊文件中導入單個或多個函數,與 * as namepage 方式不同,這個是按需導入。如下例子:

//導入square和 diag 兩個函數import { square, diag } from 'lib';// 只導入square 一個函數import { square } from 'lib';// 導入默認模塊import _ from 'lodash';// 導入默認模塊和單個函數,這樣做主要是簡化單個函數的調用import _, { each } from 'lodash';

3. Rename multiple exports during import

和 export 一樣,也可以用 as 關鍵字來設置別名,當import的兩個類的名字一樣時,可以使用 as 來重設導入模塊的名字,也可以用as 來簡化名稱。比如:

// 用 as 來 簡化函數名稱import {  reallyReallyLongModuleExportName as shortName,  anotherLongModuleName as short} from '/modules/my-module.js';// 避免重名import { lib as UserLib} from "alib";import { lib as GlobalLib } from "blib";

4. Import a module for its side effects only

有時候我們只想import一個模塊進來,比如樣式,或者一個類庫。

// 導入樣式import './index.less';// 導入類庫import 'lodash';

5. Dynamic Imports

靜態import在首次加載時候會把全部模塊資源都下載下來.

我們實際開發時候,有時候需要動態import(dynamic import)。

例如點擊某個選項卡,才去加載某些新的模塊:

// 當動態import時,返回的是一個promiseimport('lodash')  .then((lodash) => {    // Do something with lodash.  });// 上面這句實際等同于const lodash = await import('lodash');

es7的新用法:

async function run() {    const myModule = await import('./myModule.js');    const { export1, export2 } = await import('./myModule.js');    const [module1, module2, module3] =        await Promise.all([            import('./module1.js'),            import('./module2.js'),            import('./module3.js'),        ]);}run();

以上是“ES6中Modules的示例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女