Shouldn't this variable default to "top-level"? - javascript

Currently I am getting the result undefined and I don't understand why that is.
var variable = "top-level";
function parentFunction() {
function childFunction() {
alert(variable);
}
childFunction();
var variable = "local";
}
parentFunction();
I thought that because I declared the variable
var variable = "local";
after I called childFunction(), it would look up the scope chain and get the top level variable instead, but it seems that this isn't the case.

That happens because of hoisting, which is putting all var statements at the top of the function, but still executes the assignment statement at the line it was made. If you have a look below, the second var variable will shadow the global variable since it declares a local variable with the same name. Then, this newly declared variable will be undefined until it reaches the assignment line.
Basically, here's what your code does:
var variable = "top-level";
function parentFunction() {
var variable;
function childFunction() {
alert(variable);
}
childFunction();
variable = 'local';
}
parentFunction();

All the variable declaration statements will be moved to the top of the function in which they are declared, but the values will be assigned to them only when the control reaches the declaration/initialization statement. In your case, childFunction doesn't have variable, so it goes up in the scope and checks the parentFunction, where variable is declared but not assigned a value yet. So, it alerts the default value undefined.
This is called variable hoisting.

Related

why userid not change the global userid , it never used userid function declare inside foo

I have declared userid as a global variable and inside function I have assign a value to userid and declared a new function userid() but return always before inner function declaration.
Why I'm not able to change the global variable.
var userid = 'test1';
function foo() {
userid = 'test2';
return;
function userid() {}
}
foo();
console.log(userid);
It return test1 however expected result should be test2.
If i remove this
function userid() {}
it works fine.
I know its java script Hoisting played here but why and how?
In JavaScript, declarations are hoisted to the top of their enclosing scope, so when you declare the function id, it is processed as this:
function foo() {
function userid() {} // Even though you placed this last, it's processed first!
userid = 'test2';
return;
}
foo();
console.log(userid);
Even though you didn't write the function as the first thing in foo, it is processed as if you did and that means that a second userid variable is now in the local scope and is "hiding" the global one.
Now, there is still a way to access the global variable and that would be through the global window object:
var userid = "something";
function foo() {
// Hoisting is why we can call functions before we've declared them!
userid();
window.userid = 'test2'; // Access the global through the global object
return;
// Normally, nothing after a return is processed, but because of
// hoisting, this function declaration will be processed first.
function userid() {
console.log("hello from userid");
}
}
foo();
console.log(userid);
Why does userid assignment not change the global userid when a userid() function is declare inside a foo() function?
First, to understand this you need to know that both function declarations and variable declarations are hoisted to the top of the containing scope (i.e. the top of the function, if is defined in a function, or the top of the global context, if outside a function). Because of this, JavaScript functions can be called before they are declared.
Also, a function declaration takes precedence over variable declarations, but not over variable assignments. Therefore, we can say that a variable assignment override a function declaration. Remember, JS only hoists declarations, not initializations.
JS var statement does not declares a variable in block-level scope (variables scoped to surrounding curly brackets). Instead, instead it declares variables in function-level scope. This means, variables declared within a function are local variables and are only accessible within that function or by functions inside that function.
If you declare a global variable and a local variable with the same name, the local variable will have priority when you attempt to use the variable inside a function (local scope).
Your code is the perfect example, of how a variable assignment overrides a function declaration in the local scope let's analyze it.
var userid = 'test1'; // Variable initialization not hoisted
var bar = 'bar1';
function foo() {
console.log('userid-type: ', typeof userid); // userid() Function declaration hoisted
// to the top of the local scope
userid = 'test2'; // Variable assignment into the local scope that overrides the
// function declaration.
console.log('userid-type: ', typeof userid); // Because, when a variable assigment takes
// precedence over function declarations, then the variable is hoisted in the local scope.
// This is why you got that behaviour.
bar = 'bar2'; // Variable assignment to the global scope.
return;
function userid() {}
}
foo();
console.log('userid-value: ', userid);
console.log('bar-value: ', bar);
Why my code does not use the global variable. Because, the userid() local function has the same name as the userid global variable. Then, when the variable assignment occurs a userid local variable exits and belongs to the userid() local function then this variable will be override in the local scope because it has priority over the global variable .

Why global let declarations get overridden by unscoped variables?

When we create a variable without specifying let or var it gets added to window object in browser. For example
function change(){
val = 20;
}
change();
console.log(window.val); //20
console.log(val); //20
Here I am getting both console logs print value 20. But I do the same using let it doesn't get added to window object. I saw this answer with the explanation why this is happening.
let val = 20;
console.log(window.val); //undefined
console.log(val); //20
Now, in the below code, can someone explain, when I assign an un scoped variable inside the function why it is not getting added to window scope? Instead how it is changing the value of the variable declared with let
let value = 10;
function change(){
value = 20;
}
change();
console.log(window.value); //undefined
console.log(value); //20 why this is 20?
MDN says this about var:
The scope of a variable declared with var is its current execution context, which is either the enclosing function or, for variables declared outside any function, global. If you re-declare a JavaScript variable, it will not lose its value.
MDN says this about let:
Variables declared by let have their scope in the block for which they are defined, as well as in any contained sub-blocks. In this way, let works very much like var. The main difference is that the scope of a var variable is the entire enclosing function:
They both end up in a scope which is then propagated to child scopes but which scope they end up in and how they go about determining that scope is different.
Note that the entirety of a <script> element does have an implicit block and this implicit block inherits window as an ancestor scope. Variable declared by var end up scoped into window while variables declared by let are scoped into this implicit block.
Declaring variables with let in the top-level of your script lets you access it inside your entire script and even outside. Inside your function, you are not assigning a value to an unscoped variable.
Even if you were to write your function as below, it would not assign to the window object as it would then be function scoped.
function change(){
var value = 20;
}

Why is this console log affected by a subsequent if statement?

Consider the following code:
var a = 'a';
function b() {
console.log(a);
if (!a) {
var a = 'b';
}
}
b();
Running b() prints undefined to the console. However, if you remove the if statement, or even simply remove the var keyword from the expression within the if statement so that you're redefining the outer a variable, the string a will be printed to the console as expected.
Can anyone explain this? The only cause I can think of is that this is a race condition, and the if statement is running just a tad faster than the console.log.
This is not a race condition - it's a language feature and is working as the designers of the Javascript language intended.
Because of hoisted variable definitions (where all variable definitions within a function scope are hoisted to the top of the function), your code is equivalent to this:
var a = 'a';
function b() {
var a;
console.log(a);
if (!a) {
a = 'b';
}
}
b();
So, the locally declared a hides the globally declared a and initially has a value of undefined until your if statement gives it a value.
You can find lots of discussion about this characteristic of the Javascript language by searching for "Javascript hoisting".
When you use var statement in a function, it will be creating a new variable which is local to that function.
All the variables declared in the function, will be moved to the top of the function, irrespective of the place where they are actually declared. This is called Hoisting.
The hoisted variables will have the value undefined, by default, till they are explicitly assigned a value.
It prints undefined as it is, because of the 3rd point.
In your case, you declared a variable a within the if block. Since the variables are hoisted, the declaration is moved to the top of the function. It has the same name as the outer variable. When you access a in the function, it first looks in the current scope if there is a variable by that name exists. It checks other scopes only if it is not found in local scope. So, the local a shadows the outer a. When you remove the var statement, there is no a in local scope, so the outer a is used. That is why it prints a.

why if statement isn't looking for a variable in global scope

I am trying to understand scoping in JS.Here i have an example which has a variable in global scope called check.It has a truthy value i mean 1.Then inside a function called main which doesn't have a variable called check but has an if statement which checks whether there is a check variable or not ,upon which it reassign another value to check variable.Then prints it out.if i use
if(check){}
it prints undefined.Here i have some questions:
1. check variable is declared in global scope.It means it has access everywhere.Then even if the IF statement fails it should print the globally assigned value which is 1 instead of undefined.Why it prints undefined instead of 1??
2. main function scope doesn't have a check variable.When if fails to find check inside main function's scope ,why it doesn't look for it in global scope??
(function(){
var check=1;
function main(){
if(check){
var check=10;
}
document.write(check);
}
main();
})();
JavaScript only has function scope and something called hoisting. Every variable declaration inside a function gets put at the beginning of the function. Thus, your code is equivalent to
var check=1;
function main(){
var check; // = undefined
if(check){ // block doesn't create scope
check=10;
}
document.write(check);
}
The local variable check shadows the outer variable check.
JavaScript will look up the chain for the most local variable it can find. Basically, local scope trumps global scope.
This is one of the potential pitfalls with global scope, and is why it should be avoided, since it creates clashes with local variables.

javascript: creating a local scope of a global variable undefines it before it is set

I do not understand this behavior:
var a = 1;
console.log('a is undefined1:', a == undefined);
var a;
//iterate selected jQuery elements:
jQuery.each(this, function(index, htmlElement) {
console.log('a is undefined2:', a == undefined);
var a;
Returns:
a is undefined1: false
a is undefined2: true
If the last line (var a;) is commented out, this is returned:
a is undefined1: false
a is undefined2: false
I would expect always the latter output. What do I not know?
Thanks so much!
Putting var a inside a function creates a different a variable that is scoped to that function.
Since you don't assign a value to it, it is undefined.
When you comment it out, you are testing the outer a which has the value of 1.
Variables are hoisted. It doesn't matter where in a function you use var foo, the foo for that function still applies to the whole function.
Declaring variable within function using var makes local copy (new variable) with scope on the whole function - it does not matter whether it is used before it is declared.
Never declare variables without var.
If you want to access the golobal variable and you have local variable of the same name, you can access the global foo variable using window.foo

Categories

Resources