2

In John Resig's 'Learning Advanced Javascript' slide #6 (http://ejohn.org/apps/learn/#6) shows that you can use a function before it's defined. Here is the code:

var canFly = function(){ return true; }; 
window.isDeadly = function(){ return true; }; 
assert( isNimble() && canFly() && isDeadly(), "Still works, even though isNimble is moved." ); 
function isNimble(){ return true; }

However, I noticed the following code does not pass the test.

assert( canFly(), "Still works, even though isNimble is moved." ); 
var canFly = function(){ return true; }; 

It looks like assigning an anonymous function to a variable is different from defining a named function. Why is that? And what is the name of this concept that describe the ability to use function before its definition in a language?

4
  • possible duplicate of JavaScript 'hoisting' Commented Dec 13, 2013 at 1:13
  • The search term is "JavaScript hoisting" - check out linked duplicate (with slightly different code, but good links) - variables are visible for whole function (way before var), but will only get value during first assignment. Commented Dec 13, 2013 at 1:15
  • @AlexeiLevenkov Isn't the top answer there more about the scope rather than the order of things? Commented Dec 13, 2013 at 1:27
  • @DennisJaheruddin - somewhat - but you can read it as an explanation of how function declared at the end of scope is immediately visible at the beginning of scope. Commented Dec 13, 2013 at 1:39

3 Answers 3

4

The function declaration:

function isNimble(){ return true; }

is defined when the code is parsed (i.e. before any code is executed), wherease the function expression:

var canFly = function(){ return true; };

is evaluated when the code is running, so the function isn't callable until after this line is executed. That's the difference causing the second example to fail.

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

Comments

2

When Javascript creates the execution context it first creates all variables, functions and arguments. Next it assigns them values. Since isNimble is a globally defined function it is created in the first stage along with canFly however canFly is not assigned the function until after the second stage when assignment occurs. The assignment does not occur before the execution of the assert statement.

See: http://davidshariff.com/blog/what-is-the-execution-context-in-javascript/

Here is an excerpt from the above link that explains it well:

Execution Context in Detail

So we now know that every time a function is called, a new execution context is created. However, inside the JavaScript interpreter, every call to an execution context has 2 stages:

Creation Stage [when the function is called, but before it executes any code inside]:
    Create variables, functions and arguments.
    Create the Scope Chain.
    Determine the value of "this".
Activation / Code Execution Stage:
    Assign values, references to functions and interpret / execute code.

2 Comments

"Since isNimble is a globally defined function" should be "Since isNimble is defined using a function declaration".
In the quoted text, note that when entering function code the ThisBinding is set first, not last.
0

Here is the answer to why it happens (and has to happen). This does not depend much on the language and I just hope that I didn't use strange terminology for javascript.

When you are at a certain point in the code, you should know what happens when you call a function. Therefore the function is typically defined only once, or an order of precedence is known. Functions are not really designed to change, so it makes sense to have them available to the user even if they are defined in the bottom of the code.

When you call a variable, you want to have the value of that variable at the time when you call it. If you didn't define the variable before you call it, it should not work. Amongst others, this allows you to assign different functions to the same variable at different point in the code.


So to conclude: do not confuse 'after' with 'below' and just consider simple function definitions to occur before variable assignments (even if you assign a function to that variable).

1 Comment

It actually depends on language - and JavaScript moves all declaration to top of the scope (hoisting). Some languages would give an error if using variable/function before declaration...

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.