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


Node應用由模塊組成,采用CommonJS模塊規范。

根據這個規范,每個文件就是一個模塊,有自己的作用域。在一個文件里面定義的變量、函數、類,都是私有的,對其他文件不可見。

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

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

語法:

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

作用:

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

2、得到被加載模塊中的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。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM