转载请注明出处 https://www.jianshu.com/p/5b68470ed484
在node中
nodejs中,module.exports初始的时候置为{}
exports只是module.exports的一个引用
打个比喻
var a = {name: 1};
var b = a;
console.log(a);
console.log(b);
b.name= 2;
console.log(a);
console.log(b);
var b = {name: 3};
console.log(a);
console.log(b);
运行 test.js 结果为:
{ name: 1 }
{ name: 1 }
{ name: 2 }
{ name: 2 }
{ name: 2 }
{ name: 3 }
解释a 是一个对象,b 是对 a 的引用,即 a 和 b 指向同一块内存,所以前两个输出一样。当对 b 作修改时,即 a 和 b 指向同一块内存地址的内容发生了改变,所以 a 也会体现出来,所以第三四个输出一样。当 b 被覆盖时,b 指向了一块新的内存,a 还是指向原来的内存,所以最后两个输出不一样。
在node中require() 一个模块,得到的是 module.exports对象 而不是 exports
用一句话来说明就是,require方能看到的只有module.exports这个对象,它是看不到exports对象的,而我们在编写模块时用到的exports对象实际上只是对module.exports的引用。
还原真实场景
var module = {
exports:{
name:"我是module的exports属性"
}
};
var exports = module.exports; //exports是对module.exports的引用,也就是exports现在指向的内存地址和module.exports指向的内存地址是一样的
console.log(module.exports); // { name: '我是module的exports属性' }
console.log(exports); // { name: '我是module的exports属性' }
exports.name = "我想改一下名字";
console.log(module.exports); // { name: '我想改一下名字' }
console.log(exports); // { name: '我想改一下名字' }
//看到没,引用的结果就是a和b都操作同一内存地址下的数据
//这个时候我在某个文件定义了一个想导出的模块
var Circle = {
name:"我是一个圆",
func:function(x){
return x*x*3.14;
}
};
exports = Circle; // 看清楚了,Circle这个Object在内存中指向了新的地址,所以exports也指向了这个新的地址,和原来的地址没有半毛钱关系了
console.log(module.exports); // { name: '我想改一下名字' }
console.log(exports); // { name: '我是一个圆', func: [Function] }
在node中,module.exports初始的时候置为{},exports也指向这个空对象。
回归案例
正常写法
module.exports.name='你好';
exports.name='hello';
//以上两种写法都没有问题,只不是是后者修改了前者,修改的同一内存地址里的东西,最后require时,以module.exports对象输出
覆盖exports引用,将他指向新的内存
module.exports.name='你好';
exports={name:123};
console.log(module.exports.name)//你好
console.log(exports.name)//123
参考: