8

I'm taking a Java course and all declarations use block scope( int, double, boolean, etc.). In JavaScript however var is function scope.

let came along in ES6 and gave JS developers block scope. I'm adjusting my coding style and am opting to get rid of var all together.

Is this O.K.?

  • 6
    Yes, even google took it out in its style guide. [Google JS Style Guide](https://google.github.io/styleguide/jsguide.html#features-use-const-and-let) – Gerardo BLANCO May 14 '18 at 17:02
  • 4
    Yes, if you decided to don't support older browser or if you are using a transpiler. In ES6, there's no any reason to prefer `var` in place of `let` or `const`. – Christian Vincenzo Traina May 14 '18 at 17:02
  • It depends on use. What benefit you will get after removing all the var?Do you have unit test case covered.Will you able to check that after replacing nothing is breaking your code – brk May 14 '18 at 17:02
  • 3
    For fun, note the [difference between java and javascript](https://stackoverflow.com/a/245073/870729) – random_user_name May 14 '18 at 17:04
  • The only useful application of `var` is that a global can be redefined in global scope multiple times without causing an error. Can happen if there are multiple scripts that define a global, but only last definition should take effect. – Estus Flask May 14 '18 at 17:15
  • @cale_b - The OP seems clear on the difference. – T.J. Crowder May 14 '18 at 17:35
  • @T.J.Crowder - indeed. But reminded me of my favorite explanation of java vs javascript, and thought it'd be fun to share it. Didn't mean to imply otherwise! – random_user_name May 14 '18 at 17:41
  • The problem I've been facing is that the **'let'** statement doesn't support the **"window.['my_var_name']"** feature. So, if you're dynamically getting variable values (by its string name), you will want to stick with the **'var'** statement for a while - or to update your code to use **'eval'** as you can see at https://stackoverflow.com/questions/50111200/windowname-equivalent-to-dynamically-access-const-and-let-declarations – Almir Campos Jan 25 '19 at 03:56
  • Does this answer your question? [What is the use case for var in ES6?](https://stackoverflow.com/questions/31836796/what-is-the-use-case-for-var-in-es6) – Oliver Sieweke Nov 16 '20 at 22:29
  • As a rule of thumb don't use ES6 in web browsers due to incompatibility issues with older browsers. Otherwise use them to your hearts content and stop using var. However var still has its uses when you need function scope. – PHP Guru Dec 14 '20 at 03:56

2 Answers2

9

Is this O.K.?

Mostly; possibly entirely. There are very few situations where you would want to use var instead of let/const for technical (rather than style) reasons:

  • If you want to declare a global variable that becomes a property of the global object (global let, const, and class create globals, but they don't become properties of the global object).

    Of course, you could use this.varName = ... instead of var varName, since this at global scope¹ is the global object.

  • If you want to have several files where any of them may be the "first" (but not last) to define the same global, as is common in older module formats, e.g.:

    var MyApp = MyApp || {};
    MyApp.something = /*...*/;
    

    That works because the var MyApp part is silently ignored if MyApp is already declared; the equivalent structure with let would fail because it cannot be used if the identifier is already declared in the current scope.

    Of course, you're probably using a new module format by now. :-) And if you aren't, again you could do

    this.MyApp = this.MyApp || {};
    MyApp.something = /*...*/;
    

    at global scope.¹

[There used to be a minor performance benefit to using var instead of let in a function where it was used as a loop counter. Recent versions of modern browsers all-but-remove that minor benefit (and it was minor anyway).]


¹ Note that top-level code in a module (ES2015 module, Node.js module, most bundlers...) is not at global scope. It's at module scope. Also note that at the top level of an ES2015 module, this has the value undefined.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • `this` isn't the global in ES6 modules, might be good to clarify. – loganfsmyth May 14 '18 at 17:43
  • @loganfsmyth - Thanks, I've highlighted it. I did say "at global scope" and of course, module scope isn't global scope. But... – T.J. Crowder May 14 '18 at 17:56
  • True! Definitely a distinction that some people miss though. – loganfsmyth May 14 '18 at 18:07
  • Why do you say that let and const create a global, the docs say they are function scoped. –  Dec 13 '18 at 21:24
  • `If you want to declare a global variable that becomes a property of the global object (global let, const, and class create globals, but they don't become properties of the global object)` –  Dec 13 '18 at 21:25
  • @johnmorsey - *"the docs say they are function scoped"* `let` and `const` aren't function-scoped, they're **block**-scoped (that is, even more narrowly-scoped than function scope). `var` is function-scoped. What I'm saying above is that `let` and `const` (and `class`) **at global scope** create globals that aren't properties of the global object. `var` at global scope creates globals that *are* properties of the global object. – T.J. Crowder Dec 14 '18 at 08:52
5

If you are only targeting platforms that support ES6, adopt let and const. Stop using var.

wuarmin
  • 3,274
  • 3
  • 18
  • 31
  • While less in depth, this is better answer imho. If you ever need to use `var`, you're doing it wrong. If you can use `const`, use `const`, otherwise use `let`. – Slava Knyazev May 14 '18 at 21:32