摘要:背景現(xiàn)在最主流的模塊機(jī)制是和。模塊模塊導(dǎo)出的變量始終指向的是模塊內(nèi)部的變量,使用時(shí)可以獲得此變量的最新值。我們叫導(dǎo)出綁定。但是在看對默認(rèn)導(dǎo)出代碼的轉(zhuǎn)換時(shí),發(fā)現(xiàn)實(shí)現(xiàn)并不使用。所以改了并不等于改了,自然的東西沒有變化。
背景
JavaScript 現(xiàn)在最主流的模塊機(jī)制是 commonjs 和 ES6 module。兩者不單是語法上有所區(qū)別,在加載的時(shí)候也有所不同,譬如 commonjs 是運(yùn)行時(shí)加載,ES6模塊是編譯時(shí)輸出接口的。還有一個(gè)重要的區(qū)別是 commonjs 導(dǎo)出的東西是值拷貝,而 ES6 模塊導(dǎo)出的東西是……暫時(shí)認(rèn)為是引用拷貝吧。具體表現(xiàn)出來的區(qū)別看下面的例子:
commonjs模塊// a.js var counter = 3; function incCounter() { counter++; } module.exports = { counter: counter, incCounter: incCounter, }; // main.js var mod = require("./a"); console.log(mod.counter); // 3 mod.incCounter(); console.log(mod.counter); // 3
可以看到 counter 在模塊內(nèi)部被改變,但是使用此模塊的代碼獲取 counter 始終是 export 時(shí)候的值,不會變。
ES6模塊// a.js export let counter = 3; export function incCounter() { counter++; } // main.js import { counter, incCounter } from "./a"; console.log(counter); // 3 incCounter(); console.log(counter); // 4
ES6 模塊導(dǎo)出的變量始終指向的是模塊內(nèi)部的變量,使用時(shí)可以獲得此變量的最新值。我們叫導(dǎo)出綁定:Exporting binding。
問題如果你去看 webpack 編譯后的實(shí)現(xiàn),它會把 counter 變量轉(zhuǎn)換成 counter 的 getter,這么就可以實(shí)現(xiàn)綁定的效果。但是在看 webpack 對默認(rèn)導(dǎo)出代碼的轉(zhuǎn)換時(shí),發(fā)現(xiàn)實(shí)現(xiàn)并不使用 getter。也就是說按這種實(shí)現(xiàn),使用 export default counter 是不會產(chǎn)生 Exporting binding??纯创a:
// a.js let counter = 3; export function incCounter() { counter++; } export default counter; // main.js import counter, { incCounter } from "./a"; console.log(counter); // 3 incCounter(); console.log(counter); // 3解釋
為什么會有這種效果?其實(shí) export default 是一種語法糖,當(dāng)模塊只有一個(gè)導(dǎo)出的時(shí)候,簡化寫代碼人的代碼量,我們把這個(gè)語法糖還原下:
// 語法糖 // myFunc.js function myFunc() {} export default myFunc; // main.js import myFunc from "./myFunc"; // 非語法糖 // myFunc.js function myFunc() {} export { myFunc as default }; // main.js import { default as myFunc } from "./myFunc";
也就是說把 export 的東西重命名/賦值給 default,再在 import 的時(shí)候把 default 重命名為你想要的名字。問題就出在這層語法糖的轉(zhuǎn)換上,規(guī)范對于 export default x 的行為有解釋,x 的類型不同,則行為不同:
有名字的函數(shù)和類export default function foo() {} export default class Bar {}
相當(dāng)于
function foo() {} export { foo as default }; class Bar {} export { Bar as default };沒有名字的函數(shù)和類
export default function () {} export default class {}
相當(dāng)于
function *default*() {} export { *default* as default }; class *default* {} export { *default* as default };
JS會把給匿名函數(shù)或類給一個(gè)內(nèi)部的變量*default*,然后再重命名為 default 導(dǎo)出。這個(gè)內(nèi)部變量是無法通過程序獲取到的。
原始類型export default 1; // --- 或者 --- let x = 4; export default x;
相當(dāng)于
let *default* = 1 export { *default* as default }; // --- 或者 --- let x = 4; let *default* = x; export { *default* as default };
當(dāng) export default x 中的 x 是沒有名字的函數(shù)或者類,又或者是原始類型,export binding 的是內(nèi)部變量*default* 并不是 x。所以改了 x 并不等于改了*default*,自然 import 的東西沒有變化。
參考文獻(xiàn)https://2ality.com/2015/07/es...
https://stackoverflow.com/que...
https://github.com/rollup/rol...
https://ponyfoo.com/articles/...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/106869.html
摘要:當(dāng)我們學(xué)習(xí)的模塊化,就會發(fā)現(xiàn)它的發(fā)展深受的影響。嚴(yán)格模式在模塊系統(tǒng)中,嚴(yán)格模式是默認(rèn)開啟的。同樣的,模塊內(nèi)部的聲明只在模塊內(nèi)部有效。在中,我們使用導(dǎo)入內(nèi)容在模塊中,我們只需要為導(dǎo)入的綁定起一個(gè)名字我們也可以導(dǎo)入具名導(dǎo)出的內(nèi)容。 ES6 模塊系統(tǒng) 在 ES6 之前,我們已經(jīng)知道了 RequireJS,AngularJS 的依賴注入,以及 CommonJS,具體可以看筆者的上一篇文章《JS...
摘要:和必須始終顯示在其各自用法的頂級范圍中。也就是說不可以在條件中放置或它們必須放在所有塊和函數(shù)之外。不幸的是,它存在一些缺點(diǎn),并正式地不鼓勵(lì)這樣做。用戶可以另外手動將和列為命名導(dǎo)入,如果他們想要的話。 ES6提供了兩個(gè)關(guān)鍵字import導(dǎo)入和export導(dǎo)出,語法上有些差別。!important: import和export必須,始終顯示在,其各自用法的,頂級范圍中。也就是說不可以在if...
摘要:模塊可以導(dǎo)入和導(dǎo)出各種類型的變量,如函數(shù),對象,字符串,數(shù)字,布爾值,等等。所以這可能會導(dǎo)致一些不符合預(yù)期的行為??勺兊幕绢愋椭翟趯?dǎo)入一些基本類型的值如數(shù)字,布爾值或字符串時(shí),可能會產(chǎn)生一個(gè)有趣的副作用。 前言 ECMAScript 2015(又稱ES6)提供了一個(gè)前端JavaScript缺失已久的特性 —— 模塊。ES2015中的模塊參考了CommonJS規(guī)范(目前Node.js的...
摘要:盲目使用替換后可能會導(dǎo)致預(yù)期意外的結(jié)果。在中,許多種方法來處理函數(shù)的參數(shù)默認(rèn)值,參數(shù)數(shù)量,參數(shù)命名。此外,處理后的值,無論是解決還是拒絕的結(jié)果值,都是不可改變的。 這是一個(gè) ES2015(ES6) 的Cheatsheet,其中包括提示、小技巧、最佳實(shí)踐和一些代碼片段,幫助你完成日復(fù)一日的開發(fā)工作。 Table of Contents var 與 let / const 聲明 代碼執(zhí)行...
摘要:目前主流的模塊規(guī)范模塊通用模塊如果你在文件頭部看到這樣的代碼,那么這個(gè)文件使用的就是規(guī)范實(shí)際上就是全局變量這三種風(fēng)格的結(jié)合這段代碼就是對當(dāng)前運(yùn)行環(huán)境的判斷,如果是環(huán)境就是使用規(guī)范,如果不是就判斷是否為環(huán)境,最后導(dǎo)出全局變量有了后我們的代碼和 目前主流的模塊規(guī)范 UMD CommonJs es6 module umd 模塊(通用模塊) (function (global, facto...
閱讀 1133·2021-09-29 09:35
閱讀 4783·2021-09-22 15:24
閱讀 1527·2021-07-25 21:37
閱讀 2241·2019-08-30 14:17
閱讀 1027·2019-08-30 13:56
閱讀 2459·2019-08-29 17:07
閱讀 1422·2019-08-29 12:44
閱讀 2759·2019-08-26 18:26