JS代码在VSCode终端与浏览器控制台运行结果不同的原因
运行结果差异原因
差异本质是浏览器全局环境和Node.js模块环境的顶层作用域规则不同,结合非严格模式下普通函数的this绑定逻辑,逐行拆解执行过程就很清楚:
第一次调用fn()的输出差异
非严格模式下,不带任何前缀直接调用普通函数时,函数内部的this会默认指向当前运行环境的顶层对象。
- 浏览器环境:
顶层作用域中用var声明的变量会自动挂载到全局顶层对象window上。你写的var length = 10等价于给window加了个length属性值为10。obj.method里直接调用fn()时,fn内部的this指向window,this.length读到的就是你声明的10,所以第一行输出10。 - Node.js环境:
用node file.js运行脚本时,整个文件代码会被封装进一个模块闭包内执行,不是全局作用域。你在文件顶层写的var length = 10只是当前模块作用域内的局部变量,不会挂载到Node的全局顶层对象global上。此时直接调用fn(),this指向global,而global上没有你自定义的length属性,自然读到undefined,第一行输出undefined。
第二次调用arguments[0]()的输出一致
这部分逻辑两个环境完全相同:当函数作为某个对象的属性被调用时,函数内部的this指向这个宿主对象。arguments[0]()的调用形式,相当于把类数组对象arguments作为宿主,调用它下标为0的属性(也就是传入的fn函数),此时fn内部的this指向arguments本身。arguments自带的length属性值等于当前函数调用时传入的实参个数——你调用obj.method(fn, 1)时一共传了2个参数,所以this.length就是2,两个环境输出一致。
快速复现浏览器一致结果的方法
如果要让Node环境下输出和浏览器完全相同,只需要把顶层变量挂载到global对象上即可:
global.length = 10; // 后续代码不变,运行就会输出10、2
内容的提问来源于stack exchange,提问作者Abdullah Al Mamun
相关产品推荐
相关产品推荐

