Understanding Inheritance in JavaScript Through Object Creation
By: Spencer Smith
Tags: Prototypal Inheritance, Classical Inheritance, Constructors, JavaScript, Object Oriented

Object Literals

How is an Object literal instance created?

Setting a variable to be an empty object is the same thing as calling new Object().

Whenever we simply declare a new Object with open-and-closed curly braces, this is known as an Object literal. Object literals implicitly call on the constructor property within the Object prototype to create instances of Object literals.

All object constructors in JavaScript, including but not limited to the Object() constructor, call on a constructor property to construct instances.

Which properties and methods does each Object literal instance have access to?

While the athlete Object here might not have any immediately visible properties or methods, it does come with one built in.

This __proto__ property, short for prototype, is attached to any instance of an Object and points to the prototype of the object constructor that was used to create that instance.

In JavaScript, all objects inherit properties and methods from a prototype that uses its constructor property to construct new instances of that Object.

Since Object literals are essentially the same thing as calling the new Object() constructor function, Object literals inherit all methods and properties associated with the Object prototype such as toString and hasOwnProperty.

How does an Object literal instance gain access to new methods and properties?

Instances of Object literals are easy to extend. You can give them new properties and methods by simply attaching them to the new instance.

Whenever we extend instances, those new properties and methods belong to that individual instance — meaning other instances do not have access to these new properties and methods.

Since Object literals inherit from the Object prototype, we would need to extend the Object prototype to allow all instances of Objects to share custom properties.

While this technically works, it’s very uncommon and leads to some weird behavior.

Since data structures like arrays are Objects by in JavaScript, adjusting the Object prototype allows all objects in the entire program to inherit whatever functionality is added to it. Messing with built-in datatype constructors like Object(), String(), and Number() is known as monkey patching and it’s much worse in practice than it is in theory.

How is using Object literals similar to or different from other approaches to object creation?

Since factory functions are basically just functions that return Object literals, you can think of a factory function as a machine that uses arguments to more easily generate customized Object literals.

Any instances created from the factory function will behave similarly to Object literals and instances of new Object();

Standalone Object literals can be more individual and specific than when Objects literals are used as prototypes. In our above examples, we gave most of the Object literals a name property of “Mookie.” Since not all athletes are named Mookie, those Object literals would not be good candidates to serve as a prototype. Objects used as prototypes need to be able to describe all instances of that object.

The way we approach inheritance with Object literals is most dissimilar to object constructor functions and class constructors. Instances of Object literals are only one step down the prototype chain from the Object prototype, but the other two are at least two steps down. Object literals are better for object composition whereas the other two more closely resemble classical inheritance patterns.

What are the general pros, cons, and use cases for Object literals?

Pros: Very simple structure with only one level of inheritance that is easy to understand syntacticly and conceptually. Great for object composition.

Cons: The only way to provide methods and properties to all instances of Object literals is to monkey patch the Object prototype, which gets messy in a hurry. Since we have to individually define the properties for every new Object literal, declaring a bunch of them all over the place would take forever.

Use cases: Object literals are best used as prototypes for other objects, so they are better for when you are intentionally trying to favor object composition (with Object.assign and Object.create) over class inheritance.