JavaScript blockscope with let - javascript

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.

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.)

Incrementing Numbers declared by new Number() via void functions

I know typeof(my_number) is a primitive number, which makes functions receive a copy of my_number instead of my_number itself, which does't make it's value change at all. This is working as expected (I also know var is deprecated, that's probably not my issue here whatever).
What i don't know is why my_object_number isn't changed. I know i could have returned number + 1 and associated it to my_object_number, but I'm intentionally trying to code something similar to what a void(int*)function would have done in C.
var my_number = 3;
var my_object_number = new Number(3);
var my_object ={
number: 3
}
function increments_number(numero){
numero = numero + 1;
}
function increments_object(number){
number.number++;
}
increments_number(my_number);
increments_number(my_object_number);
increments_object(my_object);
console.log("primitive number = 3, which increased by a function = " + my_number);
console.log("object Number = 3 , which increased by a function = " + my_object_number)
console.log("prop number of a hardcoded object = 3, which increased by a function = " + my_object.number)
the code above prints.
primitive number = 3, which increased by a function = 3
object Number = 3 , which increased by a function = 3
prop number of a hardcoded object = 3, which increased by a function = 4
I'm not sure why my_object_number isn't incremented
I know typeof(my_number) is a primitive number, which makes functions receive a copy of my_number instead of my_number itself, which does't make it's value change at all.
There is no difference between primitives and objects in JavaScript in this respect. Actually, you can forget there’s a difference at all, for the most part – in strict mode, they’ll either behave the same in every situation or throw an error. Function calls aren’t related either. Instead, the difference is between mutating a value and reassigning something that contains a value, like a variable or a property, to contain a different value.
var a = {};
var b = a;
b = {foo: 'bar'};
console.log(a); // didn’t change, because assignment to `b` changes the variable `b`,
// not the value `{}`
var d = 5;
var e = d;
e = 6;
console.log(d); // didn’t change, because assignment to `e` changes the variable `e`,
// not the value `5`
'use strict';
var a = {};
var b = a;
b.foo = 'bar';
console.log(a); // the value {} changed; all variables stayed the same
var d = 5;
var e = d;
e.foo = 'bar'; // throws an error; a primitive is indistinguishable from…
var f = Object.freeze({});
var g = f;
g.foo = 'bar'; // … an immutable object.
++, like all math operators in JavaScript, is an operation on something that contains a value – it doesn’t mutate a value. ++x acts like x = x + 1.

How to understand 'let' in 'for' statement? [duplicate]

This question already has answers here:
What is the difference between "let" and "var"?
(39 answers)
let keyword in the for loop
(3 answers)
Closed 5 years ago.
As far as I know, 'let' is used for declaring block variable. But it can't declare twice with same name. For example:
'use strict';
let a = 1;
let a = 2; // syntax error
So how to separate each scope in 'for' iteration with the same variable name?
'use strict';
for(let i = 0; i < 3; i++){
setTimeout(function(){
console.log(i);
});
}
// output:
// 0
// 1
// 2
Dose interpreter change the variable name silently? Any info will be appreciated.
I don't think is a duplicated question. Because I really want to ask is the conflict between two theory.
let scopes your variable to the block it's in.
After you've assigned a scope to a, you can't overwrite it. So the second time you use let, it can't handle that.
Correct usage would be:
'use strict';
let a = 1;
a = 2;
In the for loop , i is declaring at the beginning only and in each iteration it change the value of it .
let is used to variable that you will write there value again .
In the first example you define variable with name 'a' so you cant define another with same name , but you can change it value , which happened in the for loop.
'use strict';
let a = 1;
let a = 2; // syntax error
'use strict';
let a = 1;
var a = 2; this will overwrite...
here you specified a value already.. your intention is , it shouldn't change in runtime. so you cant able to change it once declared in block with same type let ..
that why you getting this error..
intention of let is value should not change..
in loop ,
it will be separate on iterate.. so it print value on runtime. so it wont overwrite it...
let allows to create the variable once, but the value of the variable can be changed,
example -
let t =5//
let t = 6 // throws an errow but
t =7
console.log(t) - gives 7
In the loop the variable is not declared again but only its value is incremented.
It is similar to the following:
'use strict';
let i = 0;
i = i + 1;
consider the code being iterated again and again until the condition fails.
for(let i = 0; i < 3; i++){
// code
}
step:
let i = 0
checkout i<3
exec code
i++, equals i = i + 1 // not occur error, while let i = i + 1 will occur exception
loop step-2 until i<3 == false
In your first example the variable a is defined twice in the same scope. This gives you an error because the variable already exists. let doesn't allow this, redeclaring with var does. This is one advantage of using let.
var a = 3;
var a = 2;
console.log(a); // 2
let b = 3;
let b = 2; //syntax error
let c = 3;
var c = 2; //also a syntax error
In a for loop, the i variable has a different scope. Meaning these two i variables here aren't the same.
let i = "my string";
console.log(i); //my string
for(let i = 1; i <= 3; ++i){
console.log(i); //1, 2, 3
}
console.log(i); //my string
The javascript runtime doesn't care if your variable is named the same. It will differentiate the scope and thus the reference to the variable. It's replacing your reference to i whichs value is 4 to the new variable in the for loop.
I have an answer on here on Stackoverflow which describes how the Android compiler doesn't care about your variable names. It's the same here, the runtime uses different "names" (different memory addresses).

What is the use of just declaring variables

I have been using python for a while now, and have just started learning javascript. In javascript you can, as I understand it, declare a variable without assigning a value to it (var cheese compared to var cheese = 4) in what situation would you want to declare a variable but not assign a value to it straight away?
Consider this snippet.
if (someCondition) {
var x = 5;
} else if (someOtherCondition) {
var x = 4;
}
if (x) {
doFunc();
}
Since x needs to exist for the doFunc to run, you simply add an undefined declaration above. var x; so that the if (x) doesn't return an error.
You do this when you want the value of the variable to be undefined.
var cheese;
console.log(cheese); // undefined
It's simpler than
var cheese = undefined;
The undefined value doesn't seem much useful, but this will allow to assign some other value later.
var cheese; can be perfectly useful (even if you never assign anything to it). Of course it's a shorter way to type var cheese = undefined;, but that's not the only reason…
Using var declares a local variable, and this has a nice property: it hides variables from parent scopes.
There's another part to your question:
If we're going to assign a value to var cheese anyway: why not assign immediately?.
Answer: it may be fine for your algorithm to return cheese without ever assigning anything to it — i.e. "undefined is valid".
Here's an example which illustrates how var hides variables from parent scopes:
var a = 3;
console.log(a); // prints 3; "a" is defined in this scope
function findEvenNumber(numbers) {
var a; // we declare this local variable, to ensure that we do _not_ refer to the variable that exists in the parent scope
numbers.forEach(function(number) {
if (number % 2 === 0) {
a = number;
}
});
return a; // if no even number was found, it returns undefined (because we never assigned anything to a)
}
findEvenNumber([1, 2]); // returns 2;
console.log(a); // prints 3; the "a" in this scope did not get overwritten by the function
Speculation: maybe the var cheese; syntax exists in ECMA to enable programmers to declare all variables at the beginning of their function. Such a convention was enforced by the C89 compiler, and some people grew fond of it.

Javascript multiple assignment clarification?

Looking at var a=b=1; , I already know that both a and b has the same value.
But my question is :
Does the a gets its value from 1 or from b ?
I made a small test :
/*1*/ (function (){
/*2*/ var j = window.j = function (){ alert('3');};
/*3*/ window.j2 = j;
/*4*/ })();
/*5*/
/*6*/ window.j(); //3
/*7*/ window.j=null;
/*8*/ window.j2();//3
As you can see line #8 yields 3 so I persume that a is not having the value of b but the value of 1.
Am I right ?
visualize :
(function (){
var j = window.j = function (){ alert('3');};
|
| ^ ^
| | | //which one ?
+----------+--------+
})();
Assignment in javascript works from right to left. So you are getting your value from window.j. Re-setting window.j will not affect the result because Javascript variables always passes by value, exception is array or object.
Example of passing value by ref in JS object:
var obj = { x: 2 };
var anotherObj = obj;
anotherObj.x++;
alert(obj.x); //3
You can find more information here.
More useful examples available in this answer.
The "=" operator associates to the right so "a=b=1" is equivalent to "a=(b=1)". So 1 is assigned to b first with a result of 1, which is then assigned to a.
Assigment in JavaScript is right associative, so you are correct.
In
a = b = c;
a takes the value of b at time of assignment, so if b is later assigned to something else, a retains its value (which happens to be the same as c)
You are right technically but are confused with reference / value assignment i think. Technically a does get it's value from b but there is no reference to b therefore if your were to do b = null it would have no affect to a, which is what you're seeing in your example.
a inherits the value of b without relying on b still existing or having that same value later on when you refer back to a. The assignment happens right to left so actually reads a = ( b = 1)

Categories