01 - Inheritance in Objects

JavaScript objects have a set of own properties, and they also inherit a set of properties from their prototype object. Every time you create an instance of a class using new, you are creating an object that inherits properties from a prototype object.

Property Lookup in the Prototype Chain

Suppose you query the property x in the object o. If o does not have an own property with that name, JavaScript will search for the property in the prototype object of o.

If the prototype object does not have an own property with that name, but has a prototype itself, the query continues on the prototype of the prototype. This process continues until the property is found or until an object with a null prototype is reached.

Prototype Chain and Property Lookup

let o = {};
// o inherits object methods from Object.prototype
o.x = 1;
// Now o has an own property x.

let p = Object.create(o); // p inherits properties from o and Object.prototype
p.y = 2;
// p now has an own property y.

let q = Object.create(p); // q inherits properties from p, o, and Object.prototype
q.z = 3;
// q has an own property z, and inherits from p, o, and Object.prototype.

let f = q.toString();
// toString is inherited from Object.prototype

q.x + q.y;
// => 3; x and y are inherited from o and p

Property Assignment and Inheritance

Suppose you assign a value to the property x of the object o. If o already has an own (non-inherited) property named x, then the assignment simply changes the value of that existing property. Otherwise, the assignment creates a new property x on the object o.

If o previously inherited the property x, that inherited property is now hidden by the newly created own property with the same name.

Key Point: Inheritance occurs when querying properties, but not when setting them. This is a key feature of JavaScript, as it allows us to selectively override inherited properties.

Overriding Inherited Properties

let unitcircle = { r: 1 };
// An object to inherit from
let c = Object.create(unitcircle); // c inherits the property r
c.x = 1; c.y = 1;
// c defines two properties of its own
c.r = 2;
// c overrides its inherited property
unitcircle.r
// => 1: the prototype is not affected

Accessor Properties and Setters

There is one exception to the rule that a property assignment either creates or sets a property in the original object: If o inherits the property x, and that property is an accessor property with a setter method, then the setter method is called instead of creating a new property x in o.

However, note that the setter method is called on the object o, not on the prototype object that defines the property. If the setter method defines any properties, they will be created on o, and the prototype chain will remain unmodified.