Concepts to revise before appearing for a JavaScript Interview (Part — 1)

Photo by Irvan Smith on Unsplash

When going for Frontend Interviews, it’s extremely important that you have the fundamentals of JavaScript down really well. Interviewers will spend a good amount of time testing your depth of knowledge in the language.

In this article, I’ve tried to list and briefly discuss some of the topics that one should definitely know -

this

Here’s a summary of how ‘this’ works in JavaScript -

  1. If the new keyword is used when calling the function, this inside the function is a brand new object.
  2. If apply, call, or bind are used to call/create a function, this inside the function is the object that is passed in as the argument.
  3. If a function is called as a method, such as obj.method() — this is the object that the function is a property of.
  4. If a function is invoked as a free function invocation, meaning it was invoked without any of the conditions present above, this is the global object. In a browser, it is the window object. If in strict mode (‘use strict’), this will be undefined instead of the global object.
  5. If multiple of the above rules apply, the rule that is higher wins and will set the this value.
  6. If the function is an ES2015 arrow function, it ignores all the rules above and receives the this value of its surrounding scope at the time it is created.

The methods — bind(), call() and apply() are used to bind a function while passing the desired scope to the inner function. Let’s look at them in detail -

bind()

  1. You can pass any context to the bind() method. This is the first argument of the bind() method. Whatever is passed as the context, the ‘this’ keyword inside the function to which the bind() method is applied, starts pointing to the passed context.
  2. You can also pass other arguments to the bind() method. But note that the first argument must always be the context. The rest of the arguments can be anything that the bind() method takes and the function, to which the bind() method is applied, accepts in parameters.

Let’s now look at an example how bind() is used -

var person = {
firstName: "Rishav",
lastName: "Bharti",
get: function () {
console.log("Outer: " + this.firstName + " " + this.lastName);
var print = function (role, language) {
console.log("Inner: " + this.firstName + " " + this.lastName + ". I'm a " + language + " " + role + ".")
}.bind(this, "Developer", "MERN Stack");
print();
},
};
person.get();

Try guessing the output of the program. Answer to it will be revealed towards the end of this article.

call() and apply() is used when you want to use a function inside an object and call that function in an entirely different object.

call()

Here’s an example showing the usage of call() -

var person = {
firstName: "Rishav",
lastName: "Bharti",
get: function () {
console.log("Outer: " + this.firstName + " " + this.lastName);
var print = function (role, language) {
console.log("Inner: " + this.firstName + " " + this.lastName + ". I'm a " + language + " " + role + ".")
}.call(this, "Developer", "MERN Stack");
},
};
person.get();

What do you think will be the output of the above program? We’ll find out soon.

apply()

var person = {
firstName: "Rishav",
lastName: "Bharti",
get: function () {
console.log("Outer: " + this.firstName + " " + this.lastName);
var print = function (role, language) {
console.log("Inner: " + this.firstName + " " + this.lastName + ". I'm a " + language + " " + role + ".")
}.apply(this, ["Developer", "MERN Stack"]);
},
};
person.get();

Are you able to guess the output of the above code snippet?

The output of all the above programs will be —

Outer: Rishav Bharti \n Inner: Rishav Bharti. I’m a MERN Stack Developer.

Closures

The power of closures is derived from the fact that the inner function remembers the environment in which it was created. In other words, the inner function has access to the outer function’s variables and parameters.

Closures are significant in the situations when you require the inner function to access the outer function’s variables (or resources) as long as the inner function wants, even when the outer function has finished executing.

Consider a scenario where you mock the functionality of adding an item to the cart. A simplified code can be considered as the one given below:

function modifyItem() {
var items = 0, inStock = 10;
return {
add: function() {
if(inStock > 0) {
console.log(“Added item to cart!”);
items++;
inStock — ;
}
else {
console.log(“Item Out of Stock!”);
}
},
getCount: function() {
return “Items in cart = “ + items;
}
}
}
var item = modifyItem();
item.add();
console.log(item.getCount()); // prints 1
item.add();
item.add();
console.log(item.getCount()); // prints 3

Here, the function modifyItem() modifies an item inside the cart. It returns an object consisting of two keys — add and getCount, which contain methods to add an item to the cart and to get the count of the total number of items in the cart.

The value returned by the function modifyItem(), which is an object, is held inside the variable item. On this variable item, the getCount() method is called. Notice that the methods — add() and getCount() are accessible even after the statement modifyItem() is executed meaning that these are accessible even after the function modifyItem() has finished executing.

Thus, you can use the closure function (closure methods — add() and getCount()) even when the outer function (function modifyItem()) in which it was defined has finished its execution and you can still access the resource(s) (items) defined inside the scope of the outer function, in which the closure was created.

Hoisting

Prototypes & Prototypal inheritance

The __proto__ property either refers to an object or is null. The prototype property of an object is where we put methods and properties that we want other objects to inherit. A prototype of an object can be assigned to another object, thus, making the latter access the resources of the former. This is what is called prototypal inheritance.

  • The Constructor’s prototype property is NOT the prototype of the Constructor itself, it’s the prototype of ALL instances that are created through it.

When a certain method (or property) is called, the search moves on to the object’s prototype. This continues until the method is found: prototype chain. That prototype object has a prototype of its own, and so on until an object is reached with null as its prototype. By definition, null has no prototype, and acts as the final link in this prototype chain. Nearly all objects in JavaScript are instances of Object, which sits on the top of a prototype chain.

In the next article, we’ll discuss some more important concepts.

P.S. — I’ve written this article as a note to myself about the topics I must revise before appearing for an interview