What are the benefits of initializing variables in JavaScript? - javascript

I understand that it's not necessary to initialize variables, but what are the benefits of doing so? It doesn't effect the scope of the variable nor the data type. The only reasons I could find were:
Avoid resulting in "undefined"
Explicitly show what the variable is intended for i.e. let myArray = [];

How you define the variable does actually affect the scope of the variable.
There is a big difference between these statements as far as scope, and also as far as mutability for const:
x = 1;
var x = 1;
let x = 1;
const x = 1;
For instance, the first line will create a global variable, the second will create a function scoped variable, and the third line will create a block scoped variable.
Another difference is the concept of "hoisting". let and const do not "hoist".

Initializing variables provides an idea of the intended use (and intended data type).
https://www.w3schools.com/js/js_best_practices.asp

Related

Is a Variable That is Equal to a Function Considered a Global Variable?

In a question on one of my quizzes, we were asked to determine how many global variables there are in the following block of code:
var one = 1;
var two = 2;
var multiplier = function(number){
}
I answered saying there are two: one and two. However, my teacher marked it wrong and stated there are 3 global variables. Is a variable that is equal to a function still considered a global variable?
Functions are first-class in Javascript - they can be assigned to any variable. A variable can hold any value - a number (as with one and two), a string, etc, an object, or a function.
A global variable which happens to point to a function (as with multiplier) is still a global variable.
Note that function declarations on the top level create global variables as well, for example:
function multiplier(number) {
}
// The function declaration created a property on the global object:
console.log(typeof window.multiplier);
// just like:
var one = 1;
console.log(typeof window.one);
Of course, global variables are best avoided when not necessary, and they're rarely necessary.

Javascript: difference in execution of duplicate var and let variables within `execution context`? [duplicate]

Why does var allow duplicate declaration but why does const and let not allow duplicate declaration?
var is allow duplicate declaration
xx=1;
xx=2;
console.log(xx+xx);//4
var xx=1;
var xx=2;
console.log(xx+xx);//4
But let and const does not allow duplicate deceleration
const yy=1;
const yy=2;
console.log(yy+yy);//Uncaught SyntaxError: Identifier 'yy' has already been declared",
let zz=1;
let zz=2;
console.log(zz+zz);//Uncaught SyntaxError: Identifier 'zz' has already been declared",
I saw something about that in here like,
Assuming strict mode, var will let you re-declare the same variable in the same scope. On the other hand, let will not.
But I want to know Why let and const doesn't allow re-declaration? and why var does? and How JavaScript handle these three type of deceleration ?
var
The var keyword was the only way to define variables until 2016*.
No matter where you write var x, the variable x is treated as if it were declared at the top of the enclosing scope (scope for var is "a function").
All declarations of the variable within the same scope are effectively talking about the same variable.
Here is an example... you might think that within the function we overwrite the outer name with fenton, and add Fenton to the inner variable...
var name = 'Ramesh';
function myFunc() {
name = 'fenton';
var name = 'Fenton';
alert(name);
}
myFunc();
alert(name);
In fact, it works just like this... the outer variable is not affected by the inner variable thanks to hoisting.
var name = 'Ramesh';
function myFunc() {
var name;
name = 'fenton';
name = 'Fenton';
alert(name);
}
myFunc();
alert(name);
Actually, you could also declare them implicitly by not using the var keyword at all, in which case they would be added to the global scope. Subtle bugs were often tracked to this.
let and const
Both let and const are block-scoped, not function-scoped. This makes them work like variables in most other C-like languages. It turns out this is just less confusing than function-scoped variables.
They are also both "more disciplined". They should be declared just once within a block.
The const keyword also disallows subsequent assignments - so you have to declare it with an assignment (i.e. you can't just write const x, you have to write const x = 'Fenton') - and you can't assign another value later.
Some people think this makes the value immutable, but this is a mistake as the value can mutate, as shown below:
const x = [];
// I can mutate even though I can't re-assign
x.push('Fenton');
// x is now ['Fenton']
Why Does it Matter?
If you want to avoid some of the more confusing aspects of var, such as multiple declarations all contributing to the same hoisted variable, and function-scope, you should use the newer const and let keywords.
I recommend using const as your default keyword, and upgrade it to let only in cases where you choose to allow re-assignment.
Unlike var, let is an ES2015 specification. The specification says:
Redeclaring the same variable within the same function or block scope raises a SyntaxError.
This is to improve scoping over vanilla var.
why does const and let not allow duplicate declaration?
There's a big difference between how c# or java (for example) handle duplicate variable names, where name collision returns a compilation error, and how it works in an interpreted language like js. Please, check the snippet below: The value of i isn't duplicated? Not really, still, in the function and block context the same variable name is referred as two different variables, depending on where those are declared.
function checkLetDuplication() {
let i = 'function scope';
for ( let i = 0 ; i < 3 ; i++ )
{
console.log('(for statement scope): inside the for loop i, equals: ', i);
}
console.log('("checkLetDuplication" function scope): outside the for loop i , equals: ', i);
}
checkLetDuplication();
Assuming you want to know whether this behavior is as per spec, check this 13.3.2
Within the scope of any VariableEnvironment a common BindingIdentifier
may appear in more than one VariableDeclaration but those declarations
collective define only one variable.
let and const are the recent editions, while var is probably as old as Javascript itself.
In old days Javascript code-base didn't used to be too big to bother about programming mistakes and most probably focus was to ensure that instead of reporting the error of re-declaration of variable JS engine should handle it.

Where to use `var` and where `let` in javascript? (NOT asking difference)

I have read my blog about the var and let. What I see is this.
var is a function or global scope variable depend on where it is defined.
where
let is block scope variable
So in lots of articles, I see they recommend to use let instead of var. I understand that because it eliminated the conflict of the scope of a variable.
So I want to ask where to use let and where to use var? If possible please provide any relevant link for that. If I go with recommendation than I have to use let everywhere.
What I understand is this.
let should be used in for loop as it creates its own lexical scope.
for(let i =0;i<5;i++){
setTimeout(function(){
console.log(i);
},100);
}
So in this case because of let, we will able to print 0,1,2,3,4, but if we have used var it would have print 5 time 5.
Also, I want to know your suggestion on what should be used in function scope and global scope?
let say, I have file index.js
var first = 1; // what should be used here and why
function function1(){
var first = 1; // what should be use here and why `let or var`
var first1 = 2; // what should be use here and why `let or var`
for(let i=0;i<2;i++){
console.log(i);
}
Also, I fill let is more than a variable, I create its own lexical scope, there would be more manipulation under the hood like creating IIFE sort of thing.
What I understand is that we should use function and global scope as var and let as only block scope? Please provide any recommended link which describes what is better where and why?
Thanks.
It's mostly right to only use let these days.
In almost all situations, let is a better or at least equivalent to var considering that leaky declarations make you write error prone code. Avoid using var.
Look at this code:
for(var i = 0; i < 6; i++) {
document.getElementById('my-element' + i)
.addEventListener('click', function() { alert(i) })
}
contrary to this code:
for(let i = 0; i < 6; i++) {
document.getElementById('my-element' + i)
.addEventListener('click', function() { alert(i) })
}
The first one makes a closure which catches i, defined by var, while the other one makes i different values. The first example makes every callback alert 6, since they are all pointing to the same object. However, the let in the second example makes a new block scope every time it iterates. This solves a very common pitfall in javascript.
In most situations, if you need to use var's scope to achieve something not available using let, it's almost always a sign that's something is wrong.
Also, don't rely on var's variable hoisting. If you are using a variable you didn't declare before, it becomes error prone.
Mostly, try to follow on the style guide you follow. If you don't have a special style guide you follow, try the AirBnB's: https://github.com/airbnb/javascript
The "never use var and use let" thing is mentioned here: https://github.com/airbnb/javascript#variables
let and var
You should use var, when you wan to define a variable globally, or locally to an entire function regardless of block scope. Variables assigned with the var keyword have functional scope. The variable isn’t accessible outside of the function.
And, you should use let to declare variables that are limited in scope to the block, statement, or expression on which it is used. When used inside a block, let limits the variable's scope to that block.
Variables assigned with let are very similar to those defined with var. The major difference is scope. This has been referenced above. Variables assigned with let have block scope. This means the variable can be seen within that block and any sub-blocks. Variables assigned with var have functional scope and ignore block scoping rules. Variables assigned with let can not be redeclared, they can only be reassigned.
According to this article, Only use the let keyword when you know that a variable will have a dynamic value. You probably don’t need to use var anymore
Clearly, you know the difference between let and var, and your question is WHERE TO USE WHICH?
First of all, if you are seeking for a better performance, use let wherever you are able to. However, you have to be aware that some old browsers may not be able to handle the let.
Second, I think the best and shortest answer to your question is " use let as long as you can, and if you couldn't then use var".
If you study the differences between let and var deeply, you can figure out where you should use var instead of let, I recommend you to read this article.

window[name] equivalent to dynamically access const and let declarations

The old style JavaScript var declaration outside of a closure is global (top-level scope) and can be accessed in a browser from the window object. For example, the declaration var x = 3; can be accessed with window['x'].
How do you similarly access a const or let declaration given the name (string) of the declaration?
var x = 3;
const y = 7;
let z = 21;
console.log('x = ' + window['x']); //x = 3
console.log('y = ' + window['y']); //y = undefined
console.log('z = ' + window['z']); //z = undefined
For the above example, how do you get the values 7 and 21 for "y" and "z" instead of undefined?
Fiddle with the code:
https://jsfiddle.net/g78ah6we/
Edits (notes added for clarity):
1. While not typical, there are use cases, such as from within a library, that it's necessary to access a declaration based only on the name of the declaration.
2. Only read access is needed (none of the declarations will be modified).
3. The window object is mentioned just to show the old way, but this question is not actually about using the window object (or the global object).
Using indirect calls to eval
Accessing global const and let definitions can be done using an indirect call to eval. That is make eval the result of a comma separated expression or assign it to a variable first. If the syntactic access is not directly to the built-in eval function it's an indirect access, and indirect access executes in global scope.
You can also set global let variables by building script to perform the setting operation.
"use strict";
let myVar = "global variable myVar";
console.log( myVar);
(function myLibrary() {
const myVar = "local variable myVar";
const indirectEval = eval;
var varName = "myVar";
console.log( eval(varName)); // direct call uses local scope
console.log( indirectEval(varName)); // indirect call uses global scope
var result = "\"updated global variable even though shadowed\"";
var js = varName + '=' + result;
indirectEval(js);
// but trying to define a new let variable doesn't attach to global scope
var js2 ='let letVar2 = "let variable two"';
indirectEval( js2);
})();
console.log( myVar)
console.log( "letVar2: " + typeof letVar2);
What you can't do is add a let or const variable to global scope using an indirect call to eval: they are block level declarations and the code eval evaluates is considered a block - so the declarations are discarded when (indirect call to ) eval returns.
PS. This is a technical answer. And yes, I have heard that "eval is evil" before, one or three times.
For read access only using hard-coded variable name strings (to prevent code insertion) you could use the pattern:
(0,eval)("identifierString");
as for example:
var x = 3;
const y = 7;
let z = 21;
{
const y = "shadow"
let z = 42;
console.log('x = ' + (0,eval)('x')); //x = 3
console.log('y = ' + (0,eval)('y')); //y = 7
console.log('z = ' + (0,eval)('z')); //z = 21
}
Indirect vs direct calls to eval
A direct call to eval only obtains the values of global variables that have not been shadowed in function scope of the call. This may restrict choice of variable names, or where the call can be made from, within the library.
An indirect call executes in global scope and can obtain the value of global variables irrespective of name shadowing within the library.
Creating a new Function object from source text, and calling it, may provide be an alternative to using an indirect call to eval in a web page. However the difference is largely semantic rather than one being better than the other.
Issues
If the global variable name (var, let, const or class identifier) comes from user input it really should be checked for validity (not all that easy) or at least accessed within a try/catch block to trap used of undeclared identifiers or use of name declarations before initialization.
Personally I would recommend finding alternatives to using global variable name strings in general. Providing a static name space object on the library (e.g. myLibrary.data) and processing string values that are property names of the object, or including option object parameters in library calls, come to mind.
Both let and const are block scoped.
In contrast, the variable declarations without var keyword creates variables in the outermost functional scope bubble. In browsers, the outermost functional scope is controlled by the window object.
What the window object doesn't control is the outermost block scope.
If your code doesn't work without being able to access variables in the window[nn] pattern, there definitely is a design issue in it.
I've marked traktor53's answer as accepted and upvoted it because it contains the technical core of the solution.
In case it's helpful for anyone, here's a solution wrapped up into a function that prevents executing code in the declaration.
var x = 3;
const y = 7;
let z = 21;
const malware = 'alert("Game over.");';
function getDeclaration(name) {
var identifierPattern = /^[_$a-zA-Z][_$a-zA-Z0-9]*$/;
var topLevelGet = (null, eval);
return identifierPattern.test(name) && topLevelGet('typeof ' + name) === 'number' ?
topLevelGet(name) : null;
}
console.log(getDeclaration('x')); //output: 3
console.log(getDeclaration('y')); //output: 7
console.log(getDeclaration('z')); //output: 21
console.log(getDeclaration('bogus')); //output: null
console.log(getDeclaration('malware')); //output: null
console.log(getDeclaration('if')); //EXCEPTION: unexpected keyword
Notes:
Be aware that the identifierPattern regex is very simplistic (does not handle all valid characters and trips up on reserved words... as traktor53 pointed out, "This is more complicated than you might think").
Change 'number' to 'object' or whatever is appropriate for your needs (for simplicity in the original question I used examples with numbers, but my real use case actually looks for objects).
Fiddle with the code:
https://jsfiddle.net/g78ah6we/6/

Why does var allow duplicate declaration but why does const and let not allow duplicate declaration?

Why does var allow duplicate declaration but why does const and let not allow duplicate declaration?
var is allow duplicate declaration
xx=1;
xx=2;
console.log(xx+xx);//4
var xx=1;
var xx=2;
console.log(xx+xx);//4
But let and const does not allow duplicate deceleration
const yy=1;
const yy=2;
console.log(yy+yy);//Uncaught SyntaxError: Identifier 'yy' has already been declared",
let zz=1;
let zz=2;
console.log(zz+zz);//Uncaught SyntaxError: Identifier 'zz' has already been declared",
I saw something about that in here like,
Assuming strict mode, var will let you re-declare the same variable in the same scope. On the other hand, let will not.
But I want to know Why let and const doesn't allow re-declaration? and why var does? and How JavaScript handle these three type of deceleration ?
var
The var keyword was the only way to define variables until 2016*.
No matter where you write var x, the variable x is treated as if it were declared at the top of the enclosing scope (scope for var is "a function").
All declarations of the variable within the same scope are effectively talking about the same variable.
Here is an example... you might think that within the function we overwrite the outer name with fenton, and add Fenton to the inner variable...
var name = 'Ramesh';
function myFunc() {
name = 'fenton';
var name = 'Fenton';
alert(name);
}
myFunc();
alert(name);
In fact, it works just like this... the outer variable is not affected by the inner variable thanks to hoisting.
var name = 'Ramesh';
function myFunc() {
var name;
name = 'fenton';
name = 'Fenton';
alert(name);
}
myFunc();
alert(name);
Actually, you could also declare them implicitly by not using the var keyword at all, in which case they would be added to the global scope. Subtle bugs were often tracked to this.
let and const
Both let and const are block-scoped, not function-scoped. This makes them work like variables in most other C-like languages. It turns out this is just less confusing than function-scoped variables.
They are also both "more disciplined". They should be declared just once within a block.
The const keyword also disallows subsequent assignments - so you have to declare it with an assignment (i.e. you can't just write const x, you have to write const x = 'Fenton') - and you can't assign another value later.
Some people think this makes the value immutable, but this is a mistake as the value can mutate, as shown below:
const x = [];
// I can mutate even though I can't re-assign
x.push('Fenton');
// x is now ['Fenton']
Why Does it Matter?
If you want to avoid some of the more confusing aspects of var, such as multiple declarations all contributing to the same hoisted variable, and function-scope, you should use the newer const and let keywords.
I recommend using const as your default keyword, and upgrade it to let only in cases where you choose to allow re-assignment.
Unlike var, let is an ES2015 specification. The specification says:
Redeclaring the same variable within the same function or block scope raises a SyntaxError.
This is to improve scoping over vanilla var.
why does const and let not allow duplicate declaration?
There's a big difference between how c# or java (for example) handle duplicate variable names, where name collision returns a compilation error, and how it works in an interpreted language like js. Please, check the snippet below: The value of i isn't duplicated? Not really, still, in the function and block context the same variable name is referred as two different variables, depending on where those are declared.
function checkLetDuplication() {
let i = 'function scope';
for ( let i = 0 ; i < 3 ; i++ )
{
console.log('(for statement scope): inside the for loop i, equals: ', i);
}
console.log('("checkLetDuplication" function scope): outside the for loop i , equals: ', i);
}
checkLetDuplication();
Assuming you want to know whether this behavior is as per spec, check this 13.3.2
Within the scope of any VariableEnvironment a common BindingIdentifier
may appear in more than one VariableDeclaration but those declarations
collective define only one variable.
let and const are the recent editions, while var is probably as old as Javascript itself.
In old days Javascript code-base didn't used to be too big to bother about programming mistakes and most probably focus was to ensure that instead of reporting the error of re-declaration of variable JS engine should handle it.

Categories