我试图了解Javascript是如何在引擎盖下工作的,所以我一直在玩。例如,以下代码在Chrome控制台中或在Node.js中生成不同的输出:
var length = 10;
function fn () {
  console.log (this.length);
}
fn();在Chrome中,我记录的值为10,而在Node中,这是未定义的。是因为在窗口对象中,全局变量被视为窗口的属性,而在节点中,全局对象具有不同的行为吗?如果是这样的话,全局对象中发生了什么,以及如何在不声明global.length的情况下获得类似的窗口行为?我这样做只是一种练习,没有别的目的,只有理解。
发布于 2020-02-19 10:53:39
差异的原因是浏览器脚本中的顶级作用域是全局作用域,而Node.js文件中的顶级作用域是模块作用域。(默认情况下,这是一个旧风格的Node.js模块,它处于松散模式,但在现代版本的Node.js中,您可以选择采用JavaScript标准模块范围,这是严格模式。)
在全局范围内,var在全局对象上创建一个属性,您可以通过window全局访问该属性,在全局范围通过this访问该属性,或者在调用松散模式函数时通过this访问该属性,而无需执行任何特定设置this的操作。上面对fn的调用是最后一类:不设置this而调用的松散模式函数。
但是在Node.js模块作用域,var只是在模块中创建一个var,而不是在全局对象上创建全局或属性。就像这样:
(function() { // The wrapper Node.js provides node-style modules
    // This is "module" scope
    var foo = 10;
    function fn () {
      console.log (this.foo);
    }
    fn();
})();         // End of the wrapper
(为什么我将length改为foo?因为默认情况下,window有一个length属性--该窗口包含的帧数--这让人感到困惑。*-)
所以这只是范围上的不同。
您还可以通过type="module"在script标记上使用现代浏览器上的模块范围,包括Chrome。但是,由于JavaScript标准模块总是处于严格模式,所以调用fn中的this将是undefined,从而导致错误:
<script type="module">
var length = 10;
function fn () {
  console.log(this);        // undefined
  console.log(this.length); // TypeError
}
fn();
</script>
https://stackoverflow.com/questions/60298608
复制相似问题