摘要:例如我們導(dǎo)入模塊,可以這么導(dǎo)入桃翁歡迎關(guān)注公眾號(hào)前端桃園報(bào)錯(cuò)不能定義相同名字變量報(bào)錯(cuò),不能重新賦值小豬可以看到導(dǎo)入綁定這里不理解綁定,文章后面會(huì)解釋時(shí),形式類似于對(duì)象解構(gòu),但實(shí)際上并無關(guān)聯(lián)。
歡迎訪問個(gè)人站點(diǎn)簡(jiǎn)介 何為模塊
一個(gè)模塊只不過是一個(gè)寫在文件中的 JavaScript 代碼塊。
模塊中的函數(shù)或變量不可用,除非模塊文件導(dǎo)出它們。
簡(jiǎn)單地說,這些模塊可以幫助你在你的模塊中編寫代碼,并且只公開應(yīng)該被你的代碼的其他部分訪問的代碼部分。
為什么要使用模塊增加可維護(hù)性:由于每個(gè)模塊都是獨(dú)立的,每個(gè)人寫的代碼是不會(huì)相互影響的,在維護(hù)代碼的時(shí)候很好排查是哪個(gè)模塊出錯(cuò)。
可復(fù)用性:在日常的開發(fā)中,特別是大點(diǎn)的項(xiàng)目,代碼的可復(fù)用性就更重要了,也許你會(huì)用復(fù)制粘貼的形式,但是直接一個(gè) import 命令就可以搞定,豈不快哉。
避免命名污染:在 javascript 腳本中,所有的 js 文件的頂級(jí)作用域創(chuàng)建的變量,會(huì)被添加到共享的全局作用域,這就會(huì)導(dǎo)致不同的人開發(fā)的代碼可能會(huì)有相同的變量名,導(dǎo)致變量名污染。
如何使用 導(dǎo)出模塊導(dǎo)出模塊所用的命令是 export。
前面也提到一個(gè)模塊就是一個(gè) javascript 文件,在這個(gè)模塊中定義的變量,外部是無法獲取到的,只有通過 export 導(dǎo)出的變量其他模塊才可以用
最簡(jiǎn)單的導(dǎo)出方式就是在聲明的變量、函數(shù)、類前面加一個(gè) export
// export1.js // 導(dǎo)出變量 export let name = "桃翁"; // 導(dǎo)出函數(shù) export function print() { console.log("歡迎關(guān)注公眾號(hào):前端桃園"); } // 導(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)做這個(gè)模塊的私有變量,其他模塊是訪問不到的。
除了上面那種導(dǎo)出方式,還有另外一種
// export2.js // 導(dǎo)出變量 let name = "桃翁"; // 導(dǎo)出函數(shù) function print() { return "歡迎關(guān)注公眾號(hào):前端桃園"; } // 導(dǎo)出類 class Person { constructor(name) { this.name = name; } } // 私有函數(shù) function privateFunction () { return "我是私有函數(shù),外部訪問不了我"; } export { name, print, Person }
上面這種寫法導(dǎo)入一組變量,與 export1.js 是等價(jià)的。
導(dǎo)入模塊導(dǎo)入的模塊可以理解為是生產(chǎn)者(或者服務(wù)的提供者),而使用導(dǎo)入的模塊的模塊就是消費(fèi)者。
導(dǎo)入模塊的命令是 import, import 的基本形式如下:
import { var1, var2 } from "./example.js"
import 語句包含兩部分:一是導(dǎo)入需要的標(biāo)識(shí)符,二是模塊的來源。
注意:瀏覽器中模塊來源要以「/」或者 「./」 或者 「../」開頭 或者 url 形式,不然會(huì)報(bào)錯(cuò)。
例如我們導(dǎo)入 export1.js 模塊,可以這么導(dǎo)入
// import1.js import { name, print, Person } from "./export1.js"; console.log(name); // 桃翁 console.log(print()); // 歡迎關(guān)注公眾號(hào):前端桃園 // 報(bào)錯(cuò), 不能定義相同名字變量 let name = 2333; // 報(bào)錯(cuò),不能重新賦值 name = "小豬";
可以看到導(dǎo)入綁定(這里不理解綁定,文章后面會(huì)解釋)時(shí),形式類似于對(duì)象解構(gòu),但實(shí)際上并無關(guān)聯(lián)。
當(dāng)導(dǎo)入綁定的時(shí)候,綁定類似于使用了 const 定義,意味著不能定義相同的變量名,但是沒有暫時(shí)性死區(qū)特性(但是在 深入理解ES6 這本書里面說是有暫時(shí)性死區(qū)限制,我在 chrome 上測(cè)試了的,讀者希望也去試下,到底受不受限制)。
let name = 2333;
上面這行代碼會(huì)報(bào)錯(cuò)。
命名空間導(dǎo)入這種導(dǎo)入方式是把整個(gè)生產(chǎn)者模塊當(dāng)做單一對(duì)象導(dǎo)入,所有的導(dǎo)出被當(dāng)做對(duì)象的屬性。
// import2.js import * as namespace from "./export1.js" console.log(namespace.name); // 桃翁 console.log(namespace.print()); // 歡迎關(guān)注公眾號(hào):前端桃園重命名導(dǎo)入導(dǎo)出
有時(shí)候你并不想導(dǎo)出變量的原名稱,需要重新命名,這個(gè)時(shí)候只需要使用 as 關(guān)鍵字來制定新的名字即可。
重命名導(dǎo)出// export3.js function print() { return "歡迎關(guān)注公眾號(hào):前端桃園"; } 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)注公眾號(hào):前端桃園
此代碼導(dǎo)入 advertising 函數(shù)并重命名為了 print ,這意味著此模塊中 advertising 標(biāo)識(shí)符不存在了。
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)注公眾號(hào):前端桃園"; } // 第二種默認(rèn)導(dǎo)出方式 function print() { return "歡迎關(guān)注公眾號(hào):前端桃園"; } export default print; // 第三種默認(rèn)導(dǎo)出方式 function print() { return "歡迎關(guān)注公眾號(hào):前端桃園"; } export { print as default }
default 這個(gè)關(guān)鍵字在 JS 中具有特殊含義,既可以作為同命名導(dǎo)出,又標(biāo)明了模塊需要使用默認(rèn)值。
注意: 一個(gè)模塊中只能有一個(gè)默認(rèn)導(dǎo)出。默認(rèn)導(dǎo)入
默認(rèn)導(dǎo)入和一般的導(dǎo)入不同之處就是不需要寫大括號(hào)了,看起來更簡(jiǎn)潔。
把上面 defaultExport.js 模塊導(dǎo)出的作為例子
import print from "./defaultExport.js" console.log(print()); // 歡迎關(guān)注公眾號(hào):前端桃園
那如果既有默認(rèn)的又有非默認(rèn)的怎么導(dǎo)入呢?看例子就明白了
// defaultImport1.js let name = "桃翁"; function print() { return "歡迎關(guān)注公眾號(hào):前端桃園"; } export { name, print as default }
// defaultImport2.js import print, { name } from "./defaultImport1.js" console.log(print()); // 歡迎關(guān)注公眾號(hào):前端桃園 console.log(name); // 桃翁
混合導(dǎo)入需要把默認(rèn)導(dǎo)入的名稱放在最前面,然后用逗號(hào)和后面非默認(rèn)導(dǎo)出的分割開。
思考了很久是否應(yīng)該加上進(jìn)階內(nèi)容,本來是想寫入門級(jí)系列的,但是想了想,還是都寫進(jìn)來吧,入門的看入門前面基礎(chǔ),深入理解的看進(jìn)階。進(jìn)階
進(jìn)階部分主要介紹 模塊的幾個(gè)特性
靜態(tài)執(zhí)行
動(dòng)態(tài)關(guān)聯(lián)
模塊不會(huì)重復(fù)執(zhí)行
靜態(tài)執(zhí)行所謂靜態(tài)執(zhí)行其實(shí)就是在編譯階段就需要確定模塊的依賴關(guān)系,那么就會(huì)出現(xiàn) import 命令會(huì)優(yōu)先于模塊其他內(nèi)容的執(zhí)行,會(huì)提前到編譯階段執(zhí)行。
// static1.js console.log("佩奇"); import { nouse } from "./static2.js" // static2.js export function nouse() { return "我是不需要的"; } console.log("小豬");
可以看到最后輸出的應(yīng)該是「小豬」先輸出,而「佩奇」后輸出,可以得出雖然 static2.js 在后面引入,但是會(huì)被提升到模塊的最前面先執(zhí)行。
這也是我前面所說的不受暫時(shí)性死區(qū)原因之一,在這里可以寫一個(gè)例子試試:
// static3.js console.log(nouse()); import { nouse } from "./static2.js" // 結(jié)果: // 小豬 // 我是不需要的
經(jīng)檢驗(yàn)確實(shí)是可以在 import 之前使用導(dǎo)入的綁定。
靜態(tài)執(zhí)行還會(huì)導(dǎo)致一個(gè)問題,那就是不能動(dòng)態(tài)導(dǎo)入模塊。
// 報(bào)錯(cuò) if (flag) { import { nouse } from "./static3.js" } // 報(bào)錯(cuò) import { "no" + "use" } from "./static3.js"
因?yàn)?import 是靜態(tài)執(zhí)行的,所以在靜態(tài)(詞法)分析階段,是沒法得到表達(dá)式或者變量的值的。
但是為了解決這個(gè)問題,因?yàn)榱?import() 這個(gè)函數(shù),這個(gè)算擴(kuò)展內(nèi)容吧,寫太多了我怕沒人看完了,后面會(huì)有擴(kuò)展閱讀鏈接。
動(dòng)態(tài)關(guān)聯(lián)所謂的動(dòng)態(tài)關(guān)聯(lián),其實(shí)就是一種綁定關(guān)系, 這是 ES6 非常重要的特性,一定仔細(xì)閱讀。
在 ES6 的模塊中,輸出的不是對(duì)象的拷貝,不管是引用類型還是基本類型, 都是動(dòng)態(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 綁定上(這個(gè)是重點(diǎn),這個(gè)反應(yīng)到了消費(fèi)者模塊), 所以我們把導(dǎo)入的變量叫做綁定。
在生產(chǎn)者模塊導(dǎo)出的變量與消費(fèi)者模塊導(dǎo)入的變量會(huì)有一個(gè)綁定關(guān)系,無論前者或者后者發(fā)生改變,都會(huì)互相影響。
注意區(qū)分在一個(gè)文件或模塊中基本類型的賦值,兩者是互不影響的。模塊不會(huì)重復(fù)執(zhí)行
這個(gè)特性比較好理解,就是如果從一個(gè)生產(chǎn)者模塊中分別導(dǎo)入綁定,而不是一次性導(dǎo)入,生產(chǎn)者模塊不會(huì)執(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í)行一次。若同一個(gè)應(yīng)用(注意是同一個(gè)應(yīng)用不是模塊)中導(dǎo)入同一個(gè)模塊,則那些模塊都會(huì)使用一個(gè)模塊實(shí)例,意思就是說是一個(gè)單例。
后記碼字不易,寫技術(shù)文章是真的累,作者花的時(shí)間至少是讀者讀的時(shí)間的十倍。在此想到阮老師寫了那么多文章,不知道是花了多少時(shí)間,竟然還有人這么恨他,攻擊他的網(wǎng)站。
我在文章中給我公眾號(hào)打了很多廣告,在此抱個(gè)歉,剛運(yùn)營的公眾號(hào),需要拉點(diǎn)粉絲,不喜歡的注重內(nèi)容就好。
拓展原生ECMAScript模塊: 動(dòng)態(tài) import()
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/94977.html
摘要:主有前端后端,并加,各一名。本著工欲善其事,必先利其器的理念,一直以來在工作效率這塊,略懷執(zhí)念一個(gè)問題不應(yīng)該被解決兩次。下圖為開發(fā)項(xiàng)目機(jī)制所涉及到的插件工欲善其事,必先利其器,語言,框架皆可以歸結(jié)為器而不當(dāng)僅局限于開發(fā)工具以及機(jī)。 原文鏈接: http://www.jeffjade.com/2016/05/08/106-vue-es6-jade-scss-webpack-gulp/ 一...
摘要:前端日?qǐng)?bào)精選變量聲明與賦值值傳遞淺拷貝與深拷貝詳解淺談自適應(yīng)學(xué)習(xí)比你想象的要簡(jiǎn)單常見排序算法之實(shí)現(xiàn)世界萬物誕生記中文深入理解筆記與異步編程譯不可變和中的知乎專欄譯怎樣避免開發(fā)時(shí)的深坑瘋狂的技術(shù)宅在翻譯網(wǎng)格布局掘金詳解改變模糊度亮 2017-08-15 前端日?qǐng)?bào) 精選 ES6 變量聲明與賦值:值傳遞、淺拷貝與深拷貝詳解淺談web自適應(yīng)學(xué)習(xí) React.js 比你想象的要簡(jiǎn)單常見排序算法之...
摘要:模塊化是隨著前端技術(shù)的發(fā)展,前端代碼爆炸式增長(zhǎng)后,工程化所采取的必然措施。目前模塊化的思想分為和。特別指出,事件不等同于異步,回調(diào)也不等同于異步。將會(huì)討論安全的類型檢測(cè)惰性載入函數(shù)凍結(jié)對(duì)象定時(shí)器等話題。 Vue.js 前后端同構(gòu)方案之準(zhǔn)備篇——代碼優(yōu)化 目前 Vue.js 的火爆不亞于當(dāng)初的 React,本人對(duì)寫代碼有潔癖,代碼也是藝術(shù)。此篇是準(zhǔn)備篇,工欲善其事,必先利其器。我們先在代...
摘要:前端日?qǐng)?bào)精選精讀個(gè)最佳特性翻譯輕量級(jí)函數(shù)式編程第章組合函數(shù)之組件類型寫的姿勢(shì)中文周二放送面試題詳解知乎專欄譯原生值得學(xué)習(xí)嗎答案是肯定的掘金個(gè)超贊的視覺效果眾成翻譯布局時(shí)常見總結(jié)騰訊前端團(tuán)隊(duì)社區(qū)歸檔打地鼠入門學(xué)習(xí)書籍 2017-08-30 前端日?qǐng)?bào) 精選 精讀《Web fonts: when you need them, when you don’t》10個(gè)最佳ES6特性翻譯 -《Jav...
閱讀 3323·2023-04-26 00:58
閱讀 1273·2021-09-22 16:04
閱讀 3321·2021-09-02 15:11
閱讀 1566·2019-08-30 15:55
閱讀 2347·2019-08-30 15:55
閱讀 3269·2019-08-23 18:41
閱讀 3468·2019-08-23 18:18
閱讀 2758·2019-08-23 17:53