-1

Why does the following code print undefined? Also after removing the if block it prints hello there as output.

var message = "hello there!";

function hello(){
  console.log(message);

  if (true) {
    var message = "wassup?!";
  }
}

hello();

3 Answers 3

2

It's called hoisting. From the Mozilla docs (emphasis added):

Variable declarations, wherever they occur, are processed before any code is executed. The scope of a variable declared with var is its current execution context, which is either the enclosing function or, for variables declared outside any function, global.

The var message declared inside the if block hides the global message variable for all the code inside the function, including the call to console.log().

Two additional points. First, JavaScript separates variable declaration from variable initialization. That's why the local message variable has an undefined value when console.log(message) executes, rather than "wassup?!". Second, because hoisting is such counter-intuitive behavior (at least for programmers used to other languages), most JavaScript linting tools will warn you about var statements that are not at the start of their execution context. I strongly recommend that you find a linting tool (JSLint, JSHint, ESLint and JSCS come to mind) and use it.

Sign up to request clarification or add additional context in comments.

Comments

1

It happens when you define a local variable with the same name as a global. Since there is a var message in the scope of the function, it will only refer to the local message rather than the global one. Since it wasn't given a value at that time it's undefined. Notice if you move it to after the if it will be "wassup?!".

The solution is you probally didn't want to make a local variable. So change var message = "wassup?!" to message = "wassup?!".

Comments

1

To add to @Spencer Wieczorek's answer, variable definition is 'hoisted' to the top of it's scope, while variable assignment remains at the location you write it. So the code you have provided actually translates like this:

var message = "hello there!";

function hello(){
  var message;
  console.log(message);

  if (true) {
    message = "wassup?!";
  }
}

hello();

Which explains a little more clearly why you see these results - BEFORE your console.log() call, the message variable is created in the scope of the hello() function, but it doesn't get the value 'wassup?!' until later in the function.

EDIT: Here's a bit more info on this behaviour, which, as @TedHopps points out in comments, is called hoisted, not 'hitched'.

2 Comments

+1, but I believe that the standard term for this behavior is hoisted, not "hitched". :)
@TedHopp You're absolutely right. You know I sat here staring at it yesterday sure that it didn't look right but unable to put my finger on what it was. Editing it in now, Thanks!

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.