Let is a game changer imo. In the world of tens of dependencies, knowing that your variables are scope restricted reduces your cognitive load. It's one less thing that can go wrong.
I agree with you on classes, but that's probably more because I've never been a big fan of OO in practice. It doesn't really seem to have seen much use in the greater js ecosystem though, unlike let/const.
The block which is long enough to need block scope is long enough to be a function.
Special bonus to couple decomposing assignment with IIFE so that any variables/symbols which "escape" from the nested function are explicit (and the locals simply disappear with the nested function).
Const would be nice, if it went further - treating the const declared identifier as if it were deeply frozen, at least within the scope of the const identifier. Alas, that touches on what is wrong with most programming languages in common use today: mutable by default, but we should be requiring "groveling" to make something mutable.
What is the difference between let and global variables? There are hundreds of articles written about the doom associated with PHP globals, but let appears to be universally lauded. I must be missing something, but I can't tell where.
It's spelled out pretty well in the article. But if you want another example, consider these two code blocks:
var foo;
var bar;
{
let foo = "hello";
var bar = "world";
}
console.log(foo);
console.log(bar);
This produces:
undefined
world
The reason being that the `let` statement restricted that variable to the block it was in (defined by the { and }). `var` declares the variable globally, allowing it to be accessed outside of the {}.
We prefer now to use `let` and `const` over `var` because it doesn't pollute the global namespace. With the asynchronous nature of Javascript, it's theoretically possible for you to declare a variable with `var`, assign it a value, then immediately use that value and find that it's different than what you expected because of another function using the same variable name. This isn't possible with `let`.
if (inner) {
let x = 'inner';
return x;
}
return x; // gets result from line 1 as expected
}
test(false); // outer
test(true); // inner
This makes it seem like let creates global variables. Why would you want to return a variable from outside the function? Doesn't that create massive overhead in terms of keeping track where variables are initially set? Easy to understand in this example, but what if let x = 'outer'; is defined at the top of a 5000 line script and this function appears near the bottom?
Edit: Turns out I don't know how to format code. This is in the first example of section 3.1 Block Scope Variables.
If you were to then reference 'x' from another block of code, say in another <script> element in the case of web development, 'x' would not be a defined variable, whereas with 'var', it would be.
This is mostly just a case of 'let' restricting a variable to the block it is in, and the child blocks. In your example, `let x = 'outer';` is sort of acting like a global variable, but the importance is that if another script were to be running, it could not access that instance of 'x'.
Ahh, I get it, Thank you! In the same way var scopes to window if defined outside of a function, let scopes it to the current script block. That is very neat.
I'll read more into uses of let over var. Function level scoping a la var feels like less mental overhead, but as I read more I'm sure my opinion will change.
Javascript (in browser) is async, but not concurrent (like say, threads). JS will run the code in an event handler to completion (or not - while(1){}) before starting the code for the next event. Thus, code from one execution path cannot update variables in another path "immediately".
You could use a variable in a callback for an event that was assigned on the line above, and it since has changed, but it's important to remember that the callback (or promise, etc) does not actually run until an arbitrary time "later".
Close. Assigning "foo" without var will look up the lexical scope stack from most nested to global. If nothing exists, it will indeed make a new global. However, if there is a "foo" somewhere in that scope stack, it will update that variable.
var a = function () {
var foo
var b = function () {
foo = 3
}
b()
}
a()
console.log( foo ) // undefined
In the code above, the "foo" in function a is set to 3, rather than creating a global. (changing the "vars" to "lets" would do the same thing, FWIW)
Also, "use strict" mode will not let you make a global that way. If in strict mode, you have to put the "var" outside of any function, then assign it (either on that line, or later) to make a global.
> With the asynchronous nature of Javascript, it's theoretically possible for you to declare a variable with `var`, assign it a value, then immediately use that value and find that it's different than what you expected
Can you give an example ? My understanding is that the closure freeze the variable in the time the function was called. It can happen if you do not use a closure (function) though.
Javascript closures are like Ruby blocks and closures: you get to "touch", as well as "look" - and also see "touches" that happened in between times elsewhere.
Cool stuff: Tail call elimination. Arrow functions. Assignment spread for multiple return values and "rest" / default parameters. Proxying (combined with computed get/set on properties) for easy decoration.
Classes and let: meh.