21

Lately after ES6 released, many sources suggested that I use "const" and "let" instead of "var", and that I should stop using "var" in my JavaScript.

What I wonder is, if "var" has no advantage over "let" in all points of view, then why didn't they just fix var, or even deprecate "var" instead of letting them go along side each other?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Leonard Li
  • 257
  • 1
  • 2
  • 5
  • 8
    Because changing or removing it would break about a billion lines of code. –  Nov 24 '17 at 02:26
  • 5
    `var` is a lot more useful than `let` when you want function scope and not block scope. – Paul Nov 24 '17 at 02:27
  • 1
    There are still uses for `var`. – jhpratt Nov 24 '17 at 02:28
  • @jhpratt: Like what? –  Nov 24 '17 at 02:30
  • What if I don't want block scope? I may very well desire the function scope of `var`, without having to say `let xyz` without a value just to define scope. – jhpratt Nov 24 '17 at 02:33
  • 2
    So your use case is declaring a variable inside a block and then using it outside of the block? –  Nov 24 '17 at 02:34
  • 3
    @jhpratt that wouldn't pass code review in any good company... and certainly is stamped on by any linter. – Shadow Nov 24 '17 at 02:35
  • @Shadow I don't do that, just know others that do. I *always* use `let` and `const`. – jhpratt Nov 24 '17 at 02:36
  • @rockstar [Global variables](https://stackoverflow.com/a/36140613/1048572) that need to be redeclable. Global variables with `let` and `const` suck. – Bergi Nov 24 '17 at 04:46
  • "*I should stop using "var" in my JavaScript.*" - Have a look at [What is the use case for `var` in ES6?](https://stackoverflow.com/q/31836796/1048572) – Bergi Nov 24 '17 at 04:46
  • 1
    @Bergi: You're right, though as a use case, it doesn't seem very compelling because of alternatives. It's more of a *"I want to do things exactly like I've always done them*" case. –  Nov 24 '17 at 13:22
  • Turn the question around—what is the good of *let* and *const*? They provide zero additional functionality over *var*, they are simply tools to help programmers not make mistakes. If you don't care about block scope or constants, why use them? Does anyone use the same variable name twice in an execution context but in different block scopes? Would you really use `let i=0` in multiple *for* loops in the same context and rely on block scope to differentiate them? Or nested *for* loops? That makes debugging and maintenance harder, not easier. – RobG Apr 28 '18 at 00:00
  • Possible duplicate of [What is the use case for var in ES6?](https://stackoverflow.com/questions/31836796/what-is-the-use-case-for-var-in-es6) – jaco0646 Apr 29 '18 at 16:19
  • They should remove this feature, even if it breaks lines of code. The industry should be forced to rewrite things that did not use good practice. – Ryan Jul 04 '22 at 02:26

3 Answers3

29

Backwards compatibility.

You're right in saying there is no real advantage to using var over let - if you define them at the start of a function their meaning is basically identical.

You're right that there is no real reason to write new code using var (except maybe this, if relevant).

There are pages on the internet that are decades old though, and no one is going to rewrite them. There is nothing really to gain by removing var from the language. For languages like HTML and Javascript that are interpreted - backward compatability is absolutely mandatory.

That is also why they chose not to simply redefine var. Take the following example code;

// THIS IS AN EXAMPLE OF BAD CODE. DO NOT COPY AND PASTE THIS.
if (logic) {
    var output = "true"
} else {
    var output = "false"
}
console.log(output)

If var was changed to behave like let then the console.log would cause a reference error because of the scope difference.

Community
  • 1
  • 1
Shadow
  • 8,749
  • 4
  • 47
  • 57
  • Thank you for your answer. I appreciate it. Yet your answer only solve one part of the question which is "why not deprecate var". How about refactoring the "var" from the beginning and not introducing any "let"? Are there good reasons for it? – Leonard Li Nov 24 '17 at 02:37
  • 1
    Again, backwards compatibility. If people were using `var` in the horrendous way described in the comments of your question (and it does happen), then that code would change meaning and break, probably without warning as far as the developer who wrote it is concerned. – Shadow Nov 24 '17 at 02:38
  • I've added an example. – Shadow Nov 24 '17 at 02:42
  • I always consider the example you show to be bad form. Better to declare the variable at a higher scope. Which means I don't think that's a good example of a good use for `var`. – jfriend00 Nov 24 '17 at 04:06
  • 3
    I agree - perhaps I should make that more obvious. It is however an example of why just changing `var` to mean `let` is a bad idea, which was the intent. – Shadow Nov 24 '17 at 04:07
  • Backwards compatibility is the ultimate reason of all the sh*tshow in the programming world. – Robo Robok Jul 08 '21 at 16:33
1

I believe sometimes you need to redeclare a variable to write less code.

One example is this function that generates a unique id:

function makeUniqueId(takenIds) {
  do {
    var id = Number.parseInt(Math.random() * 10);
  } while (takenIds.includes(id))
}

Which may be invoked like that

makeUniqueId([1,2,3,4,5,6,7])

Here I declare id variable simply inside do block and it get's "hoisted" to the function scope. That would cause an error if I used let, because while block wouldn't see the variable from the do block. Of course I could declate let before do..while, but that would create the same function scoped variable with extra line of code.

Another example is when you copypaste code to devtools console and every time variables get redeclared.

One more example. What if you want to keep your variable declarations close to their usages but still treat them as function globals? If you use let in this fashion, you'll get rather confusing expirience in dev tools (all those Block, Block scopes). enter image description here

But var 'keeps' them together in one 'Local' list: enter image description here

vloginov
  • 92
  • 1
  • 4
  • 3
    "*As you can see, id is probably going to be redeclared many times…*" No it wont. Declarations are processed exactly once when control enters a new execution context (or block for block-scoped declarations). The variable *id* exists with function scope before any of the body of *makeUniqueId* is executed. There is no *while* block, there is a *while* expression and you're right, the scope of a *let* declaration in a *do..while* loop doesn't extend to the *while* condition so *id* would be out of scope if declared using *let* in the *do* block. – RobG Mar 26 '18 at 04:18
  • Thanks for catching that! – vloginov Apr 27 '18 at 14:03
  • All those use cases are not sufficient reasons to keep var around. It brings more confusion and bugs than benefits. Simplification would be much appreciated. – Joan Jun 16 '19 at 20:00
  • All examples demonstrates exactly the opposite: [ex. 1]: the logic of _id_ is to be in the external scope, and it must be declared there, not in _do{}_, then use **let** above; [ex. 2]: copy-pasting re-declared variables is extremely dangerous; using **let** will show explicitly the issues; [ex. 3] is similar to 1: you say that you want to declare a variable close to its usage, but you want treat it as global: therefore the declaration must be in the global scope. In general, it isn't wise to use global variable, unless in a Module pattern, i.e. a **const** declared object. – allez l'OM Dec 02 '19 at 10:31
-1

Everything has their own advantages and disadvantages using var const and let is dependent on their use cases.

var

Variable declarations are processed before the execution of the code. The scope of a JavaScript variable declared with var is its current execution context. The scope of a JavaScript variable declared outside the function is global.

let

The let statement allows you to create a variable with the scope limited to the block on which it is used.

const

const statement values can be assigned once and they cannot be reassigned. The scope of const statement works similar to let statements.

I hope you understand.

Sultan Khan
  • 308
  • 2
  • 11
  • 2
    You didn't list any advantages for `var`. You can use `let` at the function or global level too, so where's the advantage, beyond doing something unpleasant like declaring a `var` in a block but then using it outside that block. –  Nov 24 '17 at 02:44
  • 1
    "*Variable declarations are processed before the execution of the code*" - [the same is true for `let` and `const`](https://stackoverflow.com/q/31219420/1048572) – Bergi Nov 24 '17 at 04:42
  • 1
    Note that "variable declarations" includes *let* and *const* (per [*ECMA-262 §13.3.1*](http://ecma-international.org/ecma-262/8.0/#sec-let-and-const-declarations)), they're all processed before code is executed (but assignments are made when the code is executed). ;-) – RobG Mar 26 '18 at 04:23