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

資訊專欄INFORMATION COLUMN

ES6之路之模塊詳解

huashiou / 3244人閱讀

摘要:例如我們導(dǎo)入模塊,可以這么導(dǎo)入桃翁歡迎關(guān)注公眾號前端桃園報錯不能定義相同名字變量報錯,不能重新賦值小豬可以看到導(dǎo)入綁定這里不理解綁定,文章后面會解釋時,形式類似于對象解構(gòu),但實際上并無關(guān)聯(lián)。

歡迎訪問個人站點
簡介 何為模塊

一個模塊只不過是一個寫在文件中的 JavaScript 代碼塊。

模塊中的函數(shù)或變量不可用,除非模塊文件導(dǎo)出它們。

簡單地說,這些模塊可以幫助你在你的模塊中編寫代碼,并且只公開應(yīng)該被你的代碼的其他部分訪問的代碼部分。

為什么要使用模塊

增加可維護(hù)性:由于每個模塊都是獨立的,每個人寫的代碼是不會相互影響的,在維護(hù)代碼的時候很好排查是哪個模塊出錯。

可復(fù)用性:在日常的開發(fā)中,特別是大點的項目,代碼的可復(fù)用性就更重要了,也許你會用復(fù)制粘貼的形式,但是直接一個 import 命令就可以搞定,豈不快哉。

避免命名污染:在 javascript 腳本中,所有的 js 文件的頂級作用域創(chuàng)建的變量,會被添加到共享的全局作用域,這就會導(dǎo)致不同的人開發(fā)的代碼可能會有相同的變量名,導(dǎo)致變量名污染。

如何使用 導(dǎo)出模塊

導(dǎo)出模塊所用的命令是 export。

前面也提到一個模塊就是一個 javascript 文件,在這個模塊中定義的變量,外部是無法獲取到的,只有通過 export 導(dǎo)出的變量其他模塊才可以用

最簡單的導(dǎo)出方式就是在聲明的變量、函數(shù)、類前面加一個 export

// export1.js 

// 導(dǎo)出變量
export let name = "桃翁";

// 導(dǎo)出函數(shù)
export function print() {
    console.log("歡迎關(guān)注公眾號:前端桃園");
}

// 導(dǎo)出類
export class Person {
    constructor(name) {
        this.name = name;
    }
}
// 私有函數(shù)
function privateFunction () {
    console.log("我是私有函數(shù),外部訪問不了我");
}
注意
1. 被導(dǎo)出的函數(shù)或者類,都必須要有名稱,意思就是說不能用這種方式導(dǎo)出匿名函數(shù)或者匿名類。
2. privateFunction 函數(shù),沒有加 export 命令,被當(dāng)做這個模塊的私有變量,其他模塊是訪問不到的。

除了上面那種導(dǎo)出方式,還有另外一種

// export2.js

// 導(dǎo)出變量
let name = "桃翁";

// 導(dǎo)出函數(shù)
function print() {
    return "歡迎關(guān)注公眾號:前端桃園";
}

// 導(dǎo)出類
class Person {
    constructor(name) {
        this.name = name;
    }
}

// 私有函數(shù)
function privateFunction () {
    return "我是私有函數(shù),外部訪問不了我";
}

export { name, print, Person }

上面這種寫法導(dǎo)入一組變量,與 export1.js 是等價的。

導(dǎo)入模塊

導(dǎo)入的模塊可以理解為是生產(chǎn)者(或者服務(wù)的提供者),而使用導(dǎo)入的模塊的模塊就是消費者。

導(dǎo)入模塊的命令是 import, import 的基本形式如下:

import { var1, var2 } from "./example.js"

import 語句包含兩部分:一是導(dǎo)入需要的標(biāo)識符,二是模塊的來源。

注意:瀏覽器中模塊來源要以「/」或者 「./」 或者 「../」開頭 或者 url 形式,不然會報錯。

例如我們導(dǎo)入 export1.js 模塊,可以這么導(dǎo)入

// import1.js
import { name, print, Person } from "./export1.js";

console.log(name); // 桃翁

console.log(print()); // 歡迎關(guān)注公眾號:前端桃園

// 報錯, 不能定義相同名字變量
let name = 2333; 

// 報錯,不能重新賦值
name = "小豬";

可以看到導(dǎo)入綁定(這里不理解綁定,文章后面會解釋)時,形式類似于對象解構(gòu),但實際上并無關(guān)聯(lián)。

當(dāng)導(dǎo)入綁定的時候,綁定類似于使用了 const 定義,意味著不能定義相同的變量名,但是沒有暫時性死區(qū)特性(但是在 深入理解ES6 這本書里面說是有暫時性死區(qū)限制,我在 chrome 上測試了的,讀者希望也去試下,到底受不受限制)。

let name = 2333;

上面這行代碼會報錯。

命名空間導(dǎo)入

這種導(dǎo)入方式是把整個生產(chǎn)者模塊當(dāng)做單一對象導(dǎo)入,所有的導(dǎo)出被當(dāng)做對象的屬性。

// import2.js
import * as namespace from "./export1.js"

console.log(namespace.name); // 桃翁

console.log(namespace.print()); // 歡迎關(guān)注公眾號:前端桃園
重命名導(dǎo)入導(dǎo)出

有時候你并不想導(dǎo)出變量的原名稱,需要重新命名,這個時候只需要使用 as 關(guān)鍵字來制定新的名字即可。

重命名導(dǎo)出
// export3.js

function print() {
    return "歡迎關(guān)注公眾號:前端桃園";
}

export { print as advertising }
導(dǎo)重命名入

拿上面導(dǎo)出的舉例子

// import3.js
import { advertising as print } from "./export3.js"

console.log(typeof advertising); // "undefined"

console.log(print()); // 歡迎關(guān)注公眾號:前端桃園 

此代碼導(dǎo)入 advertising 函數(shù)并重命名為了 print ,這意味著此模塊中 advertising 標(biāo)識符不存在了。

default 關(guān)鍵字

default 關(guān)鍵字是用來做默認(rèn)導(dǎo)入導(dǎo)出的。

默認(rèn)導(dǎo)出
// defaultExport.js

// 第一種默認(rèn)導(dǎo)出方式
export default function print() {
    return "歡迎關(guān)注公眾號:前端桃園";
}

// 第二種默認(rèn)導(dǎo)出方式
function print() {
    return "歡迎關(guān)注公眾號:前端桃園";
}

export default print;

// 第三種默認(rèn)導(dǎo)出方式
function print() {
    return "歡迎關(guān)注公眾號:前端桃園";
}

export { print as default }

default 這個關(guān)鍵字在 JS 中具有特殊含義,既可以作為同命名導(dǎo)出,又標(biāo)明了模塊需要使用默認(rèn)值。

注意: 一個模塊中只能有一個默認(rèn)導(dǎo)出。
默認(rèn)導(dǎo)入

默認(rèn)導(dǎo)入和一般的導(dǎo)入不同之處就是不需要寫大括號了,看起來更簡潔。

把上面 defaultExport.js 模塊導(dǎo)出的作為例子

import print from "./defaultExport.js"

console.log(print()); // 歡迎關(guān)注公眾號:前端桃園 

那如果既有默認(rèn)的又有非默認(rèn)的怎么導(dǎo)入呢?看例子就明白了

// defaultImport1.js

let name = "桃翁";

function print() {
    return "歡迎關(guān)注公眾號:前端桃園";
}

export { name, print as default }
// defaultImport2.js

import print, { name } from "./defaultImport1.js"

console.log(print()); // 歡迎關(guān)注公眾號:前端桃園

console.log(name); // 桃翁

混合導(dǎo)入需要把默認(rèn)導(dǎo)入的名稱放在最前面,然后用逗號和后面非默認(rèn)導(dǎo)出的分割開。

思考了很久是否應(yīng)該加上進(jìn)階內(nèi)容,本來是想寫入門級系列的,但是想了想,還是都寫進(jìn)來吧,入門的看入門前面基礎(chǔ),深入理解的看進(jìn)階。
進(jìn)階

進(jìn)階部分主要介紹 模塊的幾個特性

靜態(tài)執(zhí)行

動態(tài)關(guān)聯(lián)

模塊不會重復(fù)執(zhí)行

靜態(tài)執(zhí)行

所謂靜態(tài)執(zhí)行其實就是在編譯階段就需要確定模塊的依賴關(guān)系,那么就會出現(xiàn) import 命令會優(yōu)先于模塊其他內(nèi)容的執(zhí)行,會提前到編譯階段執(zhí)行。

// static1.js
console.log("佩奇");

import { nouse } from "./static2.js"

// static2.js
export function nouse() {
    return "我是不需要的";
}

console.log("小豬");

可以看到最后輸出的應(yīng)該是「小豬」先輸出,而「佩奇」后輸出,可以得出雖然 static2.js 在后面引入,但是會被提升到模塊的最前面先執(zhí)行。

這也是我前面所說的不受暫時性死區(qū)原因之一,在這里可以寫一個例子試試:

// static3.js
console.log(nouse());

import { nouse } from "./static2.js"

// 結(jié)果:
// 小豬
// 我是不需要的

經(jīng)檢驗確實是可以在 import 之前使用導(dǎo)入的綁定。

靜態(tài)執(zhí)行還會導(dǎo)致一個問題,那就是不能動態(tài)導(dǎo)入模塊。

// 報錯
if (flag) {
    import { nouse } from "./static3.js"
}

// 報錯
import { "no" + "use" } from "./static3.js"

因為 import 是靜態(tài)執(zhí)行的,所以在靜態(tài)(詞法)分析階段,是沒法得到表達(dá)式或者變量的值的。

但是為了解決這個問題,因為了 import() 這個函數(shù),這個算擴(kuò)展內(nèi)容吧,寫太多了我怕沒人看完了,后面會有擴(kuò)展閱讀鏈接。

動態(tài)關(guān)聯(lián)

所謂的動態(tài)關(guān)聯(lián),其實就是一種綁定關(guān)系, 這是 ES6 非常重要的特性,一定仔細(xì)閱讀。

在 ES6 的模塊中,輸出的不是對象的拷貝,不管是引用類型還是基本類型, 都是動態(tài)關(guān)聯(lián)模塊中的值,。

// dynamic1.js
export let name = "桃翁";

export function setName(name) {
    name = name;
}

// dynamic2.js
import { name, setName } from "./dynamic1.js"

console.log(name); // 桃翁

setName("不要臉");

console.log(name); // 不要臉

奇跡般的發(fā)現(xiàn)在 dynamic2.js 模塊中可以修改 dynamic1.js 模塊里面的值, 并且反應(yīng)到 name 綁定上(這個是重點,這個反應(yīng)到了消費者模塊), 所以我們把導(dǎo)入的變量叫做綁定。

在生產(chǎn)者模塊導(dǎo)出的變量與消費者模塊導(dǎo)入的變量會有一個綁定關(guān)系,無論前者或者后者發(fā)生改變,都會互相影響。

注意區(qū)分在一個文件或模塊中基本類型的賦值,兩者是互不影響的。
模塊不會重復(fù)執(zhí)行

這個特性比較好理解,就是如果從一個生產(chǎn)者模塊中分別導(dǎo)入綁定,而不是一次性導(dǎo)入,生產(chǎn)者模塊不會執(zhí)行多次。

// noRepeat1.js
export let name = "桃翁";

export let age = "22";

console.log("我正在執(zhí)行。。。");

// noRepeat2.js
import { name } from "./noRepeat1.js";
import { age } from "./noRepeat1.js";

console.log(name);
console.log(age);

// 結(jié)果
// 我正在執(zhí)行。。。
// 桃翁
// 22

雖然導(dǎo)入了兩次,但是 noRepeat1.js 只有執(zhí)行一次。若同一個應(yīng)用(注意是同一個應(yīng)用不是模塊)中導(dǎo)入同一個模塊,則那些模塊都會使用一個模塊實例,意思就是說是一個單例。

后記

碼字不易,寫技術(shù)文章是真的累,作者花的時間至少是讀者讀的時間的十倍。在此想到阮老師寫了那么多文章,不知道是花了多少時間,竟然還有人這么恨他,攻擊他的網(wǎng)站。

我在文章中給我公眾號打了很多廣告,在此抱個歉,剛運營的公眾號,需要拉點粉絲,不喜歡的注重內(nèi)容就好。

拓展

原生ECMAScript模塊: 動態(tài) import()

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

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

相關(guān)文章

  • Vue ES6 Jade Scss Webpack Gulp

    摘要:主有前端后端,并加,各一名。本著工欲善其事,必先利其器的理念,一直以來在工作效率這塊,略懷執(zhí)念一個問題不應(yīng)該被解決兩次。下圖為開發(fā)項目機(jī)制所涉及到的插件工欲善其事,必先利其器,語言,框架皆可以歸結(jié)為器而不當(dāng)僅局限于開發(fā)工具以及機(jī)。 原文鏈接: http://www.jeffjade.com/2016/05/08/106-vue-es6-jade-scss-webpack-gulp/ 一...

    rickchen 評論0 收藏0
  • 2017-08-15 前端日報

    摘要:前端日報精選變量聲明與賦值值傳遞淺拷貝與深拷貝詳解淺談自適應(yīng)學(xué)習(xí)比你想象的要簡單常見排序算法之實現(xiàn)世界萬物誕生記中文深入理解筆記與異步編程譯不可變和中的知乎專欄譯怎樣避免開發(fā)時的深坑瘋狂的技術(shù)宅在翻譯網(wǎng)格布局掘金詳解改變模糊度亮 2017-08-15 前端日報 精選 ES6 變量聲明與賦值:值傳遞、淺拷貝與深拷貝詳解淺談web自適應(yīng)學(xué)習(xí) React.js 比你想象的要簡單常見排序算法之...

    xinhaip 評論0 收藏0
  • javascript知識點

    摘要:模塊化是隨著前端技術(shù)的發(fā)展,前端代碼爆炸式增長后,工程化所采取的必然措施。目前模塊化的思想分為和。特別指出,事件不等同于異步,回調(diào)也不等同于異步。將會討論安全的類型檢測惰性載入函數(shù)凍結(jié)對象定時器等話題。 Vue.js 前后端同構(gòu)方案之準(zhǔn)備篇——代碼優(yōu)化 目前 Vue.js 的火爆不亞于當(dāng)初的 React,本人對寫代碼有潔癖,代碼也是藝術(shù)。此篇是準(zhǔn)備篇,工欲善其事,必先利其器。我們先在代...

    Karrdy 評論0 收藏0
  • 2017-08-30 前端日報

    摘要:前端日報精選精讀個最佳特性翻譯輕量級函數(shù)式編程第章組合函數(shù)之組件類型寫的姿勢中文周二放送面試題詳解知乎專欄譯原生值得學(xué)習(xí)嗎答案是肯定的掘金個超贊的視覺效果眾成翻譯布局時常見總結(jié)騰訊前端團(tuán)隊社區(qū)歸檔打地鼠入門學(xué)習(xí)書籍 2017-08-30 前端日報 精選 精讀《Web fonts: when you need them, when you don’t》10個最佳ES6特性翻譯 -《Jav...

    weizx 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<