node.js模塊中exports和module.exports的區別

Node應用由模塊組成,採用CommonJS模塊規範。javascript

根據這個規範,每一個文件就是一個模塊,有本身的做用域。在一個文件裏面定義的變量、函數、類,都是私有的,對其餘文件不可見。java

CommonJS規範規定,每一個模塊內部,module變量表明當前模塊。這個變量是一個對象,它的exports屬性(即module.exports)是對外的接口。加載某個模塊,實際上是加載該模塊的module.exports屬性。app

var x = 5; var addX = function (value) { return value + x; }; module.exports.x = x; module.exports.addX = addX;

上面代碼經過module.exports輸出變量x和函數addX。函數

require方法用於加載模塊。工具

var example = require('./example.js'); console.log(example.x); // 5 console.log(example.addX(1)); // 6

加載:require

語法:ui

var 自定義變量名稱 = require('模塊')

做用:spa

一、執行被加載模塊中的代碼code

二、獲得被加載模塊中的exports導出接口對象對象

導出:exports

Node中是模塊做用域,默認文件中全部的成員只在當前文件模塊有效。接口

對於但願能夠被其它模塊訪問的成員,咱們就須要把這些公開的成員都掛載到exports接口對象中就能夠了。

1. 導出多個成員(必須在對象中)

//foo.js var foo = 'bar' function add(x, y) { return x + y } exports.foo = foo exports.a = "科比" exports.b= "詹姆斯" exports.c = add //main.js var fooExports = require('./foo') console.log(fooExports) //結果 { foo: 'bar', a: '科比', b: '詹姆斯', c: [Function: add] }

2. 導出單個成員

錯誤寫法1

//foo.js var foo = 'bar' function add(x, y) { return x + y } exports = foo exports.a = "科比" exports.b= "詹姆斯" exports.c = add //main.js var fooExports = require('./foo') console.log(fooExports) 結果爲空對象 {}

錯誤寫法2

//foo.js var foo = 'bar' function add(x, y) { return x + y } exports.a = "科比" exports.b= "詹姆斯" exports.c = add exports = foo //main.js var fooExports = require('./foo') console.log(fooExports) 結果爲{ a: '科比', b: '詹姆斯', c: [Function: add] }

若是一個模塊須要直接導出某個成員,而非掛載的方式,那這個時候必須使用下面這種方式

//foo.js var foo = 'bar' function add(x, y) { return x + y } module.exports = foo //位置一 exports.a = "科比" exports.b= "詹姆斯" exports.c = add //module.exports = foo 位置二 /* module.exports = { 位置三 add: function () { return x + y }, str: 'hello' } */ //main.js var fooExports = require('./foo') console.log(fooExports)

結果:

只有一個module.exports時,無論是在位置一仍是位置二,都爲 bar。

當有兩個module.exports 時,好比一個在位置一,另外一個在位置三,會導出位置三的對象(module.exports會被後者覆蓋)。

上面的結果出現的緣由:exports 和module.exports是有區別的。

在Node中,每一個模塊內部都有一個本身的module 對象,該 module 對象中,有一個成員叫exports也是一個對象,相似這樣:

var module = { exports: { foo: 'bar', add: function } }

每次導出的對象是module.exports,若是你須要對外導出成員,只須要把導出的成員掛載到module.exports中。

也就是說module.exports纔是真正的接口,exports只不過是它的一個輔助工具。最終返回給調用的是module.exports而不是exports。

爲了方便,Node爲每一個模塊提供一個exports變量,指向module.exports。這等同在每一個模塊頭部,有一行這樣的命令:

var exports = module.exports

exports至關因而 一個引用,指向module.exports對象,因此有

console.log(module.exports === exports) ///true 

因而咱們能夠直接在 exports 對象上添加方法,表示對外輸出的接口,如同在module.exports上添加同樣。注意,不能直接將exports變量指向一個值,由於這樣等於切斷了exports與module.exports的聯繫。

同理,給 module.exports 從新賦值也會斷開。

可是這裏又從新創建二者的引用關係:

exports = module.exports

最後,必定要記得return的是module.exports

若是給exports賦值,斷開了兩個引用之間的聯繫,就無論用了。

module.exports.foo = 'bar' exports.a = 'abc' exports = {} exports.b = '123' //斷開鏈接後,就沒聯繫了,需從新聯繫起來 exports = module.exports exports.foo = 'haha' module.exports.a = 'cba' 結果 { foo: 'haha', a: 'cba' }

exports 和 module.exports 的使用

若是要對外暴露屬性或方法,就用 exports 就行,要暴露對象(相似class,包含了不少屬性和方法),就用 module.exports。

相關文章
相關標籤/搜索