1.前言
说到模块化,我们会想到es6的模块化,或者node.js环境下commonJs规范的模块化,其他他们两者是不同的,我们今天来说下commonJs规范的模块化的exports和module.exports的导出区别!
2.例子
先看个简单的例子!
let a = 10;
let b = a;
b = 20;
console.log(a);//10
console.log(b);//20
这个例子再简单不过了,a和b都是简单数据类型,所以都存在栈中,看下图:
再看下例子:
let a = {
name: "张三"
};
let b = a;
b.age =18;
b = {
"name": "李四"
};
console.log(a);{name: "张三", age: 18}
console.log(b);//{name: "李四"}
现在a,b是对象了,a,b变量是存在栈中,值存在堆里面,都是指向内存中同一个地址看下图:
当在b上添加了一个属性age,值为18的时候,还是指向内存中同一个地址,看下图:
b再次被赋值时候,这里b不再指向之前的地址,而是指向内存中一个新的地址!看下图:
3.exports和module.exports的区别
有个上面例子铺垫,下面就好理解多了,首先基于common.js规范的模块化导出的对象是module.exports
let module={
exports:{}
}
let exports = module.exports
其实可以看出来exports就是module.exports的一个引用,两者是一样的,都是个空对象,其实他们两者真的没区别吗?当然是有区别的!我们可能经常这样写!
//test.js
exports.data = {
name: "张三",
age: "18",
"getAge": function () {
return this.age;
}
}
其实它等价于下面的代码
//test.js
module.exports.data = {
name: "张三",
age: "18",
"getAge": function () {
return this.age;
}
}
当外面引入时
//test.js
let test= require("./test.js")
//其实等价于
let test = module.exports;
最后外面引入文件时候,返回出来永远是module.exports,由此我们可以得出结论,我在exports对象上加属性,方法,最终返回来的是module.exports,好比你(exports)辛辛苦苦在外面赚钱,结果钱全给你老婆(module.exports),最后消费也是你老婆(module.exports)消费!那么你(exports)想自己独立,你可以把你老婆(module.exports)离婚,解除婚姻关系,那么你自由了!看下面代码
//test.js
exports = {
name: "张三",
age: "18",
"getAge": function () {
return this.age;
}
}
现在赋值个新对象,内存中指向了一个新的地址,那么现在你老婆(module.exports)一无所有,她还是之前那个空对象,当外面引入时候,最终返回出来的还是你老婆(module.exports)空对象!
4.exports,module.exports分别什么时候用?
如果只是返回一些属性或者方法,exports就可以(直接拿过来用或者调用),如果返回是一个类,外面需要new 才能使用,这里就要用module.exports,如果你还傻傻分不清楚,你就索性用module.exports
//test.js
module.exports = function Person() {
this.name = "张三";
this.age = 18;
this.getAge = function () {
return this.age;
}
}
//index.js
let test= require("./test.js")
console.log(new test())
打印结果:
·