我們前端在開發過程中經常會遇到匯入匯出功能, 在匯入時,有時候是require,有時候是import 在匯出時,有時候是exports,module.exports,有時候是export,export default 今天我們對這些內容進行簡單的介紹
import,export,export default
import,export,export default屬於ES6規範
import
import 是在編譯過程中執行 也就是說是在程式碼執行前執行, 比如說,import後面的路徑寫錯了,在執行程式碼前就會拋錯, 在編寫程式碼時,import不是一定要寫在js的最前面 import命令具有提升效果,會提升到整個模組的頭部,首先執行。(是在編譯階段執行的) import是靜態執行的 因為import是靜態執行的,不能使用表示式和變數,即在執行時才能拿到結果的語法結構 比如,不能再if和else中使用import 再比如,import後的from的路徑,可以是相對路徑,可以是絕對路徑,但是不能是根據變數得來的路徑
//import 路徑不可以為變數
var url = './output'
import {
a,
b
} from url//這麼寫會報錯
//------------------
//import 的引入與否不能和程式碼邏輯向關聯
let status= true
if(status){
import {
a,
b
} from url//這麼寫會報錯
}
複製程式碼
import可以使用as進行重新命名 import 的有很多種匯入方式,
import foo from './output'
import {b as B} from './output'
import * as OBj from './output'
import {a} from './output'
import {b as BB} from './output'
import c, {d} from './output'
複製程式碼
匯入的方式和匯出有些關聯,我們在下面說匯出的時候,對以上這些匯入方式進行逐一介紹
exoprt和export default
將exoprt和export default放在一起,因為它們關聯性很大 簡單說:export是匯出,export default是預設匯出 一個模組可以有多個export,但是隻能有一個export default,export default可以和多個export共存 export default 為預設匯出,匯出的是用{}包裹的一個物件,以鍵值對的形式存在 匯出的方式不同,匯入的方式也就不同, 所以建議同一個專案下使用同一的匯入匯出方式,方便開發 export default解構以後就是export 通過兩個直觀的demo看下export和export default的區別 先看一段程式碼(export) output.js
const a = 'valueA1'
export {a}
複製程式碼
input.js
import {a} from './output.js'//此處的import {a}和export {a},兩個a是一一對應關係
console.log(a)//=>valueA1
複製程式碼
留意上面的程式碼其中export {a}匯出的a,和import {a}匯入的a是同一個a 再看一段程式碼(export default)
const a = 'valueA1'
export default{a}
複製程式碼
input.js
import a from './output.js'//此處的a和export default{a},不是一個a,
console.log(a)//=>{ a: 'valueA1' }
複製程式碼
看下export default的栗子中的input.js,我們稍作改動
import abc from './output.js'//此處的a和export default{a},不是一個a,
console.log(abc)//=>{ a: 'valueA1' }
複製程式碼
我們做了些改動,但是輸出沒有變化,import匯入的是export default下的物件,叫什麼名字都可以,因為只會存在一個export default
exoprt和export default混合使用
exoprt和export default在同一個模組中同時使用,是支援的,雖然我們一般不會這麼做 看一個栗子 output.js
const a = 'valueA1'
const b = 'valueB1'
const c = 'valueC1'
const d = 'valueD1'
function foo() {
console.log(`foo執行,c的值是${c}`);
}
export {a}
export {b}
export default { b,d,foo}
複製程式碼
input.js
import obj, {a,b } from './output'
console.log(a); //=>valueA1
console.log(b); //=>valueB1
console.log(obj); //=>{ b: 'valueB1', d: 'valueD1', foo: [Function: foo] }
複製程式碼
as 重新命名
通過 exoprt和export default匯出的在import引入時都支援通過as進行重新命名 看個栗子 還是上面的那個output.js
const a = 'valueA1'
const b = 'valueB1'
const c = 'valueC1'
const d = 'valueD1'
function foo() {
console.log(`foo執行,c的值是${c}`);
}
export {a}
export {b}
export default { b,d,foo}
複製程式碼
input.js
import {a as A} from './output'
import {* as A} from './output'//這是不支援的
import * as obj from './output'
console.log(A); //=>valueA1
console.log(obj); //=>{ a: 'valueA1',default: { b: 'valueB1', d: 'valueD1', foo: [Function: foo] },b: 'valueB1' }
複製程式碼
as後面的變數是你要在input.js中使用的 重點看這一部分
import {* as A} from './output'//這是不支援的
import * as obj from './output'
console.log(obj); //=>{ a: 'valueA1',default: { b: 'valueB1', d: 'valueD1', foo: [Function: foo] },b: 'valueB1' }
複製程式碼
- 代表了所有,包括了export和export default匯出的 我們之前說import{}和export{},是一一對應關係,所以在export匯出的,在import{}不支援使用* 關於 import,export,export default先介紹到這裡,我們繼續
require,exports,module.exports(記得後面的s)
這是 AMD規範
require
require是執行時呼叫,所以require理論上可以運用在程式碼的任何地方
require支援動態引入
例如,這樣是支援的
let flag = true
if (flag) {
const a = require('./output.js')
console.log(a); //支援
}
複製程式碼
require路徑支援變數
let flag = true
let url = './output.js'
if (flag) {
const a = require(url)
console.log(a); //支援
}
複製程式碼
通過require引入,是一個賦值的過程
exports 與 module.exports
根據AMD規範 每個檔案就是一個模組,有自己的作用域。在一個檔案裡面定義的變數、函式、類,都是私有的,對其他檔案不可見。 每個模組內部,module變數代表當前模組。這個變數是一個物件,它的exports屬性(即module.exports)是對外的介面。載入某個模組,其實是載入該模組的module.exports屬性。
為了方便,Node為每個模組提供一個exports變數,指向module.exports。這等同在每個模組頭部,有一行這樣的命令。
const exports = module.exports;
複製程式碼
所以說 以下兩種寫法等價
exports.a ='valueA1'
module.exports.a='valueA1'
複製程式碼
前面說在每個模組提供一個exports變數,指向module.exports。 所以不能直接給exports賦值,賦值會覆蓋
const exports = module.exports;
複製程式碼
直接給exports賦值會切斷exports和 module.exports的關聯關係 看一個栗子 output.js
const a = 'valueA1'
const b = 'valueB1'
const c = 'valueC1'
module.exports = { c}
exports.b = b//當直接給 module.exports時,exports會失效
module.exports.a = a
複製程式碼
input.js
const obj = require('./output.js')
console.log(obj); //=>{ c: 'valueC1', a: 'valueA1' }
複製程式碼
繼續看程式碼 output.js
//部分省略
exports.b = b//這樣可以生效
module.exports.a = a
複製程式碼
input.js
const obj = require('./output.js')
console.log(obj); //=>{ b: 'valueB1', a: 'valueA1' }
複製程式碼
再看一段程式碼 output.js
//部分省略
module.exports = { c}
module.exports.a = a
複製程式碼
input.js
const obj = require('./output.js')
console.log(obj); //=>{ c: 'valueC1', a: 'valueA1' }
複製程式碼
當直接給 module.exports時,exports會失效
交叉使用
在ES6中export default 匯出的是一個物件 在AMD中exports和module.exports匯出的也都是一個物件 所以如果你手中的專案程式碼支援兩種規範,那麼事可以交叉使用的(當然不建議這麼去做) 通過export匯出的不一定是一個物件
demo1
output.js
//部分省略
module.exports = { c}
module.exports.a = a
複製程式碼
inputj.s
import obj from './output'
import {a} from './output'
console.log(a);//=>valueA1
console.log(obj);//=>{ c: 'valueC1', a: 'valueA1' }
複製程式碼
demo2
output.js
const a = 'valueA1'
const b = 'valueB1'
const c = 'valueC1'
function foo() {
console.log(`foo執行,c的值是${c}`);
}
export {a}
export default {b,c,foo}
export {b}
複製程式碼
input.js
const a = require('./output.js')
console.log(a); //=>{ a: 'valueA1',default: { b: 'valueB1', c: 'valueC1', foo: [Function: foo] }, b: 'valueB1' }
複製程式碼
總結
- require,exports,module.exports屬於AMD規範,import,export,export default屬於ES6規範
- require支援動態匯入,動態匹配路徑,import對這兩者都不支援
- require是執行時呼叫,import是編譯時呼叫
- require是賦值過程,import是解構過程
- 對於export和export default 不同的使用方式,import就要採取不同的引用方式,主要區別在於是否存在{},export匯出的,import匯入需要{},匯入和匯出一一對應,export default預設匯出的,import匯入不需要{}
- exports是module.exports一種簡寫形式,不能直接給exports賦值
- 當直接給module.exports賦值時,exports會失效
更多前端資源請關注微信公眾號“前端陌上寒”
參考連結 關於import與require的區別
module.exports和exports和export和export default的區別,import和require的區別