Featured resource
2026 Tech Forecast
2026 Tech Forecast

1,500+ tech insiders, business leaders, and Pluralsight Authors share their predictions on what’s shifting fastest and how to stay ahead.

Download the forecast
  • Lab
    • Libraries: If you want this lab, consider one of these libraries.
    • Core Tech
Labs

Prototypal Inheritance and Property Protection

You will learn about prototypal inheritance in JavaScript, starting with object creation and prototypal chains, and ending with property protection and property descriptors. Enumeration will also be used.

Lab platform
Lab Info
Level
Intermediate
Last updated
Jun 11, 2026
Duration
30m

Contact sales

By clicking submit, you agree to our Privacy Policy and Terms of Use, and consent to receive marketing emails from Pluralsight.
Table of Contents
  1. Challenge

    Step 1: Explore JavaScript objects

    Every JavaScript object carries a hidden link to another object called its prototype. When you read a property the object doesn't own, the runtime follows that link and keeps searching until it finds a match or reaches the end of the chain. In this lab, you'll build a vehicle registry, a Node.js application where car types share properties and behavior through explicit prototype links. You'll define shared properties at the prototype level, derive a specific vehicle from it using Object.create, fine-tune each property's behavior with Object.defineProperty, and finish by locking the entire prototype with Object.freeze.

    The lab's codebase lives in the application directory. All your changes happen in src/registry.js, which starts with placeholder variables and TODO comments that mark each task. A pre-built demo.js script ties the completed registry together. Run it at the end of the lab to see the prototype chain, property enumeration, and freeze protection working in a single output.

  2. Challenge

    Step 2: Build a prototype chain

    The prototype chain is the mechanism that routes property lookups from an object up through its ancestors, and Object.create() is how you wire that link explicitly. In this step, you'll define a vehiclePrototype object with shared properties and a method, then derive a car object from it and assign its own distinct property values. Calling a method on car that only exists on vehiclePrototype will show you the chain at work. After adding the property assignments, you'll run the registry script and see the output in the terminal.

    Note referenced files are in the application/ directory. In the Terminal, confirm you're in the application folder and run:

    node src/registry.js
    

    You should see output similar to:

    car own properties: [ 'make', 'model', 'year' ]
    car.describe(): 2023 Toyota Camry
    

    This means the registry script ran successfully. You can see car's own properties and the result of calling describe() through the prototype chain.

  3. Challenge

    Step 3: Control property attributes

    The prototype chain you built gives car access to vehiclePrototype's properties, and that makes it worth thinking carefully about which of those properties should be freely changeable and which should be locked down. In this step, you'll use Object.defineProperty to add two properties to vehiclePrototype with explicit descriptor flags: one that prevents reassignment and one that hides itself from enumeration loops. Configuring these flags precisely is how you express intent about which parts of an object are stable and which are internal.

  4. Challenge

    Step 4: Inspect and enumerate properties

    With vin and _id both carrying explicit descriptor flags, the difference between enumerable and non-enumerable properties now has real meaning. In this step, you'll use Object.getOwnPropertyNames to list exactly which properties each object owns, including non-enumerable ones, and then write two for...in loops that show the difference between iterating all enumerable properties and filtering to own-only properties. Comparing the two approaches makes the prototype chain's role in enumeration concrete. In the Terminal, run:

    node src/registry.js
    

    You should see output similar to:

    car own properties: [ 'make', 'model', 'year' ]
    vehiclePrototype own properties: [ 'make', 'model', 'year', 'describe', 'vin', '_id' ]
    for...in (all enumerable): [ 'make', 'model', 'year', 'describe', 'vin' ]
    for...in (own only): [ 'make', 'model', 'year' ]
    

    This shows the registry script ran and showed the enumeration output. You can compare the own-property names against all enumerable results.

  5. Challenge

    Step 5: freeze and protect objects

    Property descriptors let you lock individual properties, but Object.freeze takes that further by making an entire object immutable in one call. No new properties can be added, existing ones cannot be reassigned or reconfigured, and nothing can be deleted. In this step, you'll freeze vehiclePrototype and then write a strict-mode try/catch block that attempts to reassign one of its properties. Because JavaScript silently ignores such assignments in sloppy mode, enabling 'use strict' is what causes the TypeError to surface as a catchable error. In the Terminal, run:

    node demo.js
    

    You should see output similar that ends in

    Demo complete.
    

    This shows the demo ran successfully. You can see the complete vehicle registry output showing the prototype chain, property protection, and freeze behavior all working together.

  6. Challenge

    Lab complete

    You completed the vehicle registry and confirmed the prototype chain, property descriptors, and freeze protection all working in the terminal output from demo.js. You practiced three techniques that shape how JavaScript objects behave at runtime: linking objects with Object.create to enable prototype-based inheritance, configuring writable, configurable, and enumerable attributes with Object.defineProperty to control property access, and applying Object.freeze to make an entire object immutable. You also saw the difference between Object.getOwnPropertyNames and for...in enumeration, and confirmed that strict mode converts a silently ignored assignment into a catchable TypeError. These patterns apply any time you need predictable, protected object structures in JavaScript.

About the author

Real skill practice before real-world application

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Learn by doing

Engage hands-on with the tools and technologies you’re learning. You pick the skill, we provide the credentials and environment.

Follow your guide

All labs have detailed instructions and objectives, guiding you through the learning process and ensuring you understand every step.

Turn time into mastery

On average, you retain 75% more of your learning if you take time to practice. Hands-on labs set you up for success to make those skills stick.

Get started with Pluralsight