To implement prototype-based inheritance in JavaScript, you essentially link one object to another so that the second object can delegate property lookups to the first.
Object.create() is the most direct way to implement prototypal inheritance. It creates a new object and allows you to specify exactly which object should be its prototype.
You can create a prototype-based inheritance by defining methods and properties on a prototype object and then using a constructor function to create instances that inherit from that prototype. This allows you to define shared behaviour that is available to all instances of the object.
Classes make the prototype-based implementation much easier to read. Even though it looks like 'Class-based' code, JavaScript is still just setting up a prototype chain behind the scenes.
We need a simple Animal constructor that other objects can inherit from using prototypes. How would you set that up so that a Dog instance can call a method defined on Animal?
If you create an object with Object.create(proto) and then add a property directly on the new object, which version of that property will be accessed when you read it?
After deleting a property from a prototype but not from an existing instance, what will console.log(obj.prop) output and why?
You added a method to Parent.prototype after creating several Child instances. Some of the existing children see the new method, others don’t. What could cause that, and how would you fix it?
While refactoring a legacy codebase, you replace a class‑style inheritance with prototype‑based inheritance. After the change, a feature that relied on instanceof starts failing. Walk me through how you would diagnose and resolve the issue.
Explain the performance implications of using Object.setPrototypeOf inside a hot loop versus creating objects with the correct prototype up‑front.
Our front‑end framework creates thousands of UI component objects per second. Discuss the trade‑offs between using Object.create versus a factory function that manually copies properties for inheritance, focusing on memory usage and GC pressure.
We need to support a plugin system where plugins can extend core objects at runtime. How would you design the prototype chain to allow safe extension without breaking existing instances?
During a production incident, you notice a memory leak traced to objects retaining references to their prototype. Explain how prototype‑based inheritance can cause such leaks and propose a mitigation strategy.
Our monorepo contains multiple services written in JavaScript, some using ES6 classes and others using prototype inheritance. We want to standardize on a single inheritance model. What factors would you consider when deciding to migrate everything to class syntax versus keeping prototype patterns, especially regarding tooling, type safety, and runtime behavior?
Design a strategy for gradually deprecating a deeply nested prototype chain in a legacy library while ensuring backward compatibility for external consumers.
How would you structure a shared utility library that provides base prototypes for domain objects, so that different teams can extend them without causing prototype pollution across the codebase?