手写Node模块系统-面试题底层原理
NodeJS 中的 this
为什么是一个空对象:
因为所有的
NodeJS
文件在执行的时候都会被包裹到一个函数中,this
都被修改为了空的module.exports
(function (exports, require, module, __filename, __dirname) {
// 我们编写的代码
// 所以说在这里面拿到的 this 就是空的 module.exports
});
compiledWrapper.call(module.exports, args);
NodeJS 中为什么可以直接使用 exports
,require
,module
,__filename
,__dirname
:
因为所有的 NodeJS 文件在执行的时候都会被包裹到一个函数中,这些属性都被通过参数的形式传递过来了
var args = [module.exports, require, module, filename, dirname];
compiledWrapper.call(this.exports, args);
NodeJS 中为什么不能直接 exports
赋值,而可以给 module.exports
赋值,如果直接给 exports
赋值拿到的是一个空对象如下:
如果不是直接赋值运行就能拿到暴露的数据如下:
先来看直接赋值暴露数据内存示例图以及所对应的代码:
对应的代码如下:
直接赋值的最终执行的代码如下,改变了 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;
直接赋值改变了形参当中 exports 所指向的对象,指向了 "BNTang",所以拿到的是一个空对象在来看看不是直接赋值的内存示例图:
内部的代码如下:
(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
接收