Thursday, December 31, 2020

JavaScript - Understanding well


Let's understand JavaScript well

  • Avoid 'var' to declare variable
What's the output?
1:  var a = "X";  
2:  console.log(a+" - "+b);  
3:  var b = "Y";  
Explanation:
Do you expect the output to be "X - Y"? or an error be thrown? both are wrong.
The output is "X - undefined"
Here's the reason: JavaScript hoisting occurs during the creation phase of the execution context that moves the variable and function declarations to the top of the script. Even though the variable 'b' is declared and initialized with a value "Y" at line # 3, the declaration gets moved to the top of the script with a value undefined.
1:  bar();  
2:  //foo();//ReferenceError: Cannot access 'foo' before initialization   
3:  let foo = () => {  
4:    console.log('hello from foo');  
5:  }  
6:  function bar() {  
7:    console.log('hello from bar');  
8:  }  
Similarly in the above code the function 'bar' is accessible even before it's defined due to hoisting which makes the code difficult to follow as a function is used before it's defined. On the other hand the function 'foo' is not accessible before it's defined as it's created using 'let'. Use only let or const to declare variables and functions

  • Closure
A closure is the combination of a function and the lexical environment within which that function was declared. This environment consists of any local variables that were in-scope at the time the closure was created.
Let's understand this with an example
1:  let simpleFactory = () => {  
2:    return () => {console.log('log from function returned by simpleFactory'); }  
3:  }  
4:  let simpleFun = simpleFactory();  
5:  simpleFun();//log from function returned by simpleFactory  
On line# 1 we define a Factory function which returns a function that simply prints a message on the console. 
Lin# 4 we got the returned function stored in a variable 'simpleFun'. 
Line# 5 we invoke the function stored in the variable 'simpleFun' which prints the log message. 
Simple to understand, right? Let's see another example

1:  let parameterizedFactory = (x) => {  
2:    return (y) => {return x*y;}  
3:  }  
4:  let parameterizedFun = parameterizedFactory(5);  
5:  console.log(parameterizedFun(2));//prints 10  
6:  console.log(parameterizedFun(3));//prints 15  
Now we are adding a little complexity to the Factory function by parameterizing it. The factory now accepts a value in parameter x and that value is used inside the function returned by the factory in line#2. 
We call parameterizedFactory by passing a value '5' which gets assigned in 'x'
The function returned in line# 2 uses the variable 'x' inside its body which is possible because when the function (at line# 2) is created an environment is created for that function which includes all the in-scoped local variables, that's 'x' in this case.
The function got stored in 'parameterizedFun' at line# 4 has access to the variable 'x' with value '5' due to Closure.

The local variable doesn't need stay constant, it can be even modified.
Let's see an example:
1:  let factoryWithLocVar = () => {  
2:    let count = 0;  
3:    return (y) => {count++; return count + y; }  
4:  }  
5:  let funWithLocVar = factoryWithLocVar();  
6:  console.log(funWithLocVar(2));//prints 3  
7:  console.log(funWithLocVar(5));//prints 7  
The function returned in line# 3 refers to a local variable count and even it modifies it during each invocation. The local variable 'count' is modified during each invocation and the modification reflects in subsequent calls to that function.

  • Pure function
A pure function in programming is a function that always produces the same output for the same set of input values and has no side effects. It means it should not change any state or data

Example:
1:  let add = (a,b) => {  
2:    return a+b;  
3:  }  
The above function would return the same result how many ever times it's called with the same input, and it doesn't modify state of any variables. In contrast an impure function may not return the same value in subsequent invocations for the same input also it could modify the state of a global variable (in the example given below it's the sum variable). 

Let's see an example:
1: let sum = 0;

2:  let add = (a,b) => {  
3:    sum += a+b;
4:    return sum;
5: }

More to follow ......

No comments:

Post a Comment