This question already has answers here:
Javascript function scoping and hoisting
(18 answers)
Closed 6 years ago.
The question is really simple but i searched everywhere couldn't get an answer.
add();
function add()
{
//function code here
}
The above code works in JavaScript even though function call is before function definition but wouldn't work in language such as C or C++. Could anyone tell me why?
It's known as hoisting, and it's definitely a trap for beginners!
Basically, if you take this code:
var x = 21;
var y = add10(x);
function add10(n) { return n + 10; }
after hoisting, it is evaluated like this:
function add10(n) { return n + 10; }
var x;
var y;
x = 21;
y = add10(x);
Because the declarations are separated from the definitions, and "hoisted" to the top.
Funnily enough, this would fail:
var x = 21;
var y = add10(x);
var add10 = function (n) { return n + 10; }
because it is evaluated like this:
var x;
var y;
var add10;
x = 21;
y = add10(x); // add10 is not a function (yet...)!
add10 = function (n) { return n + 10; }
It's called hoisting.
The javascript engine first looks for function declarations and 'hoists' them to the top before your actual code starts running.
Here's the documentation: http://www.w3schools.com/js/js_hoisting.asp
Related
This question already has answers here:
Export const arrow function or basic function?
(1 answer)
What are the advantages/disadvantages for creating a top level function in ES6 with arrows or without?
(2 answers)
Closed 4 years ago.
What are the differences between the following function declaration formats?
When is it more correct to use which?
From a beginner's perspective, and a high level (non-deep) point of view, they all three appear to work the same - hence it makes things feel confusing and demands the question.
1.
const counter1 = function(num) {
var x = 0;
while (x < num) {
console.log(x);
x ++;
};
return 0;
};
2.
function counter2(num) {
var x = 0;
while (x < num) {
console.log(x);
x ++;
};
return 0;
};
3.
const counter3 = (num) => {
var x = 0;
while (x < num) {
console.log(x);
x ++;
};
return 0;
};
All of them appear to behave the same.
There are more than a few differences between your three examples actually.
So, for one, you have to be careful using const for your function declarations.
counter1(5); // counter1 is undefined, this will fail
const counter1 = function(num) {
var x = 0;
while (x < num) {
console.log(x);
x ++;
};
return 0;
};
Whereas the function will be hoisted and available for use (Edit: technically let and const are also hoisted, but they aren't initialized so you cannot access them before they are declared, more info here.
counter2(5); // works fine
function counter2(num) {
var x = 0;
while (x < num) {
console.log(x);
x ++;
};
return 0;
};
Also note that const prohibits reassigning the variable, so you couldn't go say const counter1 = {} later down the line, whereas you could feasibly do so with the function example.
As far as the difference between function(num) { versus (num) => {, well in your example it makes no difference. But there are some differences... for example
const thisWillFail = () => {
console.log(arguments.length);
};
const thisWorks = function() {
console.log(arguments.length);
};
If you're unfamiliar with the arguments object, you can find info here.
This question already has answers here:
Surprised that global variable has undefined value in JavaScript
(6 answers)
Closed 7 years ago.
Hi I have a snippet of code. I am confused about change of value x1 when I remove non-related part of same code. I searched about it and I came to know that it has to do with hoisting. But the value x1 is still unclear even with hoisting concept for me. Can someone please make me clear on this?
var x = 10;
function main() {
document.write("<br>x1 is " + x);
x = 20;
if (x > 0) {
var x = 30;
document.write("<br>x2 is " + x);
}
var x = 40;
var f = function(x) {
document.write("<br>x3 is " + x);
}
f(50);
}
main();
The output of this code is:
x1 is undefined
x2 is 30
x3 is 50
If I change this code to:
var x = 10;
function main() {
document.write("<br>x1 is " + x);
}
main();
The output is:
x1 is 10
So what is happening here is a common pitfall.
The simplest way to put this is. When you set var x = 30 inside your main function, you are actually redefining the scope that var x = 10 had for use inside this function. This has to do with how Javascript executes and scope.
By defining x inside the function, your scope for x has changed. Below is an example of what I mean and a version of your code that works
Example:
var test = 'test';
function run(){
console.log(test);
var test=1;
}
Your Code Updated:
var x = 10;
function main() {
console.log("<br>x1 is " + x);
x = 20;
if (x > 0) {
x = 30;
console.log("<br>x2 is " + x);
}
x = 40;
var f = function(x) { console.log("<br>x3 is " + x); }
f(50);
}
main();
Good question btw.
Since this is somewhat of a very interesting scope of how Javascript executes, consider the following code and its outputs to get the full idea
var test = 'test';
function run(){
console.log(test);
test=1;
console.log(test);
var test=2;
console.log(test);
}
console.log(test);
run();
console.log(test);
Very interesting to see how this reacts.
All variable and function declarations get "hoisted" or moved to the top of their scope. The undefined value for x is caused because the var x statement gets moved up to the top of main however the assignment = 30 does not.
So, your code will read more like this:
var x = 10; // x is 10
function main() {
var x; // x declaration is "hoisted"
document.write("<br>x1 is" + x); // x1 is undefined
x = 20; // x is 20
if (x > 0) {
x = 30; // x is 30
document.write("<br>x2 is" + x);// x2 is 30
}
x = 40; // x is 40
var f = function(x) { // x is 50
document.write("<br>x3 is" + x);// x3 is 50
}
f(50);
}
main();
You can read more about Hoisting here: JavaScript Scoping and Hoisting
This question already has answers here:
Surprised that global variable has undefined value in JavaScript
(6 answers)
Closed 8 years ago.
I m a newbie to javascript. I usually program in Java. I am confused by this following code snippet.
<script>
x = "foo";
function bar(p){
if (p){
document.writeln("x = " + x);
} else {
var x = "baz";
}
}
bar("baz");
</script>
When I run the above code snipped its printing
x = undefined
Why does it print undefined, since x is a global variable it should print foo right ? Can anyone explain ?
since x is a global variable it should print foo right
It would if it wasn't shadowed by the var x = "baz"; declaration further up in your function; due to hoisting it will execute the function as if you wrote
function bar(p){
var x; // = undefined
if (p){
document.writeln("x = " + x);
} else {
x = "baz";
}
}
To make the code do what you want, you could simply write x = "baz"; instead of var x = "baz";.
try this output is x = foo
var x="foo";
function bar(p){
if (p){
document.writeln("x = " + x);
} else {
x = "baz";
}
}
bar("baz");
In JavaScript why i value is printed when we are printing outside the scope
test();
function test(){
for(var i=0;i<10 ;i++){
console.log(i)
}
console.log('outside'+i)
}
As comparison to Java it is giving compile error?
for(int x = 10; x < 20; x = x+1) {
System.out.println("value of x : " + x );
}
System.out.print("value o " + x );
JavaScript has function scope not block scope (C, C#, C++, Java and many other programming languages have block scope). In JavaScript a variable defined anywhere inside the function will be visible anywhere in the function:
function test() {
console.log(x); // logs undefined, because x is a variable that has no value yet
if (true) {
x = 42;
} else {
var x = 5; // x is not set to 5, but it is acknowledged as a variable
}
console.log(x); // logs 42 because the value in variable x has been set to 42
console.log(y); // Error because y is not declared
}
One thing you might see mentioned regarding this is var hoisting. This means the JS interpreter will act as if all the var statements in a scope (function or global) are moved at the begining of that scope:
function foo() {
console.log(x,y);
var x = 4;
var y = 2;
var x = 0;
}
// is equivalent to:
function foo() {
var x,y;
console.log(x,y);
x = 4;
y = 2;
x = 0;
}
More details on MDN
Also, note the difference between var and let from ECMAScript6
The scope of i in this case isn't the for loop, but the test() function.
In the following example, JavaScript seems to be completely ignoring my return statement, and just carrying on executing code.
var x = 1;
(function() {
x = 2;
return;
var x = 3;
})();
console.log(x); // Outputs 1 in both Chrome and FF
Surely the code should output 2? If I remove the var keyword from var x = 3, it outputs 2 as expected. Is there some strange compiler optimization at work here?
No, the code shouldn't output 2 because variable declarations are hoisted so your code is equivalent to
var x = 1;
(function() {
var x;
x = 2; // changes the internal x variable
return;
x = 3; // does nothing because it's not reached
})();
console.log(x); // Outputs the outside x, which is still 1
The line
x = 2;
only changes the internal x variable which shadows the outside one.
The scope of a non global variable is the entire function in which it is declared. From the start of this function to its end.