程序员

node.js中exports与module.exports的区

2018-07-11  本文已影响78人  闲睡猫

node.js中,每个js文件都可以当成一个模块,每个模块中,都隐含了一个名为module的对象,module对象中有一个exports属性,这个属性的功能是将模块中的变量暴露给其他模块调用。

console.log(typeof module)
console.log(module)

结果:

object
Module {
  id: '.',
  exports: {},
  parent: null,
  ...
}

当模块被引用时,如果没有使用exports暴露变量,其他模块就不能使用其数据。正所谓,你能得到我的人,却得不到我的心...

13.js

require('./14')
console.log(name)

14.js

let name = '叶文洁'

执行会报找不到name变量

☁  01 [master] ⚡ node 13.js
console.log(name)
            ^

ReferenceError: name is not defined

接下来我们使用module.exports暴露变量

15.js

let moduleExports = require('./16')
console.log(moduleExports)
console.log(moduleExports.name)
let name = '罗辑'
moduleExports.introduce(name)

16.js

let name = '叶文洁'
module.exports.name = name
module.exports.introduce = function (name) {
    console.log('请介绍' + name + '的人物生平')
}

运行结果:

☁  01 [master] ⚡ node 15.js
{ name: '叶文洁', introduce: [Function] }
叶文洁
请介绍罗辑的人物生平

以上的写法比较繁琐,每次要暴露变量,都需要写module.exports,在以懒惰为美德的程序员看来,这是不能忍受的。因此node.js提供了一个变量exports作为module.exports的引用

16.js也可以写成:

let name = '叶文洁'
// exports 是 module.exports 的引用
console.log(exports === module.exports) // true
exports.name = name
exports.introduce = function (name) {
    console.log('请介绍' + name + '的人物生平')
}

接下来,问题来了,如果我们想将模块暴露的变量重新赋值呢?默认情况下,exports是一个对象,假设我们的需求是要得到一个字符串。要怎么弄?

也许你觉得这个很简单,直接给exports重新赋值就可以了。我们来试下:

17.js

let moduleExport = require('./18')
console.log(moduleExport)

18.js

let name = '章北海'
exports = name

执行结果:

☁  01 [master] ⚡ node 17.js
{}

为何不是我们期待的结果?让我们将exports换为module.exports试下:

18.js

let name = '章北海'
module.exports = name

结果:

☁  01 [master] ⚡ node 17.js
章北海

既然exports === module.exports,那么为何修改exports不起作用?

原因是,exportsmodule.exports的引用,当exports被重新赋值时,并不会影响到module.exports的值,而模块返回的是module.exports,因而只有给module.exports重新赋值,才起作用

同一个引用

来个更复杂点的例子:

18.js

let name = '章北海'
module.exports = name
exports = {}
exports.age = 10
module.exports = {}
module.exports.skill = '隐蔽真实想法,一个真正的面壁者'

结果:

☁  01 [master] ⚡ node 17.js
{ skill: '隐蔽真实想法,一个真正的面壁者' }
上一篇 下一篇

猜你喜欢

热点阅读