JavaScript
Related Concepts
Create Objects
、Prototype Chain
、Call/Apply/Bind Functions
、Array Slice/Splice Methods
、Object/Map Differences and Similarities
、Operators ==/===
、Keywords let/var
、Memoization
etc
1. What are the possible ways to create objects in JavaScript
1️⃣ Object literal syntax
const object = {
name: "Sudheer",
age: 34
};
2️⃣ Object constructor
const object = new Object();
const object2 = Object(); // The Object() is a built-in constructor function so "new" keyword is not required
3️⃣ Object's create method
const object = Object.create(null);
let vehicle = {
wheels: '4',
fuelType: 'Gasoline',
color: 'Green'
}
let carProps = {
type: {
value: 'Volkswagen'
},
model: {
value: 'Golf'
}
}
const car = Object.create(vehicle, carProps);
console.log(car);
4️⃣ Function constructor
function Person(name) {
this.name = name;
this.age = 21;
}
const object = new Person("Sudheer");
5️⃣ Function constructor with prototype
function Person() {}
Person.prototype.name = "Sudheer";
const object = new Person();
6️⃣ Object's assign method
const orgObject = { company: 'XYZ Corp'};
const carObject = { name: 'Toyota'};
const staff = Object.assign({}, orgObject, carObject);
console.log(staff)
7️⃣ ES6 Class syntax
class Person {
constructor(name) {
this.name = name;
}
}
const object = new Person("Sudheer");
8️⃣ Singleton pattern
const object = new (function () {
this.name = "Sudheer";
})();
2. What is a prototype chain
Prototype chaining
is used to build new types of objects based on existing ones. It is similar to inheritance in a class based language. i.e, When you create an object using a constructor function or a class, the created object inherits properties from a prototype object.
The prototype on object instance is available through Object.getPrototypeOf(object)
or __proto__
property whereas prototype on constructor function is available through Object.prototype
.
3. What is the difference between Call, Apply and Bind
1️⃣ Call()
The call()
method invokes a function with a given this
value and arguments provided one by one
const employee1 = { firstName: "John", lastName: "Rodson" };
const employee2 = { firstName: "Jimmy", lastName: "Baily" };
function invite(greeting1, greeting2) {
console.log(
greeting1 + " " + this.firstName + " " + this.lastName + ", " + greeting2
);
}
invite.call(employee1, "Hello", "How are you?"); // Hello John Rodson, How are you?
invite.call(employee2, "Hello", "How are you?"); // Hello Jimmy Baily, How are you?
2️⃣ Apply()
Invokes the function with a given this
value and allows you to pass in arguments as an array
const employee1 = { firstName: "John", lastName: "Rodson" };
const employee2 = { firstName: "Jimmy", lastName: "Baily" };
function invite(greeting1, greeting2) {
console.log(
greeting1 + " " + this.firstName + " " + this.lastName + ", " + greeting2
);
}
invite.apply(employee1, ["Hello", "How are you?"]); // Hello John Rodson, How are you?
invite.apply(employee2, ["Hello", "How are you?"]); // Hello Jimmy Baily, How are you?
3️⃣ Bind()
returns a new function, allowing you to pass any number of arguments
const employee1 = { firstName: "John", lastName: "Rodson" };
const employee2 = { firstName: "Jimmy", lastName: "Baily" };
function invite(greeting1, greeting2) {
console.log(
greeting1 + " " + this.firstName + " " + this.lastName + ", " + greeting2
);
}
const inviteEmployee1 = invite.bind(employee1);
const inviteEmployee2 = invite.bind(employee2);
inviteEmployee1("Hello", "How are you?"); // Hello John Rodson, How are you?
inviteEmployee2("Hello", "How are you?"); // Hello Jimmy Baily, How are you?
4. What is the purpose of the array slice method
const arrayIntegers = [1, 2, 3, 4, 5];
const arrayIntegers1 = arrayIntegers.slice(0, 2); // returns [1,2]
const arrayIntegers2 = arrayIntegers.slice(2, 3); // returns [3]
const arrayIntegers3 = arrayIntegers.slice(4); //returns [5]
WARNING
- End argument without including the last element.
- If you omit the second argument then it selects till the end of the array.
5. What is the purpose of the array splice method
let arrayIntegersOriginal1 = [1, 2, 3, 4, 5];
let arrayIntegersOriginal2 = [1, 2, 3, 4, 5];
let arrayIntegersOriginal3 = [1, 2, 3, 4, 5];
let arrayIntegers1 = arrayIntegersOriginal1.splice(0, 2); // returns [1, 2]; original array: [3, 4, 5]
let arrayIntegers2 = arrayIntegersOriginal2.splice(3); // returns [4, 5]; original array: [1, 2, 3]
let arrayIntegers3 = arrayIntegersOriginal3.splice(3, 1, "a", "b", "c"); //returns [4]; original array: [1, 2, 3, "a", "b", "c", 5]
WARNING
Splice method modifies the original array and returns the deleted array.
6. How do you compare Object and Map
Objects are similar to Maps in that both let you set keys to values, retrieve those values, delete keys, and detect whether something is stored at a key. Due to this reason, Objects have been used as Maps historically. But there are important differences that make using a Map preferable in certain cases:
- The keys of an Object can be Strings and Symbols, whereas they can be any value for a Map, including functions, objects, and any primitive type.
- The keys in a Map are ordered while keys added to Object are not. Thus, when iterating over it, a Map object returns keys in the order of insertion.
- You can get the size of a Map easily with the size property, while the number of properties in an Object must be determined manually.
- A Map is an iterable and can thus be directly iterated, whereas iterating over an Object requires obtaining its keys in some fashion and iterating over them.
- An Object has a prototype, so there are default keys in an object that could collide with your keys if you're not careful. As of ES5 this can be bypassed by creating an object(which can be called a map) using
Object.create(null)
, but this practice is seldom done. - A Map may perform better in scenarios involving frequent addition and removal of key pairs.
7. What is the difference between == and === operators
0 == false // true
0 === false // false
1 == "1" // true
1 === "1" // false
null == undefined // true
null === undefined // false
'0' == false // true
'0' === false // false
NaN == NaN or NaN === NaN // false
[] == [] or [] === [] // false, refer different objects in memory
{} == {} or {} === {} // false, refer different objects in memory
8. What is the difference between let and var
var | let |
---|---|
It has been available from the beginning of JavaScript | Introduced as part of ES6 |
It has function scope | It has block scope |
Variable declaration will be hoisted | Hoisted but not initialized |
It is possible to re-declare the variable in the same scope | It is not possible to re-declare the variable |
function userDetails(username) {
if (username) {
console.log(salary); // undefined due to hoisting
console.log(age); // ReferenceError: Cannot access 'age' before initialization
let age = 30;
var salary = 10000;
}
console.log(salary); //10000 (accessible due to function scope)
console.log(age); //error: age is not defined(due to block scope)
}
userDetails("John");
9. How do you redeclare variables in a switch block without an error
Old, Have Problem
let counter = 1;
switch (x) {
case 0:
let name;
break;
case 1:
let name; // SyntaxError for redeclaration.
break;
}
New, No Problem
let counter = 1;
switch (x) {
case 0: {
let name;
break;
}
case 1: {
let name; // No SyntaxError for redeclaration.
break;
}
}
10. What is memoization
const memoizAddition = () => {
let cache = {};
return (value) => {
if (value in cache) {
console.log("Fetching from cache");
return cache[value]; // Here, cache.value cannot be used as property name starts with the number which is not a valid JavaScript identifier. Hence, can only be accessed using the square bracket notation.
} else {
console.log("Calculating result");
let result = value + 20;
cache[value] = result;
return result;
}
};
};
// returned function from memoizAddition
const addition = memoizAddition();
console.log(addition(20)); //output: 40 calculated
console.log(addition(20)); //output: 40 cached