javascript variable is undefined [duplicate] - javascript

This question already has answers here:
Surprised that global variable has undefined value in JavaScript
(6 answers)
Closed 3 years ago.
First , let's see the code.
var a=0;
b=1;
document.write(a);
function run(){
document.write(b);
var b=1;
}
run();
I think the result is 01 .but in fact , The result is 0undefined.
Then I modify this code.
var a=0;
b=1;
document.write(a);
function run(){
document.write(this.b); //or document.write(window.b)
var b=1;
}
run();
Yeah, this time it runs as expected. 01 . I can't understand, WHY?
More interesting, I modify the code again .
var a=0;
b=1;
document.write(a);
function run(){
document.write(b);
//var b=1; //I comment this line
}
run();
The result is 01.
So , Can anyone explain this?
Thanks for share your viewpoints.
I simplify this code
b=1;
function run(){
console.log(b); //1
}
two:
b=1;
function run(){
var b=2;
console.log(b); //2
}
three:
b=1;
function run(){
console.log(b); //undefined
var b=2;
}

When you refer to a variable within a function JS first checks if that variable is declared in the current scope, i.e., within that function. If not found it looks in the containing scope. If still not found it looks in the next scope up, and so forth until finally it reaches the global scope. (Bear in mind that you can nest functions inside each other, so that's how you get several levels of containing scope though of course your exmaple doesn't do that.)
The statement:
b=1;
without var declares a global variable that is accessible within any function, except that then in your first function you also declare a local b. This is called variable shadowing.
"But", you say, "I declare the local b after document.write(b)". Here you are running into declaration "hoisting". A variable declared anywhere in a function is treated by the JS interpreter as if it had been declared at the top of the function (i.e., it is "hoisted" to the top), but, any value assignment happens in place. So your first function is actually executed as if it was like this:
function run(){
var b; // defaults to undefined
document.write(b); // write value of local b
b=1; // set value of local b
}
In your second function when you use this.b, you'll find that this refers to window, and global variables are essentially properties of window. So you are accessing the global b and ignoring the local one.
In your third function you don't declare a local b at all so it references the global one.

When you write b = 1, you're creating a property in the global object.
In an ordinary function, b will refer to this global.
Since your function contains var b;, b within the function refers to the local variable. (var statements create local variables throughout the function, no matter where the var is).
However, the executable portion of the var statement (b = 1) is only executed at that point.

The var directive is processed on the pre-execution stage, the b becomes local variable before document.write(b);, so at that time, b is undefined.
Note: assign a value to a variable is at the execution time, so you could image your code is like below.
function run(){
    document.write(b);
    var b=1;
}
is the same as:
function run(){
var b;
document.write(b);
b=1;
}
Addtion:
This is why Put every var definition at the top of the function is good practice.

This code work fine for me
if(var_name === "undefined"){
alert(var_name+' : undefined');
}

Related

keywords like var re-initialize the global variables in functions?

if i write something like this:
var a = 1;
function lol(){
console.log(a);
}
lol();
it outputs 1 as intended, as i initialized a=1 in global scope. So i thought in function it initialized its value as well.
But when i write something like this:
var a = 1;
function lol(){
var a = a + a;
console.log(a);
}
lol();
it outputs NaN, which confuses me, cuz i thought the variable has already been initialized in global scope.
Here's my thoughts, don't know if it's correct or not, so i'm asking: i think the keywords like var/let/const, each time it's mentioned, it kind of re-initialize the variable or what? and since the second var is in block scope, so when mentioned with var, the variable a goes initialized again and thus becomes undefined, outputs NaN.
am i correct? plz help.
You initialize the variable then just use the same variable
var a = 1;
function lol(){
a = a + a;
console.log(a);
}
lol();
at statement var a = a + a; you are defining altogether different variable which was not initialize before arithmetic operation so it is resulting NaN compiler declared another variable with same name a
Maybe it's happening because of hoisting. Please refer https://developer.mozilla.org/en-US/docs/Glossary/Hoisting#var_hoisting
As per MDN,
JavaScript Hoisting refers to the process whereby the interpreter appears to move the declaration of functions, variables or classes to the top of their scope, prior to execution of the code.

javaScript hoisting not working properly

These are 2 examples which must have attained same result:
Example 1
<script>
console.log(a);
var a = 10;
console.log(a);
</script>
Rendered
<script>
var a = "";
console.log(a); //will result undefined
a = 10;
console.log(a); //will result 10
</script>
Result
undefined
10
Example 2
<script>
console.log(a);
a = 10;
console.log(a);
</script>
Expectation of Rendering
<script>
var a = "";
console.log(a); //should result undefined
a = 10;
console.log(a); //should result 10
</script>
Result
Now, as per JS Hoisting in Scenario 2, the variable if not declared must have been automatically declared onto top of its scope and still result should have been the same. Why is it not? Where is the concept failed?
The second case is different, because
a = 10
... does not declare a hoisted variable. It creates a property in the window object (even if the code would have been inside a function). This is not a declaration, and thus something that is not hoisted. So before you create that property, it does not exist.
Note that what you listed as rendered code is not entirely correct. A hoisted variable does not get a value, so for your first example it should look like this:
var a; // undefined!
console.log(a); // will output undefined
a = 10;
console.log(a); // will output 10
Note that if this code is not part of a function body, var a also creates the window.a property, and this happens at the hoisted declaration.
And for your second example, the rendered code could look like this
console.log(a); // Error: does not exist.
window.a = 10;
console.log(a); // will output 10
JavaScript hoists declarations, not initializations, see this page.
If you add a 'var a;' somewhere in your second example, it should work fine!
On example 2, at the time you run the first console log, a is really undefined.
a = 10 sets a new property a to the window object and there's no 'hoisting' when setting a property to an object that already exists.
when we will execute a source code .IN hoisting, The declaration variable goes over console.log().Then the variable allowcated a memory but does not access it. When I declaration a variable in memory. Then we give by default undefined value in place of that variable. (as like ,in html,place Holder works like this.
--- So you have not declared any variable. Hosting will not work here.
--- Can't access a here..Because when you define a variable.
Then you must be defined a variable.here u can not make variable so output: cannot access a

Difference in declaring variable

Please let me know the difference between the below two codes.
var a = 1;
function b() {
a = 10;
return;
}
b();
console.log(a);
This prints 10 in console.
whereas the below code prints 1 in console
var a = 1;
function b() {
var a = 10;
return;
function a() {}
}
b();
console.log(a);
Thanks for help.
In the first code there is one global variable 'a' which can be modified by any function and that change would be permanent.
But in the second code, there are two 'a' variable. Lets call them ag (a global) and al (a local). In second code b() function is modifying al (local variable a) not the global variable. But we are printing global variable in console.
Thats why results are varying in both the codes.
It's a metter of scope. In the first a is declared only out of function b, so when you edit a inside function b you are referencing the "outer" a.
In the second snippet you are re-declaring var a inside the function, so when you edit a variable inside the b function you are referencing the latest leaving untouched the "outer" a variable.
You have declared a in your second code inside the function hence the scope(availability) of your variable a persists only till function execution.
Once we return back from the function, local variable a is no more hence outer global a's value is printed.
when you are using var ,its scope will be local to its function.
and without var it will be a global function.
The first example is quite straight-forward: You declare an a variable which your b function closes over. So b sets a to 10.
Your second example is deliberately complex and confusing. You declare an a variable that b closes over, but then shadow it with an a variable inside b. To make matters worse, there's also a function declaration of a that is also in scope in b. The var wins over the function declaration, because function declarations are processed before var statements are. The outer a is completely unaffected by b, so the console.log at the end logs 1.
That's easier to describe with a diagram of sorts:
var a = 1; // <== The declaration `b` closes over
function b() {
var a = 10; // <== The inner `a` variable
return; // <== Returns from `b`
function a() {} // <=== Declaration that was processed immediately
// upon entering `b` (the `return` doesn't affect it
// at all), but which is then superceded by `var a`
}
b();
console.log(a); // Logs 1

JavaScript scope gets changed? Why does this happen?

The value of 'a' seems to lose global scope when the constructor a is called.
var a = 6;
function b() {
a = 10;
function a() {}
console.log(a); //10
}
b();
console.log(a); //6
The order is interpreted as shown below due to variable hoisting. Note that as #ShadowCreeper correctly points out, function a(){} is actually creating a local variable a inside of function b which is hoisted as shown below.
var a;
var b;
a = 6;
b = function() {
var a;
a = function(){};
a = 10;
console.log(a); //10
}
b();
console.log(a); //6
Because you are creating a local variable (the function a) then replacing that local variable's value (the function) with 10.
One way to avoid things like this is to precede all local variables and functions with "_" (underscore).
This answer has a really nice explanation of what is going on here.
The summary is that Javascript is processed in two phases, compilation and then execution. The function definitions occur during the compilation step, so inside of b the compiler sees the definition function a() {} and the local variable a is created within the scope of b. Later on when the code is executed, the scope of b already contains the local variable a before any code is executed, so the line a = 10; is just giving the local variable a new value. The function definition was already processed during compilation so that will not happen during execution, so console.log(a) will output 10.

Are variables statically or dynamically "scoped" in javascript?

Or more specific to what I need:
If I call a function from within another function, is it going to pull the variable from within the calling function, or from the level above? Ex:
myVar=0;
function runMe(){
myVar = 10;
callMe();
}
function callMe(){
addMe = myVar+10;
}
What does myVar end up being if callMe() is called through runMe()?
Jeff is right. Note that this is not actually a good test of static scoping (which JS does have). A better one would be:
myVar=0;
function runMe(){
var myVar = 10;
callMe();
}
function callMe(){
addMe = myVar+10;
}
runMe();
alert(addMe);
alert(myVar);
In a statically scoped language (like JS), that alerts 10, and 0. The var myVar (local variable) in runMe shadows the global myVar in that function. However, it has no effect in callMe, so callMe uses the global myVar which is still at 0.
In a dynamically scoped language (unlike JS), callMe would inherit scope from runMe, so addMe would become 20. Note that myVar would still be 0 at the alert, because the alert does not inherit scope from either function.
if your next line is callMe();, then addMe will be 10, and myVar will be 0.
if your next line is runMe();, then addMe will be 20, and myVar will be 10.
Forgive me for asking - what does this have to do with static/dynamic binding? Isn't myVar simply a global variable, and won't the procedural code (unwrap everything onto the call stack) determine the values?
Variables are statically scoped in JavaScript (dynamic scoping is really a pretty messy business: you can read more about it on Wikipedia).
In your case though, you're using a global variable, so all functions will access that same variable. Matthew Flaschen's reply shows how you can change it so the second myVar is actually a different variable.
This Page explains how to declare global vs. local variables in JavaScript, in case you're not too familiar with it. It's different from the way most scripting languages do it. (In summary: the "var" keyword makes a variable local if declared inside a function, otherwise the variable is global.)
Unless you use the keyword var to define your variables, everything ends up being a property on the window object. So your code would be equivalent to the following:
window.myVar=0;
function runMe(){
window.myVar = 10;
window.callMe();
}
function callMe(){
window.addMe = window.myVar+10;
}
If you keep this in mind, it should always be clear what is happening.
I would like to add that lambda expressions are also statically scoped at the location that the expression is defined. For example,
var myVar = 0;
function foo() {
var myVar = 10;
return { bar: function() { addMe = myVar + 10; }}
}
var myObj = foo();
var addMe = 6;
alert(addMe);
myVar = 42;
myObj.bar();
alert(addMe);
This will display 6 and 20.
As far as I understand, any variable without the var keyword is treated global, with it, its local scoped, so:
// This is a local scoped variable.
var local_var = "something";
// This is a global scoped variable.
global_var = "something_else";
As a good JS practice, it is recommended to ALWAYS add the var keyword.
myVar=0;
function runMe(){
myVar = 10;
callMe();
}
function callMe(){
addMe = myVar+10;
}
As far as the output is concerned myVar and addMe both will be global variable in this case , as in javascript if you don't declare a variable with var then it implicitly declares it as global hence when you call runMe() then myVar will have the value 10 and addMe will have 20 .

Categories