一个困惑多时的问题,在nodejs中导出一个模块有时用exports或module.exports都可以,但偶尔会报错。
结论:
1.如果要导出一个键值对象{},则可以使用exports;
2.如果要导出一个函数或数组,只能对module.exports赋值;
所以,任何时候导出模块都用module.exports即可。
实验:
1.用exports导出方法及报错
// exports-test.js
var name = 'JonnyOu'
// 函数
function funTest(adj) {
console.log(name, ' is ', adj);
}
exports = funTest
// test.js
const et = require('./exports-test')
var name = 'cool'
et.funTest(name);
错误:
et.funTest(name);
^
TypeError: et.funTest is not a function
2.用module.exports导出方法
// exports-test.js
var name = 'JonnyOu'
// 函数
function funTest(adj) {
console.log(name, 'is', adj);
}
function funTest2(adj) {
console.log(name, 'is so', adj);
}
module.exports = {
abc: funTest,
def: funTest2
}
// test.js
const et = require('./exports-test')
var name = 'cool'
et.abc(name) // JonnyOu is cool
et.def(name) // JonnyOu is so cool
对于示例2的补充:
1.在test.js中引用函数时用了属性名而不是方法名,说明module.exports其实是一个对象,这与module的实现机制相关,在模块导出时把函数名或数组名放入{}里面即可,没必要用以上键值对的形式导出。
2.test.js中的name与exports-test.js中的name并不冲突,javascript支持闭包,它把js文件用一个函数包装起来,使得这段代码中的"全局"变量,变成了函数内部的局部变量。
(function () {
var name = ‘JonnyOu’
…
})()
参考:缪雪峰的网站
再补充:Nodejs对class的引用
两个注意点:
1.module.exports = ClassName // 直接引用类名,不能加上{}
2.var test = new ClassName(); // 新建一个类对象
class Test {
constructor (x, y) {
this.x = x
this.y = y
}
add() {
return this.x + this.y;
}
}
module.exports = Test
const ct = require('./class-test')
var test = new ct(3,5) // 调用构造函数
console.log('3+5=', test.add()) // const ct = require('./class-test')
var test = new ct(3,5)
console.log('3+5=', test.add()) // 3+5= 8