Avoid nesting if-else, use guard clauses technique instead
Guard clauses (guard, guard code or guard statement) is technique to write cleaner and more readable code. Guard The definition of guard clause by …
Scope is set of rules that determines where and how a variable can be referenced or is visible. Because we can nest blocks or functions inside another block or function, scopes are nested inside another scope. That means that we usually have more than one scope to consider.
In JavaScript there are 3 types of scope:
Global scope is a space, where its defined variables can be accessed and changed from anywhere in program. Variable becomes global, when defined outside of a function or block scope.
Let’s see an example:
let a = 'hello';
function foo() {
console.log(a);
}
foo();
Variable a is defined in the top level of the code, thus in the global scope. We can use it anywhere in the code, in this case inside the sayHello() function.
The value of global variable can also be changed anywhere in the code:
let a = 'hello';
function foo() {
a = true;
}
console.log(a); // hello
// greet will change the value of 'a'
foo();
console.log(a); // true
Usage or defining a global variable is considered as bad practice, because global variable can be changed in different areas of the program. This may result in unexpected results or behavior of the program.
function foo() {
a = "hello";
}
foo();
console.log(a); // hello
In the above code snippet we created a global variable a inside the hello() function and set its value to ‘hello’. When the console.log() was run, the printed value is ‘hello’.
In JavaScript, there is a ‘strict-mode;’ statement in which variables cannot be used without declaring it. Usage of var, let or const would fix this code and code execution would results in ReferenceError (desired behavior).
'use strict';
function foo() {
a = "hello";
}
foo(); // ReferenceError: 'a' is not defined
console.log(a);
If we wrap any code snippet in a function, it will ‘hide’ any enclosed variables or function declarations from the outside scope inside that function’s inner scope.
let a = 2;
function foo() {
let a = 3;
console.log(a); // 3
}
foo();
console.log(a); // 2
This approach of hiding variables from global scope is still not very ideal, because we are creating named function foo, this still ‘pollutes’ the global scope and we also have to explicitly call the function by its name foo() to execute the wrapped code.
However, the function can access all variables and functions declared inside the scope in which it is defined. This means, that function defined in a global scope can access all variables and function defined in the global scope and function defined in another function can access all function and variables defined in the parent function.
Prior to ES2015 only global and function scope was available, but in ES2015 block scope and let and const keywords were introduced.
Block scope restricts that a variable declared inside any block cannot be accessed from the outside of that block.
let and const keywords attaches the variable declaration to the scope of whatever block (in general any {…} pair) it is contained in. In other words, any variable declared inside a block scope with let or const cannot be accessed from outside.
{
let a = 1;
}
console.log(a); // ReferenceError: 'a' is not defined
Block scope is supported quite heavily in other languages than JavaScript (like C++ or Java), so programmers from those languages are accustomed to this design approach, but those working solely in JavaScript may find this concept not so obvious.
for (let i = 0; i < 5; i++) {
console.log(i); // will produce logs 0, 1, 2, 3, 4
}
console.log(i); // ReferenceError: 'i' is not found
This example shows, that for loop creates a block scope for i variable. The i is declared directly inside the for loop and if accessed outside the block will produce a ReferenceError. And the limitation to the block scope is intentional, we want i to be available only in given context. We want declared variables to be as close as possible and as local as possible to where they will be used (Principe of Least Privilege).
The very first block scope was introduced in ES3 (1997-1999) together with try/catch, where catch clause was creating block scope.
try {
throw new Error('crash');
} catch (error) {
console.error(error); // Works
}
console.error(error); // ReferenceError: 'error' is not found
As mentioned earlier, var is function scoped and let and const are function and block scoped.
Consider this example:
{
var v = true;
let l = 10;
const c = 'block`;
}
console.log(v); // true
console.log(l); // ReferenceError
console.log(c); // ReferenceError
var only attaches the variable declaration to function scope, but does not respect the block scope and is available in outer scope of block scope (or even in global scope).
And difference between let and const is that const creates a variable with fixed (constant) value. Attempts to change value of const will result in an error.
Avoid declaring variables in a global scope as it can result in unexpected program behavior. Use function or block scope to limit the visibility of any variable declared in your program but have in mind, that var is only function scoped and can leak outside any block scope.
Guard clauses (guard, guard code or guard statement) is technique to write cleaner and more readable code. Guard The definition of guard clause by …
Abstract factory is a creational design pattern that creates objects that follow a general pattern. Abstract factory is considered to be an another …