Problem with hoisting

Hi guys ,i was at the end of the js course and learned about the hoisting , and this is the code in one of the exercises =

var foo = function() {
 return "I love Codecademy!"
};
 
function foo() {
 return "why put code here"
}
let phrase = foo();
console.log(phrase);

my question is = why I love Codecademy! is getting logged out , and not put code here .
based on the lesson =

  • a function declaration can be called from anywhere within the scope as long as it is in fact declared in the code.

  • var variables are hoisted to the top of function blocks, but not other types of blocks

  • let and const variables are hoisted to the top of their parent block for scope

  • function expressions will follow the rules of variable hoisting.

so if it doesn’t matter where to declare a function declration , because it wont get it’s place changed in hoisting and var will be teleported (i dont know what other word to use :sweat_smile:), why var is overwriting function declration

i even searched for , if there is any priotrization and the results are =

  1. Function Declarations
  2. Variable Declarations (var)
  3. Function Expressions

but again i don’t get it

There’s a good explanation in the Redeclarations section of the following article:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function

1 Like

For what it is worth, function declarations have no real advantage over function expressions. What’s more, function expressions can be protected and persistent for the entire session.

const foo = function (faz) {
    return faz
}
const bar = baz => baz;

As for var, one suggests forego its use and stick to let for transient variables (mutable/volatile) and const for persistent, non-mutable variables.

Above both function expressions are largely the same but with some distinct differences. The former has strict syntax in that it requires opening and closing curly braces and an explicit return. The latter has no this property and no arguments property, and cannot be used as a constructor, though that is old hat, anyway, now that we have class objects with their own build in constructor.

Bottom line, focus on the ES6 syntax and take the ES5 syntax into consideration only in passing. Use function () { } when writing multiline code blocks, and arrow functions when writing simple, one line lambdas, such as call backs and helper functions.

1 Like

thanks for the explanation , but i havent got my answer , why when i use console.log(phrase); my output is I love Codecademy! and not why put code here

Could it be because foo, the variable, is hoisted first? What happens when you reverse the order? It also might be where the two are stored. The variable is in the heap, the function is in the stack. More detail than that I cannot give without digging. Have you followed up on the reading posted by @cassian-goode?

yes i read that but it didnt had any information that can be useful on this manner , i also reverse it and still the same output

1 Like

Then I suspect it has something to do with the storage. Sorry I cannot be of more help.

1 Like

the only thing was that = “Note : that [function expressions are not hoisted”
but ií dont think it have anything to do with the problem

no problem , its ok

… (just to make it 20 charachter so i can send this message)

Function expressions are not hoisted, but their variable is.

maybe you have any idea about it , do you ?

so if the variable is , why it wont get logged and gets overwritted by the function declration

Cannot say. More to the point, do we really need to know why? Is it not enough to witness the behavior and accept it? Don’t use function declarations and this will never come into question.

isnt it better to undrestand the behavior , and see why one overwrite the other

That’s only chasing after one’s tail once the behavior is known. It is what it is. Accept it. We don’t need to know the inner workings of JavaScript to learn and use the language. Use what works, and not what you want to work, but can’t make it.

i found some stuff =

there is an prioritization =

  1. Function Declarations
  2. Variable Declarations (var)
  3. Function Expressions

and also =
when there is both a function declaration and a function expression with the same name within the same scope, the function declaration takes precedence over the function expression. This means that the function declaration will overwrite the function expression.

so in here make sense =

and also, even if you do = (the reverse)

function foo() {
 return "why put code here"
};

var foo = function() {
 return "I love Codecademy!"
};

let phrase = foo();
console.log(phrase);

you still get the why put code here as the output , becaus as said =

when there is both a function declaration and a function expression with the same name within the same scope, the function declaration takes precedence over the function expression. This means that the function declaration will overwrite the function expression

can you resend it again you just deleted it before i can read it

The above is a screenshot from the article previously posted.

My (very tentative) understanding is as follows (note this may not be correct - I am still fairly new to coding!):

The function declaration (i.e. the function that returns “why put code here”) is hoisted above the function expression (i.e. the code that returns “I love Codecademy!”).

As it runs, the function declaration is reached first, and then overridden by the assignment of the function expression to the variable ‘foo’, which is reached second.

To me, this seems to be similar to the example in the screenshot where the console logs “1”.

Please let me know if either of you think my understanding is incorrect!

As @mtf said earlier, it seems sensible to stick to let/const unless there is a specific reason to use var - to me, it seems difficult to understand/predict how var will work…

3 Likes

i didnt undrstood the “above”
wasnt it under it ?

Taking the example from MDN, the function declaration seems to be hoisted above “var a = 1”.

So when you log “a” to the console, you get “1” - because the “initializer comes later and overrides the value”.