创建一个foo.js文件,内容如下:
exports.foo = 'bar';
创建index.js文件,内容如下:
// 1. 在Node中,每个文件模块都是一个对象,我们模拟一个
function Module() {
this.exports = {};
}
// 2. Node在定位到具体的文件后,Node会新建一个模块对象
var module = new Module();
// 3. 如果是.js文件。Node会通过fs模块同步读取文件
var fs = require('fs');
var foo_js = fs.readFileSync('./foo.js');
// 4. 读取出文件内容后,将文件进行头尾包装,这里只是简单的模拟
var packStr = '(function(exports,module){' + foo_js + ' return module.exports; })';
// 注:这样每个模块之间都进行了作用域隔离
// 5. 包装之后的代码通过一个类似eval(Node中并不是eval)的函数执行返回一个具体的function对象
var packObj = eval(packStr);
// 6. 执行该函数,将module对象的exports属性以及module对象本身作为参数传递进去
// 而内部是通过return module.exports; 的方式返回的
var foo = packObj(module.exports, module);
// 在第6点中,就是为什么通过exports = ‘bar’; 赋值,但是外部却拿不到
// 这是因为在JavaScript中,引用传递的是引用的副本,而不是引用本身,这叫做共享传递
// 所以exports = ‘bar’ 改变的是形参的引用()而并没有影响到外部的实参exports对象
// 而通过exports.foo = ‘bar’; 确实可以得到,这是因为虽然引用传递的是引用副本,但他们指向的是同一个对象
// 自然而然的,通过module.exports = ‘bar’; 就是成功的
// 7. 所以在外部我们最终得到了被引用模块中导出的变量、函数或对象
console.log(foo);
网友评论