Skills Recommended for a JavaScript Enthusiast

Pooja Mehta
The Startup
Published in
6 min readSep 26, 2020

--

Photo Courtesy — Danielle MacInnes on Unsplash

After having some years of experience working with JavaScript, I realised that a person who loves working with JavaScript or wants to establish his/her career in JavaScript must have knowledge about some of the advanced concepts. To be honest, when I started my career, I did not know any of these concepts, but I learnt them over a period of time.

You’re never too old to start learning, and you’re never too young to aim high and achieve great things. — Asa Hutchinson

IIFE — Immediately Invoked Function Expressions

As the name suggests, an “Immediately Invoked Function Expression” is a function which is executed immediately as soon as it is created. There cannot be separate invocation call for such function after its execution is completed. The main benefit of using an IIFE is that it does not pollute the global object. The variables defined within an IIFE cannot be accessed in outer scope. Syntax for defining an IIFE is as below:

(function() {
/* code to be executed */
})();

Closures

A closure is an inner function which has access to the variables from it’s enclosing function’s scope. The closure function has access to variables in three scopes — variable in its own scope, variables in the enclosing function’s scope, and global variables.

var userName = "Jade";
function greetUser(name) {
var greeting = "Hey there, " + name + "!";
var welcomeMessage = function() {
var welcome = greeting + " Welcome!";
console.log(greeting); // access to outer scope's variable
console.log(userName); // access to global scope's variable
};
return welcomeMessage; // access to its own scope's variable
}
var greetingMessage = greetUser("John");
greetingMessage();

Here the method welcomeMessage is a closure function as it is defined within an enclosing function greetUser having access to variables of global scope, enclosing function’s scope and its own scope.

Currying

It is a process of transforming a function with more than two arguments to a sequence of functions each with a single argument. Its main benefit is it prevents calling the same function frequently with the same argument.

function multiplyNumbers(a, b, c) { // traditional method
return a * b * c;
}
var result = multiplyNumbers(3, 4, 5);
console.log(result); // prints 60
function multiplyNumbers(a) { // currying function
return (b) => {
return (c) => {
return a * b * c;
}
}
}
var result = multiplyNumbers(3)(4)(5);
console.log(result); // prints 60

Scope

Scope in JavaScript refers to accessibility of the variables. There are two types of scope in JavaScript— Global and Local scope.

  • Global Scope: Variables defined in the global scope can be used or referred in any of the functions defined in that scope. The variables which are only defined but not declared will automatically be treated as global scoped variables.
  • Local Scope: Variables defined in any function are termed as local scope variables. Function arguments are always local scoped variables limited to the scope of the function.
var userName = "John Doe"; // global scoped variablefunction transformUserName() {
var userName = "Jade"; // local scoped variable
console.log(userName); // refers to local scoped variable
}
console.log(userName); // refers to global scoped variable

Variables in JavaScript can be defined using keywords like var, let and const. Variables defined with keyword let and const have block scope and is recommended after introduction of ES2015. The keyword var was used prior to ES2015 and has function scope.

  • var — Variables defined with var keyword can be re-assigned, re-declared and are always hoisted by JavaScript engine.
  • let — Variables defined with let keyword can be re-assigned, but cannot be re-declared and are never hoisted by JavaScript engine.
  • const — Variables defined with const keyword can never be re-assigned, re-declared and are never hoisted by JavaScript engine.

Hoisting

As the name suggests, it moves all the variable declarations to the top of the script during the initialisation phase of the execution context. However, all the variables declared with var keyword are defined with undefined. This allows using variables directly without defining them. The variables declared with let keyword are not hoisted so it causes Reference Error when trying to use them without declaring them explicitly. Like variables, function declarations are also hoisted by JavaScript engine. This allows invoking of functions before they are initialised. Function expressions and arrow functions are not hoisted, which means the JavaScript engine will throw an error if we try to access them before they are defined.

console.log(a); // undefined // this works
var a = 1;
console.log(x); // this does not work
let x = 1;

Prototypal Inheritance

As the name suggests, inheritance allows us to inherit properties and methods of one object into another object. JavaScript does not support such classical inheritance, instead it supports inheritance via prototypal inheritance. JavaScript objects have a special property known as “Prototype” whose value is either null or references link to another object.

let Parent = {
name: "abc",
age: 23,
walk: function() {
console.log('walk');
}
};
let Child = {
education: "Graduation",
run: function() {
console.log('run');
}
};

In the above mentioned code snippet, we have two objects Parent and Child, now we want Child to inherit all properties of Parent, so we can use dunder proto syntax (__proto__) for achieving this.

Child.__proto__ = Parent; // it will pass properties of Parent object to Child object

Now, if we try to access property or method which is not available in Child object, it will try to find that in its prototype (which in this case is Parent).

Child.walk(); // will print walk to console from Parent object

Call Stack

A call stack is a mechanism for a JavaScript engine to keep track of the functions it executes in LIFO — Last-In-First-Out manner. Whenever a script starts its execution, JavaScript engine creates a Global Execution Context and pushes it onto the top of the call stack. When a function is called, JavaScript engine creates a new Function Execution Context and pushes it on the top of the stack and starts its execution. Each function call will create a different Function Execution Context and be pushed onto the top of the stack. As the function execution gets completed, its corresponding execution context gets popped from the stack.

function doSomething() {
// code execution...
doSomething1();
// code execution...
}
function doSomething1() {
// code execution...
}
doSomething();

The code above would be executed like this:

  1. Ignore all functions, until it reaches the doSomething() function invocation.
  2. Push the doSomething() function to the Call Stack.
  3. Call Stack:
    - doSomething
  4. Execute code inside the doSomething() function.
  5. Get to the doSomething1() function invocation.
  6. Push the doSomething1() function to the Call Stack.
  7. Call Stack:
    - doSomething
    - doSomething1
  8. Execute code inside the doSomething1() function, until it reaches its end.
  9. Return execution to the line that invoked doSomething1() and continue executing the rest of the doSomething() function.
  10. Pop the doSomething1() function from Call Stack
  11. Call Stack:
    - doSomething
  12. When everything inside the doSomething() function has been executed, return to its invoking line to continue the execution of the rest of the script.
  13. Pop the doSomething() function from the Call Stack.
  14. Call Stack:
    EMPTY

Async/Await

With the introduction of ES2017, we got a new addition of Async/Await functions which will allow developers to convert their asynchronous tasks to synchronous code without writing the callbacks. We can make a function async by simply writing async before the function declaration. await is a new operator introduced which will wait for a Promise to resolve or reject. It works only with async functions.

const getGreetingMessage = (name) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(`Welcome ${name}!`);
}, 2000);
});
};
const run = async () => {
let message = await getGreetingMessage("John");
console.log(message); // this will be executed after promise is returned from the invoked method i.e. in synchronous fashion
};
run();

Resources

  • Check out this cool website for amazing JavaScript related stuff
  • Check out this course for sharpening your JavaScript skills

You can share in comments about concepts that you think are necessary for a JavaScript enthusiast.👩‍💻 Happy Learning! 😄

--

--