I find function lexical scope more natural for JavaScript which is very function orientated, where you pass functions around and use closures a lot. I also find it a PITA having to declare variables before the block, instead of where they are first used. Ex:
if(..) {
... huge block of code ..
var foo = 1;
}
Means I do not have to scroll back and forth to declare and set the variables at different places.
That's probably because you're a more experienced Javascript developer and happen to know about it - and have experienced the pitfalls already. Most people, including myself (and I'm a fairly experienced JS developer myself) find block scoping to make more sense. Less prone to bugs and whatnot too.
In strict mode JS runtimes will hoist the `var` declaration to the top of the declared scope anyway. So `foo` would be declared at the start of the containing function scope, regardless of where you appear to declare them.
What I think he means is that if you "use strict" you will get an error if you reference a undeclared variable, but due to the hoisting you will not get an error if you use a variable before it has been declared - if it's declared later in the scope. But if you use let, you will get an error!
Such errors are trivial to detect even for beginners though ... Something more nasty is when you have an undeclared (undefined), maybe misspelled object property, then neither "use strict" block scope, or even const will help. It's also hard to find such bugs via static analysis, Typescript nor Eslint will detect it! This is a feature in JavaScript though, and has nothing to do (but often confused) with block scope vs function scope, or loose type vs strict types. In other languages you would need several lines of boilerplate just to do something like "foo.bar=1", and I think the convenience outweigh the possible hard to debug errors, and I'm also working on a static analysis tool that will detect some of those errors.
The only reason I can think of is if you want hoisting for some reason. For example, if you want to call functions before they are declared. Personally, I don't like that style, but some people do.
"In ECMAScript 2015, let bindings are not subject to Variable Hoisting, which means that let declarations do not move to the top of the current execution context."
Sort of, but the effect is very different due to the "temporal dead zone." Attempting to access a variable declared with `let/const` or const before the declaration will throw an error, vs just getting `undefined` for a variable declared with `var`.