Hacker News new | past | comments | ask | show | jobs | submit login

That's not quite accurate. It's actually the reverse.

Think of the closure as an object. It contains variables like `this`, `arguments`, a pointer to the parent closure, all your variables, etc.

The interpreter needs to create this closure object BEFORE it runs the function. Before the function can run, it has to be parsed. It looks for any parameters, `var` statements, and function statements. These are all added to the list of properties in the object with a value of `undefined`. If you have `var foo` twice, it only creates one property with that name.

Now when it runs, it just ignores any `var` statements and instead, it looks up the value in the object. If it's not there, then it looks in the parent closure and throws an error if it reaches the top closure and doesn't find a property with that name. Since all the variables were assigned `undefined` beforehand, a lookup always returns the correct value.

`let` wrecks this simple strategy. When you're creating the closure, you have to specify if a variable belongs in the `var` group or in the `let` group. If it is in the `let` group, it isn't given a default value of `undefined`. Because of the TDZ (temporal dead zone), it is instead give a pseudo "really undefined" placeholder value.

When your function runs and comes across a variable in the let group, it must do a couple checks.

Case 1: we have a `let` statement. Re-assign all the given variables to their assigned value or to `undefined` if no value is given.

Case 2: we have an assignment statement. Check if we are "really undefined" or if we have an actual value. If "really undefined", then we must throw an error that we used before assignment. Otherwise, assign the variable the given value;

Case 3: We are accessing a variable. Check if we are "really undefined" and throw if we are. Otherwise, return the value.

To my knowledge, there's no technical reason for implementing the rule of only one declaration aside from forcing some idea of purity. The biggest general downside of `let` IMO is that you must do extra checks and branches every time you access a variable else have the JIT generate another code path (both of which are less efficient).




We are on the same page.

My point is having 2 let or var statements doesn't actually do anything on the interpreter side.

If JS allowed 2 var/lets without complaining, it would be entirely a social convention as to what that meant, since it would have no effect on the actual code that was run.

And the social convention benefit (which could more easily be achieved with just putting a comment at the end) is probably far outweighed by the many, real examples I've seen where someone has accidentally created a new variable without realizing that variable already exists in scope.

Disallowing multiple vars helps linters identify these situations (which are far more common with var's function level scoping than let's block level scoping).




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: