0

I was reading Kyle Simpson book: https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/scope%20%26%20closures/ch4.md#functions-first.

But I don't fully understand this line "Notice that var foo was the duplicate (and thus ignored) declaration, even though it came before the function foo()... declaration, because function declarations are hoisted before normal variables."

Let's say this is the code:

console.log(foo);     // The output is: foo() { return 2; }

function foo() {
    return 1;
}

function foo() {
    return 2;
}

var foo = 3;

I want to visualize what would be the output in JS Engine after Memory Creation phase. Will it be like this?

function foo() {
    return 2;
}

console.log(foo);

If yes, why var foo = 3; was ignored? There is no duplicate for var in the snippet. If no, can anyone please help me visualize what would be the output in JS Engine after Memory creation phase?

Thanks

newbie
  • 530
  • 1
  • 9
  • 36

2 Answers2

2
  • Function declarations
    1. Declare a variable with the same name as the function (this is hoisted)
    2. Assign the function to that variable (this is hoisted)
  • var statements with associated assignments
    1. Declare a variable with that name (this is hoisted)
    2. Assign the value to that variable (this is not hoisted)

var foo = 3 is not ignored.

The variable declaration (var foo) is ignored because the earlier function declarations already declared that variable. (i.e. because it duplicates the declaration of foo).

foo = 3 is not ignored and does assign 3 to foo … it just does so after your console.log statement runs because it isn't hosited.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
2

I think the text refers to

// scope creation
var foo; // the name was declared. Thrice.
foo = undefined; // from the var
foo = function foo() { return 1 }; // from the first declaration
foo = function foo() { return 1 }; // from the second iteration

// execution
console.log(foo);
;
;
foo = 3;

where foo is initialised with undefined due to the var foo declaration, but then gets overwritten by the initialisation value from the function foo declaration which takes precedence - regardless of the order in which the declarations appeared in the code, function declarations overrule var declarations.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • 2
    "*But in the book it says, functions are hoisted first, and then variables*" - oh well. Different approaches, some outcome. While I chose to say variables come first and then are overwritten, the book says "*multiple/duplicate var declarations are effectively ignored*", i.e. variables come second but don't overwrite functions. That's another reason why [hoisting is a bad metaphor](https://stackoverflow.com/a/32475965/1048572), no code is "moved around" and nothing of this is observable, all that matters is the resulting state at the beginning of the execution. – Bergi Aug 15 '21 at 19:31
  • 1
    Btw, you really should be reading [the second edition of the book](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/scope-closures/ch5.md), not the first one. – Bergi Aug 15 '21 at 19:31
  • Thank you so much for the explanation and the link. Really appreciate your effort :) – newbie Aug 16 '21 at 07:39