1

Why there is no Syntax error in the following code?

var num = 8;
var num = 10;
console.log(num) // 10

whereas

var num = 8;
let num = 10;
console.log(num) // already decleared error
VLAZ
  • 26,331
  • 9
  • 49
  • 67
K.Kaur
  • 91
  • 3
  • 8
  • 1
    Both of the declarations are hoisted to the top of the scope, but when later meeting `var` in the code, it is ignored, where as `let` (or `const` as well) doesn't allow redeclaration. The behavior of `var` is not fixed due to historical reasons, changing it would break millions of websites. – Teemu Jul 10 '20 at 08:37

2 Answers2

2

The first case will be rendered as:

var num;
num = 8;
num = 10;
console.log(num); // output : 10

The second case will be rendered as:

var num;
num = 8;
let num; // throws Uncaught SyntaxError: Identifier 'num' has already been declared
num = 10
console.log(num);
omer blechman
  • 277
  • 2
  • 16
1

Because unlike var, variables cannot be re-declared using let, trying to do that will throw a Syntax error: Identifier has already been declared. What is important if you will avoid anti-patterns like global variables, if you will keep your vars in the scope and make the methods small, you will avoid redeclaration of the vars bugs.. probably. What is important number two: var declaration works faster then const and let, so in loops, if you HAVE TO OPTIMIZE the method you can use var instead of let/const.

Arthur Rubens
  • 4,626
  • 1
  • 8
  • 11
  • "*avoid anti-patterns like global variables*" I don't see how `let` or `const` have any relevance to this. You can still declare a global `const myVar` and the shadow it in a function with another declaration. You will not get a syntax error in that case. The same thing would happen if you used `var` instead. "*What is important number two: var declaration works faster then const and let, so in loops, if you HAVE TO OPTIMIZE" no, I do not believe you have to optimise this. It's extremely unlikely this to be *the* bottleneck in application. – VLAZ Jul 10 '20 at 10:38
  • The term "scope" is not used only for js "this". You can read this article to understand the disadvantages of global variables: https://wiki.c2.com/?GlobalVariablesAreBad "no, I do not believe you have to optimise this." <-- that is subjective feelings. "In huge loops event nanoseconds matters" <-- and that is fact. – Arthur Rubens Jul 10 '20 at 11:10
  • I don't know why you're linking me to an article on global variables - I'm well aware of what they are. What I'm not aware is why you say that `let` and `const` have any relation to them. If you have `var a; function test() { var a; }` that's shadowing the global variable and you get two distinct declarations. You'd get *the same* if you used `const a` or `let a` in either place. It's not counted as a redeclaration, so no real help when it comes to global variables. – VLAZ Jul 10 '20 at 11:22
  • "*that is subjective feelings.*" based on my long experience of micro-optimisations not being worth it. It's quite a well understood idea. With giant loops it's better to find a way to avoid the loop or cut it short altogether than just shuffle code around to *maybe* shave off a millisecond or two – VLAZ Jul 10 '20 at 11:30
  • "*and that is fact*" I can point out to the fact that there are well known, long standing compiler optimisations for loops already that might make what you do useless. If you have, say `const = i * 10` that can be optimised as [an induction variable](https://en.wikipedia.org/wiki/Induction_variable) or if you have something that's static, that would be moved out of the loop via [loop-invariant code motion](https://en.wikipedia.org/wiki/Loop-invariant_code_motion). So, simply changing `let` to a `var` might not actually do anything at all. – VLAZ Jul 10 '20 at 11:30
  • You are again wrong. You are speaking about ONE compiler (compiler or interpreter?) optimization as there is only one browser. Unfortunately there are different browsers and different versions of browsers in the world. You can see some test results here: https://stackoverflow.com/questions/21467642/is-there-a-performance-difference-between-let-and-var-in-javascript . About the shadowing, I am avoiding to shadow variables. Shadowing decreasing the readability and makes code potentially buggy. – Arthur Rubens Jul 10 '20 at 11:48
  • I'm talking about *compiler optimisations* - these can also be used by whatever is running the code. Nowadays any environment you use will have a JIT compilation step. Any browser that would have been called "modern" five years ago would have long implemented a loop-invariant code motion. Namely in the `for (var i = 0; i < array.length; i++)` construct the `array.length` expression would be moved out of the body of the loop, so it will not be re-fetched. The days of having to do `for (var i = 0, l = array.length` are long past us. – VLAZ Jul 10 '20 at 11:54
  • "*About the shadowing, I am avoiding to shadow variables. Shadowing decreasing the readability and makes code potentially buggy. *" however your own suggestion that `let` and `const` somehow help with global variables relies on shadowing not existing. If it didn't *then* you'd have a benefit in preventing global scoped issues. However, there is no relation currently - you can have a `const` in the global scope and in an inner scope. I still don't understand why you suggested they help. – VLAZ Jul 10 '20 at 11:56
  • yes, if somebody already used global variables, let an const can be useful to avoid bugs, that is fact! I have NEVER suggested to use global variables, that is also fact! – Arthur Rubens Jul 10 '20 at 12:07
  • I never claimed you have suggested using globals. But you suggest that using `let` and `const` will *avoid* the anti-pattern of globals. I don't see how that would be. There is nothing with `let` or `const` that will change the globals behaviour compared to a `var`. At best you avoid *redeclaration* which can also happen outside the global scope therefore it's not unique to that scenario. So, I don't see how `let` and `const` interact with globals in order to discourage them. – VLAZ Jul 10 '20 at 12:14
  • „At best you avoid redeclaration“ you are right, in some cases let and const help to avoid the redeclaration of variables, in some cases redeclaration can be source of latent bugs. That is all, what I wanted to say. – Arthur Rubens Jul 10 '20 at 12:22