In the MDN documentation about let I find the following piece of text:
"At the top level of programs and functions, let, unlike var, does not create a property on the global object."
And accompanying sample code:
var x = 'global';
let y = 'global';
console.log(this.x); // "global"
console.log(this.y); // undefined
When I add this code to an HTML file like so:
<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>
I get the expected output in the console:
global
undefined
However, if I run the code in node I get:
undefined
undefined
And if I run the same code in JSFiddle I also get:
undefined
undefined
Why is this the case? Does the global object act differently in different runtime environments? Where is this behaviour documented?
Or is "the top level of programs" something different in these situations?
Thanks!
The top level is indeed different in node. Try the following:
// 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'
The reason that your code 'works' in node is that in node.js the top level is scoped to the module, not the global environment like browsers (which is a great feature of node.js that the browsers can't add for legacy reasons). So your let
statement creates a module-level binding. However if you were to import that module from another module:
require('./path/to/module/with/xandy');
console.log(typeof x); // 'undefined'
console.log(typeof y); // 'undefined'
The binding isn't shared across the module boundary.
As for the fiddle, I can only assume that they're doing some sort of sandboxing that prevents your fiddle code from working as expected.