Are functions set before variables in the javascript 'creation phase'?
Asked Answered
Y

2

3

I am doing the Udemy course Javascript: Understanding the Weird Parts right now, and I just learned about the creation phase and the execution phase that occurs when the interpreter interprets the JS.

I have a question, but I will first show you the code I am playing with:

http://codepen.io/rsf/pen/bEgpNY

b();

function b () {

  console.log(a);
}

var a = 'peas';

b();

If I understand correctly, in the creation phase, the variables and functions are 'set', meaning they are given spots in memory. The variables are all given the placeholder value of undefined. Then in the execution phase, the engine executes the lines starting at the top. When b() is first called, 'a' still has the placeholder value of undefined, then 'a' is given its initial value of 'peas', b() is called again and this time 'a' has the value of 'peas'. In my mind, one of two things has to be happening here. Alternative 1: In the creation phase, all variables are set before functions. This means that when a memory space for the function b() is created, the function includes a's value of undefined (because the 'a' memory space was already created with the value of 'undefined'). Alternative 2: the functions and variables are set in the lexical order they are in (in this case, b is created before a), and when b is created, the 'a' reference somehow means that the function is listening for any possible creation of an 'a' memory location, and when later the 'a' location is actually created, the reference refers to that spot.

Am I on the right track with either of these scenarios?

Yogurt answered 1/1, 2016 at 23:38 Comment(2)
I'm not sure about the details of the implementations but a good rule of thumb is to know that in var statements, the declaration of the variable is hoisted, but the assignment part is not. So your alternative 2 is wrong. And about the alternative 1, I think all variables and functions are assigned memory at the same time conceptually.Sherrilsherrill
Did any of the answers answer your question?Wilhoit
H
2

You can think of it like this.
Your original code:

b();

function b () {

  console.log(a);
}

var a = 'peas';

b();

is actually executed like this:

var a;
function b () {
  console.log(a);
}

b(); // log undefined because a doesn't have a value yet

a = 'peas';

b(); // log peas because a has a value

Basically all the variable and function definitions are hoisted at the top of the enclosing scope. The order doesn't really matter because the code inside the b function doesn't get executed until you actually call the function.

Hyacinthus answered 1/1, 2016 at 23:50 Comment(2)
Thank you. You interpretation implies the the 'a' memory space is created before the 'b' memory space. Is that really the case? If not, I just wonder what goes behind the scenes when the 'b' memory space gets created... Is it set to something like 'console.log whatever will the 'a' memory space, even though one doesn't exist yet..'?Yogurt
The console.log doesn't get get executed until you actually call b. To test that out inside b you can call a function that doesn't exists function b() { sadds(); } and you will notice that the error is thrown when you call b not when you define it.Hyacinthus
W
2

If I understand correctly, in the creation phase, the variables and functions are 'set', meaning they are given spots in memory.

I would not use the term set for this--it usually is used to refer to a variable being set to (assigned) a particular value. I also would not use the term "spot" or "memory"--we don't need to worry about these internals. It's clearer just to say declared.

I also don't really like the use of the term "creation phase", which is both non-standard and confusing--what is being created, exactly? I would prefer the term "compilation".

The variables are all given the placeholder value of undefined.

To be precise, I would not say they "have the value of undefined", but rather "have no value", or "are not defined". undefined is not a value held by a variable which has not been assigned to yet; rather it's a state, which causes the variable to evaluate to the undefined value when accessed.

Alternative 1: In the creation phase, all variables are set before functions.

Yes, although again it's going to be confusing to use the word "set". Say, "all variables are declared before functions". This is the process of hoisting.

Alternative 2: the functions and variables are set in the lexical order they are in (in this case, b is created before a), and when b is created, the 'a' reference somehow means that the function is listening for any possible creation of an 'a' memory location, and when later the 'a' location is actually created, the reference refers to that spot.

No. The function does not "listen" to anything. It just executes when you tell it to.

Is this important?

Not really. It falls into the category of arcana. So we clog up our brains with rules like, variables hoist this way, function declarations hoist some other way, let has yet some other hoisting behavior. In practice, almost all style guides will call for you to declare variables at the top of the function, and linters will warn you if you don't (or can be configured to do so). This immediately eliminates all variable hoisting issues.

Some people like to put internal functions at the bottom of their function, and that works fine since, if it's a function declaration (ie function foo() { }) the whole thing (including the definition) is hoisted. If it's a function expression being assigned to a variable (ie var foo = function() { }), then it's a variable, and we already decided to put those at the top of our function--see paragraph above.

In general, if your program depends on hoisting behavior, it's written badly. If you need to understand hoisting behavior to understand how the program works, it's written badly.

To summarize, all you really need to learn is one rule: put variable declarations (and their initializations) at the top of your function. Then you don't have to worry about hoisting at all.

(There are some exceptions, such as declaring a variable inside a for statement, as in for (var i...), which is fine, assuming i is not being used for anything other than the index of the loop.)

For some reason, people learning JS seem sometimes to focus on these oddities--such as "why does " " == false or something. I would suggest instead focusing on the how to think about your problems, and break them down, and writing nice clean code that just works, and that you and other people can maintain without worrying about the arcana. I've been writing JS for many years, and cannot remember the last time I encountered a problem related to hoisting.

Wilhoit answered 2/1, 2016 at 5:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.