JavaScript Prototypes
JavaScript Prototypes Interview with follow-up questions
1. What is a prototype in JavaScript?
In JavaScript, a prototype is an object that another object delegates to for properties and methods it doesn't have itself. Every object has an internal link, [[Prototype]] (readable via Object.getPrototypeOf(obj), historically __proto__), pointing to its prototype. When you access a property, the engine walks this prototype chain until it finds the property or hits null.
There are two related-but-distinct things people conflate:
obj.[[Prototype]]— the object an instance inherits from.Fn.prototype— a property on a constructor function whose object becomes the[[Prototype]]of instances created withnew Fn().
function Person(name) { this.name = name; }
Person.prototype.greet = function () {
return `Hi, I'm ${this.name}`;
};
const p = new Person('Ada');
p.greet(); // found via the prototype chain
Object.getPrototypeOf(p) === Person.prototype; // true
Interview framing: prototypes are JavaScript's inheritance mechanism. class syntax (ES2015) is sugar over prototypes — methods you declare in a class still live on Class.prototype. Avoid mutating built-in prototypes like Array.prototype, since it affects every object globally.
Follow-up 1
How is a prototype different from a class in JavaScript?
In JavaScript, prototypes are used to implement inheritance, whereas classes are a more recent addition to the language. Prototypes allow objects to inherit properties and methods from other objects, while classes provide a more structured and syntactic way to define objects and their behavior.
Follow-up 2
Can you modify a prototype object in JavaScript?
Yes, you can modify a prototype object in JavaScript. Since the prototype is an object, you can add, remove, or modify properties and methods on it. Any objects created using the constructor function or object literal will inherit these modifications.
Follow-up 3
What is prototype chaining in JavaScript?
Prototype chaining is the process of searching for properties and methods in an object's prototype chain. When a property or method is accessed on an object, JavaScript first looks for it in the object itself. If it is not found, it continues to search in the object's prototype, and so on, until it reaches the end of the prototype chain. This allows objects to inherit properties and methods from their prototypes.
2. How do you add a method to a prototype in JavaScript?
You assign the method onto the constructor's prototype object, so every instance shares one copy via the prototype chain rather than each instance getting its own function.
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function () {
console.log(`Hello, my name is ${this.name}`);
};
const person = new Person('John');
person.sayHello(); // "Hello, my name is John"
Things interviewers expect you to add:
- Why the prototype and not the constructor body? Defining the method inside the constructor creates a new function per instance (more memory); on the prototype it's shared once.
- Use a regular
function, not an arrow, for prototype methods — arrows have no ownthis, sothis.namewould not refer to the instance. - The modern equivalent is
classsyntax, which puts methods on the prototype for you:
class Person {
constructor(name) { this.name = name; }
sayHello() { console.log(`Hello, my name is ${this.name}`); }
}
- Don't add methods to built-in prototypes (
Array.prototype, etc.) — that pollutes every object of that type globally.
Follow-up 1
What happens if you add a method to a prototype after creating an instance of the object?
If you add a method to a prototype after creating an instance of the object, the existing instances will still be able to access and use the newly added method. This is because the prototype is shared among all instances of an object, and any changes made to the prototype will be reflected in all instances.
Here's an example:
function Person(name) {
this.name = name;
}
var person = new Person('John');
Person.prototype.sayHello = function() {
console.log('Hello, my name is ' + this.name);
};
person.sayHello(); // Output: Hello, my name is John
In the above example, the sayHello method is added to the Person prototype after creating the person instance. However, the person instance is still able to access and use the sayHello method.
Follow-up 2
Can you add properties to a prototype as well?
Yes, you can add properties to a prototype in JavaScript. Properties added to a prototype will be shared among all instances of an object.
Here's an example:
function Person(name) {
this.name = name;
}
Person.prototype.age = 25;
var person1 = new Person('John');
var person2 = new Person('Jane');
console.log(person1.age); // Output: 25
console.log(person2.age); // Output: 25
In the above example, the age property is added to the Person prototype using Person.prototype.age = 25. Both person1 and person2 instances can access and use the age property.
Follow-up 3
What is the performance impact of adding methods to a prototype?
Adding methods to a prototype in JavaScript can have a positive impact on performance. When a method is added to a prototype, it is shared among all instances of an object. This means that each instance does not need to have its own copy of the method, resulting in reduced memory usage.
Additionally, adding methods to a prototype allows for better code organization and maintainability. It separates the object's behavior from its data, making the code easier to understand and modify.
However, it's important to note that adding methods to a prototype can also have a slight negative impact on performance when compared to adding methods directly to an object. This is because accessing a method through the prototype chain may be slightly slower than accessing a method directly on the object.
In most cases, the performance impact of adding methods to a prototype is negligible and the benefits outweigh the drawbacks.
3. What is the 'prototype' property in JavaScript?
The prototype property is a property that exists on functions (specifically those usable as constructors). It points to an object that becomes the [[Prototype]] of every instance created with new. Methods and shared properties placed on it are inherited by all instances through the prototype chain — defined once, shared by all.
function Animal(name) { this.name = name; }
Animal.prototype.speak = function () {
return `${this.name} makes a sound`;
};
const a = new Animal('Rex');
a.speak(); // inherited from Animal.prototype
Object.getPrototypeOf(a) === Animal.prototype; // true
The distinction interviewers want clarified:
Fn.prototypeis the object future instances will delegate to. It exists before you create any instance.instance.[[Prototype]](a.k.a.__proto__) is the actual link an existing object follows for lookups. Afternew Fn(),instance.[[Prototype]] === Fn.prototype.- Plain objects and arrow functions don't have a meaningful
prototypeproperty — arrow functions can't benew-ed, so they have none. - With
classsyntax the same thing applies: methods live onClass.prototype; the keyword is just sugar over this mechanism.
Follow-up 1
What is the difference between 'prototype' and '__proto__' in JavaScript?
The 'prototype' property is a property of a constructor function, whereas 'proto' is a property of an object. The 'prototype' property is used to define properties and methods that are shared among all instances of the constructor function, while 'proto' is used to access the prototype object of an instance.
Follow-up 2
Can you explain the concept of prototype inheritance with an example?
Prototype inheritance is a mechanism in JavaScript where an object can inherit properties and methods from another object. This allows for code reuse and the creation of object hierarchies. Here's an example:
function Animal(name) {
this.name = name;
}
Animal.prototype.sayHello = function() {
console.log('Hello, my name is ' + this.name);
};
function Dog(name, breed) {
Animal.call(this, name);
this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.bark = function() {
console.log('Woof!');
};
var myDog = new Dog('Max', 'Labrador');
myDog.sayHello(); // Output: Hello, my name is Max
myDog.bark(); // Output: Woof!
Follow-up 3
What is the purpose of the 'constructor' property in a prototype?
The 'constructor' property is a property of a prototype object that references the constructor function that created the object. It is used to determine the constructor function of an object and can be useful for checking the type of an object. For example:
function Person(name) {
this.name = name;
}
var john = new Person('John');
console.log(john.constructor === Person); // Output: true
4. How does JavaScript handle inheritance and how does prototype play a role in it?
JavaScript inheritance is prototypal: objects delegate to other objects through the prototype chain. Every object has an internal [[Prototype]] link; when a property isn't found on the object itself, the engine walks up that chain until it finds the property or reaches null.
class Animal {
constructor(name) { this.name = name; }
speak() { return `${this.name} makes a sound`; }
}
class Dog extends Animal {
speak() { return `${super.speak()} — woof`; } // super walks the chain
}
const d = new Dog('Rex');
d.speak(); // "Rex makes a sound — woof"
Object.getPrototypeOf(Dog.prototype) === Animal.prototype; // true
How prototype plays the role:
class … extendssets up the chain soDog.prototype's[[Prototype]]isAnimal.prototype, andsupercalls into the parent.classis sugar over prototypes — pre-ES2015 you'd wire this manually withObject.create(Animal.prototype)and call the parent constructor yourself.- Lookups go child → parent → … →
Object.prototype→ null; the first match wins, which is how method overriding works.
Modern code uses class/extends; the prototype chain is just the mechanism underneath.
Follow-up 1
Can you explain with an example how inheritance is achieved in JavaScript using prototypes?
Sure! Here's an example:
function Animal(name) {
this.name = name;
}
Animal.prototype.sayName = function() {
console.log('My name is ' + this.name);
}
function Dog(name, breed) {
Animal.call(this, name);
this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.bark = function() {
console.log('Woof!');
}
var myDog = new Dog('Max', 'Labrador');
myDog.sayName(); // Output: My name is Max
myDog.bark(); // Output: Woof!
Follow-up 2
What are the limitations of using prototypes for inheritance?
There are a few limitations of using prototypes for inheritance in JavaScript:
Prototypes can only be objects: In JavaScript, prototypes can only be objects. This means that you cannot inherit from a primitive value like a number or a string.
Shared state: When using prototypes, all instances of an object share the same prototype object. If you modify a property or method on the prototype, it will affect all instances of the object.
Lack of private members: JavaScript does not have built-in support for private members. All properties and methods on an object's prototype are accessible from outside the object.
Limited control over inheritance: JavaScript's prototypal inheritance is based on the prototype chain, which can sometimes be difficult to understand and control. This can make it challenging to implement more complex inheritance patterns.
Follow-up 3
How does JavaScript's prototypal inheritance differ from classical inheritance?
JavaScript's prototypal inheritance differs from classical inheritance in a few ways:
Class-based vs. prototype-based: Classical inheritance is class-based, where objects are instances of classes and inherit from a class hierarchy. JavaScript's prototypal inheritance is prototype-based, where objects inherit directly from other objects.
Object cloning vs. object linking: In classical inheritance, objects are typically created by cloning a class blueprint. In JavaScript, objects are created by linking to a prototype object.
Multiple inheritance: Classical inheritance supports multiple inheritance, where an object can inherit from multiple classes. JavaScript's prototypal inheritance does not support multiple inheritance, as an object can only have one prototype.
Constructor functions: In JavaScript, constructor functions are used to create objects and set up their initial state. In classical inheritance, constructor functions are used to define classes and their properties/methods.
5. What is prototypal encapsulation in JavaScript?
"Prototypal encapsulation" is the idea of hiding internal state and behavior while exposing only an intended API, built on JavaScript's prototype/object model. Historically, since the prototype chain itself has no true privacy, developers faked it with closures — state lived in a constructor's scope, and only the prototype methods that closed over it could touch it.
The modern, real answer interviewers want in 2026 is private class fields (#), which give genuine, language-enforced encapsulation:
class Counter {
#count = 0; // private — inaccessible outside the class
increment() { this.#count++; }
get value() { return this.#count; }
}
const c = new Counter();
c.increment();
c.value; // 1
c.#count; // SyntaxError — truly private
Points to make:
#-fields are hard private: not reachable viathis['#count'],Object.keys, or subclasses — unlike the old_underscoreconvention, which was only a hint.- Private methods (
#helper()) and private static members work the same way. - Static initialization blocks (
static { ... }) can set up private state with full logic. - Closures still provide encapsulation for factory functions, but for class-based OOP,
#fields are the standard tool. Both are widely supported across browsers and Node today.
Follow-up 1
How does prototypal encapsulation differ from classical encapsulation?
Prototypal encapsulation differs from classical encapsulation in that it does not rely on classes and inheritance hierarchies. In classical encapsulation, objects are created from classes, and the class defines the structure and behavior of the objects. In prototypal encapsulation, objects are created directly from other objects, and the prototype chain is used to inherit properties and methods. This allows for more flexible and dynamic object creation and composition.
Follow-up 2
Can you provide an example of prototypal encapsulation?
Sure! Here's an example of prototypal encapsulation in JavaScript:
function Person(name) {
var privateAge = 0;
this.getName = function() {
return name;
};
this.getAge = function() {
return privateAge;
};
this.setAge = function(age) {
privateAge = age;
};
}
var person = new Person('John');
console.log(person.getName()); // Output: 'John'
person.setAge(30);
console.log(person.getAge()); // Output: 30
Follow-up 3
What are the advantages of using prototypal encapsulation?
There are several advantages of using prototypal encapsulation in JavaScript:
Code reusability: By leveraging the prototype chain, we can create objects that inherit properties and methods from other objects, allowing for code reuse and avoiding duplication.
Flexibility: Prototypal encapsulation allows for dynamic object creation and composition. Objects can be created directly from other objects, and their behavior can be modified at runtime by adding or modifying properties and methods on the prototype chain.
Privacy: By using closures and private variables, we can create encapsulated objects that have private data and methods. This helps to prevent accidental modification of internal state and provides better control over access to data.
Performance: Prototypal encapsulation can be more performant than classical encapsulation in certain scenarios, as it avoids the overhead of class instantiation and constructor calls.
Live mock interview
Mock interview: JavaScript Prototypes
- Read your scene and goals
- Talk it out; goals tick off live
- Get a score and stronger lines
Your voice and your AI key never touch our servers; the key stays in this browser and is sent only to Google. Only your round scores are saved to track progress.