手写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接收

浙公网安备 33010602011771号