0
点赞
收藏
分享

微信扫一扫

手写Node模块系统-面试题底层原理

沐之轻语 2022-05-24 阅读 34

NodeJS 中的 ​​this​​ 为什么是一个空对象:


因为所有的 ​​NodeJS​​​ 文件在执行的时候都会被包裹到一个函数中,​​this​​​ 都被修改为了空的 ​​module.exports​


(function (exports, require, module, __filename, __dirname) {
// 我们编写的代码
// 所以说在这里面拿到的 this 就是空的 module.exports
});

compiledWrapper.call(module.exports, args);

手写Node模块系统-面试题底层原理_赋值

NodeJS 中为什么可以直接使用 ​​exports​​​,​​require​​​,​​module​​​,​​__filename​​​,​​__dirname​​:


因为所有的 NodeJS 文件在执行的时候都会被包裹到一个函数中,这些属性都被通过参数的形式传递过来了


var args = [module.exports, require, module, filename, dirname];

compiledWrapper.call(this.exports, args);

手写Node模块系统-面试题底层原理_数据_02

NodeJS 中为什么不能直接 ​​exports​​​ 赋值,而可以给 ​​module.exports​​​ 赋值,如果直接给 ​​exports​​ 赋值拿到的是一个空对象如下:

手写Node模块系统-面试题底层原理_赋值_03

手写Node模块系统-面试题底层原理_赋值_04

如果不是直接赋值运行就能拿到暴露的数据如下:

手写Node模块系统-面试题底层原理_赋值_05

手写Node模块系统-面试题底层原理_数据_06

先来看直接赋值暴露数据内存示例图以及所对应的代码:

手写Node模块系统-面试题底层原理_数据_07

对应的代码如下:

手写Node模块系统-面试题底层原理_数据_08

手写Node模块系统-面试题底层原理_数据_09

直接赋值的最终执行的代码如下,改变了 exports 的指向:

(function (exports, require, module, __filename, __dirname) {
exports = "BNTang";
});

jsScript.call(module.exports, module.exports);
return module.exports;

相当于如下代码:

let exports = module.exports;

exports = "BNTang";

return module.exports;

手写Node模块系统-面试题底层原理_数据_10

直接赋值改变了形参当中 exports 所指向的对象,指向了 "BNTang",所以拿到的是一个空对象在来看看不是直接赋值的内存示例图:

手写Node模块系统-面试题底层原理_赋值_11

内部的代码如下:

(function (exports, require, module, __filename, __dirname) {
exports.name = "BNTang";
});

jsScript.call(module.exports, module.exports);
return module.exports;


因为形参当中的 exports 所指向的对象和 module.exports 是同一个所以拿到的不是空对象


通过 ​​require​​​ 导入包的时候应该使用 ​​var / let​​​ 还是 ​​const​​:


导入包的目的是使用包而不是修改包,所以导入包时使用 ​​const​​ 接收





举报

相关推荐

0 条评论