require 用來加載代碼骂删,而 exports 和 module.exports 則用來導(dǎo)出代碼。
很多新手可能會(huì)迷惑于 exports 和 module.exports 的區(qū)別德澈,為了更好的理解 exports 和 module.exports 的關(guān)系,我們先來鞏固下 js 的基礎(chǔ)固惯。示例:
test.js
var a = {name: 1}
var b = a
console.log(a)
console.log(b)
b.name = 2
console.log(a)
console.log(b)
var b = {name: 3}
console.log(a)
console.log(b)
運(yùn)行 test.js 結(jié)果為:
{ name: 1 }
{ name: 1 }
{ name: 2 }
{ name: 2 }
{ name: 2 }
{ name: 3 }
解釋:a 是一個(gè)對(duì)象梆造,b 是對(duì) a 的引用,即 a 和 b 指向同一塊內(nèi)存葬毫,所以前兩個(gè)輸出一樣镇辉。當(dāng)對(duì) b 作修改時(shí),即 a 和 b 指向同一塊內(nèi)存地址的內(nèi)容發(fā)生了改變贴捡,所以 a 也會(huì)體現(xiàn)出來忽肛,所以第三四個(gè)輸出一樣。當(dāng) b 被覆蓋時(shí)烂斋,b 指向了一塊新的內(nèi)存屹逛,a 還是指向原來的內(nèi)存,所以最后兩個(gè)輸出不一樣汛骂。
明白了上述例子后罕模,我們只需知道三點(diǎn)就知道 exports 和 module.exports 的區(qū)別了:
- module.exports 初始值為一個(gè)空對(duì)象 {}
- exports 是指向的 module.exports 的引用
- require() 返回的是 module.exports 而不是 exports
Node.js 官方文檔的截圖證實(shí)了我們的觀點(diǎn):
我們經(jīng)常看到這樣的寫法:
exports = module.exports = {...}
上面的代碼等價(jià)于:
module.exports = {...}
exports = module.exports
原理很簡(jiǎn)單:module.exports 指向新的對(duì)象時(shí)香缺,exports 斷開了與 module.exports 的引用,那么通過 exports = module.exports 讓 exports 重新指向 module.exports歇僧。
export default與export
export default就是輸出一個(gè)叫做default的變量或方法图张,然后系統(tǒng)允許你為它取任意名字。所以诈悍,下面的寫法是有效的祸轮。
// modules.js
function add(x, y) {
return x * y;
}
export {add as default};
// 等同于
// export default add;
// app.js
import { default as foo } from 'modules';
// 等同于
// import foo from 'modules';
下面比較一下默認(rèn)輸出和正常輸出。
// 第一組
export default function crc32() { // 輸出
// ...
}
import crc32 from 'crc32'; // 輸入
// 第二組
export function crc32() { // 輸出
// ...
};
import {crc32} from 'crc32'; // 輸入
上面代碼的兩組寫法侥钳,第一組是使用export default時(shí)适袜,對(duì)應(yīng)的import語句不需要使用大括號(hào);第二組是不使用export default時(shí)舷夺,對(duì)應(yīng)的import語句需要使用大括號(hào)苦酱。
export default命令用于指定模塊的默認(rèn)輸出售貌。顯然,一個(gè)模塊只能有一個(gè)默認(rèn)輸出疫萤,因此export default命令只能使用一次颂跨。所以,import命令后面才不用加大括號(hào)扯饶,因?yàn)橹豢赡芪ㄒ粚?duì)應(yīng)export default命令恒削。
本質(zhì)上,export default就是輸出一個(gè)叫做default的變量或方法尾序,然后系統(tǒng)允許你為它取任意名字钓丰。所以,下面的寫法是有效的每币。