Other JS Theory
What are the different data types present in JavaScript
Primitive types
String - It represents a series of characters and is written with quotes. A string can be represented using a single or a double quote. Example:
var str = "Vivek Singh Bisht"; //using double quotes
var str2 = "John Doe"; //using single quotes
Number - It represents a number and can be written with or without decimals. Example:
var x = 3; //without decimal
var y = 3.6; //with decimal
BigInt - This data type is used to store numbers which are above the limitation of the Number data type. It can store large integers and is represented by adding “n” to an integer literal. Example:
var bigInteger = 234567890123456789012345678901234567890n;
Boolean - It represents a logical entity and can have only two values: true or false. Booleans are generally used for conditional testing. Example:
var a = 2;
var b = 3;
var c = 2;
(a == b)(
// returns false
a == c,
); //returns true
Undefined - When a variable is declared but not assigned, it has the value of undefined and its type is also undefined. Example:
var x; // value of x is undefined
var y = undefined; // we can also set the value of a variable as undefined
Null - It represents a non-existent or an invalid value. Example:
var z = null;
Symbol - It is a new data type introduced in the ES6 version of JavaScript. It is used to store an anonymous and unique value. Example:
var symbol1 = Symbol("symbol");
typeof of primitive types
typeof "John Doe"; // Returns "string"
typeof 3.14; // Returns "number"
typeof true; // Returns "boolean"
typeof 234567890123456789012345678901234567890n; // Returns "bigint"
typeof undefined; // Returns "undefined"
typeof null; // Returns "object" (kind of a bug in JavaScript)
typeof Symbol("symbol"); // Returns "symbol"
Non-primitive types
Primitive data types can store only a single value. To store multiple and complex values, non-primitive data types are used.
Object - Used to store a collection of data.
Example:
// Collection of data in key-value pairs
var obj1 = {
x: 43,
y: "Hello world!",
z: function () {
return this.x;
},
};
// Collection of data as an ordered list
var array1 = [5, "Hello", true, 4.1];
Note: It is important to remember that any data type that is not a primitive data type is of Object type in JavaScript.
Why do we use the word “debugger” in JavaScript
The debugger for the browser must be activated in order to debug the code. Built-in debuggers may be switched on and off, requiring the user to report faults. The remaining section of the code should stop execution before moving on to the next line while debugging.
Difference between “ == “ and “ === “ operators
Both are comparison operators. The difference between both the operators is that “==” is used to compare values whereas, “ === “ is used to compare both values and types.
Example:
var x = 2;
var y = "2";
(x == y)(
// Returns true since the value of both x and y is the same
x === y,
); // Returns false since the typeof x is "number" and typeof y is "string"
Difference between var and let keyword in JavaScript
Some differences are:
- From the very beginning, the 'var' keyword was used in JavaScript programming whereas the keyword 'let' was just added in 2015.
- The keyword 'Var' has function scope. Anywhere in the function, the variable specified using var is accessible but in ‘let’ the scope of a variable declared with the 'let' keyword is limited to the block in which it is declared. Let's start with a Block Scope.
- 'var' declares a variable that will be hoisted but 'let' declares a variable that will not be hoisted.
Is JavaScript a statically typed or a dynamically typed language
JavaScript is a dynamically typed language. In a dynamically typed language, the type of a variable is checked during run-time in contrast to a statically typed language, where the type of a variable is checked during compile-time.
Since JavaScript is a loosely (dynamically) typed language, variables in JS are not associated with any type. A variable can hold the value of any data type.
For example, a variable that is assigned a number type can be converted to a string type:
var a = 23;
var a = "Hello World!";
What is an Immediately Invoked Function in JavaScript
An Immediately Invoked Function ( known as IIFE and pronounced as IIFY) is a function that runs as soon as it is defined.
Syntax of IIFE:
(function () {
// Do something;
})();
The first set of parentheses:
(function () {
//Do something;
});
The second set of parentheses:
(function () {
//Do something;
})();
What do you mean by strict mode in JavaScript and the characteristics of JavaScript strict mode
In ECMAScript 5, a new feature called JavaScript Strict Mode allows you to write a code or a function in a "strict" operational environment. In most cases, this language is 'not particularly severe' when it comes to throwing errors. In 'Strict mode,' however, all forms of errors, including silent errors, will be thrown. As a result, debugging becomes a lot simpler. Thus programmer's chances of making an error are lowered.
Characteristics of strict mode in JavaScript:
- Duplicate arguments are not allowed by developers.
- In strict mode, you won't be able to use the JavaScript keyword as a parameter or function name.
- The 'use strict' keyword is used to define strict mode at the start of the script. Strict mode is supported by all browsers.
- Engineers will not be allowed to create global variables in 'Strict Mode.
Explain Higher Order Functions in JavaScript
Functions that operate on other functions, either by taking them as arguments or by returning them, are called higher-order functions.
Higher-order functions are a result of functions being first-class citizens in JavaScript.
Examples of higher-order functions:
function higherOrder(fn) {
fn();
}
higherOrder(function () {
console.log("Hello world");
});
function higherOrder2() {
return function () {
return "Do something";
};
}
var x = higherOrder2();
x(); // Returns "Do something"
What do you mean by Self Invoking Functions
Without being requested, a self-invoking expression is automatically invoked (initiated). If a function expression is followed by (), it will execute automatically. A function declaration cannot be invoked by itself.
Normally, we declare a function and call it, however, anonymous functions may be used to run a function automatically when it is described and will not be called again. And there is no name for these kinds of functions.
What are some advantages of using External JavaScript
External JavaScript is the JavaScript Code (script) written in a separate file with the extension .js, and then we link that file inside the <head> or <body> element of the HTML file where the code is to be placed.
Some advantages of external JavaScript are:
- It allows web designers and developers to collaborate on HTML and JavaScript files.
- We can reuse the code.
- Code readability is simple in external JavaScript.
Mention some advantages of JavaScript
There are many advantages of JavaScript. Some of them are:
- JavaScript is executed on the client-side as well as server-side also. There are a variety of Frontend Frameworks that you may study and utilize. However, if you want to use JavaScript on the backend, you'll need to learn NodeJS. It is currently the only JavaScript framework that may be used on the backend.
- JavaScript is a simple language to learn.
- Web pages now have more functionality because of JavaScript.
- To the end-user, JavaScript is quite quick.
What is memoization
Memoization is a form of caching where the return value of a function is cached based on its parameters. If the parameter of that function is not changed, the cached version of the function is returned. Let’s understand memoization, by converting a simple function to a memoized function:
Example:
function memoizedAddTo256() {
var cache = {};
return function (num) {
if (num in cache) {
console.log("cached value");
return cache[num];
} else {
cache[num] = num + 256;
return cache[num];
}
};
}
var memoizedFunc = memoizedAddTo256();
memoizedFunc(20); // Normal return
memoizedFunc(20); // Cached return
What is recursion in a programming language
Recursion is a technique to iterate over an operation by having a function call itself repeatedly until it arrives at a result.
Example of a recursive function:
function add(number) {
if (number <= 0) {
return 0;
} else {
return number + add(number - 1);
}
}
add(3) => 3 + add(2)
3 + 2 + add(1)
3 + 2 + 1 + add(0)
3 + 2 + 1 + 0 = 6
What is the use of a constructor function in JavaScript
Constructor functions are used to create objects in JavaScript.
If we want to create multiple objects having similar properties and methods, constructor functions are used.
Example:
function Person(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
var person1 = new Person("Vivek", 76, "male");
console.log(person1);
var person2 = new Person("Courtney", 34, "female");
console.log(person2);
Which method is used to retrieve a character from a certain index
The charAt() function of the JavaScript string finds a char element at the supplied index. The index number begins at 0 and continues up to n-1, where n is the string length. The index value must be positive, higher than, or the same as the string length.
What do you mean by BOM (Browser Object Model)
Browser Object Model is known as BOM. It allows users to interact with the browser. A browser's initial object is a window. As a result, you may call all of the window's functions directly or by referencing the window. The document, history, screen, navigator, location, and other attributes are available in the window object.
What is the distinction between client-side and server-side JavaScript
Client-side JavaScript is made up of two parts, a fundamental language, and predefined objects for performing JavaScript in a browser. JavaScript for the client is automatically included in the HTML pages. At runtime, the browser understands this script.
Client-side JavaScript is similar to server-side JavaScript. It includes JavaScript that will execute on a server. Only after processing is the server-side JavaScript deployed.
What are arrow functions
Arrow functions were introduced in the ES6 version of JavaScript. They provide us with a new and shorter syntax for declaring functions. Arrow functions can only be used as a function expression.
Example:
// Traditional Function Expression
var add = function (a, b) {
return a + b;
};
// Arrow Function Expression
var arrowAdd = (a, b) => a + b;
The biggest difference between the traditional function expression and the arrow function is the handling of this keyword. Arrow functions do not have their own this.
Example:
var obj1 = {
valueOfThis: function () {
return this;
},
};
var obj2 = {
valueOfThis: () => {
return this;
},
};
obj1.valueOfThis(); // Will return the object obj1
obj2.valueOfThis(); // Will return window/global object
What do you mean by the prototype design pattern
The Prototype Pattern produces different objects, but instead of returning uninitialized objects, it produces objects that have values replicated from a template – or sample – object. Also known as the Properties pattern, the Prototype pattern is used to create prototypes.
Differences between declaring variables using var, let and const
Before the ES6 version of javascript, only the keyword var was used to declare variables. With the ES6 Version, keywords let and const were introduced to declare variables.
Let’s understand the differences with examples:
var variable1 = 23;
let variable2 = 89;
function catchValues() {
console.log(variable1);
console.log(variable2);
// Both the variables can be accessed anywhere since they are declared in the global scope
}
window.variable1; // Returns the value 23
window.variable2; // Returns undefined
The variables declared with the let keyword in the global scope behave just like the variable declared with the var keyword in the global scope. Variables declared in the global scope with var and let keywords can be accessed from anywhere in the code. But, there is one difference! Variables that are declared with the var keyword in the global scope are added to the window/global object. Therefore, they can be accessed using window.variableName. Whereas, the variables declared with the let keyword are not added to the global object, therefore, trying to access such variables using window.variableName results in an error.
{
var variable3 = [1, 2, 3, 4];
}
console.log(variable3); // Outputs [1,2,3,4]
{
let variable4 = [6, 55, -1, 2];
}
console.log(variable4); // Throws error
for (let i = 0; i < 2; i++) {
//Do something
}
console.log(i); // Throws error
for (var j = 0; i < 2; i++) {
// Do something
}
console.log(j); // Outputs 2
Variables declared with var keyword do not have block scope. It means a variable declared in block scope with the var keyword is the same as declaring the variable in the global scope. Variables declared with let keyword inside the block scope cannot be accessed from outside of the block.
What is the rest parameter and spread operator
Both rest parameter and spread operator were introduced in the ES6 version of javascript.
Rest parameter ( … ):
- It provides an improved way of handling the parameters of a function.
- Using the rest parameter syntax, we can create functions that can take a variable number of arguments.
- Any number of arguments will be converted into an array using the rest parameter.
- It also helps in extracting all or some parts of the arguments.
Rest parameters can be used by applying three dots (...) before the parameters.
function extractingArgs(...args) {
return args[1];
}
// extractingArgs(8,9,1); // Returns 9
function addAllArgs(...args) {
let sumOfArgs = 0;
let i = 0;
while (i < args.length) {
sumOfArgs += args[i];
i++;
}
return sumOfArgs;
}
addAllArgs(6, 5, 7, 99); // Returns 117
addAllArgs(1, 3, 4); // Returns 8
Note- Rest parameter should always be used at the last parameter of a function:
// Incorrect way to use rest parameter
function randomFunc(a,...args,c){
//Do something
}
// Correct way to use rest parameter
function randomFunc2(a,b,...args){
//Do something
}
Spread operator (…): Although the syntax of the spread operator is exactly the same as the rest parameter, the spread operator is used to spreading an array, and object literals. We also use spread operators where one or more arguments are expected in a function call.
function addFourNumbers(num1, num2, num3, num4) {
return num1 + num2 + num3 + num4;
}
let fourNumbers = [5, 6, 7, 8];
addFourNumbers(...fourNumbers);
// Spreads [5,6,7,8] as 5,6,7,8
let array1 = [3, 4, 5, 6];
let clonedArray1 = [...array1];
// Spreads the array into 3,4,5,6
console.log(clonedArray1); // Outputs [3,4,5,6]
let obj1 = { x: "Hello", y: "Bye" };
let clonedObj1 = { ...obj1 }; // Spreads and clones obj1
console.log(obj1);
let obj2 = { z: "Yes", a: "No" };
let mergedObj = { ...obj1, ...obj2 }; // Spreads both the objects and merges it
console.log(mergedObj);
// Outputs {x:'Hello', y:'Bye',z:'Yes',a:'No'};
In JavaScript, how many different methods can you make an object
In JavaScript, there are several ways to declare or construct an object.
- Object.
- Using Class.
- create Method.
- Object Literals.
- Using Function.
- Object Constructor.
What is the use of promises in javascript
Promises are used to handle asynchronous operations in JavaScript.
Before promises, callbacks were used to handle asynchronous operations. But due to the limited functionality of callbacks, using multiple callbacks to handle asynchronous code can lead to unmanageable code.
A promise is created using the Promise constructor which takes in a callback function with two parameters, resolve and reject respectively.
Example of a promise:
function sumOfThreeElements(...elements) {
return new Promise((resolve, reject) => {
if (elements.length > 3) {
reject("Only three elements or less are allowed");
} else {
let sum = 0;
let i = 0;
while (i < elements.length) {
sum += elements[i];
i++;
}
resolve("Sum has been calculated: " + sum);
}
});
}
In the code above, we are calculating the sum of three elements, if the length of the elements array is more than 3, a promise is rejected, or else the promise is resolved and the sum is returned.
We can consume any promise by attaching then() and catch() methods to the consumer.
sumOfThreeElements(4, 5, 6)
.then((result) => console.log(result))
.catch((error) => console.log(error));
// In the code above, the promise is fulfilled so the then() method gets executed
sumOfThreeElements(7, 0, 33, 41)
.then((result) => console.log(result))
.catch((error) => console.log(error));
// In the code above, the promise is rejected hence the catch() method gets executed
What are classes in javascript
Introduced in the ES6 version, classes are nothing but syntactic sugars for constructor functions. They provide a new way of declaring constructor functions in JavaScript. Below are the examples of how classes are declared and used:
// Before ES6 version, using constructor functions
function Student(name,rollNumber,grade,section){
this.name = name;
this.rollNumber = rollNumber;
this.grade = grade;
this.section is the section;
}
// Way to add methods to a constructor function
Student.prototype.getDetails = function(){
return 'Name: ${this.name}, Roll no: ${this.rollNumber}, Grade: ${this.grade}, Section:${this.section}';
}
let student1 = new Student("Vivek", 354, "6th", "A");
student1.getDetails();
// Returns Name: Vivek, Roll no:354, Grade: 6th, Section:A
// ES6 version classes
class Student{
constructor(name,rollNumber,grade,section){
this.name = name;
this.rollNumber = rollNumber;
this.grade = grade;
this.section is the section;
}
// Methods can be directly added inside the class
getDetails(){
return 'Name: ${this.name}, Roll no: ${this.rollNumber}, Grade:${this.grade}, Section:${this.section}';
}
}
let student2 = new Student("Garry", 673, "7th", "C");
student2.getDetails();
// Returns Name: Garry, Roll no:673, Grade: 7th, Section:C
Explain WeakSet in javascript
In JavaScript, a Set is a collection of unique and ordered elements. Just like Set, WeakSet is also a collection of unique and ordered elements with some key differences:
- WeakSet contains only objects and no other type.
- An object inside the WeakSet is referenced weakly. This means that if the object inside the WeakSet does not have a reference, it will be garbage collected.
- Unlike Set, WeakSet only has three methods:
add(),delete(), andhas().
Explain WeakMap in JavaScript
In JavaScript, a Map is used to store key-value pairs. The key-value pairs can be of both primitive and non-primitive types. WeakMap is similar to Map with key differences:
- The keys and values in WeakMap should always be objects.
- If there are no references to the object, the object will be garbage collected.
Example:
let obj = { name: "Vivek" };
const map3 = new WeakMap();
map3.set(obj, { age: 23 });
What is Object Destructuring
Object destructuring is a new way to extract elements from an object or an array.
Example:
Before ES6 version:
const classDetails = {
strength: 78,
benches: 39,
blackBoard: 1,
};
const classStrength = classDetails.strength;
const classBenches = classDetails.benches;
const classBlackBoard = classDetails.blackBoard;
The same example using object destructuring:
const classDetails = {
strength: 78,
benches: 39,
blackBoard: 1,
};
const {
strength: classStrength,
benches: classBenches,
blackBoard: classBlackBoard,
} = classDetails;
console.log(classStrength); // Outputs 78
console.log(classBenches); // Outputs 39
console.log(classBlackBoard); // Outputs 1
Difference between prototypal and classical inheritance
Programmers build objects, which are representations of real-time entities, in traditional OO programming. Classes and objects are the two sorts of abstractions. A class is a generalization of an object, whereas an object is an abstraction of an actual thing.
Classical inheritance differs from prototypal inheritance in that classical inheritance is confined to classes that inherit from those remaining classes, but prototypal inheritance allows any object to be cloned via an object linking method.
What is a Temporal Dead Zone
Temporal Dead Zone (TDZ) is a behavior that occurs with variables declared using let and const keywords. It is a behavior where we try to access a variable before it is initialized.
Examples of temporal dead zone:
x = 23; // Gives reference error
let x;
function anotherRandomFunc() {
message = "Hello"; // Throws a reference error
let message;
}
anotherRandomFunc();
What do you mean by JavaScript Design Patterns
JavaScript design patterns are repeatable approaches for errors that arise sometimes when building JavaScript browser applications. They assist in making the code more stable.
They are divided mainly into 3 categories:
- Creational Design Pattern: Addresses the object generation mechanism, creating objects suitable for a particular scenario.
- Structural Design Pattern: Describes how the classes and objects can be combined to construct bigger frameworks.
- Behavioral Design Pattern: Highlights typical patterns of communication between objects in JavaScript, making it more flexible.
Is JavaScript a pass-by-reference or pass-by-value language
JavaScript is pass-by-value, but when dealing with objects, the value passed is a reference to the object, making it seem like pass-by-reference. When you pass an object and modify its members inside the function, the changes persist outside of it. However, if you modify the value of the object variable, the change does not persist, demonstrating that it is indeed passed by value.
Difference between Async/Await and Generators usage to achieve the same functionality
- Generator functions are run by their generator yield by yield which means one output at a time, whereas Async-await functions are executed sequentially one after another.
- Async/await provides a certain use case for Generators easier to execute.
- The output result of the Generator function is always
value: X,done: Boolean, but the return value of the Async function is always an assurance or throws an error.
What are the primitive data types in JavaScript
A primitive is a data type that isn't composed of other data types. It's only capable of displaying one value at a time. In JavaScript, there are 5 different forms of basic data:
- Boolean
- Undefined
- Null
- Number
- String
What is the role of deferred scripts in JavaScript
Deferred scripts delay the execution of the script until the HTML document has been completely parsed and loaded. This improves the loading time of the page, allowing the content to be visible faster. It also ensures that scripts that depend on the entire document being loaded are executed correctly.
What has to be done in order to put Lexical Scoping into practice
To support lexical scoping, a JavaScript function object's internal state must include not just the function's code but also a reference to the current scope chain.