欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

ECMAScript6中Modules的用法

當(dāng)下, 我們幾乎所有的項(xiàng)目都是基于 webpack、rollup 等構(gòu)建工具進(jìn)行開發(fā)的,模塊化已經(jīng)是常態(tài)。

創(chuàng)新互聯(lián)公司:2013年至今為各行業(yè)開拓出企業(yè)自己的“網(wǎng)站建設(shè)”服務(wù),為上千余家公司企業(yè)提供了專業(yè)的成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)和網(wǎng)站推廣服務(wù), 按需制作網(wǎng)站由設(shè)計(jì)師親自精心設(shè)計(jì),設(shè)計(jì)的效果完全按照客戶的要求,并適當(dāng)?shù)奶岢龊侠淼慕ㄗh,擁有的視覺效果,策劃師分析客戶的同行競爭對手,根據(jù)客戶的實(shí)際情況給出合理的網(wǎng)站構(gòu)架,制作客戶同行業(yè)具有領(lǐng)先地位的。

我們對它并不陌生,今天,我們就再系統(tǒng)的回顧一下ES6的模塊機(jī)制, 并總結(jié)下常用的操作和最佳實(shí)踐, 希望對你有所幫助。

一些簡單的背景

隨用隨取, 是一種我們都希望實(shí)現(xiàn)的機(jī)制。

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

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

到2015年,一個標(biāo)準(zhǔn)的模塊化系統(tǒng)誕生了,這就是我們今天要說的主角 - ES6 模型系統(tǒng)。

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

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

//file.js
module.exports = value;

// 引入value
const value = require('file.js')

而在ES6中:

// const.js
export const value = 'xxx';


import { value } from 'const.js'

語法是非常相似的。

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

模塊化的好處

模塊化的好處主要是兩點(diǎn):

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

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

ECMAScript 6中Modules的用法

先看個簡單的例子:

<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.js
import { showMessage } from '/show.js'

document.getElementById('test').onclick = function() {
  showMessage();
}

// show.js
export function showMessage() {
  alert("Hello World!")
}

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

$ http-server

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

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

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

嚴(yán)格模式

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

'use strict' 聲明我們都不陌生, 在es5 時代我們也經(jīng)常使用, 一般是在文件頂部加這個聲明,目的就是禁用Javascript中不太友好的一部分,有助于我們寫更嚴(yán)謹(jǐn)?shù)拇a。

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

ECMAScript 6中Modules的用法

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

  • Variables can’t be left undeclared
  • Function parameters must have unique names (or are considered syntax errors)
  • with is forbidden
  • Errors are thrown on assignment to read-only properties
  • Octal numbers like 00840 are syntax errors
  • Attempts to delete undeletable properties throw an error
  • delete prop is a syntax error, instead of assuming delete global[prop]
  • eval doesn’t introduce new variables into its surrounding scope
  • eval and arguments can’t be bound or assigned to
  • arguments doesn’t magically track changes to method parameters
  • arguments.callee throws a TypeError, no longer supported
  • arguments.caller throws a TypeError, no longer supported
  • Context passed as this in method invocations is not “boxed” (forced) into becoming an Object
  • No longer able to use fn.caller and fn.arguments to access the JavaScript stack
  • Reserved words (e.g protected, static, interface, etc) cannot be bound

exports 的幾種用法

ES6模塊只支持靜態(tài)導(dǎo)出,你只可以在模塊的最外層作用域使用export,不可在條件語句中使用,也不能在函數(shù)作用域中使用。

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

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

2、Default Exports (One per module)

3、Hybrid Exports

exports 總覽:

// Exporting inpidual features
export let name1, name2, …, nameN; // also var, const
export let name1 = …, name2 = …, …, nameN; // also var, const
export function functionName(){...}
export class ClassName {...}

// Export list
export { name1, name2, …, nameN };

// Renaming exports
export { variable1 as name1, variable2 as name2, …, nameN };

// Exporting destructured assignments with renaming
export const { name1, name2: bar } = o;

// Default exports
export default expression;
export default function (…) { … } // also class, function*
export default function name1(…) { … } // also class, function*
export { name1 as default, … };

// Aggregating modules
export * from …; // does not set the default export
export * as name1 from …;
export { name1, name2, …, nameN } from …;
export { import1 as name1, import2 as name2, …, nameN } from …;
export { default } from …;

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

1. Named exports (導(dǎo)出每個函數(shù)/變量)

具名導(dǎo)出,這種方式導(dǎo)出多個函數(shù),一般使用場景比如 utils、tools、common 之類的工具類函數(shù)集,或者全站統(tǒng)一變量等。

只需要在變量或函數(shù)前面加 export 關(guān)鍵字即可。

//------ 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)); // 121
console.log(diag(4, 3)); // 5

//------ main.js 使用方式2 ------
import * as lib from 'lib';
console.log(lib.square(11)); // 121
console.log(lib.diag(4, 3)); // 5

我們也可以直接導(dǎo)出一個列表,例如上面的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 (導(dǎo)出一個默認(rèn) 函數(shù)/類)

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

一個模塊中只能有一個export default默認(rèn)輸出。

export default與export的主要區(qū)別有兩個:

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

//------ myFunc.js ------
export default function () {};

//------ main.js ------
import myFunc from 'myFunc';
myFunc();

導(dǎo)出一個類

//------ MyClass.js ------
class MyClass{}

export default MyClass;

//------ Main.js ------
import MyClass from 'MyClass';

注意這里默認(rèn)導(dǎo)出不需要用{}。

3. Mixed exports (混合導(dǎo)出)

混合導(dǎo)出,也就是 上面第一點(diǎn)和第二點(diǎn)結(jié)合在一起的情況。比較常見的比如 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 (別名導(dǎo)出)

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

//------ lib.js ------
export function getUserName(){
  // ...
};
export function setName(){
  // ...
};

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

5. Module Redirects (中轉(zhuǎn)模塊導(dǎo)出)

有時候?yàn)榱吮苊馍蠈幽K導(dǎo)入太多的模塊,我們可能使用底層模塊作為中轉(zhuǎn),直接導(dǎo)出另一個模塊的內(nèi)容如下:

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

export 只支持在最外層靜態(tài)導(dǎo)出、只支持導(dǎo)出變量、函數(shù)、類,如下的幾種用法都是錯誤的。

`錯誤`的export用法:

//直接輸出變量的值
export 'Mark';

// 未使用中括號 或 未加default
// 當(dāng)只有一個導(dǎo)出數(shù),需加default,或者使用中括號
var name = 'Mark';
export name;

//export不要輸出塊作用域內(nèi)的變量
function () {
  var name = 'Mark';
  export  { name };
}

import的幾種用法

import的用法和export是一一對應(yīng)的,但是import支持靜態(tài)導(dǎo)入和動態(tài)導(dǎo)入兩種方式,動態(tài)import支持晚一些,兼容性要差一些。

ECMAScript 6中Modules的用法

下面我就總結(jié)下import的基本用法:

1. Import All things

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

//導(dǎo)出lib的所有函數(shù)及變量
import * as lib from 'lib';

//以 lib 做為命名空間進(jìn)行調(diào)用,類似于object的方式
console.log(lib.square(11)); // 121

2. Import a single/multiple export from a module

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

//導(dǎo)入square和 diag 兩個函數(shù)
import { square, diag } from 'lib';

// 只導(dǎo)入square 一個函數(shù)
import { square } from 'lib';

// 導(dǎo)入默認(rèn)模塊
import _ from 'lodash';

// 導(dǎo)入默認(rèn)模塊和單個函數(shù),這樣做主要是簡化單個函數(shù)的調(diào)用
import _, { each } from 'lodash';

3. Rename multiple exports during import

和 export 一樣,也可以用 as 關(guān)鍵字來設(shè)置別名,當(dāng)import的兩個類的名字一樣時,可以使用 as 來重設(shè)導(dǎo)入模塊的名字,也可以用as 來簡化名稱。
比如:

// 用 as 來 簡化函數(shù)名稱
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一個模塊進(jìn)來,比如樣式,或者一個類庫。

// 導(dǎo)入樣式
import './index.less';

// 導(dǎo)入類庫
import 'lodash';

5. Dynamic Imports

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

我們實(shí)際開發(fā)時候,有時候需要動態(tài)import(dynamic import)。

例如點(diǎn)擊某個選項(xiàng)卡,才去加載某些新的模塊:

// 當(dāng)動態(tài)import時,返回的是一個promise
import('lodash')
  .then((lodash) => {
    // Do something with lodash.
  });

// 上面這句實(shí)際等同于
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的詳細(xì)內(nèi)容,更多請關(guān)注創(chuàng)新互聯(lián)其它相關(guān)文章!

網(wǎng)站題目:ECMAScript6中Modules的用法
URL地址:http://chinadenli.net/article10/gogodo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供電子商務(wù)網(wǎng)站設(shè)計(jì)網(wǎng)站營銷動態(tài)網(wǎng)站定制開發(fā)面包屑導(dǎo)航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)頁設(shè)計(jì)公司