Oliver Hunt (2014-01-30T16:25:22.000Z)
domenic at domenicdenicola.com (2014-02-04T21:34:10.441Z)
On Jan 30, 2014, at 8:07 AM, Dean Landolt <dean at deanlandolt.com> wrote: > It's not obvious at all -- what happens when you drop the initial `let x = 0;` and you just have `{ if (y) let x = 42; alert(x); }` -- now what happens? Is x declared or not? > > To my mind `if (y) let x = 42;` reads like it's own 1-line noop block -- at least, that's what I'd expect of the scope. So while it could be allowed in that sense, it'd only serve as a footgun when y is true. This is exactly foot gun the language restriction is intended to avoid. Most modern [Obj-]C[++] will warn on this (well, s/let/int/) You might be getting confused because of the bizarro var hoisting semantics of var ```js if (y) let x = “nope"; alert(x) ``` Results in an unusable binding of x, and so this would throw (the foot gun occurs if you’re shadowing x, that’s another shadow that i think C compilers will warn on), e.g.. ```js y = true; let x = “whoops”; if (y) let x = “nope"; alert(x) // “whoops" ``` The var case ```js y = true; var x = “whoops”; if (y) var x = “nope"; alert(x); // “nope" ``` is actually interpreted as ```js var x; y= true; x = “whoops”; if (y) x = “nope”; alert(x); // “nope" ``` That craziness is the whole point of block scoping let. More interestingly ```js if (window.SomeCrazyDomFeature) var foo = true; ``` is a common web idiom as it brings foo into scope for everything, so makes later "if (foo) “ statements safe. Anyone trying to do this with a |let| would get incorrect (from their PoV) behaviour. Again that’s why we error out. Give that this is the behaviour of every other block scoped language i don’t see why this is confusing.