In general, most of the individuals get confused which type of questions they have to go through to prepare for a front-end web development interview. It is very simple to find different practice questions, but it is difficult to choose the right ones among them. Choosing the right questions is crucial for everyone to crack the job interview. This article will hopefully give you some insight on how to succeed in the front-end developer interview.
“This is the second part of Front-End Developer Interview Series which covers some of the most common and critical interview questions for Front-End Developers. If you have missed the 1st Part, you can read it here.”
1. What do you know about the call, bind and apply ? What is the difference bet ween call and bind?
We read about the this in the previous part. How it’s value is determined by and how the function is called. This was implicit binding. But, we can also choose to call our function on our own this using call or apply. This is called explicit binding.
var myMethod = function () { console.log(this); }; var myObject = { myMethod: myMethod }; var newObject = { myNewMethod: myMethod}; myMethod() // this === window myObject.myMethod() // this === myObject myMethod.call(newObject, args1, args2, …) // this === newObject myMethod.apply(newObject, [array of args]) // this === newObject
A good example of this can be found at https://codepen.io/shoaibkhan94/pen/qxaEPw?editors=1010.
So what does call method do? It calls a function with a given this value and arguments provided individually. What does apply method do? It is similar to call with the fundamental difference being call() accepts an argument list, while apply() accepts a single array of arguments.
What about bind method? The bind() method creates a new function that, when called, has its this keyword set to the provided value.
myNewMethod = myMethod.bind(myObject); myNewMethod(); // this === myObject
This might seem similar to call() method. The main differences between bind() and call() is that :
The call() executes the function it was called upon right away. The bind() returns a new function altogether with it’s this set to the this provided inside the bind().
The official MDN docs say, “A closure is the combination of a function and the lexical environment within which that function was declared.” To understand closure’s, you must understand scope and scope chain (I covered scope in the previous article). Consider this example:
// We have two functions. One is named outer and other is named inner. //this is inner's global scope function outer(name) { //this is inner's outer scope var text = 'Hello ' + name; var inner = function() { //this is inner's local scope console.log(text); } inner(); } outer('John'); //Outputs 'Hello John'.
From the above example, we see that the inner function has access to three scope chains. The inner function has access to its own variables via the first chain. It can access the variables and parameters of the outer function via the second chain. And the third chain allows it to access the global variables. Upon every addition of a function, we add a new link to the scope chain.
Whenever we create a function within another function we create a closure. Another example :
function init(args){ var firstName = args.firstName; var lastName = args.lastName; function returningFunc(action){ return firstName + " " + lastName + " " + "is" + " " + action; } return returningFunc; } var data = {firstName: "Alan", lastName: "Smith" }; var zombieOne = init(data); //when we initialize the outer function, it returns undefined. The outer function is dead, but... /* 20 lines of code later... */ zombieOne("walking"); // Outputs 'Alan Smith is walking’
If you see the above example, we can still access the firstName of this “zombie” isn’t due to any sci-fi magic, it’s because closures don’t store value. Values are static. Instead, they store references to values in their scope chains. The amazing thing is that if you were to change the value of a variable up in the scope chain before returning the closure, the same value used within the closure will then update. Example:
function outer() { // Local variable that ends up within closure var num = 30; var say = function() { console.log(num); } num++; return say; } var sayNumber = outer(); sayNumber(); // logs 31
To summarize, a closure in JavaScript is like keeping a copy of all the local variables, just as they were when a function exited.
Use of closure:
Creating modular patterns with private variables and functions. Example:
var zombieOne = (function(){ //private variables var firstName = ""; var lastName = ""; //private functions function init(data){ firstName = data.firstName; lastName = data.lastName; } function combineName(){ return firstName + " " + lastName; } function gerunding(action){ return firstName + " " + lastName + " " + "is" + " " + action; } //public functions return { getName: function(){ return combineName(); }, setName: function(data){ return init(data); }, setAction: function(action){ return gerunding(action); } }; })(); var data = {firstName: "Alan", lastName: "Smith" }; zombieOne.setName(data); zombieOne.getName(); // "Alan Smith" zombieOne.setAction("walking");// "Alan Smith is walking”
You can check this codepen for better understanding.
P.S.: In the last example we have created an anonymous closure or Immediately Invoked Function Expression (IIFE). They execute immediately and allow us to manage privacy.
3. What are promises? What are the pros and cons of using Promises instead of callbacks?
A promise is an object that represents a value available as a result of an asynchronous operation: either a resolved value or a reason that it’s not resolved (e.g., a network error occurred).
As per MDN, a Promise is in one of these states:
pending: initial state, neither fulfilled nor rejected.
fulfilled: meaning that the operation completed successfully.
rejected: meaning that the operation failed.
It’s similar to passing callbacks to a function. Promises return an object to which you can attach callbacks. If you are not sure of what is a callback it is simply a function called at the completion of a given task.
E.g.,You might have created multiple callbacks for handling success and error cases as given below:
function getUserSuccess(user) { console.log("The User is: " + user); } function getUserFailure(error) { console.log("Failed to get user: " + error); } API.getUser(getUserSuccess, getUserFailure);
…with the introduction of promises, functions now return a promise you can attach your callbacks to instead:
let promise = API.getUser(); promise.then(getUserSuccess, getUserFailure);
or simply
API.getUser().then(getUserSuccess, getUserFailure);
Pros and Cons
You might have of the pyramid of doom or callback hell which is a classic case of several asynchronous operations in one after another:
API.getUser(function(user) { API.getUserAddress(user, function(address) { // do something with address API.saveUserAddress(address, function(newAddress) { console.log('New User Address: ' + newAddress); }, failureCallback); }, failureCallback); }, failureCallback);
With promises, we can attach our callbacks to the promises returned by the functions and form a promise chain:
API.getUser().then(function(user) { return API.getUserAddress(user); }) .then(function(address) { // do something with address return API.saveUserAddress(address); }) .then(function(newAddress) { console.log('New User Address: ' + newAddress); }) .catch(failureCallback); //One catch to handle all failures
Promises also make error handling easier. Consider this:
save().then( handleSuccess, handleError );
With promises you should not handle errors inside the .then(). Also, the handleSuccess() might itself throw an error. Therefore, it is considered as an anti-pattern. The following is recommended:
save() .then(handleSuccess) .catch(handleError);
In the above example, .catch() will handle rejections from either save(), or errors from handleSuccess(). Therefore it is recommend to end all promise chains with a .catch().
A good general rule in programming is to use the simplest possible tool for the job. This is the one disadvantage of using simple callbacks over promises, as a callback is a simpler tool than Promises, though the problem is equally simple. For a single asynchronous request, a callback will do fine. But, for multiple requests at the same time promises are more suited than callbacks
4. What is the difference between Class and Prototypal inheritance?
Inheritance in JavaScript is different from most other languages. The object system in JavaScript is prototype based, not class based.
Objects in JavaScript are just a collection of a name (key) and value pairs.
As per MDN, when it comes to inheritance, JavaScript only has one construct: objects. Each object has a private property which holds a link to another object called its prototype. 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.
All objects in JavaScript are instances of Object which sits on the top of the prototype chain.
function Greeter (name) { this.name = name || 'John Doe'; } Greeter.prototype.hello = function hello () { return 'Hello, my name is ' + this.name; } var george = new Greeter('George'); var msg = george.hello(); console.log(msg); // Hello, my name is George
Prototype Chain
Whenever you try to access a property on an object, the object’s own properties are checked first. If it’s not found, then the [[Prototype]] is checked, and so the check goes up the prototype chain until it gets back to Object.prototype, which is the root delegate for most objects.
Here is an example on Codepen to explain it further.
So, this was a brief on Prototypal inheritance in JS, now let's come back to the original question of Class vs Prototypal inheritance.
https://codepen.io/shoaibkhan94/pen/bMmdaj
Here is an example on Codepen to explain the difference between the two in detail.
The following points are noteworthy in the above example:
When we call “new Point(3, 4)”, essentially we create a new object which inherits from Point.prototype, then it’s Point() constructor is called within the context of the new object. This is how the properties of the new object are created and initialized.
When we call “new Point3D(3, 4, 5)” to create a new object, we are again creating a new object which inherits from Point3D.prototype, which inherits from Point object and calls Point3D() constructor within the context of the new object.
This is how prototypal inheritance is different, we are directly creating a new object from an existing object, without the notion of classes. We are using “Object.create” to create a new object. It takes an object as a parameter which will be the prototype for the new object.
Note that, “p2” and “point_3d” are created in the same way. However, we extend “point_3d” with additional properties and methods.
It is important to note that JavaScript doesn’t have the notion of class-based inheritance. We are just pseudo implementing it using the “prototype” property to build the inheritance chain.
Class Inheritance: Instances inherit from classes which are a blueprint (a description) of the object. Instances are created via constructor functions with the new keyword.
Prototypal Inheritance: Instances inherit directly from other objects via the prototype. Instances are created via factory functions or Object.create(). Instances can be composed of many different objects, allowing for easy selective inheritance.
TL;DR:
A class is a blueprint.
A prototype is an object instance.
Hope, all the above discussed front-end developer interview questions help you through the hardest parts of your coding journey. In the next series article, I will cover questions on HTML, CSS and the Web.
Good luck in your future endeavors!!
Leave a Reply
Your email address will not be published. Required fields are marked *