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

資訊專欄INFORMATION COLUMN

ES6模塊默認(rèn)導(dǎo)出和變量綁定(Default Exports and Exporting bindi

Benedict Evans / 3037人閱讀

摘要:背景現(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

相關(guān)文章

  • [譯]ES6 模塊化入門

    摘要:當(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...

    shmily 評論0 收藏0
  • import and export 之 (export)

    摘要:和必須始終顯示在其各自用法的頂級范圍中。也就是說不可以在條件中放置或它們必須放在所有塊和函數(shù)之外。不幸的是,它存在一些缺點(diǎn),并正式地不鼓勵(lì)這樣做。用戶可以另外手動將和列為命名導(dǎo)入,如果他們想要的話。 ES6提供了兩個(gè)關(guān)鍵字import導(dǎo)入和export導(dǎo)出,語法上有些差別。!important: import和export必須,始終顯示在,其各自用法的,頂級范圍中。也就是說不可以在if...

    weij 評論0 收藏0
  • [譯]JavaScript ES6模塊指南

    摘要:模塊可以導(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的...

    yimo 評論0 收藏0
  • ES6中文手冊、ES6 Cheatsheet

    摘要:盲目使用替換后可能會導(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í)行...

    Cristalven 評論0 收藏0
  • 深入 CommonJs 與 ES6 Module

    摘要:目前主流的模塊規(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...

    sanyang 評論0 收藏0

發(fā)表評論

0條評論

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