Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchJavaScript objects find properties by checking themselves first, then following an internal link called [[Prototype]] to other objects. That lookup continues until a matching property is found or the chain ends at null. Once you separate that link from a constructor’s .prototype property, inheritance, shared methods, and shadowing become much easier to reason about.
How JavaScript prototype lookup works
Every ordinary object has an internal [[Prototype]] link. It points to another object, whose own link may point to another. When JavaScript evaluates a property access such as obj.name, it checks obj first. If the property is not there, it checks the object’s prototype, then the next prototype, continuing until it finds the property or reaches null. This is delegation: inherited methods are found through the chain rather than copied onto every instance. See MDN’s guide to inheritance and the prototype chain.
A typical object created with a constructor has this chain:
instance → Constructor.prototype → Object.prototype → null
A class hierarchy created with class Base {}, class Derived extends Base {}, and new Derived() follows the corresponding chain through Derived.prototype, Base.prototype, and Object.prototype, ending at null.
Recommended Free Tools
#1 Best Overall
What is the difference between [[Prototype]] and .prototype?
The names are similar, but they refer to different things:
[[Prototype]]is an internal link on an object. It determines where property lookup continues when the object does not have a property itself.Constructor.prototypeis a property on a constructor function. When that function is called withnew, the new instance’s[[Prototype]]is set to the value of the constructor’s.prototypeproperty.Object.getPrototypeOf(obj)is the standard API for reading an object’s prototype link.obj.__proto__is a legacy accessor available in implementations, not the preferred standard API. The special{ __proto__: proto }form in an object literal is separate, standardized syntax for setting the new object’s prototype.
In short: an instance has a prototype link; a constructor’s .prototype is commonly the object that link points to for instances created with new. MDN covers these terms and the prototype chain in its inheritance guide.
Inspect an object’s prototype and its own properties
Use Object.getPrototypeOf() to inspect the link, and Object.hasOwn() to check whether a property belongs directly to an object:
Rank #2
const date = new Date();
Object.getPrototypeOf(date) === Date.prototype; // true
Object.hasOwn(date, "getTime"); // false
date.getTime(); // found on Date.prototype
The getTime method is available on the date because lookup reaches Date.prototype; it is not stored as an own property on that particular date object. MDN’s object prototypes guide demonstrates this kind of chain inspection and recommends Object.hasOwn() for checking own properties.
For an object with no matching property, lookup continues through its prototypes until the chain ends at null. This is why checking ownership and checking whether a property can be read are different questions: an inherited property may be readable without being an own property.
How shadowing changes a property lookup
If an object defines a property with the same name as one on its prototype, the own property is found first. It shadows the inherited property for that object:
const date = new Date();
date.getTime = () => "custom";
date.getTime(); // "custom"
The instance’s own getTime takes precedence over Date.prototype.getTime. The prototype method remains on Date.prototype; the instance’s property does not replace it for other dates. MDN describes this behavior as shadowing in its object prototypes guide.
Also, a property whose value is undefined is not necessarily absent. If the distinction matters, test whether the property exists or is owned explicitly instead of treating its value alone as proof of absence.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Share methods while keeping state on each instance
A common constructor pattern puts per-instance values on each object and reusable methods on the constructor’s prototype:
Rank #4
function Person(name) {
this.name = name; // own, per-instance state
}
Person.prototype.greet = function () {
return `Hello, ${this.name}`;
};
const ada = new Person("Ada");
ada.greet(); // "Hello, Ada"
ada.name is an own property. The call to ada.greet() finds greet on Person.prototype, and the method uses the calling object as this. Other instances made by the same constructor can use that inherited method too. MDN’s object prototypes guide explains this pattern of keeping instance values on objects and shared methods on the prototype.
Choose between classes, constructors, and Object.create()
These approaches express different ways to establish a prototype relationship. None is universally best; choose based on how the object should be created and what will be clearest to the maintainers of the code.
| Approach | How the relationship is established | When it is useful |
|---|---|---|
class and extends |
Class syntax sets up the prototype relationships for instances and derived classes. | A recognizable syntax for many modern examples, especially when objects are created through constructors and a derived type is useful. |
Constructor function and new |
The instance receives the constructor’s .prototype as its [[Prototype]]. |
Understanding existing code and seeing directly how shared prototype methods work. |
Object.create(proto) |
The supplied object is selected directly as the new object’s prototype. | When you want an object to delegate to a chosen object without defining a constructor function. |
Use class and extends for familiar type syntax
class Person {
constructor(name) {
this.name = name;
}
greet() {
return `Hello, ${this.name}`;
}
}
class Developer extends Person {}
const ada = new Developer("Ada");
The instance finds greet through the class prototype chain. Class syntax expresses the same prototype-based inheritance model; it does not introduce a separate inheritance mechanism. As MDN puts it, “Although classes are now widely adopted and have become a new paradigm in JavaScript, classes do not bring a new inheritance pattern.” Read the full MDN inheritance guide.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteBest Value
Use constructors to understand or maintain function-based patterns
A constructor function is useful when reading code that predates class syntax or when the function-based pattern is already established in a codebase. With new Person("Ada"), JavaScript creates an instance whose prototype is the current value of Person.prototype. Replacing a constructor’s entire .prototype object can remove its conventional constructor property, which can make code that relies on that property confusing or error-prone.
Use Object.create() when the prototype is the point
const personPrototype = {
greet() {
return `Hello, ${this.name}`;
},
};
const ada = Object.create(personPrototype);
ada.name = "Ada";
ada.greet(); // "Hello, Ada"
This makes the delegation relationship explicit: ada is created with personPrototype as its prototype. You can also call Object.create(null) to create an object with no prototype. Such an object does not inherit Object.prototype methods, so code must not assume it has methods such as hasOwnProperty. Use Object.hasOwn(obj, key) when checking an own property.
Prototype practices that avoid common problems
- Prefer standard inspection: use
Object.getPrototypeOf()rather than teaching or relying on the legacy__proto__accessor. - Set relationships at creation time: avoid changing the prototype of an already-created object as a routine pattern. MDN notes that prototype mutation can have performance implications; it does not establish a universal cost or threshold. See the MDN inheritance guide.
- Keep chains understandable: very long or complicated chains can be harder to follow and may cause performance problems. There is no single numeric chain-length limit established here; keep a chain only as deep as the design needs.
- Do not casually extend built-in prototypes: adding methods to native prototypes can affect other code. MDN advises against it except where needed for compatibility with newer JavaScript features; see its guidance on inheritance.
- Check existence, not just value: a property may exist with the value
undefined. Use an ownership or existence check when that distinction affects behavior.
There is no universal performance ranking for classes, constructors, or Object.create() established by these sources. Prefer the form that makes object creation and delegation clear in your codebase, and measure a specific performance concern in its actual context rather than relying on a blanket claim.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →




