JavaScript let 绑定(bind)不应添加到全局对象中,浏览器、Node 和 jsfiddle 中的行为不同

标签 javascript node.js jsfiddle

MDN documentation about let我发现以下一段文字:

“在程序和函数的顶层,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

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

undefined
undefined

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

undefined
undefined

为什么会出现这样的情况呢?全局对象在不同的​​运行环境中行为是否不同?此行为记录在哪里?

或者在这些情况下“程序的顶层”是否有所不同?

谢谢!

最佳答案

Node 的顶层确实不同。请尝试以下操作:

// 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 中“工作”的原因是,在 Node.js 中,顶层的范围仅限于模块,而不是像浏览器那样的全局环境(这是浏览器无法实现的 Node.js 的一个很棒的功能)出于遗留原因添加)。因此,您的 let 语句创建了一个模块级绑定(bind)。但是,如果您要从另一个模块导入该模块:

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

绑定(bind)不会跨模块边界共享。

至于 fiddle ,我只能假设他们正在做某种沙箱,阻止你的 fiddle 代码按预期工作。

关于JavaScript let 绑定(bind)不应添加到全局对象中,浏览器、Node 和 jsfiddle 中的行为不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48765893/

相关文章:

用于检查 IP 地址的 javascript 正则表达式

javascript - 如何缩放(jQuery)?

node.js - Zombie Js如何在特定情况下使用

javascript - 为什么我无法在 JSFiddle 中执行这个简单的 JavaScript 测试程序?

javascript - 如何将 .js 文件放入 html 中

javascript - 如何删除cookie值

javascript - 确定对象是 <div> 还是窗口

mysql - 如何使用 node.js 在 mySQL 中进行批量插入

javascript - 与 GET 请求一起发出虚假的 ajax OPTIONS 请求

javascript - Animate.css 摇动不起作用