2

Look at the following snippet:

var fruit = "Orange";
echoThis();

function echoThis() {    
    alert(fruit);
    var fruit = "Apple";
}

When I run this snippet, the alert of fruit is undefined. Why?

First I thought it has something to do with hoisting, that within a funciton, the JS engine "lifts" all var declarations to the top or something, but then I would expect the alert to display Apple, not undefined.

There's probably some elementary JS behaviour I'm unaware of. Anyone care to explain?

JS fiddle: https://jsfiddle.net/z37230c9/

2
  • You have to pass fruit as an argument to the function. Or make your variable "fruit" public by removing the "var" Commented Feb 26, 2016 at 20:48
  • I know how I can get it to work. Now I'm just trying to figure out why it behaves this way. Commented Feb 26, 2016 at 20:48

4 Answers 4

6

It's because of hoisting. Variables declared in a function are available for the entire scope, but they are assigned a value where you put it.

This:

function echoThis() {    
    alert(fruit);
    var fruit = "Apple";
}

becomes this:

function echoThis() {    
   var fruit;
   alert(fruit);
   fruit = "Apple";
}

This is why you code is evaluated successfully, but fruit's value is undefined.

also:

var fruit = "Orange"; //this fruit variable
echoThis();

function echoThis() {    
    alert(fruit);
    var fruit = "Apple"; // is overridden by this, 
     //because it's re-declared in a local scope. 
}

if you really want to change this then remove the var in the function.

   function echoThis() {    
        alert(fruit);
        fruit = "Apple";  //this now accesses the global fruit.
    }
Sign up to request clarification or add additional context in comments.

2 Comments

Great answer, thanks. I wasn't trying to accomplish anything particular except learning JS behaviour here. So basically the answer to my question is: Var declarations are hoisted, but variable assignments are not?
Additionally, function declarations will be fully hoisted; function expressions, just the variable name (as above).
3

The variable is hoisted to the top of the function when it is compiled.

function echoThis() {    
    alert(fruit);
    var fruit = "Apple";
}

Translates to this

function echoThis() {    
    var fruit;
    alert(fruit);
    fruit = "Apple";
}

So when the alert is called it is technically undefined at this point. To stop seeing that move your variable declaration before the alert statement.

4 Comments

Allright, but why is only "var fruit" hoisted, and not "var fruit = "Apple"?
Only variable declarations are hoisted, but not the assignments.. that is how the compiler works
@Weblurk Because only declarations are hoisted, not asignments.
@Cristy Gotcha, makes sense now!
0

that's because js has lexical scope and hoisting.

so echoThis looks for fruit within itself before looking outside and since you have var fruit = "Apple"; , fruit is hoisted in echoThis.

1 Comment

I don't think lexical scope has anything to do with this. pierrespring.com/2010/05/11/function-scope-and-lexical-scoping
0

Besides the above responses, if you want to get the orange AND the apple after.. you could try to pass the variable simply as a parameter and work in the function

var fruit = "Orange"; 
echoThis(fruit);

function echoThis(fruit) {
  alert(fruit); // You will get the orange
  var fruit = "Apple";
  alert(fruit); // You will get the apple
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.