0

In this example, I know that it's going to print undefined.

var bar = typeof foo;
var foo = function() {
  console.log('abcd');
}
foo();
console.log(bar); // -> undefined

So I understand that when the variables are hoisted, bar remains above foo, but foo gets executed, so shouldn't the interpreter know what foo is?

Note: I'm trying to understand how the interpreter works. My question isn't about how to fix the above snippet.

Ben Harrison
  • 2,121
  • 4
  • 24
  • 40
TheRealFakeNews
  • 7,512
  • 16
  • 73
  • 114
  • 3
    `foo` wasn't executed when `bar` was assigned a value of `typeof foo`. During hoisting, the value of `foo` was undefined. – Tarun Dugar Jul 24 '16 at 03:57
  • Usually, it's best to forget that hoisting exists. It's only really useful to know about if your functions are getting in the way of readability and you want to declare them last, but you have to declare them using a named function expression. – 4castle Jul 24 '16 at 04:07

1 Answers1

5

If you account for the variable definition hoisting, your code is equivalent to this:

var bar;
var foo;

// foo does not yet have a value, so it it's still undefined
bar = typeof foo;

// foo gets a value here
foo = function() {
  console.log('abcd');
}

// since foo got a value in the previous statement, you can now execute it here
foo();
console.log(bar);

Only the variable definitions themselves are hoisted, not the assignments.

So, you can see from this ordering that when you execute bar = typeof foo that foo does not yet have a value so thus you assign undefined to bar.


Function definitions such as:

function foo() {
    console.log('abcd');
}

are also hoisted, so if you defined foo like this, then it would be a different story. But the function assignment you are using is not itself hoisted. The way you define foo, it is just a variable assignment like any other.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • But as you state, foo get's it's value on the second variable assignment, by the time `bar` is called on the last line, shouldn't the interpreter know what foo is? – TheRealFakeNews Jul 24 '16 at 04:11
  • 1
    @AlanH - `bar` contains a copy of whatever `foo` had at the time of the assignment. You can change `foo` to your heart's content and `bar` won't change. It's like `var y = 1; var x = y; y = 2;` The value of `x` didn't change just because you assigned to `y`. `x` has a copy of whatever was originally in `y`. – jfriend00 Jul 24 '16 at 04:13
  • @AlanH - See this answer from earlier in the day: http://stackoverflow.com/questions/38538330/when-command-line-order-matters/38538444#38538444 – jfriend00 Jul 24 '16 at 04:15