I tried following code:
var a = 5;
function x() {
console.log(a);
}
x();
It runs as expected and prints 5.
But i changed the code so the global variable a will be overwrite as follows:
var a = 5;
function x() {
console.log(a);
var a = 1;
}
x();
It prints undefined. It doesn't make sense for me since the overwrite should be happened right after console.log(a). So what is the problem?
This is happening because your second a variable is being 'hoisted' to the top of the function and it hides the first a. What is actually happening is this:
var a = 5;
function x() {
var a;
console.log(a);
a = 1;
}
x();
Here is an article on hoisting from adequately good for further reading on the subject.
var a = 5;
function x() {
var a = 1;
console.log(a);
}
x();
you need to initalize variable a before console.log();
Related
Shouldn't the value of research be undefined as it has been declared as var research in the end. And hence the output be a type error. But I am getting the output as 'hello'. Any idea why?
function newFunc() {
function research() { console.log('hello') };
research();
var research;
}
newFunc();
Because of hoisting, what actually happens is more like this:
function newFunc() {
var research;
research = function() { console.log('hello') };
research();
}
newFunc();
The variable declarations and function definitions are hoisted - moved to the top of the function scope. So even though you are declaring it at the end, the compiler will move it to the top of the function so it ends up like:
function newFunc() {
var research = function () { console.log('hello') };
research();
}
newFunc();
JS only hoists declarations, not initializations. JS also hoists the actual function definition.
JavaScript only hoists declarations, not initializations. Documentation
So values will be assigned in the order they are placed, for instance:
x = 2;
console.log(x); //2
x = 3;
console.log(x); //3
var x ;
or in your case:
var x = 2;
console.log(x); //2
var x = 3;
console.log(x); //3
var x ;
Another thing is that, research in the var research; part is not undefined; it's rather a function expression till you override it by another assignment, like var research = '';
So in your case, it's like the following:
function newFunc() {
function research() { console.log('hello') };
research(); //'hello'
var research;
console.log(research) //function research(){console.log('hello');}
}
Please explain what is the logic behind this two types of behaviour to understand easily.
var a = 10;
function foo(){
a = 20;
}
foo();
console.log(a);
Prints---> a = 20;
var a = 10;
function foo(a){
a = 20;
}
foo();
console.log(a);
Prints---> a = 10;
Because of the scope
In Javascript, when you assign a parameter in a function you define it in the scope of that function, regardless if a variable already exists with the name in the outer/global scope.
Update:
It is worth mentioning that with ES6's arrow functions you could still access the outer var if your function was defined in a parent class or function, using the this keyword.
Example
class Bar {
this.a = 10;
this.foo = function(a) {
this.a = 20;
};
this.foo2 = (a) => {
this.a = 20;
};
}
Not exactly the same but it is about scopes
Check the following code snippet
var a =10;
var b = a;
function foo(a){
// a here woukd refer to the parameter a and not the global variable, since it got overridden
console.log(a, b);
a= 20;
}
foo();
// prints the global variable a
console.log(a);
function bar(){
console.log(a, b);
// overrides the global variable a
a = 20;
}
bar();
// prints the global variable a
console.log(a);
the first one is because of global scope
var a =10;
function foo(){
a= 20;
}
here varieble a is accesed globaly and updated from inside the function global varieble can access every place
in the 2nd example just passing a referece of varieble a as a parameter and inside the function the recived parameter value get changed
var a =10;
function foo(a){
a= 20;
console.log(a)
}
foo();
console.log(a);
please run the second example of code in console then you can understand the change.
In the first example a in the function is replacing the first declaration of a outside the function because you're not scoping it locally with var (or let or const).
In the second example the function accepts a as an argument so it becomes scoped locally to the function. Note that this occurs even if a isn't actually passed into the function (and is therefore undefined).
A good article on scope and context that might be of some use to you.
In javascript, function variables has its own scope, if you used var,let,const or using variable as provided in formal parameters in function. if you don't use any of above variable's scope will be global.
I have a problem with a local scope. The second console.log doesn't show "a" value, but shows undefined. Why so?
"use strict"
console.log(a); //undefined
var a = "a";
function b(){
console.log(a); // why is undefined here?
var a = "a1";
console.log(a); // here is "a1"
}
b();
JS will process your code like:
"use strict"
var a; // undefined
console.log(a); //undefined
a = "a";
function b(){
var a; // undefined
console.log(a); // all is clear, LOCAL variable a is undefined.
a = "a1";
console.log(a); // here is "a1"
}
b();
read more about hoisting here.
Also you can read about Function declaration hoisting, this is an important part of JavaScript fundamentals too.
Object-Oriented JavaScript, 2nd Edition: When your JavaScript program execution enters a new function, all the variables declared
anywhere in the function are moved (or elevated, or hoisted) to the
top of the function. This is an important concept to keep in mind.
Further, only the declaration is hoisted, meaning only the presence of
the variable is moved to the top. Any assignments stay where they are.
In the preceding example, the declaration of the local variable a was
hoisted to the top.
var a = 123;
function f() {
var a; // same as: var a = undefined;
alert(a); // undefined
a = 1;
alert(a); // 1
}
Hoisting is JavaScript's default behavior of moving declarations to the top. You have an a variable in your function scope. This is how it looks like when you're executing it:
"use strict"
console.log(a); //undefined
var a = "a";
function b(){
var a;
console.log(a); // Undefined because a is not set
a = "a1";
console.log(a); // here is "a1"
}
b();
Because you have another variable a defined in function b, so it' like this:
function b() {
var a;
console.log(a);
a = "a1";
console.log(a);
}
I just tried to check the scope variation by using the following code, but the result is coming not in an expected way. Can anyone explain what's going on exactly behind this..?
var a = 10;
+ function () {
a = 5;
var a;
alert("inline " + a); //Expected undefined but it displayed as 5
}();
alert(a); //Expected 5 but it alerted 10
DEMO
var hoisting
Because variable declarations (and declarations in general) are
processed before any code is executed, declaring a variable anywhere
in the code is equivalent to declaring it at the top. This also means
that a variable can appear to be used before it's declare
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var
The compiler understands your code as
var a;
a = 5;
The position of a var declaration within a function doesn't matter. These are entirely equivalent:
function () {
var a;
a = 5;
}
function () {
a = 5;
var a;
}
when use "var a" you request global value of variable, use "window.a" to display it:
<script>
var a = 10;
+ function () {
a = 5;
var a;
alert("inline " + window.a); //Expected undefined but it displayed as 5
}();
</script>
var a = 10; // Global scope
+ function () {
a = 5; // You are not using Var here .. so it is also a global scope
var a; // Now you are mentioning your a is Var so scope is changed from global to this function
alert("inline " + a); // Printing 5 because you local scope a has value of 5.
}();
alert(a); // Printing 10 because of global scope a has value 10
For this snippet, I'm not surprised global variable 'a' evaluates to be 5.
http://jsfiddle.net/MeiJsVa23/gZSxY/ :
var a = 10;
function func(){
a = 5;
}
func(); // expect global variable 'a' to be modified to 5;
alert(a); // and this prints out 5 as expected. No surprise here.
But how come for this code snippet, global variable 'a' evaluates to be 10 and not 5? It's as if the a = 5 never happened.
http://jsfiddle.net/MeiJsVa23/2WZ7w/ :
var a = 10;
function func(){
a = 5;
var a = 23;
}
func(); // expect global variable 'a' to be modified to 5;
alert(a); // but this prints out 10!! why?
This is due to variable hoisting: anything defined with the var keyword gets 'hoisted' to the top of the current scope, creating a local variable a. See: http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting
So, there are two things are going here: hoisting and shadowing.
Because the first one, variable declarations are "hoisted" to the top, so your code is equivalent to:
var a = 10;
function func(){
var a;
a = 5;
a = 23;
}
And because the second one, you're "shadowed" the global variable a with a local ones, so the changes are not reflected to the global a.
This is called "variable hoisting". var declarations (and function() declarations) are moved to the top of their scope.
This has to do with hoisting.
In the function, a local variable with the same name is declared. Even though it happens after your modification, it is deemed to have been declared before it - this is called hoisting.
Local variables hoist for declaration but not value. So:
function someFunc() {
alert(localVar); //undefined
var localVar = 5;
}
Functions, if declared with function name() {... syntax, hoist for both declaration and value.
function someFunc() {
alert(someInnerFunc()); //5
function someInnerFunc() { return 5; }
}
var a = 10; //a is 10
function func(){
a = 5; //a is 5
var a = 23; // a is now in local scope (via hoisting) and is 23
}
func();
alert(a); // prints global a = 10
Presumably, the statement var a = 23 creates a local variable for the whole scope. So the global a is shadowed for the entirety of func(), not just for the lines below the statement. So in your second snippet, a = 5 is assigning to the local variable declared below.