关于nodejs面试题详解

nodejs的一个经典面试题

this.d = 4;
exports.c = 3;
module.exports = {
    
    
     a: 1,
     b: 2
 }
//module.exports.a = 1
//module.exports.b = 2

const a = require('./a.js')
console.log(a);

这里执行的结果是:
在这里插入图片描述

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

this.d = 4;
exports.c = 3;
//module.exports = {
    
    
//     a: 1,
//     b: 2
// }
module.exports.a = 1
module.exports.b = 2
const a = require('./a.js')
console.log(a);

这里执行的结果是:
在这里插入图片描述
这里仅仅只是两个的输出方式不一样就导致了不一样的结果,其原因是有关node的底层代码:
因为require执行的时候会经过以下几个步骤:
注意以下代码都是理论代码不能执行,只是用作分析
1.调用了resolve方法拼接成了一个绝对路径


function require(modulePath){
    
    //模块路径
	
}

2.在cache部分判断该模块是否有缓存。cache是require函数的缓存区

	if(require.cache["C:\\Users\\admin\\Desktop\\0315nodejs\\04.js"]){
    
    
		return require.cache["C:\\Users\\admin\\Desktop\\0315nodejs\\04.js"]
	}	

3.读取目标文件内容
4.包裹到一个函数中去


function require(modulePath){
    
    //模块路径
	if(require.cache["C:\\Users\\admin\\Desktop\\0315nodejs\\04.js"]){
    
    
		return require.cache["C:\\Users\\admin\\Desktop\\0315nodejs\\04.js"]
	}	
	function _temp(module,exports,require,__dirname,__filename){
    
    
	//在require目标对象的所有代码都在这个内部函数执行
		this.d = 4;
		exports.c = 3;
		module.exports = {
    
    
			a : 1,
			b : 2
		}
	}
}
	

5.创建module.exports对象(重点)

function require(modulePath){
    
    //模块路径
	if(require.cache["C:\\Users\\admin\\Desktop\\0315nodejs\\04.js"]){
    
    
		return require.cache["C:\\Users\\admin\\Desktop\\0315nodejs\\04.js"]
	}	
	function _temp(module,exports,require,__dirname,__filename){
    
    
	//在require目标对象的所有代码都在这个内部函数执行
		this.d = 4;
		exports.c = 3;
		module.exports = {
    
    
			a : 1,
			b : 2
		}
	}
	// 5.创建module.exports对象
		module.exports = {
    
    }
		const exports = module.exports
		_temp.call(module.exports,exports,require,__dirname,__filename)
	
		return module.exports;
}

在执行内部函数_temp的时候它会通过call来改变this的指向将其指向module.exports同时创建module.exports对象,然后创建exports同时把module.exports赋值exports也就是说现在this、module.exports、exports其实是一个东西:

console.log(module.exports === exports)//true
console.log(module.exports === this)//true

最后返回module.exports;

所以说

this.d = 4;
exports.c = 3;
module.exports.a = 1
module.exports.b = 2

输出{d:4, c:3, a:1, b:2}是因为它们都在往module.exports里加东西;

但是

this.d = 4;
exports.c = 3;
module.exports = {
    
    
     a: 1,
     b: 2
 }

这里就有问题了一开始本来就创建了个module.exports的空对象,现在有赋值了一个新的对象。这就导致了module.exports指向了一个新的地址
这里我画个图来表示
第一种情况:
在这里插入图片描述
第二种情况:
在这里插入图片描述
而require函数返回的是module.exports自然也就输出的是{a:1,b:2}了

猜你喜欢

转载自blog.csdn.net/weixin_48549175/article/details/114996615