This question already has answers here:
What are the precise semantics of block-level functions in ES6?
(2 answers)
Closed 6 years ago.
I read Kyle's I don't know JS and came to know that function declarations will hoist first before the var. So in the below code
<script>
foo();
var a = true;
if ( a ) {
function foo() { console.log( "a" ); }
}else {
function foo() { console.log( "b" ); }
}
foo();
</script>
foo should be hoisted first and should print "b" as output for the first foo(), right? or am I missing anything?
Explanation or a link to understand to the code and hoisting in different scenario's would be a great help.
Hoisting (in the way that you're expecting here) will only work when there is a precedential order of things that is unambiguous. In this case, because your function is defined inside an if block, hoisting it will not happen as you expect it to.
This will work:
foo();
var a = true;
function foo() { console.log( "a" ); }
foo();
Because it removes from the equation your if statement.
Related
This question already has answers here:
Javascript - Precedence in hoisting
(2 answers)
Closed 5 months ago.
Recently, I received this interview question, I know it's weird to declare var name and function name the same, but the code runs without errors, and I don't know how to explain this behavior, hence the question.
In the Chrome console, the following code logs 1:
var foo = function () {
console.log(1)
}
function foo() {
console.log(2)
}
foo()
And the following code logs 2:
function foo() {
console.log(1)
}
function foo() {
console.log(2)
}
foo()
Why are the results not the same?
Function declarations, including the assignment of their values, are hoisted. Variable assignments are not.
In the first case, the function declaration for foo is hoisted so is overwritten by the variable assignment even though that appears earlier in the source order.
This question already has answers here:
Function declarations precedence/overwriting variable declarations? Hoisting? Why?
(2 answers)
JavaScript hoisting for multiple declarations of the same variable
(1 answer)
Order of hoisting in JavaScript
(2 answers)
Closed 4 years ago.
I'm reading the second book of the series "You don't know JS" and I've read that functions are hoisted before variables.
So this is the code:
foo(); // 1
var foo;
function foo() {
console.log( 1 );
}
foo = function() {
console.log( 2 );
};
The output of this will be 1. But why? Functions are hoisted first and then variables. So after my function foo (the one that prints 1) is hoisted it has to be followed by the variable foo. So the result should be "undefined" instead of "1".
I expect the code to behave as if it had been:
// hoisted first
function foo() {
console.log( 1 );
}
// hoisted second
var foo; // implicitly initialized to 'undefined'
foo(); // call 'undefined' - error?
foo = function() {
console.log( 2 );
};
What's happening here?
As said, functions are hoisted before variables; if the interpterer comes across var foo after foo has already been defined in the scope, it will simply be ignored. It doesn't assign foo to undefined, it only ensures that a variable named foo exists in the current scope - which it already does.
As it says in your You Don't Know JS link:
multiple/duplicate var declarations are effectively ignored
Here's another commonly seen example of hoisted duplicate variables being ignored that might be more familiar/intuitive:
if (false)
var foo = false;
else
var foo = true;
turns into
var foo;
var foo; // does not actually do anything; does not assign `undefined` to `foo`, ignored
// foo just *happens* to not have anything assigned to it in almost all cases like this
if (false)
foo = false;
else
foo = true;
This question already has answers here:
What is the scope of variables in JavaScript?
(27 answers)
Closed 5 years ago.
I have small function logically output should be 1 but i am getting 10 .. Can any one help me out with this logic.
var a=1;
function foo() {
if(!a){
var a=10;
}
console.log(a);
}
foo();
Output is coming 10 not 1 . how.
It's because of something called "hoisting".
https://www.w3schools.com/js/js_hoisting.asp
JS interpret your code like this
var a=1;
function foo(){
var a;
if(!a){
a=10;
}
console.log(a);
}
foo();
In addition to hoisting as mentioned in other answers, keep in mind that when writing ES6 (by using let or const) your code will behave as you expect it to.
Why does this happen? Because let and const have block-level scoping and not function-level scoping.
let a = 1;
function foo() {
if (!a) {
let a = 10;
}
console.log(a);
}
foo();
This is why, when you use a JavaScript linting mechanism, like ESLint, you will see rules like vars-on-top ( https://eslint.org/docs/rules/vars-on-top ) specifically to avoid these types of issues.
This question already has an answer here:
Why JavaScript function declaration behave differently in chrome and safari? [duplicate]
(1 answer)
Closed 5 years ago.
In a book You Don't Know JS: Scope & Closures There is this sample of code I don't understand fully.
"Function declarations that appear inside of normal blocks typically hoist to the enclosing scope, rather than being conditional as this code implies:"
foo(); // "b"
var a = true;
if (a) {
function foo() { console.log( "a" ); }
}
else {
function foo() { console.log( "b" ); }
}
What does it mean? How is it even possible? Is the conditional not working?
It's happening because function declarations are moved to the top of the file by the javascript parser. That's what they mean by hoisting. The last declaration of foo overwrites the first when they are hoisted.
This question already has answers here:
Why does an undefined variable in Javascript sometimes evaluate to false and sometimes throw an uncaught ReferenceError?
(8 answers)
Closed 7 years ago.
I understand the following function because variable hoisting happens.
foo();
function foo() {
console.log( a ); // undefined
var a = 2;
}
However what I don't understand is the following part.
I got Reference Error, why?
foo()
function foo() {
console.log( a ); // Reference Error
a = 2;
}
--- Edit ---
So far, what I understand from the answers is the second does not make any hoisting and we cannot use any undefined variable.
foo()
function foo() {
// we cannot use any undefined variable, which "a" here
console.log( a );
window.a = 2;
}
For example
var a;
a; //undefined
b; //Reference error
In the first one, a is declared, but undefined, in the second it's also also undeclared (can't be found in foo or in global scope), so throws a ReferenceError.