Overview

9 Objects, prototypes, and classes

JavaScript objects are far more flexible than simple key-value records. This chapter explains how property behavior can be customized with getters and setters, either directly in object literals and classes or dynamically with Object.defineProperty. It also shows how property descriptors control details such as whether a property is enumerable, writable, or configurable, which lets developers shape how objects are read, updated, copied, and serialized.

The chapter then expands into proxies, which can intercept nearly any interaction with an object, including reads, writes, deletions, key enumeration, and property definition. Using Proxy together with Reflect, JavaScript can transparently validate, log, transform, or block operations without changing the original object. This makes proxies extremely powerful for advanced patterns and testing, though they come with performance costs and should be used carefully.

Finally, the chapter builds the foundation for object-oriented programming in JavaScript by explaining prototypes and class-based inheritance. It shows how property lookup falls back through a prototype chain, how constructor functions and new create objects linked to a prototype, and how modern class and extends syntax provides a clearer way to express the same model. It also introduces super and private fields, emphasizing that JavaScript’s class system is still rooted in prototype behavior while adding more structured and encapsulated object design.

The syntax for defining getters and setters. Prefix the property name with either the get or the set keyword.
Accessing the name property directly (on the left) and indirectly, through a proxy (on the right)
Initially, each object has access to only its own properties.
When we access a property that the object doesn’t have, the object’s prototype is searched for that property. Here, we can access hattori’s sneak property through yoshi, because hattori is yoshi’s prototype.
The search for a particular property stops when there are no more prototypes to explore. Accessing yoshi.creep triggers the search first in yoshi, then in hattori, and finally in kuma.
Every function, when created, gets a new prototype object. When we use a function as a constructor, the constructed object’s prototype is set to the function’s prototype.
Properties assigned to an object in the constructor are direct properties of that object. Properties from class prototypes are inherited as fallbacks, following the same rules we saw earlier for prototype inheritance.

Summary

  • We can use accessor methods (getters and setters) to run functions when properties are accessed or assigned.
  • Accessor properties can be defined by using the built-in Object.defineProperty method or with a special get and set syntax as parts of object literals or ES6 classes.
  • We can also use Object.defineProperty to control whether properties are writable or enumerable.
  • With proxies, we can define custom actions that will be executed when an object is interacted with in any way.
  • Proxy handlers for specific actions are called “traps.”
  • The Reflect.get and Reflect.set methods allow us to perform property access from within a proxy trap while preserving the this context.
  • Every object can have a prototype, an object to which we delegate the search for a particular property, if the object itself doesn’t have the searched-for property. An object’s prototype can have its own prototype, and so on, forming a prototype chain.
  • Prototypes are closely linked to constructor functions. Every function has a prototype property that’s set as the prototype of objects that it instantiates.
  • A function’s prototype object has a constructor property pointing back to the function itself. This property is accessible to all objects instantiated with that function and, with certain limitations, can be used to find out whether an object was created by a particular function.
  • With the class keyword, we can define a constructor function and a prototype at the same time.
  • The extends keyword creates a prototype chain where the parent class’s prototype is the fallback from the child class’s.
  • Within a child class, the parent can be referenced with super.
  • Fields whose names start with # are called private elements. They can only be referenced by using the dot syntax from within the same class in which they’re defined.

FAQ

What are the main ways JavaScript objects can be customized beyond simple key-value pairs?JavaScript objects can use special property behaviors such as getters and setters, non-enumerable or read-only properties, proxies that intercept operations, and prototypes that provide inherited fallback behavior. Classes build on top of prototypes to provide a more familiar OOP style.
What is the difference between a getter/setter method by convention and a true JavaScript getter/setter?A method named with get or set in its name is only a naming convention. A true getter or setter uses the get or set keyword in an object literal or class, so the property is accessed like a normal value but actually runs code behind the scenes.It seems the template requires the answer inside the details element; the content should be:
What is the difference between a getter/setter method by convention and a true JavaScript getter/setter?A method named with get or set in its name is only a naming convention. A true getter or setter uses the get or set keyword in an object literal or class, so the property is accessed like a normal value but actually runs code behind the scenes.
Why would you use Object.defineProperty instead of object-literal get/set syntax?Object.defineProperty is used when you need to add or redefine a property on an object that already exists. It also lets you precisely control descriptor options like enumerable, configurable, and writable.
What does it mean for a property to be enumerable?Enumerable properties are included in common iteration and copying operations such as Object.keys, Object.values, Object.entries, for...in, JSON.stringify, and object spread. Properties defined with Object.defineProperty are non-enumerable by default unless enumerable: true is set.
What is the difference between accessor descriptors and data descriptors?An accessor descriptor uses get and/or set to define computed behavior when a property is read or written. A data descriptor uses a direct value and can also specify writable. Both kinds can also use enumerable and configurable.
How does a Proxy object work in JavaScript?A proxy wraps a target object and uses a handler with traps to intercept operations like property reads, writes, deletes, and key enumeration. The proxy can change, validate, or block behavior before passing operations through with Reflect.
What is prototype chaining?Prototype chaining is the process where JavaScript looks for a property on an object, then on its prototype, then on that prototype’s prototype, and so on until the property is found or the chain ends. This is how objects inherit fallback properties and methods.
How does the new keyword relate to prototypes and constructors?When a function is used as a constructor with new, JavaScript creates a new object whose prototype is set to the function’s prototype object. That is why methods placed on Constructor.prototype are inherited by instances.
How are classes connected to prototypes in JavaScript?Classes are syntax sugar over the prototype system. Instance methods defined in a class become properties of the class’s prototype, while properties assigned in the constructor become direct instance properties.
What does extends do in a class, and what is super for?extends creates inheritance between classes so a child class can inherit methods from a parent class. super calls the parent constructor or accesses parent members, and in a constructor it must be called before using this.
What are private class fields, and how are they different from normal properties?Private fields are prefixed with # and can only be accessed inside the class definition. They cannot be accessed externally, and they also can’t be proxied, enumerated, or deleted.

pro $24.99 per month

  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose one free eBook per month to keep
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime

lite $19.99 per month

  • access to all Manning books, including MEAPs!

team

5, 10 or 20 seats+ for your team - learn more


choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Secrets of the JavaScript Ninja, Third Edition ebook for free
choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Secrets of the JavaScript Ninja, Third Edition ebook for free