15 most important concepts that every JavaScript Programmer must know.

Antony Raj
12 min readDec 18, 2020

--

We will be covering basic concept every JavaScript programmer must know and master this.

1. IIFE

IFEE (Immediately Invoked Function Expression) is a JavaScript function that executes when it is defined.

(() => {
console.log(“Hello World”);
})()

This might look quite confusing at first but actually, the pattern is very simple.

Normally JavaScript functions can be created either through a function declaration or a function expression. A function declaration is a normal way of creating a named function.

A function created in the context of an expression is also a function expression. The key thing about JavaScript expressions is that they return values.

In both cases above the return value of the expression is the function.
That means that if we want to invoke the function expression right away we just need to tackle a couple of parentheses on the end. This brings us back to the first bit of code we looked at:

(() => {
var greet = "Welcome All";
console.log(greet); // Welcome All
})()
console.log(greet); // Error: greet is not defined

The primary reason to use an IIFE is to obtain data privacy. Because JavaScript’s var scopes variables to their containing function, any variables declared within the IIFE cannot be accessed by the outside world.

2. Understanding Scope

Scope is the accessibility of variables, functions, and objects in some particular part of your code during runtime. In other words, scope determines the visibility of variables and other resources in areas of your code.

As per the above definition of scope. So, the point in limiting the visibility if variables and not having everything available everywhere in your code.

The Scope can be defined in two ways,

  • Global Scope
  • Local Scope
var name = "Anto" // global scopeconst greet = () => {
console.log(`Hello ${name}`) // Hello Anto
}
greet();

Above code, name variable is the global scope and it can be accessed anywhere inside the function,

const greet = () => {
var name = "Anto" // local scope
console.log(`Hello ${name}`) // Hello Anto
}
greet();console.log(name) // name is not undefined

In scope level variables in JavaScript ES6 has updated hoisting variable let, var, const type check with that, In order to learn the scope, you need to understand hoisting also.

3. JavaScript Closures

A closure is the combination of a function and the lexical environment within which that function was declared.

A closure is an inner function that has access to the outer variables and functions — scope chain. The closure has three scope chains: it has access to its own scope (variables defined between its curly brackets), it has access to the outer function’s variables, and it has access to the global variables.

var globalVariable = "I am a Global variable";const greetWith = (greet) => {
return (name) => {
console.log(globalVariable); // "I am a Global variable"
console.log(`${greet} ${name}`); // Hello Anto
}
}
const greet = greetWith("Hello"); // returns a Functiongreet("Anto");

In the above code, We have an outer function greetWith() which returns a function that takes a name as an argument.

The scope of the variable greet is accessible inside the inner function, even after the outer function is returned.

4. Hoisting:

Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their scope before code execution.

This mechanism is called hoisting,

console.log(variable); // undefinedconst variable = "Hoisting"

actually, JavaScript has hoisted the variable declaration. This is what the code above looks like to the interpreter

var variable;console.log(variable)variable = "Hoist";

JavaScript only hoists declarations, not initialization.

Inevitably, this means that no matter where functions and variables are declared, they are moved to the top of their scope regardless of whether their scope is global or local.

so this also match for a variable of function-level scope also hoisted

But, This is not the case with keywords like let and const in JavaScript(ES6)

Before we start, to be noted is the fact that variables declared with the keyword let are block-scoped and not function scoped. That’s significant, but it shouldn’t trouble us here. Briefly, however, it just means that the variable’s scope is bound to the block in which it is declared and not the function in which it is declared.

Let’s start by looking at the let keyword’s behavior.

console.log(variable); 
// ReferenceError: Cannot access 'hoist' before initialization
let variable

Like before, for the var keyword, we expect the output of the log to be undefined. However, since the es6 let doesn’t take kindly on us using undeclared variables, the interpreter explicitly spits out a Reference error.

This ensures that we always declare our variables first.

However, we still have to be careful here. An implementation like the following will result in an output of undefined instead of a Reference error.

let variable;

console.log(variable); //undefined
variable = 'Hoisted'

Hence, to err on the side of caution, we should declare then assign our variables to a value before using them.

5. The Module Pattern

In JavaScript, a module is a small unit of independent, reusable code. Modules are the foundation of many JavaScript design patterns and are critically necessary when building any non-trivial JavaScript-based application.

JavaScript module export as the value rather than define a type, as JavaScript JavaScript module can export an object, Modules that export a string containing an HTML template or a CSS stylesheet are also common.

JavaScript doesn’t have private keywords but we can achieve private methods and properties using closures.

const app = (() => {
`use strict`
var _myPrivateProp = "secret"; const _privateMethod = () => {
console.log(_myPrivateProp);
}
return {
publicMethod: () => {
_myPrivateProp();
}
}
})();app.publicMethod(); // secret
app._myPrivateProp; // undefined
app._myPrivateProp(); // TypeError

these modules can have exported to the other JS files using the export keyword,

export default app;

modules can import to another JS file

import app from "./app.js";

Why do we need to use a Module?

There are a lot of benefits to using modules in favor of a sprawling,

some are,

  1. maintainability
  2. reusability
  3. Namespacing

6. Currying:

Currying is a technique of evaluating the function with multiple arguments, into a sequence of functions with a single argument.

In other words, when a function, instead of taking all arguments at one time, takes the first one and return a new function that takes the second one and returns a new function which takes the third one, and so forth until all arguments have been fulfilled.

For better understanding,

// ES5
function concat(str1) {
return function(str2) {
return function(str3) {
console.log(`${str1} ${str2} ${str3}`);
}
}
}
//ES6
const concat = (str1) => (str2) => (str3) => {
console.log(`${str1} ${str2} ${str3}`);
}
concat("JavaScript")("For")("Life"); output: "JavaScript For Life"

this currying achieving through closures, so above program variables str1, str2 private properties of the parent function

Why Useful Currying?

Mainly It helps to create a higher-order function. It is extremely helpful in event handling.

7. Memoization:

Memoization is a programming technique that attempts to increase a function’s performance by caching its previously computed results. Because JavaScript objects behave like associative arrays, they are ideal candidates to act as caches. Each time a memoized function is called, its parameters are used to index the cache. If the data is present, then it can be returned, without executing the entire function. However, if the data is not cached, then the function is executed, and the result is added to the cache.

The function is an integral part of the programming, they help to modularity and reusable to our code, as per the above definition memoization is an optimizing our code

const apiService = () => {
let cache = {};
const fetchDataById = async (id) => {
if(id in cache) {
return cache[id];
}
const response = await fetch("https://www.mock.com/"+ id);
const data = JSON.parse(await response.json());
cache[id] = data;
return data;
}
}
const service = apiService();// data fetched from server
service.fetchDataById(1).then(data => console.log(data))
// data from cache
service.fetchDataById(1).then(data => console.log(data))

8. The apply, call, and bind methods:

In traditionally JS have object, Properties, and methods, so each object has properties and methods.

In JavaScript, we can do some magic using call, apply, bind methods,

Consider the above image Object1 can have its own Properties and Object2 can have its own property, so we can write a common method for these objects and use within that using call/apply/bind method. I hope you now you can understand why call/apply/bind method using.

let’s look at the difference and code for the Call/Apply/Bind method

1.Call method:

consider below code, obj have the property of num, using call method we can bound obj to add function,

var obj = {
n1: 1
}
function add(n2, n3, n4) {
return this.n1 + n2 + n3 + n4;
}
// Call
console.log(add.call(obj, 3, 4, 5)); // 10
// Apply
console.log(add.apply(obj, [2, 3, 4])); // 10
// Bind
const bonded = add.bind(obj);
console.log(bonded(3, 4, 5)); // 10

2.Apply Method

The same way the Apply method also works but the only difference is using the apply method the passing arguments could be an array, refer to the below code.

3.Bind Method:

bind method returns a method instance instead of result value, after that need to execute a bound method with arguments.

In the above Code simply explain how to use the call/Apply/Bind method with an argument.

9. JavaScript Prototype

Let me explain the various way of creating objects in JavaScript. One of the ways to create objects in JavaScript is the constructor function. Consider the below constructor function:

function FoodItem(name, type) {
this.name = name;
this.type = type;
this.getDetails = function() {
return this.name+" is a "+this.type;
}
}
const FerreroRocher = new FoodItem("Ferrero Rocher", "Chocolate");
const Cake = new FoodItem("Giant Twix Cheesecake", "Dessert");
console.log(FerreroRocher.getDetails);
// Ferrero Rocher is a Chocolate
console.log(Cake.getDetails);
// Giant Twix Cheesecake is a Dessert

In the above example, we are creating two objects FerreroRocher, Cake using a constructor. In JavaScript, every object has its own methods and properties. In our example, two objects have two instances of the constructor function getDetails(). It doesn’t make sense to have a copy of getDetails doing the same thing.

Instead of using a copy of instances, we are going to use the prototype property of a constructor function.

Prototype

When an object is created in JavaScript, the JavaScript engine adds a __proto__ property to the newly created object which is called dunder proto. dunder proto or __proto__ points to the prototype object of the constructor function.

function FoodItem(name, type) {
this.name = name;
this.type = type;
}
FoodItem.prototype.getDetails = function() {
return this.name+" is a "+this.type;
}
const FerreroRocher = new FoodItem("Ferrero Rocher", "Chocolate");console.log(FerreroRocher.getDetails);
// Ferrero Rocher is a Chocolate

The FerreroRocher object, which is created using the Bike constructor function, has a dunder proto or __proto__ property which points to the prototype object of the constructor function FoodItem.

In the below code, both FerreroRocher it's dunder proto or __proto__ property and FerreroRocher.prototype property is equal. Let’s check if they point at the same location using === operator.

console.log(FerreroRocher.__proto__ === FoodItem.prototype)// true

So using prototype property, how many objects are created functions are loaded into memory only once and we can override functions if required.

10. JavaScript(ES6) Class

JavaScript classes, introduced in ES6, are primarily syntactical sugar over JavaScript’s existing prototype-based inheritance. The class syntax does not introduce a new object-oriented inheritance model to JavaScript. In early ES5 using function expression.

existing Prototype based inheritance:

function FoodItem(name, type) {
this.name = name;
this.type = type;
}
FoodItem.prototype.getDetails = function() {
return this.name+" is a "+this.type;
}
const FerreroRocher = new FoodItem("Ferrero Rocher", "Chocolate");

ES6

class FoodItem {
constructor(name, type) {
this.name = name;
this.type = type;
}
getDetails() {
return this.name+" is a "+this.type;
}
}

Benefits of Using class

  • Convenient, self-contained syntax.
  • A single, canonical way to emulate classes in JavaScript. Prior to ES6, there were several competing implementations in popular libraries.
  • More familiar to people from a class-based language background.

11. Polymorphism in JavaScript:

Polymorphism is one of the tenets of Object-Oriented Programming (OOP). It is the practice of designing objects to share behaviors and to be able to override shared behaviors with specific ones. Polymorphism takes advantage of inheritance in order to make this happen.

let’s look at the sample code for an override a function in JavaScript

function User(name) {
this.name = name;
}
User.prototype.getName = function() {
return this.name;
}
const Anto = User("anto");console.log(Anto.getName); // anto//override
User.prototype.getName = function() {
return this.name.toUpperCase();
}
console.log(Anto.getName); // Anto

In the above simple program prototype-based method for a User, the constructor function has to override by another prototype function to return the Name as uppercase.

So we can override a function in different Scope, and also possible for method overloading, JS doesn’t have method overloading native but still, we can achieve.

Still few concepts are in oops, which are all are Method overloading, Abstraction, Inheritance in JavaScript.

12. Asynchronous Js :

In JavaScript Synchronous and asynchronous are code execution Pattern,

In JavaScript Code Execution done In two separate ways:

  1. Browser JS Engine (popular V8 JS Engine)
  2. NodeJs V8 Engine

Browser JS Engine parse Html file and executes JavaScript by three patterns,

  1. synchronous
  2. Asynchronous
  3. defer
index.html<script src='index.js'>           //default Synchronous<script async src='index.js'>    //parse as 

Asynchronously<script defer src='index.js'> //parse as deferred

while browser JS Engine parsing HTML file if <Script > tag occurs means there will be blocking, so how it gets execute JavaScript Code for that above three patterns.

  1. If synchronous <script > tag occurs, JS engine will download the code and execute that code and after that only parsing the below HTML code, generally Synchronous is a blocking script execution.
  2. If Asynchronous <script async> tag occurs, while downloading the code JS engine will parse the HTML, and once If JS code gets downloaded pause the parsing and back into the JS Code Execution, generally Asynchronous is a Non-blocking script execution.
  3. If the Asynchronous <script defer> tag occurs, JS Engine will parse all HTML code and after that only executes the JS Code.

13. Callback Function:

A reference to executable code, or a piece of executable code, that is passed as an argument to other code.

From the above definition, the callback function is a function passed into another function as an argument, which is then invoked inside the outer function to complete some kind of routine or action.

const greet(callback) => {
const name = prompt("Enter your name"); // Anto
callback(name);
}
greet((name) => {
console.log("Hello " + name); // Hello Anto
}

In the above program, the function is passed as an argument to the greet function, so I hope now you can understand callback in JavaScript.

14. Understand Promises :

The Promise object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value.

A promise represents the result of the asynchronous function. Promises can be used to avoid chaining callbacks. In JavaScript,

so whenever JavaScript Code Execute as Asynchronously, need to handle an operation as one of the ways would be using promises.

Promises, have been around quite a while and are defined by a spec called Promise/A+. ES6 has adopted this spec for its Promise implementation; but there are other Promise libraries out there such as Q, Bluebird, RSVP, and others that adhere to this spec and offer other features on top of it.

A Promise is in one of these states:

  • pending: initial state, neither fulfilled nor rejected.
  • resolved: meaning that the operation completed successfully.
  • rejected: meaning that the operation failed.
const promise = new Promise((resolve, reject) => {
try {
const result = someComplexOperation();
resolve(result);
} catch(error) {
reject(error.message);
}
});
promise.then(result => {
console.log(result); // [result data]
}).catch(error => {
console.log(error);
})

consider above code for a sample promise assume like doing some complex Operation as asynchronously, In that promise Object arguments as two function resolve and reject,

whenever we execute that promise using .then() and .catch() as callback function In order to get resolve or reject values

15. Async & Await:

Babel now supporting async/await out of the box, and ES2016 (or ES7) just around the corner, async & await basically just syntactic sugar on top of Promises, these two keywords alone should make writing asynchronous code in Node much more bearable.

In JavaScript Asynchronous pattern handled in various versions,

ES5 -> Callback

ES6 -> Promise

ES7 -> async & await

However, what a lot of people may have missed is that the entire foundation for async/await is promises. In fact, every async function you write will return a promise, and every single thing you await will ordinarily be a promise.

const doSomething = async () => {
try {
const result = await someComplexOperation();
console.log(result);
} catch(error) {
console.log(error);
}
}

Above code for a simple async & await,

Good, async/await is a great syntactic improvement for both nodejs and browser programmers. Comparing to Promises, it is a shortcut to reach the same destination. It helps the developer to implement functional programming in JavaScript, and increases the code readability, making JavaScript more enjoyable.

In order to understand about Async&Await, you just need to understand promises.

In Async & Await lot more stuff there, Just play around with it.

conclusion:

As far, In this Post, we have covered many important concepts in JavaScript and got Introduction to it. Generally for each concept just provided a sample code in order to understand the concepts.

Here JavaScript API cheatsheet for the front end developer

http://overapi.com/javascript,

So, you can get a lot more stuff and play around with each and every concept.

I had just gone through the Introduction in all concepts, so If you had any queries Just Ask in the response section.

Thanks for Reading!…

--

--

Antony Raj

I’m a deeply passionate young programmer. You’ll probably find me honing my programming skills.In my spare time I contribute to these domains using my skills.