前言
本文是在node环境下运行,考察到模块化、以及导入导出问题及相关知识
问题
下面这行代码输出结果是什么
//aModule.js this.m = 3 ; exports.c = 4; module.exports = { a:1, b:2 }//bModule.js const result = require("./aModule") console.log(result)答案:{a:1,b:2}
转换一下
//aModule.js exports.c = 4; module.exports.a=1; module.exports.b=2; this.m = 3 ;//bModule.js const result = require("./aModule") console.log(result)答案:{ c: 4, a: 1, b: 2, m: 3 }
这是为什么呢?不是说在模块化中没有 this吗?为什么最后还能导出m呢?直接蒙了
这就涉及到当我们使用require时,它到底做了什么事来讲起了,下面就用 伪代码简单说一下这个require
require的"伪"实现
function require(modulePath){
//1.将modulePath转换为绝对路径 : D:\modejs\aModule.js
//2.判断是否该模块已有缓存 通过打印module可以通过cache对象查看
if(require.cache["D:\modejs\aModule.js"]){
//如果有直接就返回结果
return require.cache["D:\modejs\aModule.js"].result
}
//3.如果没有缓存则读取文件内容
//4.读取文件将其包裹在函数中(以上面例子作为栗子)
function __temp(module,exports,require,__dirname,__filename{
// exports.c = 4;
// module.exports.a=1;
// module.exports.b=2;
// this.m = 3 ;
}
//5.创建module对象
module.exports ={};
const exports = module.exports;
//6.调用函数
__temp.call(module.exports,module,exports,require,module.path,module.filename)
}
通过上面伪代码就能看出问题了,__temp函数通过call来调用,那么我们正常调用call是怎么调用的呢?
aaa.call(this,a)call第一个函数传入的就是this,那么来看看此this是不是彼this?
通过打印对比 此时的this就是为module的exports,所以真相也浮出水面了,当this.m = 3 ;就是为module赋值,导致最终输出结果有m:3
总结
使用exports导出时不要混合使用,更不要使用this来赋值属性,避免不必要的错误发生
文章有错误的理解可以指出~~~