关于node中的this,module,exports

接触到node后对于node中可以自由使用module和exports感到很神奇,再加上自己碰到的一些问题,做了一些总结,先抛出自己的一些问题:
场景1:

const redis=require("redis");
var client=redis.createClient("6379","127.0.0.1");
client.on("error", (error)=>{
   console.log(error);
});
client.on("connect", ()=>{
    console.log("redis connect successful");
 });
 console.log(this); //{}
 console.log(exports);//{}
 console.log(module.exports);//{}
 module.exports=client;
 console.log(this);//{}
 console.log(exports);//{}
 console.log(module.exports);// RedisClientObj

场景2

const redis=require("redis");
var client=redis.createClient("6379","127.0.0.1");
client.on("error", (error)=>{
   console.log(error);
});
client.on("connect", ()=>{
    console.log("redis connect successful");
 });
 console.log(this); //{}
 console.log(exports);//{}
 console.log(module.exports);//{}
 exports=client;
 console.log(this);//{}
 console.log(exports);//RedisClientObj         console.log(module.exports);// {}

场景3

const redis=require("redis");
var client=redis.createClient("6379","127.0.0.1");
client.on("error", (error)=>{
   console.log(error);
});
client.on("connect", ()=>{
    console.log("redis connect successful");
 });
 console.log(this); //{}
 console.log(exports);//{}
 console.log(module.exports);//{}
 exports.result=client;
 console.log(this);//{'result':RedisClientObj}
 console.log(exports);//{'result':RedisClientObj}
 console.log(module.exports);// {'result':RedisClientObj}

这个模块就是简单引入redis,这里redis不是重点,可以忽略,关键点是之后的那些console

查询了很多资料后,感觉以上的问题可以归咎为2点:
1.node模块执行时帮我们做了什么操作
2.函数参数的传递是值传递还是引用传递

别急,喝口水,让我一步步往下讲。

首先关键是要弄清楚,你写了一个模块以后,node做了什么封装操作,以上面的代码为例:

let module={"id":"module_id","exports":{},"path_name":"path_name","children":"children"};

let getResult=function(exports,module){
//开始自己模块的代码
const redis=require("redis");
var client=redis.createClient("6379","127.0.0.1");
client.on("error", (error)=>{
   console.log(error);
});
client.on("connect", ()=>{
    console.log("redis connect successful");
 });
 module.exports=client;
 //自己代码块结束
return module.exports;
}
 let exported = getResult.call(module.exports,module.exports,module);

从上面看来,node会为我们先准备一个module对象,然后把他当作函数的参数传进来,由于使用了call,导致函数体内的this就会指向module.exports,而传进去的参数又是module.exports和module。
接着在函数体内,我们就可以使用module和exports这两个参数了,这里要注意的是,这里传参是值传递,即该对象的内存地址,不是引用传递!

然后我们先来看场景1:
通过上面代码可以很清楚知道,开始实际上module.exports和exports是指向同一个对象,而this开始又是指向module.exports,所以开始的三个console出来都是空对象。之后开始对module.exports赋值,这里要注意了,我们使用的module,实际上是传进来的参数,是外面定义那个module对象的地址,现在我们对module.exports赋值,如此一来,module里面这个exports的地址指向已经变了,指向了另一块内存,而由于是值传递,this和exports保存的仍然是之前的内存地址,所以他们仍然为{}

再看场景2:
同样的道理,这次对exports赋值,也只有exports会变化,而this和module.exports还是指向之前的内存地址。

场景3:
这里的赋值是对exports.res来说的,这里并没有开辟新的内存去覆盖exports,只是在exports上新加了一个属性罢了,所以exports的内存地址没有改变,最后三个打印出来都是被赋了值的对象。

以上只是自己的一些总结,欢迎指正。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值