Quiz

Explain the concept of the Prototype pattern

Topics
JavaScriptOOP

TL;DR

The Prototype pattern creates an object from an existing prototype or template when construction should be configured by existing state. In JavaScript, distinguish two ideas that are often conflated:

  • Object.create(prototype) creates an empty object whose [[Prototype]] delegates property lookup to prototype; it does not copy the prototype's properties.
  • Cloning copies state into another object. The code must define whether nested state is shared, shallow-copied, or deep-cloned and how class invariants and external resources are handled.

Use prototype delegation to share behavior among many objects. Use cloning only when copying a configured instance is clearer and safer than calling a normal factory or constructor.


Prototype delegation in JavaScript

This factory creates each report with its own state while sharing methods through the prototype chain:

const reportMethods = {
summarize() {
return `${this.title}: ${this.rows.length} rows`;
},
};
function createReport({ title, rows }) {
const report = Object.create(reportMethods);
report.title = title;
report.rows = [...rows];
return report;
}
const report = createReport({ title: 'Sales', rows: [10, 20, 30] });
console.log(report.summarize()); // Sales: 3 rows
console.log(Object.hasOwn(report, 'summarize')); // false
console.log(Object.getPrototypeOf(report) === reportMethods); // true

summarize is inherited, not copied into every report. JavaScript constructor functions and class syntax use the same prototype-chain mechanism for instance methods.

Cloning a configured object

The GoF-style Prototype pattern often gives an object a clone() operation. The hard part is defining copy semantics:

const invoiceTemplate = {
currency: 'USD',
lineItems: [],
};
function createInvoice(customerId) {
return {
...invoiceTemplate,
customerId,
// Avoid sharing this mutable array with the template or other invoices.
lineItems: [...invoiceTemplate.lineItems],
};
}

The object spread is shallow. structuredClone() can deeply copy many data types and cycles, but it cannot clone functions and does not preserve custom class prototypes. DOM nodes, open connections, streams, and similar resources usually need explicit construction rather than generic cloning.

When to use it

Use the pattern when object creation starts from a meaningful configured template, or when prototype delegation provides a compact shared behavior model. Prefer a factory or constructor when required inputs and invariants should be explicit. Avoid cloning large graphs without measuring the cost and defining ownership of every mutable nested value.

Further reading

Exercises

Check your understanding
Beta
Check your understanding Exercise 1 of 2
Check your understanding Exercise 1 of 2

Which statements correctly distinguish prototype delegation from cloning? Select all that apply.