JavaScript不允许将绑定添加到全局对象,浏览器与Node vs jsfiddle中的不同行为

时间:2018-02-13 11:35:52

标签: javascript node.js jsfiddle

MDN documentation about let中,我找到了以下文字:

“在程序和函数的顶层,让我们与var不同,不会在全局对象上创建属性。”

随附示例代码:

var x = 'global';
let y = 'global';
console.log(this.x); // "global"
console.log(this.y); // undefined

当我将此代码添加到HTML文件时,如下所示:

<html>

<head>
  <script type="text/javascript">
    var x = 'global';
    let y = 'global';
    console.log(this.x); // "global"
    console.log(this.y); // undefined
  </script>
</head>

<body>
  <h1>foo</h1>
</body>

</html>

我在控制台中获得了预期的输出:

global
undefined

但是,如果我在节点中运行代码,我会得到:

undefined
undefined

如果我在JSFiddle中运行相同的代码,我也会得到:

undefined
undefined

为什么会这样?全局对象在不同的​​运行时环境中的行为是否不同?这种行为记录在哪里?

或者“最高级别的节目”在这些情况下会有什么不同?

谢谢!

1 个答案:

答案 0 :(得分:1)

节点中的顶层确实不同。请尝试以下方法:

// get access to the global object e.g. window, global
var g = (new Function('return this;'))();
var x = 1;
let y = 2;
console.log(typeof x); // 'number'
console.log(typeof y); // 'number'
console.log(typeof g.x); // 'undefined'
console.log(typeof g.y); // 'undefined'

你的代码在节点中“工作”的原因是在node.js中,顶层是作用于模块的,而不是像浏览器这样的全局环境(这是一个很好的node.js功能,浏览器不能添加遗留原因)。因此,您的let语句会创建模块级绑定。但是,如果您要从另一个模块导入该模块:

require('./path/to/module/with/xandy');
console.log(typeof x); // 'undefined'
console.log(typeof y); // 'undefined'

不在模块边界共享绑定。

至于小提琴,我只能假设他们正在做某种沙盒,以防止你的小提琴代码按预期工作。