node学习(2)exports/require
知识点:
1:node.js中每个文件就是一个模块,有自己的作用域。在一个文件中定义的变量,函数,类都是私有的。对其他文件不可见。
2:node.js遵循common.js规范,也就是说在ES Module中我们的导入导出使用的是import和export。在node中引入和暴露使用的是require和module.exports。
3:require用来加载某个模块
//b.js
var a = require('a.js')
console.log(a.name) // 'morrain'
console.log(a.getAge())// 18
4:module代表当前模块,是一个对象,保存了当前模块信息。exports是module上的一个属性,保存了当前模块要导出的接口或变量。使用require加载某个模块取到的值,就是模块使用exports导出的值。
// a.js
var name = 'morrain'
var age = 18
module.exports.name = name
module.exports.getAge = function(){
return age
}
5:CommonJS 规范规定,每个模块内部有两个变量可以使用,require 和 module。node.js在实现common.js规范的时候,为每个模块提供了一个exports的私有变量。指向了module.exports。可以理解为node.js在每个模块开始的地方,添加了一行如下代码。
var exports = module.exports;
所以上面的代码也可以写成:
// a.js
var name = 'morrain'
var age = 18
exports.name = name
exports.getAge = function(){
return age
}
注意:exports是模块内的私有局部变量,它只是指向了module.exports,所以直接对exports赋值是无效的,这样只会让exports不再指向module.exports而已。
错误写法
// a.js
var name = 'morrain'
var age = 18
exports = name
6:require的基本功能:读入并执行一个js文件,然后返回该模块的exports对象,如果没有发现指定模块对报错。
7:第一次加载某模块时,nodejs会缓存该模块,以后再加载该模块,就直接从缓存取出该模块的module.exports属性返回了。
// a.js
var name = 'morrain'
var age = 18
exports.name = name
exports.getAge = function(){
return age
}
// b.js
var a = require('a.js')
console.log(a.name) // 'morrain'
a.name = 'rename'
var b = require('a.js')
console.log(b.name) // 'rename'
第二次require(a.js)的时候,并没有重新加载去执行a.js,而是直接返回了第一次require的结果,所以我们得到的是rename。
注意:commonjs的加载机制是,require的是对导出值的深拷贝,也就是说,一旦导出了,模块之后内部再怎么变化也不会影响该值的变化
// a.js
var name = 'morrain'
var age = 18
exports.name = name
exports.age = age
exports.setAge = function(a){
age = a
}
// b.js
var a = require('a.js')
console.log(a.age) // 18
a.setAge(19)
console.log(a.age) // 18