40

Would the following code cause any issues?:

var a = 1;
var a = 2;

My understanding is that javascript variables are declared at the start of the scope. For example:

var foo = 'a';
foo = 'b';
var bar = 'c';

Is processed as:

var foo;
var bar;
foo = 'a';
foo = 'b';
bar = 'c';

Therefore would my initial code snippet become:

var a;
a = 1;
a = 2;

Or would it become:

var a;
var a;
a = 1;
a = 2;

I understand that declaring a javascript variable twice in the same scope isn't good practice, but I'm more interested in the impact of doing this.

Curtis
  • 101,612
  • 66
  • 270
  • 352
  • 2
    var a,a; is the same as var a; If your are wanting to use the same variable name but have multiple values then you need to look into using arrays. –  Feb 12 '14 at 11:44
  • Check this [question](http://stackoverflow.com/questions/500431/javascript-variable-scope) about variable scope. [1] – djluis Feb 12 '14 at 11:44
  • @Curt Sorry for blind comment guyz – Deepak Ingole Feb 12 '14 at 11:47
  • In terms of impact I think this is an implementation-specific. JS engines do not change source code. But they can process it differently, applying some optimizations, until it doesn't conflict with ECMAScript specification. Specification says it's directly same variable. So I think no impact at all. – likern Mar 07 '21 at 19:57

5 Answers5

39

As you said, by twice of more the same var, JavaScript moves that declaration to the top of the scope and then your code would become like this:

var a;
a = 1;
a = 2;

Therefore, it doesn't give us any error.

This same behaviour occurs to for loops (they doesn't have a local scope in their headers), so the code below is really common:

for (var i = 0; i < n; i++) {
    // ...
}
for (var i = 0; i < m; i++) {
    // ...
}

That's why JavaScript gurus like Douglas Crockford suggest programmers to manually move those declarations to the top of the scope:

var i;    // declare here
for (i = 0; i < n; i++) {    // initialize here...
    // ...
}
for (i = 0; i < m; i++) {    // ... and here
    // ...
}
Danilo Valente
  • 11,270
  • 8
  • 53
  • 67
  • 1
    @k.stm You'll end up with a cleaner code. You also avoid redeclaring variables. – Danilo Valente Oct 17 '15 at 22:15
  • 2
    @k.stm You will also use less characters shaving a couple of bytes off your file, which is useful when you are sending large amounts of js files to the client:) – tkellehe Nov 19 '15 at 12:12
  • 2
    counter point - if two var declaration do no harm aside from adding a few bytes then why risk moving the declaration to the top and introduce the potential to inadvertently creating a global variable because I thought it was already declared. Seems like a possibility in a complex multi-file environment. – kpg Apr 30 '18 at 13:37
4

Declaring the same variable twice is as good as declaring it once. Below statement will not bring any impact.

var a, a;

in the below case you are just overriding the variable foo. This will have an impact if you have foo defined in the local and global scope. JS will search foo in the local scope first and then if it doesn't find it will look in the global scope.

var foo;
var bar;
foo = 'a';
foo = 'b';
bar = 'c';
Abhidev
  • 7,063
  • 6
  • 21
  • 26
3

Let's try to transcript what ECMAScript® 2021 Language Specification says.

First, according to JavaScript: Understanding the Weird Parts there are two phases of running code: Creation Phase and Execution Phase. Conceptually it's like code is processed twice (not executed, processed).

For var a = 5; statement this is happening:

  • Creation Phase: memory allocation for identifier a and undefined value set to this memory (so called hoisting)
  • Execution Phase: put value 5 into memory associated with identifier a (instead of undefined)

Now 14.3.2 Variable Statement section of ECMAScript® 2021 Language Specification says this

A var statement declares variables that are scoped to the running execution context's VariableEnvironment. Var variables are created when their containing Environment Record is instantiated and are initialized to undefined when created. Within the scope of any VariableEnvironment a common BindingIdentifier may appear in more than one VariableDeclaration but those declarations collectively define only one variable. A variable defined by a VariableDeclaration with an Initializer is assigned the value of its Initializer's AssignmentExpression when the VariableDeclaration is executed, not when the variable is created.

Let's examine it line by line.

Within the scope of any VariableEnvironment a common BindingIdentifier may appear in more than one VariableDeclaration

In this case BindingIdentifier is just a identifier. Statement means these syntaxes are allowed officially.

var a;
var a;
var a = 1;
var a = 2;
var a, a;
var a = 1, a = 2;

but those declarations collectively define only one variable

Directly says it's the same variable, only one memory is allocated.

Conceptually you might think that if at Creation Phase variable with identifier (a is our case) was already created, it's creation is skipped (previous statement already allocated memory and set undefined into it).

A variable defined by a VariableDeclaration with an Initializer is assigned the value of its Initializer's AssignmentExpression when the VariableDeclaration is executed, not when the variable is created

Just further emphasizes difference between assignment (happens at Execution Phase) and variable creation (happens at Creation Phase) of this statement

var a = 5;

Explanation

Now let's summarize what we know. This syntax is officially supported by specification. It means only one variable is created (one memory location to hold value)

var a = 1;
var a = 2;

It has nothing to do with hoisting. Hoisting is still happening as usual.

console.log(a) // this is undefined
var a = 1;
var a = 2;

Assignments will happen at Execution Phase line by line, changing value at the same memory location.

console.log(a) // undefined
var a = 1;
console.log(a) // 1
var a = 2;
console.log(a) // 2
likern
  • 3,744
  • 5
  • 36
  • 47
0

Such a duplicate variable declaration will not cause any problems thanks to javascript's variable hoisting feature. so in your DOM wherever you have declared variables but assigned (or) not assigned, they will be placed at the top during compilation.

Example:
    var foo='hai!';
    bar='welcome!';
    var bar;

You may expect above code snippet should throw "unidentified" error but still javascript manages it by placing the bar variable's declaration at the top. So even before variable declaration its value can be assigned as opposed to other languages.

Hope this helps you to some extent

0

If you initialize the same variable twice, there will be no error on the console but if you are working on some application (like guess my number) and want to reset all the elements to the initial state. All the elements will be set to the initial state but the variable that was initialized twice will stick to its modified value only. Example, If the initial score is 20 and then modified to say some number 15, now reset button is pressed in order to set the value to initial but it will not.