7

I was trying to understand the scope in JavaScript. If I declare a variable outside of a function, it is GLOBAL. Hence I tested the following code to understand sequence of execution. In the following code, I expected the "demo1" to take the global value which is "Volvo" since the I render that text before declaring the local variable with the same name inside the function. But to my surprise I see the value to be "undefined".

<!DOCTYPE html>
<html>

<body>
    <p id="demo"></p>
    <p id="demo1"></p>
    <p id="demo2"></p>
    <script>
        var carName = "Volvo";
        myFunction();
        document.getElementById("demo").innerHTML = carName;

        function myFunction() {
            document.getElementById("demo1").innerHTML = carName;
            var carName = "Volvo1";
            document.getElementById("demo2").innerHTML = carName;
        }
    </script>
</body>

</html>

RESULT:

Volvo

undefined

Volvo1

I modified further to see what happens if a declare another Global variable inside the function as follows:

<!DOCTYPE html>
<html>

<body>

    <p id="demo"></p>
    <p id="demo1"></p>
    <p id="demo2"></p>

    <script>
        var carName = "Volvo";
        myFunction();
        document.getElementById("demo").innerHTML = carName;

        function myFunction() {
            document.getElementById("demo1").innerHTML = carName;

            //declaring another global variable
            carName = "Volvo1";
            document.getElementById("demo2").innerHTML = carName;
        }
    </script>
</body>

</html>

RESULT:

Volvo1

Volvo

Volvo1

This time the "demo1" assumes the global variable declared outside of the function i.e "Volvo".

Can someone explain this to me?

cнŝdk
  • 28,676
  • 7
  • 47
  • 67
Sigma
  • 115
  • 1
  • 1
  • 4

4 Answers4

4

In JavaScript this is called Variable hoisting, which is defined as:

One of the trickier aspects of JavaScript for new JavaScript developers is the fact that variables and functions are "hoisted."

Rather than being available after their declaration, they might actually be available beforehand.

That means the second var declaration of your carName variable is excluding/eliminating the first one inside the function.

Because if you declare a variable with var keyword in the global scope of your code (beginning of your code) and then re-declare the same variable with var keyword in another scope(function, ...) this second declaration will exclude the first one and this variable value becomes undefined.


EDIT:

You can see in the Variable Hoisting section here the impact of variable hoisting and the difference between variable declaration and variable assignement:

All variable declarations are hoisted (lifted and declared) to the top of the function, if defined in a function, or the top of the global context, if outside a function.

It is important to know that only variable declarations are hoisted to the top, not variable initialization or assignments (when the variable is assigned a value).

Community
  • 1
  • 1
cнŝdk
  • 28,676
  • 7
  • 47
  • 67
  • OK. But in the second block of code, if it is eliminating the first one, the value of demo1 should be Volvo1 instead it is "Volvo" (the first value). – Sigma Jun 04 '15 at 15:13
  • @Sigma, no because only declaration are hoisted. Assignement stays where it was written. See other answers with examples – Andrey Jun 04 '15 at 15:20
  • yes it's the expected result, it should be `volvo` because you are writing to `demo1` before affecting the new value to it, and keep in mind that you have removed the **var** keyword so it's an **assignement** and not a **declaration**. – cнŝdk Jun 04 '15 at 15:21
  • @Sigma And to answer one of your question in a comment no variable hoisting is a dangerous aspect if you are not aware of it and all an application could be broken cause of it, you can read [**A Dangerous Example of Javascript Hoisting**](http://ignaciothayer.com/post/a-dangerous-example-of-javascript-hoisting/). – cнŝdk Jun 04 '15 at 15:27
2

This is due to the hoisting of the var declaration. So what happens inside myFunction is actually something like this:

function myFunction() {
    // This declaration hides your carName from the outer scope
    var carName; // Var declared here by hoisting
    document.getElementById("demo1").innerHTML = carName; // undefined
    carName = "Volvo1"; // Assigned value
    document.getElementById("demo2").innerHTML = carName;
}

In the second example, you circumvent this declaration

CodingIntrigue
  • 65,670
  • 26
  • 159
  • 166
  • OK. But I am compelled to declare a global variable inside the function. Is hoisting useful in any way ? – Sigma Jun 04 '15 at 15:15
  • You could rename `carName` inside `myFunction` to something else? After all, if you expect it to only have the scope of the function it doesn't make sense to name it the same. Hoisting is very useful. Really it's how you should be writing your variable declarations since it shows explicitly what variables are declared and where. – CodingIntrigue Jun 04 '15 at 15:17
  • Yes I know I can rename. Since I am learning JS, I was trying to understand how it works. Thanks a lot. This is helping me. – Sigma Jun 04 '15 at 15:24
0

Working Code: here is the demo http://jsfiddle.net/patelmit69/qa34ky3z/

var carName = "Volvo";
myFunction();
document.getElementById("demo").innerHTML = carName;
function myFunction() {
    document.getElementById("demo1").innerHTML = carName;
    carName = "Volvo1";
    document.getElementById("demo2").innerHTML = carName;
}
Mitul
  • 3,543
  • 2
  • 18
  • 34
0

It happens because of variable hoisting. Variable declarations are hoisted to the top of function, so your function works like following code:

    function myFunction() {
        var carName; //declaration
        document.getElementById("demo1").innerHTML = carName; // here carName is not defined yet
        carName = "Volvo1"; //assignment
        document.getElementById("demo2").innerHTML = carName;
    }

that is why #demo1 value is undefined.

Andrey
  • 3,823
  • 17
  • 31