You will be able to explain how JavaScript uses prototypes to share methods and inherit properties, and add a method to an existing type.
What it is
A prototype is an ordinary object that JavaScript uses as a fallback when a property or method is not found on an object. When you access obj.name, the engine checks obj, then obj's prototype, then that prototype's prototype, until it reaches null. This lookup path is the prototype chain.
Functions have a prototype property. When a function is used with new, the created object's internal [[Prototype]] points to that function's prototype. Related terms: [[Prototype]], Object.getPrototypeOf(), prototype property, constructor, inheritance, delegation.
Why it matters
- It lets many objects share one method instead of copying it into each instance.
- It is the mechanism behind classic JavaScript inheritance and many built-in methods.
- It explains why array methods are available on every array.
- It helps you debug unexpected inherited properties or method collisions.
Syntax or steps
The smallest useful pattern is to add a method to a constructor's prototype:
TypeName.prototype.methodName = function () {
return this.someProperty;
};
Inside the function, this refers to the object that called the method. The method is stored once on the prototype, but every instance can use it.
Example
Array.prototype.last = function () {
return this[this.length - 1];
};
const numbers = [10, 20, 30];
console.log(numbers.last()); // 30
function Person(name) {
this.name = name;
}
Person.prototype.greet = function () {
return "Hello, " + this.name;
};
const ada = new Person("Ada");
console.log(ada.greet()); // Hello, Ada
console.log(Object.getPrototypeOf(ada) === Person.prototype); // true
Part by part:
Array.prototype.last = function () { ... }adds a method to the prototype shared by all arrays.this[this.length - 1]uses the calling array's length and indexes the final element.numbers.last()does not findlastonnumbers, so JavaScript follows the prototype chain toArray.prototype.Person.prototype.greetgives everyPersoninstance access to the same function.Object.getPrototypeOf(ada) === Person.prototypeconfirms the instance's prototype link.
Common mistakes
- Adding methods directly to each object wastes memory and makes updates harder. Put shared behavior on the prototype instead.
- Using
__proto__in production code is non-standard and discouraged. UseObject.getPrototypeOf()orObject.setPrototypeOf()when needed. - Extending built-in prototypes like
Array.prototypecan collide with future language features or other libraries. Prefer a helper function or a subclass in real projects. - Forgetting that
thisdepends on how a method is called can break prototype methods. Call them asobj.method(), not as a detached function.
When to use it
Prototype-based inheritance is useful when you need to understand existing JavaScript objects or add shared behavior to constructor functions. For new code, classes are often clearer because they provide the same prototype chain with a more readable syntax.
| Approach | Best when | Trade-off |
|---|---|---|
| Direct prototype assignment | Learning, small utilities, legacy constructor functions | Easy to understand, but built-in prototype changes can be risky |
| Class syntax | New application code | Clearer structure, still uses prototypes underneath |
| Helper functions | One-off behavior without inheritance | Less coupling, but no shared method lookup |
Practice
Guided exercise: create a Stack constructor with an internal array, then add push and pop methods to Stack.prototype.
function Stack() {
this.items = [];
}
Stack.prototype.push = function (value) {
this.items.push(value);
return this.items.length;
};
Stack.prototype.pop = function () {
return this.items.pop();
};
const stack = new Stack();
stack.push("a");
stack.push("b");
console.log(stack.pop()); // b
Challenge: add peek() to Stack.prototype so it returns the top item without removing it. Expected output after pushing "x" and "y": y.
Quick check
Question: If a method is not found on an object, where does JavaScript look next?
Answer: It looks on the object's prototype, then continues up the prototype chain until it finds the method or reaches null.
Summary
Prototypes are JavaScript's shared fallback objects for property lookup. They let constructors and built-in types provide methods to many instances without copying behavior. Understanding the prototype chain makes inheritance, delegation, and debugging much clearer.