成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

[譯]JavaScript ES6模塊指南

yimo / 805人閱讀

摘要:模塊可以導(dǎo)入和導(dǎo)出各種類型的變量,如函數(shù),對(duì)象,字符串,數(shù)字,布爾值,等等。所以這可能會(huì)導(dǎo)致一些不符合預(yù)期的行為??勺兊幕绢愋椭翟趯?dǎo)入一些基本類型的值如數(shù)字,布爾值或字符串時(shí),可能會(huì)產(chǎn)生一個(gè)有趣的副作用。

前言

ECMAScript 2015(又稱ES6)提供了一個(gè)前端JavaScript缺失已久的特性 —— 模塊。ES2015中的模塊參考了CommonJS規(guī)范(目前Node.js的模塊規(guī)范)以及AMD規(guī)范,并且盡可能的取其精華,去其糟粕:

它提供了簡(jiǎn)潔的語(yǔ)法

以及異步的,可配置的模塊加載

這篇文章將會(huì)專注于ES2015的模塊語(yǔ)法以及注意點(diǎn)。關(guān)于模塊的加載和打包,將會(huì)在另一篇文章中細(xì)述。

為什么要使用模塊?

目前最普遍的JavaScript運(yùn)行平臺(tái)便是瀏覽器,在瀏覽器中,所有的代碼都運(yùn)行在同一個(gè)全局上下文中。這使得你即使更改應(yīng)用中的很小一部分,你也要擔(dān)心可能會(huì)產(chǎn)生的命名沖突。

傳統(tǒng)的JavaScript應(yīng)用被分離在多個(gè)文件中,并且在構(gòu)建的時(shí)候連接在一起,這稍顯笨重。所以人們開(kāi)始將每個(gè)文件內(nèi)的代碼都包在一個(gè)自執(zhí)行函數(shù)中:(function() { ... })();。這種方法創(chuàng)建了一個(gè)本地作用域,于是最初的模塊化的概念產(chǎn)生了。之后的CommonJS和AMD系統(tǒng)中所稱的模塊,也是由此實(shí)現(xiàn)的。

換句話說(shuō),現(xiàn)存的“模塊”系統(tǒng)是使用已有的語(yǔ)言特性所實(shí)現(xiàn)的。而ES2015則通過(guò)添加適當(dāng)?shù)男碌恼Z(yǔ)言特性,來(lái)使之官方化了。

創(chuàng)建模塊

一個(gè)JavaScript模塊就是一個(gè)對(duì)其他模塊暴露一些內(nèi)部屬性/方法的文件。我們?cè)谶@里僅會(huì)討論瀏覽器中的ES2015模塊系統(tǒng),并不會(huì)涉及Node.js是如何組織它自身的模塊的。一些在創(chuàng)建ES2015模塊時(shí)需要注意的點(diǎn):

每個(gè)模塊都有自己的上下文

和傳統(tǒng)的JavaScript不同,在使用模塊時(shí),你不必?fù)?dān)心污染全局作用域。恰恰相反,你需要把所以你需要用到的東西從其他模塊中導(dǎo)入進(jìn)來(lái)。但是,這樣也會(huì)使模塊之間的依賴關(guān)系更為清晰。

模塊的名字

模塊的名字由它的文件名或文件夾名所決定,并且你可以忽略它的.js后綴:

如果你有一個(gè)叫utils.js的文件,那么你可以通過(guò)./utils這樣的相對(duì)路徑導(dǎo)入它

如果你有一個(gè)叫./utils/index.js的文件,則你可以通過(guò)./utils/index./utils來(lái)導(dǎo)入它。這使得你可以批量導(dǎo)入一個(gè)文件夾內(nèi)的所有模塊。

導(dǎo)出和導(dǎo)入

可以使用ES2015的新關(guān)鍵字importexports來(lái)導(dǎo)入或?qū)С瞿K中的東西。模塊可以導(dǎo)入和導(dǎo)出各種類型的變量,如函數(shù),對(duì)象,字符串,數(shù)字,布爾值,等等。

默認(rèn)導(dǎo)出

每一個(gè)模塊都支持導(dǎo)出一個(gè)不具名的變量,這稱作默認(rèn)導(dǎo)出:

// hello-world.js
export default function() {}
 
// main.js
import helloWorld from "./hello-world";
import anotherFunction from "./hello-world";
 
helloWorld();
console.log(helloWorld === anotherFunction);

等價(jià)的CommonJS語(yǔ)法:

// hello.js
module.exports = function() {}
 
// main.js
var helloWorld = require("./hello-world");
var anotherFunction = require("./hello-world");
 
helloWorld();
console.log(helloWorld === anotherFunction);

任何的JavaScript值都可以被默認(rèn)導(dǎo)出:

export default 3.14;
export default {foo: "bar"};
export default "hello world";
具名導(dǎo)出

除了默認(rèn)導(dǎo)出外,ES2015的模塊系統(tǒng)還支持導(dǎo)出任意數(shù)量個(gè)具名的變量:

const PI = 3.14;
const value = 42;
export function helloWorld() {}
export {PI, value};

等價(jià)的CommonJS語(yǔ)法:

var PI = 3.14;
var value = 42;
module.exports.helloWorld = function() {}
module.exports.PI = PI;
module.exports.value = value;

你也可以在導(dǎo)出變量時(shí)對(duì)其重命名:

const value = 42;
export {value as THE_ANSWER};

等價(jià)的CommonJS語(yǔ)法:

var value = 42;
module.exports.THE_ANSWER = value;

在導(dǎo)入時(shí),你也可以使用as關(guān)鍵字來(lái)重命名導(dǎo)入的變量:

import {value as THE_ANSWER} from "./module";

等價(jià)的CommonJS語(yǔ)法:

var THE_ANSWER = require("./module"").value;
導(dǎo)入所有

最簡(jiǎn)單的,在一條命令中導(dǎo)入一個(gè)模塊中所有變量的方法,是使用*標(biāo)記。這樣一來(lái),被導(dǎo)入模塊中所有導(dǎo)出的變量都會(huì)變成它的屬性,默認(rèn)導(dǎo)出的變量則會(huì)被置于default屬性中。

// module.js
export default 3.14;
export const table = {foo: "bar"};
export function hello() {};
 
// main.js
import * as module from "./module";
console.log(module.default);
console.log(module.table);
console.log(module.hello());

等價(jià)的CommonJS語(yǔ)法:

// module.js
module.exports.default = 3.14;
module.exports.table = {foo: "bar"};
module.exports.hello = function () {};
 
// main.js
var module = require("./module");
console.log(module.default);
console.log(module.table);
console.log(module.hello());

值得再?gòu)?qiáng)調(diào)的是,import * as foo fromimport foo from的區(qū)別。后者僅僅會(huì)導(dǎo)入默認(rèn)導(dǎo)出的變量,而前者則會(huì)在一個(gè)對(duì)象中導(dǎo)入所有。

導(dǎo)出所有

一個(gè)可能的需求是,你需要將另一個(gè)模塊中的一些(或所有)值在你的模塊中再次導(dǎo)出,這被稱作二次導(dǎo)出(re-exporting)。值得注意的是,你可以二次導(dǎo)出許多同名的值,這將不會(huì)導(dǎo)致異常,而是最后一個(gè)被導(dǎo)出的值將會(huì)獲得勝利。

// module.js
const PI = 3.14;
const value = 42;
export const table = {foo: "bar"};
export function hello() {};
 
// main.js
export * from "./module";
export {hello} from "./module";
export {hello as foo} from "./module";

等價(jià)的CommonJS語(yǔ)法:

// module.js
module.exports.table = {foo: "bar"};
module.exports.hello = function () {};
 
// main.js
module.exports = require("./module");
module.exports.hello = require("./module").hello;
module.exports.foo = require("./module").hello;
注意點(diǎn)

一個(gè)關(guān)鍵點(diǎn)時(shí),導(dǎo)入模塊的東西,并不是一個(gè)引用或一個(gè)值,而是一個(gè)類似與被導(dǎo)入模塊內(nèi)部的一個(gè)getter對(duì)象。所以這可能會(huì)導(dǎo)致一些不符合預(yù)期的行為。

缺乏異常

在具名地導(dǎo)入其他模塊的變量時(shí),如果你不小心打錯(cuò)了變量名,這將不會(huì)拋出異常,而是導(dǎo)入的值將會(huì)變成undefined。

// module.js
export const value = 42;
 
// main.js
import {valu} from "./module"; // no errors
console.log(valu); // undefined
可變的基本類型值

在導(dǎo)入一些基本類型的值(如數(shù)字,布爾值或字符串)時(shí),可能會(huì)產(chǎn)生一個(gè)有趣的副作用。這些值可能會(huì)在模塊外被修改。例子:

// module.js
export let count = 0;
 
export function inc() { 
  count++;
}
 
// main.js
import {count, inc} from "./module"; // `count` is a `Number` variable
 
assert.equal(count, 0);
inc();
assert.equal(count, 1);

上面的例子中,count變量是一個(gè)數(shù)值類型,它在main模塊中被修改了值。

導(dǎo)入的變量是只讀的

不論你以何種聲明導(dǎo)出變量,它們都是只讀的。但是,如果導(dǎo)出的是對(duì)象,你可以改變變量的屬性。

// module.js
export let count = 0;
export const table = {foo: "bar"};
 
// main.js
import {count, table} from "./module;
 
table.foo = "Bar"; // OK
count++; // read-only error
測(cè)試模塊

如果想要測(cè)試,或mock被導(dǎo)出的變量,很不幸,這在新的ES2015模塊系統(tǒng)中是辦不到的。因?yàn)榕cCommonJS一樣,導(dǎo)出的變量在外面不能被重新賦值。唯一的解決辦法是,導(dǎo)出一個(gè)多帶帶的對(duì)象。

// module.js
export default {
  value: 42,
  print: () => console.log(this.value)
}
 
// module-test.js
import m from "./module";
m.value = 10;
m.print(); // 10
最后

ES2015的模塊標(biāo)準(zhǔn)化了模塊的加載和解析方式。CommonJS和AMD之間的爭(zhēng)論終于被解決了。

我們得到了更簡(jiǎn)潔的模塊語(yǔ)法,以及靜態(tài)的模塊定義,這有助于編譯器的優(yōu)化,甚至是類型檢查。

原文鏈接:https://strongloop.com/strongblog/an-introduction-to-javascript-es6-modules/

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/78256.html

相關(guān)文章

  • []JavaScript ES6解構(gòu)賦值指南

    摘要:解構(gòu)賦值允許我們將右邊的表達(dá)式看起來(lái)也像變量聲明一般,然后在左邊將值一一提取。數(shù)組的解構(gòu)賦值現(xiàn)在假設(shè)我們有一個(gè)變量,其值為。通過(guò),這會(huì)看上去更清晰簡(jiǎn)潔最后的解構(gòu)賦值給的語(yǔ)法帶來(lái)了更多的現(xiàn)代化。 前言 讓我們來(lái)仔細(xì)地看看ES6所帶來(lái)的更清晰的變量聲明與賦值語(yǔ)法?,F(xiàn)今的變量聲明語(yǔ)法十分的直接:左邊是一個(gè)變量名,右邊可以是一個(gè)數(shù)組:[]的表達(dá)式或一個(gè)對(duì)象:{}的表達(dá)式,等等。解構(gòu)賦值允許我...

    Jeff 評(píng)論0 收藏0
  • []JavaScript ES6 class指南

    摘要:前言又稱通過(guò)一些新的關(guān)鍵字,使類成為了中一個(gè)新的一等公民。類聲明在中,有兩個(gè)聲明類的方式。在使用了新的關(guān)鍵字后在底層,所做的,也只是將這個(gè)方法添加為構(gòu)造函數(shù)的一個(gè)屬性。在想要調(diào)用父類的構(gòu)造函數(shù)時(shí),你可以簡(jiǎn)單地將關(guān)鍵字視作一個(gè)函數(shù)使用,如。 前言 EcmaScript 2015 (又稱ES6)通過(guò)一些新的關(guān)鍵字,使類成為了JS中一個(gè)新的一等公民。但是目前為止,這些關(guān)于類的新關(guān)鍵字僅僅是建...

    CoderDock 評(píng)論0 收藏0
  • []JavaScript ES6迭代器指南

    摘要:前言又稱提供一個(gè)全新的迭代器的概念,它允許我們?cè)谡Z(yǔ)言層面上定義一個(gè)有限或無(wú)限的序列。后者可以被用來(lái)幫助我們理解迭代器。但是當(dāng)我們使用迭代器時(shí),這個(gè)問(wèn)題就迎刃而解了。是中的新語(yǔ)法,用來(lái)配合迭代器。這是因?yàn)閿?shù)組的迭代器只返回其中預(yù)期的元素。 前言 EcmaScript 2015 (又稱ES6)提供一個(gè)全新的迭代器的概念,它允許我們?cè)谡Z(yǔ)言層面上定義一個(gè)(有限或無(wú)限的)序列。 暫時(shí)先拋開(kāi)它...

    daryl 評(píng)論0 收藏0
  • []JavaScript ES6箭頭函數(shù)指南

    摘要:以下例子的目的是使用來(lái)展示一個(gè)每秒都會(huì)更新的時(shí)鐘當(dāng)嘗試在的回調(diào)中使用來(lái)引用元素時(shí),很不幸,我們得到的只是一個(gè)屬于回調(diào)函數(shù)自身上下文的。 前言 胖箭頭函數(shù)(Fat arrow functions),又稱箭頭函數(shù),是一個(gè)來(lái)自ECMAScript 2015(又稱ES6)的全新特性。有傳聞?wù)f,箭頭函數(shù)的語(yǔ)法=>,是受到了CoffeeScript 的影響,并且它與CoffeeScript中的=>...

    makeFoxPlay 評(píng)論0 收藏0
  • 性能優(yōu)化

    摘要:如果你的運(yùn)行緩慢,你可以考慮是否能優(yōu)化請(qǐng)求,減少對(duì)的操作,盡量少的操,或者犧牲其它的來(lái)?yè)Q取性能。在認(rèn)識(shí)描述這些核心元素的過(guò)程中,我們也會(huì)分享一些當(dāng)我們構(gòu)建的時(shí)候遵守的一些經(jīng)驗(yàn)規(guī)則,一個(gè)應(yīng)用應(yīng)該保持健壯和高性能來(lái)維持競(jìng)爭(zhēng)力。 一個(gè)開(kāi)源的前端錯(cuò)誤收集工具 frontend-tracker,你值得收藏~ 蒲公英團(tuán)隊(duì)最近開(kāi)發(fā)了一款前端錯(cuò)誤收集工具,名叫 frontend-tracker ,這款...

    liangzai_cool 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<