当前位置: 首页 > 后端技术 > Node.js

this和scope在浏览器和node中的问题

时间:2023-04-03 17:22:10 Node.js

之前面试遇到一个问题,问functiona(){this.b=5;}varb=9;a();console.log(b)请问b的输出是什么?简单的答案是5。然而,这不是正确的答案,应该从js的运行环境说起。先说运行结果:我们在node上得到的结果是9,而在浏览器上得到的结果是5。为什么会这样,我们先知道一个js规则:全局变量就是声明的变量换句话说,在全局范围内,一个从所有其他范围可见的变量。在JavaScript中它是全局对象的一个??属性。全局变量是在全局范围内声明的变量,对所有其他范围可见。在javascript中,全局变量是全局对象的属性。我们知道浏览器中的全局变量是window,所以在全局作用域声明的变量是全局属性,全局属性也是全局变量。题目中,运行a时,this指向全局变量window,即this.a===window.a===vara;所以执行函数a后,全局变量b变为5;那么在node中,node中的一个js其实就是一个模块,首先要明确node中this指向的问题this.a=6;(function(){this.a=6;})();this在函数外的指向和this在函数内的指向是不一样的。函数外的this指向模块,即this===module.exports,立即执行的函数内的this指向节点执行环境中的全局变量global。然后说说node中的模块是如何执行的functionModule(){//Node模块管理类this.exports={};}functionFun(exports,require,module,__filename,__dirname){//自定义模块包装后变量x=1;控制台日志(模块.x);//未定义的console.log(exports.x);//未定义的console.log(this.x);//未定义的console.log(this===module);//falseconsole.log(this===exports);//true}varmodule=newModule();//实例化varexports=module.exports;varoptions=[exports,require,module,filename,dirname];Fun.apply(exports,options);//自定义模块实例化我们可以发现在node中的模块中用var声明的变量实际上是在函数中用var声明的变量,它不是全局变量。从作用域链可以看出,函数作用域中的b覆盖了全局作用域中的b,所以node中的输出为9。node中的var变量参考MDN全局变量