Calling a function before it is declared, browser independent? - javascript

If I do this in my <head> tag:
<script type="text/javascript" src="foo.js"></script>
And inside foo.js I do this:
var foo = new Foo();
function Foo()
{
//code here
}
Would this code reliably instantiate the variable foo even though its included above the function definition, or should I move it instead to the bottom of the file, like this:
function Foo()
{
//code here
}
var foo = new Foo();

Your example will work in any browser that follow the ECMAScript standard (all do at least with regards to this question).
See sections 10.3-10.5 of the specification.
First the local scope is set up and just thereafter the function body is actually run.
Read 10.5 (the section is really not very long) to understand why #meder's answer is right.
If you don't want to read the specs yourself:
10.5 tells to declare variables in that order (overwriting if a some name occurs twice):
Inheriting from outer scope = setting will affect the outer scope:
Variables of the surrounding scope.
The own function name.
Local scope = setting won't affect the outer scope:
The parameters (left to right).
The arguments object.
Declare all the inner variables (not overwriting the current value if any, undefined if none, yet)
All in all:
Returns the function x itself:
function x() {
return x;
}
Returns the parameter x:
function x(x) {
return x;
}
Returns the inner function x:
function x(x) {
return x; // the return does no harm, x is already set
function x() {} // before the actual body is evaluated
}
Also returns the inner function x:
function x(x) {
var x; // in this case a no-op
return x;
function x() {}
}
Returns 42:
function x(x) {
var x = 42; // overwrite x in local scope
return x;
function x() {}
}
Returns the second argument:
function x(x,x) { // assign left to right, last one "wins"
return x; // arguments[0] would still name the first argument
}
Returns 2 when x is called the second time, as x is set to the inner function:
function x() {
x = function() { return 2; } // set x in outer scope
return 1;
}

It's only necessary to move it above if you define it via var, such as:
var Foo = function(){};
var foo = new Foo;
Otherwise, to my knowledge the interpreter reads function definitions in advance.

As far as i know, JS does this to your code due to hoisting:
var foo; //var declarations hoisted up
function Foo(){ //function declarations hoisted up
//code here
}
foo = new Foo(); //the operation
so it should be fine. However, I'd not rely solely on hoisting because, for me at least, it's hard to debug when declarations are all over the place. For readability, order the code this way:
variable declarations
functions
operations
code 1:
console.log(foo); //undefined
var foo = new Foo();
console.log(foo); //Foo
function Foo(){
//code here
}
console.log(foo); //Foo
//acts like:
var foo; //var declaration hoisted up
function Foo(){} //function declaration hoisted up
console.log(foo); //undefined
foo = new Foo();
console.log(foo); //Foo
console.log(foo); //Foo
code 2:
console.log(foo); //undefined
function Foo(){
//code here
}
console.log(foo); //undefined
var foo = new Foo();
console.log(foo); //Foo
//acts like:
var foo; //var declaration hoisted up
function Foo(){} //function declaration hoisted up
console.log(foo); //undefined
console.log(foo); //undefined
foo = new Foo();
console.log(foo); //Foo

Related

JavaScript Hoisting - Hoisted code after Memory Creation phase

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
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.
Function declarations
Declare a variable with the same name as the function (this is hoisted)
Assign the function to that variable (this is hoisted)
var statements with associated assignments
Declare a variable with that name (this is hoisted)
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.

Way to understand this code. How is it working?

I was exploring scopes in javascript and came to know this problem. I don't understand how this problem is working.
function checkType() {
return foo;
foo = 10;
function foo() {};
var foo = 11;
};
console.log(typeof checkType())
My question is this how does javascript compiler decide to return function not variable. Any reference or explanation are welcome.
This is how the compiler will compile the above code..
function checkType() {
var foo = function() {}; /* function will be hoisted to the top,
and will be assigned to the variable as
the name is the same for the two.. */
return foo;
// Code will never reach here as you are returning before this
foo = 10;
foo = 11;
};
console.log(typeof checkType());
Functions which are defined using function() syntax will be hoisted, in this case, the nested function will be hoisted insde the checkType() and hence, the checkType() returns the function instead of the integer.
Note: Because the function was defined using function(){} syntax, it
was hoisted to the parent function scope, else, if the function was
defined using var foo = function() {} then the hoisting would not
have worked in the same way, your function would've returned undefined instead.
More reference on Scoping & Hoisting
http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting/
First all the function declarations are hoisted in a scope. So first of all the code moves the variable foo to the top of the scope and initialize its value to function.
The second declaration of variable is not hoisted because the function declaration is already hoisted. So the code is same as
function checkType() {
var foo = function(){}
return foo;
foo = 10;
foo = 11;
};
When we run a code there are two phase of it first is creation phase in this phase the syntax parser will read the code and hoist the function and variables, and second phase is execution phase in which the values are assigned to hoisted variables,
A point to note here is function are stored in memory during creation phase as it is where as the variables are hoisted but values
are not initialized ( which will be assigned during execution phase )
Compiler will treat your code like this after hoisting
function checkType() {
var foo = function() {}; //hoisted function
return foo;
foo = 10;
foo = 11;
};
console.log(typeof checkType(), '\nRturned value from function --->', checkType())
If you define your function as variable than it will be hoisted only but will not be initialized with value, you can see the below example
function checkType() {
return foo;
foo = 10;
var foo = function foo() {};
var foo = 11;
};
console.log(typeof checkType(), '\nRturned value from function --->', checkType())

How come function is first declared before a variabe but then the same function can't be resolved but the variable can?

The reason why in (A) "function" is printed out is probably because of hoisting respectively because in the creation stage the function is created in the variable object before the variable foo.
But if the function is created before the variable foo, how come I can't resolve the function (see (D)) but instead I can resolve the variable (see (C))?
(function() {
console.log(typeof foo); // (A) function pointer
var foo = 'hi';
function foo() {
return 'hello';
}
console.log(foo); // (C) hi
foo();// (D) TypeError: foo is not a function
})();
The is the order of events
var foo is hoisted and declares the variable foo.
function foo() {} is hoisted, redeclares the variable foo and assigns it a value (a function)
console.log(typeof foo) logs the function
foo = 'hi' assigns a string to foo, overwriting the previous value (the function)
console.log(foo) logs the string
foo() throws an error because a string is not a function
functions declaration are run before everything else
(function() {
function foo() { //Function declaration
return 'hello';
}
console.log(typeof foo); // (A) function pointer
console.log(typeof bar); // (B) undefined
var foo = 'hi',
bar = function() { //Function expression
return 'world';
};
console.log(foo); // (C) hi
foo();// (D) error
})();
Imagine your program looks like this, because foo() is the first thing to run
In the beginning you variable foo is hoisted but without initialisation, so it's undefined. Then it's overwritten by the function declaration. That's why typeof returns Function. Then the value is assigned to it ('hi'), so trying to call the function fails.
In the case of bar, you are using the Function expression syntax (var bar = function()) rather than Function decalration (function bar()), so bar is hoisted as an undefined variable and later a value is assigned to it.

In JavaScript, declare the variable inside a function, why function gets the higher priority? [duplicate]

This question already has answers here:
Javascript variable and function hoisting
(3 answers)
Closed 6 years ago.
function bar() {
return foo;
foo = 10;
function foo() {}
var foo = 11;
}
console.log(typeof bar());
typeof bar returns function?!
why not number?
JS functions are executed in two passes three passes. First, the engine walks through the code, looks for function declarations and hoists them (=moves them to the top), second, it hoists variable declarations (unless the same name is already hoisted), finally it runs the "normalized" code.
In your snippet, the engine picks function foo and moves it to the top of the function. The subsequent var foo is ignored.
This results in the following "normalized" code:
function bar() {
function foo() {}
return foo;
foo = 10;
foo = 11;
}
which explains your results.
Reference: Declaration Binding Instantiation, notice steps 5 and 8.
return foo just references to function foo() {} so it's returning Function
function bar() {
return foo; // function foo() {}
foo = 10;
function foo() {}
var foo = 11;
}
alert(typeof bar()); // function
another scenario
function bar() {
return foo; // returns foo undefined as no value is assigned
foo = 10;
var foo = function () {} // referenced to variable
var foo = 11;
}
alert(typeof bar()) // undefined
here it will return number
function bar() {
foo = 10;
return foo; // 10
function foo() {}
var foo = 11;
}
alert(typeof bar()); // number 10
this too will return a closure function which returns a number
function bar() {
foo = 10;
return function () {
return foo
}
var foo = 11;
}
alert(typeof bar()()); // number 10
You messed with return :).
It is not about the priority. It is about the thing you last return from the function. Alter them and see. You get number.
function bar() {
function foo() {}
var foo = 11;
return foo;
foo = 10;
}
alert(typeof bar());
This gives you number.
The reason for this behavior is due to Hoisting in javascript.
When javascript is interpreted, any variable definition is processed first, so in the scope of your function, the actual order of the call is something like this:
function bar {
var foo = 11;
function foo() {}
return foo;
}
The hoisting positions the var foo = 11 declaration first, and then the foo is overwritten by the foo named function. hence return foo returns the function itself, not the numeric value.
This is a good starting point to understand hoisting
The return statement prevents the number assignments from executing, but the function declaration doesn't care.
function bar() {
return foo;
foo = 10; //assignment is never executed
function foo() {} //function definition happens even if code is not executed
var foo = 11; //assignment is never executed
}
console.log(typeof bar());
To test this out, comment out the function foo() {} line. You'll see that bar() returns undefined. The assignment statements define foo even if the statements are not executed, but they don't clobber the value of foo until they are executed (thus leaving the function definition in place).
Fiddle with the code:
https://jsfiddle.net/vwm31faq
Function gets Hoisted to the top of the current scope, hence you code at execution time would look like
function bar() {
var foo;
function foo() {}
return foo;
foo = 10;
function foo() {}
foo = 11;
}
console.log(typeof bar());

Javascript variable and function hoisting

david sharif made a JS quiz which pretty much looks like-
var foo=1;
function bar(){
return foo;
foo=10;
function foo(){}
var foo =5;
}
typeof bar();//?
In my understanding, functions are hosited first and then variable declared inside. the hosited form of the function would be something like (correct me if i am wrong)-
var foo=1;
function bar(){
function foo(){}
var foo;
return foo;
foo=10;
foo =5;
}
typeof bar();//?
why typeof bar() is function not undefined?
Is this because of, at the time of function execution, it finds the first foo (which is a function) and returns happily without continuing search. Or something else?
Appreciate your time.
I found the answer in David Shariff blog.
"Shamelessly copied from his blog"-
Even though foo is declared twice, we know from the creation stage that functions are created on the activation object before variables, and if the property name already exists on the activation object, we simply bypass the declaration.
Therefore, a reference to function foo() is first created on the activation object, and when we get interpreter gets to var foo, we already see the property name foo exists so the code does nothing and proceeds.
If this sound like greek, read the whole blog
The Function Declaration "shadows" the var statement.
Paste this in to your console:
var foo = function(){}
var foo
typeof foo
This is how the code "looks like" to the Interpreter after compiletime:
var bar = function bar(){
var foo = function foo(){}
foo
return foo;
// never reached
foo = 10;
foo = 5;
}
var foo;
foo = 1
typeof bar();//"function"
Function declarations are evaluated upon entry into the enclosing scope, before any step-by-step code is executed. The function's name (foo) is added to the enclosing scope (technically, the variable object for the execution context the function is defined in).
Example 1
From this example wecan see that even we are declaring foo after the return statement, we can still get foo returned.
function bar() {
return foo;
function foo() {} // this will get initialized before the return statement.
}
console.log(typeof bar()); // this will be function
Example 2
From this example we can see that if we are declaring our variables in a normal way after the return statement, they will not execute(assigned).
Declare function after return.
function bar() {
return foo;
var foo = function() {} // this will not get assigned
}
console.log(typeof bar()); // this will be undefined
Declare number after return
function bar() {
return foo;
var foo = 12; // this will not get assigned
}
console.log(typeof bar()); // this will be undefined
Example 3
Now let's walk through a messier example line-by-line.
function bar() {
return foo;
function foo() {} // <-- initialize foo as a function
var foo = 11; // <-- this will not get assigned
}
console.log(typeof bar()); // function
I hope the above example will not only answer you question but also give you a better understanding of:
var foo = function() {} vs function foo() {}

Categories