Why do both var and let exist?

Question: Why do both var and let exist? And as a bonus question: Couldn't we just keep let?


Initially var existed. The scope of names was delimited by functions (i.e. there was no block-level scope). And also the design of the language included that before execution an initial lexcial analysis pass would recollect (hoist) all name declarations (variables, functions).

Everyone lived happily in the woods… Well, no. There was a number of grumpy rabbits angry about two things. Una was block-level scope, which, for some reason, they felt they needed it for… something. And then there was that thing on hoisting that made some of them cry while confusing others when it was mentioned, even though they might not have noticed too much about it in daily use.

So, after a number of years, let was introduced as an alternative that allows delimiting scope to blocks and didn't “suffer hoisting”… Well, no, not really. To make it fit with the philosophy of JavaScript, let simulates that there is no hoisting, even though there is, by introducing a TDZ 1) to enforce forward declaration.

Ok, but, couldn't we just have let (or modify var to behave like let and just keep one word)? No, of course not. On the one hand, there's retro-compatibility and not suddenly breaking half (or more) of the sites in the world just because you don't like having two options. And on the other, let introduces its own concerns (e.g. there's an unavoidable 5-10x performance hit; and the use of TDZs doesn't seem like an ideal situation).

Some may prefer ignoring this and telling everyone that they should always use let or else they are bad persons. ¯\_(ツ)_/¯

Temporal Dead Zone