學習Node也有一段時間了,好多東西屬於那種會用殊不知道其原理的狀態,本身也決心打破它,因此會不按期的總結一下本身所學到的東西。下面就梳理一下不一樣模塊的導入導出方法之間的區別。node
首先先看看模塊導入導出有哪些方式:express
模塊導入方式有:require、import、import xxx from yyy、import {xx} from yyy
模塊導出方式有:exports、module.exports、export、export.default
複製代碼
再看看其使用規則和範圍:bash
模塊導入方面
require: node和ES6都支持的模塊導入方式
import和import xxx from yyy和import {xx} from yyy:只有ES6支持
模塊導出方面
module.exports/exports: node自己支持的模塊導出方式
export/import: 只有ES6支持的模塊導出方式
複製代碼
CommonJS規範(node中模塊的導入導出) 因爲以前js沒有很統一比較混亂,代碼按照各自的喜愛寫並無一個模塊的概念,而這個規範說白了就是對模塊的定義:函數
CommonJS定義模塊分爲:模塊標識(module)、模塊定義(exports)、模塊引用(require)
複製代碼
而後問題來了上面的exports和module.exports之間又什麼關係呢? 實際上是這樣的每個node.js執行文件,都會自動建立一個exports和module對象,同時module對象會建立一個叫exports的屬性,初始化的值是 {},也就是以下:學習
exports = module.exports = {}
exports和module.exports都會指向一個{}內存區域
複製代碼
下面舉個例子:ui
//foo.js
let a = 24;
console.log(module.exports); //打印結果爲 {}
console.log(exports); //打印結果爲 {}
exports.a = 2400; // exports改變module.exports裏面的內容爲{a: 2400}
console.log(module.exports); //打印結果爲 {a: 2400}
console.log(exports); //打印結果爲 {a: 2400}
exports = '指向其餘內存區域再也不指向a'; //改變exports指向的內存區域
//test.js
let a = require('./foo');
console.log(a); //打印結果爲 {a: 2400}
由此結果能夠很清晰的看出,require導入進來的內容是module.exports導出的所指向內存a的內容並非exports的。說白了exports就是領導(module.exports)的祕書只負責起草稿子,出去念稿子的仍是領導(module.exports)。
複製代碼
若是用內存概念去理解的話,應該就是exports和module.exports最開始都指向一個內存塊(a),而後exports手賤修改了內存塊(a)裏面的內容可是exports和module.exports都仍是指向a,而後exports又指向了其餘內存,最後暴露出去的是module.exports所指向的內存塊(a)的內容。最後爲了不分不清統一使用module.exports導出用require導入就OK了。spa
ES6中的模塊導入導出 ES6出來以後模塊的導入導出方法開始豐富起來,導出有export和export default,導入有import xxx from yyy 、import {xxx} from yyycode
首先先看看導出export和export default之間的區別:router
下面也是老樣子上代碼舉例:對象
//foo.js
'use strict'
//導出變量
export const a = 'ES6的export導出常量'
const b = 24;
export default b; //不能寫 export defult const b = 24;
//導出function
export const func1 = function(){
console.log('ES6的export導出function1')
}
export const func2 = function(){
console.log('ES6的export導出function2')
}
export {func1,func2}
//test.js
'use strict'
const express = require('express');
const router = express.Router();
import {func1, func2} from './foo.js'; //導入export導出的兩個function
import b from './foo.js'; //導入 export default導出的常量b
import * as testModule from './foo.js'; //as是做爲集合成對象導入
/*GET HOME PAGE */
router.get('/',function(req,res,next){
func1(); //ES6的export導出function1
func2(); //ES6的export導出function2
console.log(b); // 24
testModule.func1(); //ES6的export導出function1
testModule.func2(); //ES6的export導出function2
console.log(testModule.b); //undefined,由於as導出是把零散的export合成一個對象而export default是導出爲default屬性
console.log(testModule.default); // 24
}
module.exports = router;
複製代碼
總算寫完了,但願對你們有所啓發或者幫助,今天週五了你們能夠稍稍休息哈了。其中也有參考了一些文檔和社區小夥伴寫的一些總結。