欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

探索export導(dǎo)出一個字面量會報錯export?default不會報錯

 更新時間:2024年01月10日 10:28:12   作者:每天寫一個小BUG  
這篇文章主要為大家介紹了export導(dǎo)出一個字面量會報錯而export?default不會報錯的問題探索解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

核心

其實總的來說就是 export 導(dǎo)出的是變量的句柄(或者說符號綁定、近似于 C 語言里面的指針,C++里面的變量別名),而 export default 導(dǎo)出的是變量的值。

需要注意的是:模塊里面的內(nèi)容只能在模塊內(nèi)部修改,模塊外部只能使用。esModule在語法層面做了一層淺層的保護(hù)(即將import導(dǎo)入的變量聲明為常量)

而變量的句柄必須通過 var、let、const、function 這些關(guān)鍵字聲明才可以由 js 引擎生成,而值(或者說數(shù)據(jù))可以通過變量運(yùn)算或者字面量直接生成。

下面是測試用例:

// a.js
export let a = 'a'

export let objA = { a: 'a' }

let defaultA = 1
export default defaultA

export function fn(str) {
    a = str
    defaultA = str
}
// test1.js
import b, { a, fn, objA } from './a.js'
console.log(a, '---', b, '---', objA.a, '---', 'test1.js')
setTimeout(() => {
    objA.a = 'hello world'
    fn('hello world')
    console.log(a, '---', b, '---', objA.a, '---', 'test1.js')
})
// test2.js
import b, { a, objA } from './a.js'
console.log(a, '---', b, '---', objA.a, '---', 'test2.js')
setTimeout(() => {
    console.log(a, '---', b, '---', objA.a, '---', 'test2.js')
}, 100)
// main.js
import './test1.js'
import './test2.js'

運(yùn)行main.js,輸出結(jié)果如下:

分析

  • 通過 a 值的變化可以看出,在 test1.js 中的修改會影響到 test2.js 中 a 的值,驗證我們說的導(dǎo)出句柄這個觀點(diǎn)。

  • 通過 b 的運(yùn)行結(jié)果可以驗證 export default 導(dǎo)出變量的值的觀點(diǎn)。

  • 通過 objA.a 的運(yùn)行結(jié)果可以驗證淺層保護(hù)的觀點(diǎn),其實和const obj = {},我們可以修改 obj 的屬性,只要不對 obj 重新賦值都是允許的是同一個邏輯。

如果看到這里你完全理解上面的內(nèi)容,那么下面的內(nèi)容就建議你跳過了,因為下面是一些細(xì)節(jié)的展開和補(bǔ)充,對你來說可能會有些啰嗦和浪費(fèi)時間。如果上面的內(nèi)容你還不是很理解,那么可以再看看下面的內(nèi)容,看看是否對你有幫助。

那我們就按照以下幾個方面具體來講講這個問題,順便再做一些擴(kuò)展和補(bǔ)充。

  • 1、句柄和值

  • 2、ES module 和 commonJs

  • 3、關(guān)于 Tree Shaking 的思考

句柄和值

其實句柄這個詞我個人理解為權(quán)限,獲得句柄就是獲得某種東西的操作權(quán)限,比如拿到文件句柄就可以對文件進(jìn)行讀寫操作。其實怎么理解都可以,只不過我引用了句柄這個詞語。我想說明的是 export 導(dǎo)出的是一個變量的句柄(或者說是引用),這個概念類似于 C 語言里面的指針,C++里面的變量別名。也就是說,導(dǎo)入模塊在拿到這個變量時,對這個變量的操作實際上是在操作原來的導(dǎo)出變量本身。

而值其實就是一份數(shù)據(jù),也可以理解成 export default 導(dǎo)出的是一份數(shù)據(jù)拷貝。

擴(kuò)展

一、js 中聲明變量的幾種方式

  • var、let、const
  • function
  • class
  • import(準(zhǔn)確來講并沒有創(chuàng)建新的變量,但是這個關(guān)鍵字導(dǎo)入了被導(dǎo)入模塊的變量的引用,而在 js 引擎層面并沒有聲明新的變量)

注意:

// main.js
export { default as a } from 'xxx/a.xxx'

這種情況下,a 這個變量在 main.js 這個模塊中是訪問不到的。如果想要在 main.js 這個模塊中訪問到 a 模塊,需要使用 import 語句進(jìn)行導(dǎo)入,再使用 export 暴露給外界。

// main.js
import a from 'xxx/a.xxx'
export a

二、堆棧內(nèi)存

  • 堆內(nèi)存:存放引用類型的數(shù)據(jù),例如對象、數(shù)組等

  • 棧內(nèi)存:存放基本數(shù)據(jù)類型和引用類型的地址(存放占用空間固定的數(shù)據(jù)

ES module 和 CommonJS

1、實現(xiàn)層面

ES module 和 CommonJS 比較大的一個區(qū)別就是一個是官方規(guī)范,一個是社區(qū)規(guī)范。官方規(guī)范自然就能的到 js 語法層面的實現(xiàn)支持,而社區(qū)規(guī)范只能通過在現(xiàn)有的語法基礎(chǔ)上進(jìn)行擴(kuò)展來實現(xiàn)。

2、單獨(dú)導(dǎo)出和默認(rèn)導(dǎo)出

其實 CommonJS 的實現(xiàn)也特別簡單,看一眼 webpack 的打包結(jié)果就知道了。核心原理就是將一個個模塊放到函數(shù)中運(yùn)行,這樣利用函數(shù)作用域的特點(diǎn),就可以實現(xiàn)模塊之間的環(huán)境隔離。所以在 CommonJS 中,module.exports 和 exports 本質(zhì)上就是同一個對象,這個對象就是這個模塊(函數(shù))運(yùn)行時 return 的對象。

而 ES module 則不然,export 和 export default 有著本質(zhì)的差別,那就是一個導(dǎo)出變量的句柄,一個導(dǎo)出變量的值。

擴(kuò)展(關(guān)于 export 導(dǎo)出的細(xì)節(jié))

關(guān)于 export 導(dǎo)出,出了這種下面常用的方式:

// a.js
export let a = 1

還有一種方式:

// b.js
let b = 1
export { b }

而這兩種模塊的導(dǎo)入方式都是一樣:

import { a } from 'xx/a.js'
import { b } from 'xx/b.js'

既然前面說了,export 導(dǎo)出的是變量的句柄,那么顯然下面這種方式是要報錯的:

// b.js
export { b: 1 } // SyntaxError: Unexpected token ':'

因為導(dǎo)入方式一樣,那么很自然的我就想測試一下,我按照下面這種方式來測試一下看會不會產(chǎn)生沖突

let b = 1
export { b }
export let b = 2 // SyntaxError: Identifier 'b' has already been declared

很顯然使用 let、const 這樣的關(guān)鍵字會產(chǎn)生一個重復(fù)定義的沖突,那么我們再試一下另外一個可以讓我們多次重復(fù)聲明同一個變量的 var 關(guān)鍵字。

var b = 1
export { b }
export var b = 2 // SyntaxError: Duplicate export of 'b'

改成 var 之后,不會在一開始編輯器就提示我們錯誤了,而是在運(yùn)行時,報一個重復(fù)導(dǎo)出的錯誤。所以通過測試,這兩種 export 導(dǎo)出方式還是不會產(chǎn)生沖突的。

3、動態(tài)導(dǎo)入

CommonJS 動態(tài)導(dǎo)入就很簡單,其實就是運(yùn)行函數(shù)。其實 CommonJS 導(dǎo)入本身就是在運(yùn)行函數(shù),所以動態(tài)或者靜態(tài)其實都一樣。

const a = require('xxx/a.js')

ES module 動態(tài)導(dǎo)入,那就需要語法的支持,使用下面這種語法:

const a = await import('xxx/a.js')

關(guān)于 Tree Shaking 的思考

我們知道,ES module 是支持 Tree Shaking 的,但是 CommonJS 是不支持的。

其實 Tree Shaking 面臨的核心困難就是怎么確定一個函數(shù)或者模塊它是否包含副作用。如果寫的都是純函數(shù),那么 Tree Shaking 其實是很實現(xiàn)的。那么像有些函數(shù),在編譯時直接可以運(yùn)行函數(shù)得到調(diào)用結(jié)果,進(jìn)而在生產(chǎn)運(yùn)行時,直接省去求值的耗時。

所以 Tree Shaking 的核心是在于副作用的檢測,特別是在復(fù)雜的模塊引用關(guān)系里面,確定每個模塊里的某些內(nèi)容是否存在副作用。另外為了更好的 Tree Shaking,比較推薦的方案是使用 ES module,并且使用 export 導(dǎo)出,這方式可以更好的進(jìn)行 Tree Shaking。

以上就是探索export導(dǎo)出一個字面量會報錯export default不會報錯的詳細(xì)內(nèi)容,更多關(guān)于export導(dǎo)出字面量的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 微信小程序開發(fā)中var that =this的用法詳解

    微信小程序開發(fā)中var that =this的用法詳解

    這篇文章主要介紹了微信小程序開發(fā)中var that =this的用法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • 快速對接payjq的個人微信支付接口過程解析

    快速對接payjq的個人微信支付接口過程解析

    這篇文章主要介紹了快速對接payjq的個人微信支付接口過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-08-08
  • javascript 自定義事件初探

    javascript 自定義事件初探

    "事件機(jī)制可以使程序邏輯更加符合現(xiàn)實世界,在JavaScript 中很多對象都有自己的事件,例如按鈕就有onclick 事件,下拉列表框就有onchange 事件,通過這些事件可以方便編程。
    2009-08-08
  • 仿服務(wù)器端腳本方式的JS模板實現(xiàn)方法

    仿服務(wù)器端腳本方式的JS模板實現(xiàn)方法

    仿服務(wù)器端腳本方式的JS模板實現(xiàn)方法...
    2007-04-04
  • js原生日歷的實例(推薦)

    js原生日歷的實例(推薦)

    下面小編就為大家?guī)硪黄猨s原生日歷的實例(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • JavaScript實現(xiàn)職責(zé)鏈模式概述

    JavaScript實現(xiàn)職責(zé)鏈模式概述

    這篇文章主要介紹了JavaScript實現(xiàn)職責(zé)鏈模式概述,詳細(xì)的介紹了什么是職責(zé)鏈模式和實現(xiàn)方式,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • 收集前端面試題之url、href、src

    收集前端面試題之url、href、src

    本文給大家分享小編日常收集整理的關(guān)于前端面試題之url、href、src的語法規(guī)則及基本概念,非常不錯,具有參考借鑒價值,需要的朋友參考下吧
    2018-03-03
  • JS簡易計算器實例講解

    JS簡易計算器實例講解

    這篇文章主要為大家詳細(xì)介紹了JS簡易計算器實例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • JS實現(xiàn)圖片放大縮小的方法

    JS實現(xiàn)圖片放大縮小的方法

    這篇文章主要介紹了JS實現(xiàn)圖片放大縮小的方法,結(jié)合實例形式分析了javascript動態(tài)操作頁面元素屬性的相關(guān)技巧,需要的朋友可以參考下
    2017-02-02
  • js中Generator函數(shù)的深入講解

    js中Generator函數(shù)的深入講解

    這篇文章主要給大家介紹了關(guān)于js中Generator函數(shù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Javascript具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04

最新評論