DEV Community

Cover image for 🔥 JavaScript Interview Series(6): Prototype & Inheritance — How JS Object Model Works
jackma
jackma

Posted on

🔥 JavaScript Interview Series(6): Prototype & Inheritance — How JS Object Model Works

Welcome to the jungle of JavaScript interviews! One of the most frequently explored—and often misunderstood—territories is JavaScript's object model, specifically prototypes and inheritance. Grasping these concepts is not just about acing the interview; it's about fundamentally understanding how JavaScript works under the hood. So, let's roll up our sleeves and dive into the questions that will set you apart from the crowd.


1. What is a prototype in JavaScript, and how does it work?

Point of Examination: This question assesses your foundational knowledge of JavaScript's object model.

Standard Answer: In JavaScript, every object has an internal, hidden property called [[Prototype]] that is a reference to another object or null. This referenced object is called the "prototype." When you try to access a property on an object, and that property isn't found on the object itself, the JavaScript engine looks at the object's prototype. If the property is not on the prototype, it will look at the prototype's prototype, and so on, until it either finds the property or reaches the end of the chain, which is an object with null as its prototype. This is known as the prototype chain.

Possible 3 Follow-up Questions: 👉 (Want to test your skills? Try a Mock Interview — each question comes with real-time voice insights)

  1. How can you access the prototype of an object?
  2. What is the difference between an object's prototype and its [[Prototype]]?
  3. How does the prototype chain end?

2. What is the difference between __proto__ and prototype?

Point of Examination: This question tests your understanding of the two primary ways prototypes are exposed in JavaScript.

Standard Answer:

  • prototype is a property that exists on all constructor functions in JavaScript. It's an object that gets attached to any new object instance created by that constructor. You use the prototype property to define methods and properties that will be shared across all instances of a particular constructor.

  • __proto__ is an accessor property on Object.prototype that exposes the internal [[Prototype]] of an object. It's a direct link to the object's prototype. It's important to note that __proto__ is considered a legacy feature and is deprecated. The modern and standard way to get an object's prototype is by using Object.getPrototypeOf().

In essence, prototype is a property of a constructor function, while __proto__ is a property of an object instance.

Possible 3 Follow-up Questions: 👉 (Want to test your skills? Try a Mock Interview — each question comes with real-time voice insights)

  1. If __proto__ is deprecated, what should be used instead to get and set the prototype of an object?
  2. Can you modify the prototype of a built-in constructor like Array? What are the potential risks?
  3. Do arrow functions have a prototype property?

3. Explain the concept of the prototype chain.

Point of Examination: This question dives deeper into your understanding of how inheritance is achieved in JavaScript.

Standard Answer: The prototype chain is the mechanism through which JavaScript objects inherit features from one another. Every object in JavaScript has an internal link to another object called its prototype. That prototype object has its own prototype, and so on, until an object is reached with null as its prototype. When you try to access a property or method on an object, the JavaScript engine first checks if the property exists directly on that object. If it doesn't, it follows the [[Prototype]] link to its prototype object and checks there. This process continues up the chain until the property is found or the end of the chain (null) is reached. This delegation model is what enables prototypal inheritance.

Possible 3 Follow-up Questions: 👉 (Want to test your skills? Try a Mock Interview — each question comes with real-time voice insights)

  1. How does the hasOwnProperty() method relate to the prototype chain?
  2. What are the performance implications of having a very long prototype chain?
  3. How can you determine if an object's prototype appears in the prototype chain of another object?

4. How do you create an object that inherits from another object?

Point of Examination: This assesses your practical knowledge of implementing prototypal inheritance.

Standard Answer: There are several ways to achieve this:

  • Object.create(): This is the most direct and recommended way. Object.create(proto, [propertiesObject]) creates a new object with the specified prototype object and optional property descriptors.
  • Constructor Functions and new: When you create an object using a constructor function with the new keyword, the new object's [[Prototype]] is set to the constructor's prototype object.
  • ES6 Classes: The class and extends keywords provide a more familiar syntax for setting up prototypal inheritance, but they are essentially syntactic sugar over the underlying prototype-based mechanics.

Possible 3 Follow-up Questions: 👉 (Want to test your skills? Try a Mock Interview — each question comes with real-time voice insights)

  1. What is the difference between Object.create(null) and {}?
  2. How would you implement inheritance using constructor functions without using ES6 classes?
  3. What does the super() keyword do within an ES6 class constructor?

5. What is the difference between classical inheritance and prototypal inheritance?

Point of Examination: This question tests your ability to compare JavaScript's inheritance model with that of more traditional object-oriented languages.

Standard Answer: The core difference lies in their fundamental models:

  • Classical Inheritance: This model, found in languages like Java or C++, is based on classes. A class acts as a blueprint, and objects are instantiated from that class. Inheritance occurs when a class extends another class, creating a hierarchy of classes.

  • Prototypal Inheritance: This model, used by JavaScript, is based on objects inheriting directly from other objects. There are no classes in the traditional sense. Instead, an object can be a "prototype" for another object, and properties are inherited through the prototype chain. It's a more flexible and dynamic model.

In short, classical inheritance is about classes inheriting from classes, while prototypal inheritance is about objects inheriting from other objects.

Possible 3 Follow-up Questions: 👉 (Want to test your skills? Try a Mock Interview — each question comes with real-time voice insights)

  1. How do ES6 classes in JavaScript relate to classical inheritance?
  2. What are some advantages of prototypal inheritance over classical inheritance?
  3. Can you simulate multiple inheritance in JavaScript? How?

6. What is a constructor function in JavaScript?

Point of Examination: This question checks your understanding of one of the primary ways objects have been created in JavaScript.

Standard Answer: A constructor function is a regular JavaScript function that is used to create and initialize objects. By convention, constructor function names start with a capital letter. When a function is called with the new keyword, it becomes a constructor call. The new keyword does four main things:

  1. Creates a new, empty object.
  2. Sets the new object's [[Prototype]] to be the prototype property of the constructor function.
  3. Binds the this keyword to the newly created object.
  4. Returns the new object (unless the constructor explicitly returns another object).

Possible 3 Follow-up Questions: 👉 (Want to test your skills? Try a Mock Interview — each question comes with real-time voice insights)

  1. What happens if you forget to use the new keyword when calling a constructor function?
  2. How is a constructor function different from a regular function?
  3. Can an arrow function be used as a constructor? Why or why not?

7. What does Object.create() do?

Point of Examination: This question assesses your knowledge of a key method for creating objects with a specific prototype.

Standard Answer: The Object.create() method creates a new object, using an existing object as the prototype of the newly created object. Its syntax is Object.create(proto, propertiesObject). The first argument, proto, is the object that will be the prototype for the new object. The optional second argument, propertiesObject, allows you to define additional properties on the new object with specific descriptors (e.g., writable, enumerable). It offers precise control over the prototype chain.

Possible 3 Follow-up Questions: 👉 (Want to test your skills? Try a Mock Interview — each question comes with real-time voice insights)

  1. What is the difference between let obj = new MyConstructor() and let obj = Object.create(MyConstructor.prototype)?
  2. How can you use Object.create() to create an object that doesn't inherit from Object.prototype? What are the implications?
  3. In what scenarios would you prefer Object.create() over using a constructor function with new?

8. Explain how this works in the context of prototypal inheritance.

Point of Examination: This question probes your understanding of the this keyword's behavior within inherited methods.

Standard Answer: When a method is called on an object, the this keyword inside that method refers to the object the method was called on, not the object where the method is defined on the prototype chain. For example, if obj inherits a doSomething() method from its prototype, and you call obj.doSomething(), this inside doSomething() will point to obj. This allows for a single method on a prototype to work on any number of instances, each with its own state.

Possible 3 Follow-up Questions: 👉 (Want to test your skills? Try a Mock Interview — each question comes with real-time voice insights)

  1. What happens to the value of this if you extract a method from an object and call it as a standalone function?
  2. How do arrow functions handle the this keyword differently, and how does that impact their use in prototype methods?
  3. How can you explicitly set the value of this when calling a function?

9. What are the potential downsides of modifying the prototype of built-in objects (e.g., Array.prototype)?

Point of Examination: This question tests your awareness of best practices and the potential pitfalls of JavaScript's dynamic nature.

Standard Answer: While JavaScript allows you to modify the prototypes of built-in objects (often called "monkey-patching"), it is generally considered a bad practice due to several risks:

  • Future Compatibility: A future version of JavaScript might add a method with the same name as the one you added, causing conflicts and unexpected behavior.
  • Code Collisions: If you're working with third-party libraries, they might also modify the same prototype, or they might not expect the modifications you've made, leading to bugs that are hard to debug.
  • Maintainability: It can make the code harder to understand for other developers, as the behavior of built-in objects is no longer standard.

Possible 3 Follow-up Questions: 👉 (Want to test your skills? Try a Mock Interview — each question comes with real-time voice insights)

  1. Are there any situations where extending built-in prototypes might be acceptable? (e.g., polyfills)
  2. How would you safely add a new method to a built-in prototype to avoid potential name collisions?
  3. What is a polyfill, and how does it relate to prototypes?

10. How do ES6 classes work under the hood?

Point of Examination: This question assesses your ability to look past syntactic sugar and understand the underlying mechanisms.

Standard Answer: ES6 classes are primarily syntactic sugar over JavaScript's existing prototype-based inheritance. They are not a new object-oriented inheritance model. When you define a class, JavaScript creates a constructor function. The methods defined within the class are added to the .prototype property of that constructor function. The extends keyword sets up the prototype chain by linking the child class's prototype to the parent class's prototype using Object.setPrototypeOf(). The constructor method within the class is the actual constructor function.

Possible 3 Follow-up Questions: 👉 (Want to test your skills? Try a Mock Interview — each question comes with real-time voice insights)

  1. What are some key differences between a class declaration and a traditional function declaration for a constructor? (e.g., hoisting, strict mode)
  2. What is the purpose of the static keyword in an ES6 class? Where are static methods stored?
  3. How does method sharing via the prototype save memory?

Top comments (0)