Node.js模块使用及原理解析
模块使用方式
在Node.js中,有两种方式可以导出变量、函数或者对象,分别如下所示·。值得注意的是,在方式二的情况下,可以对exports对象的属性赋值,但是不能直接对exports对象赋值,否则导出的对象为空对象,原因在解释Node.js实现模块化原理的时候在阐述,为了避免错误可以只使用方式1。
1.
module.exports.variable = variable;
module.exports.function = function;
module.exports = variable || function;
exports.variable = variable;
exports.function = function;
如果要使用导出的变量,使用方式如下
// 如果为全局模块或者内置模块
var variable = require('模块名');
// 如果是自己写的模块,模块名就是js文件名
var variable = require('路径/模块名');
模块实现原理
在js语法中,有闭包这一个特性,如果把各个js文件中的代码放在函数的闭包中,那么每个模块中的变量都是函数的局部变量,从而命名不会发生冲突。原理的伪代码如下
// 导出模块main.js
let student = {
age: 25,
sex: 'man'
}
module.exports = student;
// 实现原理如下
let module = {
name:"main",
exports:{}
}
var load = function(exports,module){
// 模块中的代码
let student = {
age: 25,
sex: 'man'
}
module.exports = student;
return module.exports;
}
let exported = load(module.exports,module);
从上面的代码可以看出,预先构造了一个module对象,exports是module的属性(代表要导出的变量),同时exports也是一个对象。load函数执行闭包函数,把module对象和module.expots作为参数传递给闭包函数,模块中的代码作为闭包在函数中执行,通过为module.exports或者exports的属性赋值,node记录了main.js的导出变量的信息,然后在其他模块可以通过module.exports访问main模块导出的变量。
接下来解释为什么不能直接对exports对象直接赋值,因为导出变量的信息存储在module.exports对象中,而模块中的exports对象是通过函数传参(引用传递)的形式将module.exports赋给模块中的exports对象,如果在模块中直接对exports对象赋值,那么只是改变了局部变量exports的引用的对象,并不会改变原来module.exports对象的值。