Why is the output 2 (and not undefined)? - javascript

I am learning JavaScript. I wrote a simple code snippet:
var a=5;
var a=7;
console.log(a);
This outputs 7 and understandably so. However:
var b=2;
var b; //!=undefined?
console.log(b);
outputs 2. I was expecting undefined since variables are initialized to undefined on initialization. What am I missing?
Thanks!

Because of hoisting. Your code will be interpreted by browser like:
var b;
var b;
b = 2;
console.log(b);
For more information: https://www.w3schools.com/js/js_hoisting.asp

var initializations are hoisted, and duplicate initializations are ignored. Variable assignments are not hoisted. So, to the interpreter, your first code looks more like:
var a;
a = 5;
a = 7;
console.log(a);
and your second code looks like:
var b;
b = 2;
Just a plain "var b" is effectively ignored if b has already been declared as a var earlier.

Related

var hoisting and value between redeclaration

Run below code in Node environment. Running it in browser console doesn't allow to redeclare variable of var.
console.log(a);
var a = 5;
According to hoisting, the above code is going to look like this
var a = undefined;
console.log(a); // undefined
a = 5;
a variable is being hoisted to the top of the file. JS Engine allocates memory for this variable before the execution. The question is why below code consols 5 instead of undefined.
var a = 5;
console.log(a);
var a = 6;
I'm looking at this code and imagining that it's going to look like this:
var a = 5;
var a = undefined;
console.log(a); // undefined
a = 6;
I'd like to be sure of the answer instead of guessing. The JS Engine is smart enough to see that a variable is already declared and is going to ignore the next var expression and rehoisting in such case? So the output should be looking like:
var a = 5;
console.log(a); // 5
a = 6;
So it's like:
JS Engine sees for the first time declaration (in this case along with initialization) of a variable so it's allocating memory.
JS Engine sees for the second time declaration of a variable but is going to ignore the hoisting because variable of given name is already in the memory.
Am I wrong in something?
Preface: In modern JavaScript, var should never be used. Use let or const.
The JavaScript engine handles var in two steps:
Upon entering the global scope or a function scope, it processes every var in the entire scope, defining variables for the them initialized wit the value undefined. If a variable is declared more than once with var, it's exactly as though it were declared once.
Then it starts the step-by-step execution of the code. In that step-by-step execution, any initializer on a var statement (the = 5 in var a = 5) is considered an assignment. So var a = 5 is treated exactly like a = 5 at this point.
So in your example:
var a = 5;
var a = undefined;
console.log(a); // undefined
a = 6;
It's as though you had written this:
var a = 5;
a = undefined;
console.log(a); // undefined
a = 6;
or this:
a = 5;
var a = undefined;
console.log(a); // undefined
a = 6;
or this:
a = 5;
a = undefined;
console.log(a); // undefined
var a = 6;
or this:
var a;
a = 5;
a = undefined;
console.log(a); // undefined
a = 6;
or this:
a = 5;
a = undefined;
console.log(a); // undefined
a = 6;
var a;
or even this (but please don't! :-) ):
var a = 5;
var a = undefined;
console.log(a); // undefined
var a = 6;
var a;
That is, first all the variables declared with var are created (and only once), then the code runs as though any initializers on them were assignments.
This is not how let, const, and class declarations are handled (collectively: lexically-scoped declarations). First: Multiple declarations in the same scope are an error (including if one of them is with var and the other is with one of the lexically-scoped ones). Second: They're hoisted (in Step 1 above), but the hoisted binding¹ is uninitialized until the declaration is executed in the step-by-step code, at which point it's initialized (either with the value from the initializer, or with undefined if it's just e.g. let a;). The time between entry to the scope and the point the binding is initialized is called the Temporal Dead Zone. var doesn't have it because var variables are initialized when they're created (with the value undefined), but let, const, and class declarations do.
¹ The term binding is the general term for variable-like things. In the code:
function example(p) {
var v;
let l;
const c = 42;
function f() {
}
class C {}
}
the bindings created upon entering the example function's scope are p (a parameter), v (a var variable), l (a let variable), c (a const constant), f (the binding created by a function declaration), and C (the binding created by a class declaration). (Note: function and class expressions are handled slightly differently.)

understanding functions and numbers

var a = 3;
var b = 5;
example(a, b);
function example(b, a) {
var result = b - a;
alert(result);
}
My question is looking at this I though the result would be 2 but its negative 2 can someone explain why please?
You've inverted the arguments in your function definition.
While you are calling (a,b), you are receiving (b,a). This means that you are passing:
example(3,5)
and receiving:
(b=3, a=5)
You then return:
(b-a) or (3-5)
which is -2.
The actual names of the parameters in the function don't matter. You're getting confused because wherever you found the example- they cleverly reversed the order of b and a. However the names in the parameter are just used in the function scope and don't affect variables of the same name outside of it. For example:
var a = 3;
var b = 5;
example(a, b);
function example(bacon, eggs) {
var result = bacon - eggs;
alert(result);
}
Would also return -2 because the first parameter we pass through to example is a (3) and the second is b (5) and 3-5 = -2. Doesn't matter what the name of the parameters in example actually are named- its important to keep this in mind.
There is no problem with your code. The problem is with your lecture of the code. The result is in fact, -2. Debug your code in Chrome Debugger or similar
var a = 3; // a equals 3
var b = 5; // b equals 5
example(a, b); // Replacing variables this is the same as example(3,5)
// Changing variables names so you don't get mixed up
function example(c, d) {
// Since you called example(3,5) then c = 3 and d = 5
var result = c - d; // This results in -2
alert(result);
}
Don't be confused with the variable names because in js, it works by the order of your function argument not by variable name of functions. To get what you want as output i.e 2, try like this.
example(b = 5, a = 3);
function example(b, a) {
var result = b - a;
alert(result);
}
If you've any confusion go to http://www.pythontutor.com/javascript.html and see what is happening under the hood.

Reference Error | javascript

Can anyone explain how below code works in JavaScript or any other programming language.
What the below referencing is called.
var a=5;
var a=b;
b=10;
console.log(a);
console.log(b);
10 // value of a returned
10 // value of b returned
or
var a=5, b;
var a=b;
b=10;
console.log(a);
console.log(b);
Both returns value as 10. Why is the value of a is assigned to 10 and how?
This will never work.
It will show b is not defined in javascript.
I think you mean this:
var a=5;
var b=a; //changed this from var a=b to var b=a. this is important
b=10;
console.log(a);
console.log(b);
line one declares var a, it equals to five.
line two declares var b, it equals to a, which is five. on ur code u said var a is b (b is never declared)
line three says var b is ten.
then u just logs them.
or if u mean this
var a=5;
var b=a; //changed this from var a=b to var b=a. this is important
a=10;
console.log(a);
console.log(b);
then it's basically the same thing except on line 3, u change value of a to 10. u would think that var b's value will also be 10 but you need to say b=a AGAIN after that

JavaScript blockscope with let

I modified the original script from the MDN website given below.
What is the type of var? Is the type assigned only after a value is assigned to a variable.
Does var b = 1 overwrite the previous statement var b = 10? Or just the variable b?
Is let a non-standard language feature? I read here that it is supported in ECMAScript 6.
var a = 5;
var b = 10;
if (a === 5) {
let a = 4; // The scope is inside the if-block
var b = 1; // The scope is inside the function
alert(a); // 4
alert(b); // 1
}
alert(a); // 5
alert(b); // 1
What is the type of var?
var has no type. It's a keyword used to declare variables.
Is the type assigned only after a value is assigned to a variable?
When you declare a variable but don't assign any value to it, its value will be undefined, whose type is Undefined.
Does var b = 1 overwrite the previous statement var b = 10? Or just the variable b?
Variable statements are hoisted to the top. That means that those are equivalent:
// ...
var b = 10;
if(cond) var b = 1;
var b;
// ...
b = 10;
if(cond) b = 1;
So, since b was already declared, var b = 1 will be equivalent to b = 1.
Is let a non-standard language feature? I read here that it is supported in ECMAScript 6.
let was introduced in JavaScript 1.7, and was not part of any ECMA-262 standard at the time.
Now ECMAScript 6 has standardized it (in a bit different way than JS 1.7). However, be aware that ECMAScript 6 is still a draft.
Yes, var x has no type. var x = 1 has a type of number.
var b doesn't overwrite the other statement, it just sets a new variable for the given scope. It means within that scope you get the newly assigned value for b.
let is es6. So yes and no, depending on where your code is running.

Javascript multiple assignment statement

I saw that line in some code
window.a = window.b = a;
How does it work?
Does the following always return true?
window.a == a
it means
window.b=a;
window.a=a;
OR You can say.
window.b=a;
window.a=window.b;
two assignments in a single statment
and
And one more thing
window.a==a right?
yes this is Right. It will return true
This assignment runs from right to left, so at first 'window.b' will be assigned with 'a' value then 'window.a' will be assigned with 'windows.b' value.
You can break this multiple assignment like this and get the same results:
window.b=a;
window.a=a;
You should be also aware of something like scoping.
If you run this code in global scope, eg simple script like this:
<script>
var a = 10;
window.a = window.b = a;
</script>
window.a==a is true, because 'a' and 'window.a' are the same variables. 'a' is really a property of 'window' object. All global variables are properties of 'window' object. Knowing that you can write you code like this, and this code will be corresponnding:
<script>
var a = 10;
a = b = a;
</script>
But if you put this code in a function, it runs in function scope, eg:
<script>
function ex() {
var a = 10; // this is local variable
window.a = window.b = a; // this time window.a != a
}
</script>
Same as:
window.b = a;
window.a = a;
And no, window.a and a is not always equal. Typically it is only equal on the global scope in a web browser JavaScript interpreter.
The a and b properties on the window are being assigned to the value of a. Yes, if this code is executed in the global scope, a and window.a are the same.
var a = "foo";
//window.a and a are the same variable
window.a = "bar";
a; //bar
function f(){
var a = "notfoo";
//window.a is a different variable from a, although they may take the same value
window.a = "baz";
a; //notfoo
}
It's the same like:
window.b=a;
window.a= window.b;
window.a == a will be true in this case, after the statements above. There are some cases that it will be false, for example: when a is a global variable.
And one more thing: please find more informative title for your question next time.
Actually, window.a==a can be false if a has the value Number.NaN. That's because Number.NaN is not equal to any value, including itself.

Categories