前言
上一篇发出之后,发现还有些问题没有说完,于是出了该续篇。
怪诞的 export
之前谈到过,这种没有 key 值没有使用默认的导出的无效的:
const text = "index.js"
// error
export text
转换一下,便成了这样:
export "index.js"
可是这么写,又行了:
export const text = "index.js"
在这种情况下,变量名就当成了 key,没有转换的那么彻底。
也是有点摸不着头脑,这两者的差别有多大呢,好歹说,我是取了一个变量名在那里,没有直接写成 export "index.js"
,变量名当作 key 不就好了。
再说你也不是 export default
,作为 expor
就不能宽容点吗,可问题,比想象的还要严重。
export
批量导出
再看一个,以对象形式批量导出。
const text = "index.js"
export {
text
}
可是,如果直接写一个值在那,又又又不行了。
const text = "index.js"
// error
export {
text,
a: 10
}
默认导出可以这样玩是另一回事,毕竟别人都能直接导出简单类型,还有什么是做不到的。
那咱们讲点道理吧,这种常规键值对形式的导出为什么不可用。
而且要求非常的变态,这里只允许存在缩写,也就是说,变量名是什么,key 就是什么,想重命名导出都做不到。
const text = "index.js"
// error
export {
newText: text
}
这把疑问的档次提升了好几级,直接写一个值在那里有问题,我可以当作,不可以导出一个常量,最起码要用变量遮盖一下,哪怕是用 const
声明。那么现在重命名 key,导出一个现有的变量,又遭到了反对,这就没法谈了。
本身也不会有人直接修改导入的值,而且这种行为是被完全禁止的
那这样吧,我玩迂回战术,先准备一个对象变量,再导出,然而还是失败了。
const text = "index.js"
const obj = {
text
}
// error
export obj
不过问题突然明了了,它不是针对某一个值,而是 everyone。想导出这个变量,也得使用变量声明。
const text = "index.js"
// OK
export const obj = {
newText: text
}
好家伙的,也就是与 export default
相反,一个不能使用声明,一个必须要声明。可是又提供了 export {}
批量导出的写法,当中就有意思了很多。
解谜
我尝试着去寻找当中不能这样做的原因是什么,或者说解决方案。重新翻阅阮老师的《ES6 入门》,找到了我想到的答案。
首先,不能将 export {}
的动作,当成 “导出一个对象”。这是一个向外暴露的接口,规则就由 export
激活。这么说,如果导出的是一个对象,另一边如何接收?其实和前面导出简单类型一样,需要 key 认领,就算是引用类型也不能这么玩,除非是 export default
。
理解上一点之后,再看重命名导出就好说了。它不是对象,只是在表示形式上很像。重命名可以有,但是不能这么写,而是要使用 as
,正常的对象那可用不了 as
。
const text = "index.js"
// OK
export {
text as newText
}
最后说一下,导出的动作请保持统一,有两种形式,选其一即可,最好不要混合。
const a = "a"
const b = "b"
export {
a,
b
}
export const a = "a"
export const b = "b"
其他导出姿势
有一种方式,适合中转站导出,export *
,以一个示例来说明:
// a.js
export const a = "a"
export const b = "b"
export default {
a,
b
}
// b.js
export * from "./a.js"
// index.js
import * as b from "./b.js"
// { a: "a", b: "b"}
console.log(b)
这种导出并不附带默认导出,需要额外补充。
// b.js
export * from "./a.js"
export { default } from "./a.js"
这种做法会导致 b.js
的默认导出与 a.js
同步,可是不能这么写。
// b.js
export * from "./a.js"
// bad
export default from "./a.js"
相比之下,这种写法更容易理解一点,当然它是不存在的。