This article covers some basic concepts in JavaScript. Every JavaScript developer should know and master these things.
JavaScript Prototype
There are different ways to create objects in JavaScript. One of the ways to create objects in JavaScript is to the constructor. Consider the constructor function below:
1 2 3 4 5 6 7 8 9 10 11 12 | function Bike(model,color){ this.model = model, this.color = color, this.getDetails = function(){ return this.model+' bike is '+this.color; } } var bikeObj1 = new Bike('BMW','BLACK'); var bikeObj2 = new Bike('BMW','WHITE'); console.log(bikeObj1.getDetails()); //output: BMW bike is BLACK console.log(bikeObj2.getDetails()); //output: BMW bike is WHITE |
In the above example we have created 2 objects: bikeObj1, bikeObj2 using 1 constructure. In JavaScript, every object has its own methods and properties. In the above example 2 objects are 2 instances of the constructor function getDetails()
Instead of using a copy of the instance, we will use the prototype of the constructor function.
Prototype
When an object is created using JavaScript, the JavaScript engine adds a __proto__
property to the newly created object called a dunder proto
. dunder proto
or __proto__
points to the prototype object of the constructor function.
1 2 3 4 5 6 7 8 9 10 | function Bike(model,color){ this.model = model, this.color = color } Bike.prototype.getDetails = function(){ return this.model+" bike is "+this.color; } var bikeObj1 = new Bike(‘BMW’,’Black’); console.log(bikeObj1.getDetails()); |
The bikeObj1
object is created with the Bike constructor function, with the dunder proto
or __proto__
pointing to the prototype object of the Bike
function constructor.
In the code below, attributes dunder proto
or __proto__
of objects bikeObj1
and attributes Bike.prototype
is equal, check with the operator ===
1 2 3 | console.log(bikeObj1.__proto__ === Bike.prototype ); //output : true |
So using the prototypec attribute, how many objects are created to function only load into memory once and we can override the functions if needed.
JavaScript (ES6) Class
JavaScript classes introduced in ES6 are mostly more syntax-based on JavaScript than inheritance based on existing prototypes. Class syntax does not introduce a new object-oriented inheritance model for JavaScript. The beginning of ES5 uses function expressions
Inheriting based on existing prototypes:
1 2 3 4 5 6 7 8 9 | function Bike(model,color) { this.model = model; this.color = color; } Bike.prototype.getInfo = function() { return this.color + ' ' + this.model+ ' bike'; }; |
Classes are in fact “special functions” and like you define function expressions and function declarations, the class syntax consists of two components: class expressions and class declarations.
ES6 class:
1 2 3 4 5 6 7 | class Bike{ constructor(color, model) { this.color= color; this.model= model; } } |
Benefits of using class
- Convenient, closed syntax.
- A unique, canonical way to describe classes in JavaScript. Before ES6, there were some competing implementations in popular libraries.
- Familiar with people from a class-based language platform.
IIFE
What is IIFE in JavaScript?
IIFE (Immediately Invoked Function Expression) is a JavaScript function that runs as soon as it is defined.
1 2 3 4 | (function () {// logic here }) (); |
At first, it sounds confusing but really, the pattern is very simple. The pattern is immediately called the function expression.
JavaScript functions can be created via a function declaration or function expression. Function declaration is how to create a normal function.
Functions created in the context of an expression are also function expressions. The important thing about JavaScript expressions is that they return values.
In both cases, the return value of the expression is a function. That means if we want to call the function expression immediately, we just need to deal with the last few parentheses. This brings us back to the first piece of code we reviewed:
1 2 3 4 5 6 7 | (function () { var foo = “hello”; console.log(foo); }) (); console.log(foo); //Error: foo is not defined |
The main reason to use IIFE is to get data privacy. Because JavaScript scans the var variable with its container, any variables declared in IIFE cannot be accessed externally.
Understanding Scope:
A simple definition of scope in JavaScript: is the ability to access variables, functions, and objects in specific parts of your code at run time. In other words, scopes determine the visibility of variables and other resources in your code areas.
Scope is defined in two main ways:
- Global Scope
- Local Scope
1 2 3 4 5 | var greeting='Welcome to blog'; (function(){ console.log(greeting); //Output: Welcome to blog })(); |
Consider the greeting variable in the code above is Global Scope, which is accessible inside the function.
1 2 3 4 5 6 | (function(){ var greeting = 'Welcome to blog'; console.log(greeting); //Output: Welcome to blog })(); console.log(greeting); //Output:Reference-Error greeting not defined |
In the above code for local scope
In scope scope variables in JavaScript ES6 updated the let, var, const type variables to learn scope, you can refer here .
JavaScript Closures
What are closures?
is a combination of a function and a lexical environment in which the function is declared. Closures has three scope ranges: it has access to its own scope, it has access to variables outside of the function, and it has access to global variables. For example :
1 2 3 4 5 6 7 8 9 10 | function User(name){ var displayName = function(greeting){ console.log(greeting+' '+name); } return displayName; } var myFunc = User('Raj'); myFunc('Welcome '); //Output: Welcome Raj myFunc('Hello '); //output: Hello Raj |
In this code, We have an external User()
function that returns an internal function, displayName()
. The internal function will have access to the variables within the outer function, even after the outer function has returned
The Module Pattern
In JavaScript, a module is a small, reusable, unit. Modules are the cornerstone of many JavaScript designs and are essential when building any JavaScript-based application.
JavaScript modules are exported as values instead of types, because JavaScript modules can export an object. Modules that export a string containing HTML templates or CSS stylesheets are also popular. JavaScript has no private keyword but we can achieve private methods and properties through closures.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | var myModule = (function() { 'use strict'; var _privateProperty = 'Hello World'; function _privateMethod() { console.log(_privateProperty); } return { publicMethod: function() { _privateMethod(); } }; }()); myModule.publicMethod(); // outputs 'Hello World' console.log(myModule._privateProperty); // is undefined protected by the module closure myModule._privateMethod(); // is TypeError protected by the module closure |
These modules may have been exported to other JS files using the export keyword
1 2 3 | //myMOdule.js file export default myModule; |
The module can import other JS files
1 2 3 | //second.js file import myModule from ‘./myModule’; |
Why do we need to use a module?
There are many benefits of using modules such as:
- maintainability
- reusability
- Namespacing
Hoisting
In JavaScript, the meaning of is a JavaScript mechanism in which variables and function declarations are moved to the top of their scope before executing the code.
A simple explanation with the following code:
1 2 3 4 | console.log(Hoist); var Hoist = ’The variable Has been hoisted’; //output : undefined// |
In fact, JavaScript has pulled up the variable declaration. This is what the above code looks like to the interpreter
1 2 3 4 | var Hoist; console.log(Hoist); Hoist = ’The variable Has been hoisted’; |
JavaScript only pulls up declarations, not initialization. This means that regardless of where functions and variables are declared, they are moved to the top of their scope regardless of whether they are global or local. The next thing you need to know about Hoisting
- let, var, const keyword in JavaScript (ES6)
- Hoisting Functions
- Hoisting classes For more reference here
Currying
Currying is a function that evaluates a function with multiple arguments, into a function sequence with a single argument. In other words, when a function, instead of taking all the arguments at once, takes the first function and returns the new function takes the second function and returns the new function takes the third function, and so on. All arguments have been completed. Consider the example code below:
1 2 3 4 5 6 7 8 9 10 | var add = function (a){ return function(b){ return function(c){ return a+b+c; } } } console.log(add(2)(3)(4)); //output 9 console.log(add(3)(4)(5)); //output 12 |
Why is currying useful?
It mainly helps to create a high-level function. It is very useful in event handling
How to convert an existing function into a curried version?
Curry function does not exist in the original JavaScript. But a library like lodash makes it easy to convert a function into a curried function