Prototypes and Inheritance
JavaScript has no classes underneath: objects delegate to other objects through the prototype chain, and `class` is sugar over that same machinery. Interviewers lean on this area hard because it separates candidates who memorized class syntax from those who know what the engine actually does on every property access.
part ofJavaScriptoverview, primer and where to startread it →on this pageshowhide
explore
- The Prototype Chain14 questions
- Property Lookup and Shadowing5 questions
- Object.create and Delegation4 questions
- __proto__ vs .prototype5 questions
- Constructor Functions and new13 questions
- What new Actually Does4 questions
- Constructor Return-Value Rules4 questions
- The constructor Property and instanceof5 questions
- Class Syntax20 questions
- Classes as Prototype Sugar5 questions
- extends and super Mechanics5 questions
- Static Members and Static Blocks4 questions
- Class Fields and Private #Members6 questions
- Property Mechanics13 questions
- Property Descriptors, Getters and Setters5 questions
- Enumerability and Key Ordering4 questions
- freeze, seal and preventExtensions4 questions
- Proxy and Reflect15 questions
- Proxy and Its Traps5 questions
- The Reflect API5 questions
- Proxy in Practice5 questions
questions
75 · 5 sectionsIn JavaScript, how do `'toString' in obj` and `Object.hasOwn(obj, 'toString')` differ for a plain object literal, and when does that difference matter?
basics
~20 sThe in operator searches the whole prototype chain, so it reports true for inherited names such as toString. Object.hasOwn checks only the object's own properties and reports false. Use hasOwn whenever you mean data the object itself carries.
In JavaScript, what is the difference between a function's `.prototype` property and an object's `__proto__`?
basics
~20 sA function's .prototype is an ordinary property holding the object that instances created from that function will delegate to. An object's proto is that object's own delegation link, the object it actually inherits from right now.
In JavaScript, what does the engine do when you read `obj.x` and `x` is not an own property of `obj`, and what does the assignment `obj.x = 1` do instead?
basics
~20 sA read walks the prototype chain, checking own properties first and then each prototype in turn, and yields undefined if nothing matches. A plain assignment creates an own property directly on obj, shadowing any inherited property of that name rather than updating it.
In JavaScript, given a `base` object that holds shared methods, what is the difference between creating a new object with `Object.create(base)` and creating one with `{ ...base }`?
basics
~20 sObject.create(base) returns an empty object linked to base, so every read falls through to base and later edits to base are visible. { ...base } copies base's own enumerable properties once into an unlinked object.
In JavaScript, what does the `new` operator actually do when you evaluate `new Person('Ada')`?
basics
~20 sThe new operator creates a fresh empty object, links its internal prototype to Person.prototype, calls Person with this bound to that object, and then evaluates to that object unless the constructor explicitly returns a different object.
How does the JavaScript `instanceof` operator decide its answer, and what exactly does it compare?
basics
~20 sx instanceof F reads the current value of F.prototype and walks the prototype chain of x, returning true if that exact object appears anywhere in the chain. It compares object identity along a chain, not names, not x.constructor.
Given `function Dog(name) { this.name = name; }`, what happens if you call `Dog('Rex')` without `new`, and how does the outcome differ between sloppy mode and strict mode?
basics
~20 sWithout new, Dog runs as a plain function and returns undefined. In sloppy mode this is the global object, so name silently leaks into global state; in strict mode this is undefined and the assignment throws a TypeError immediately.
In a JavaScript constructor function invoked with `new`, what happens if the function body explicitly returns an object, and what happens if it returns a primitive such as 42 or null?
basics
~20 sAn object returned from a constructor replaces the freshly created this that new would otherwise hand back. A returned primitive - number, string, boolean, symbol, bigint, null or undefined - is ignored, and new still returns this.
In JavaScript, what does an object's `constructor` property refer to, and is it an own property of the instance?
basics
~10 sThe constructor property is inherited, not own. It sits on the function's prototype object as a non-enumerable property pointing back at that function, and instances reach it by walking the prototype chain.
In a JavaScript class, what is the difference between `super(...)` and `super.someMethod()`, and where is each one allowed to appear?
basics
~20 ssuper(...) invokes the parent constructor and is legal only inside the constructor of a class written with extends. super.someMethod() calls the parent's version of a method with the current instance as this, and is legal in any method or accessor.
In a JavaScript class body, what does declaring a field as #count = 0 give you that the older convention of naming it _count does not?
basics
~20 sA #-prefixed field is privacy enforced by the engine: it can only be named inside the class body that declares it, it is invisible to Object.keys and JSON.stringify, and touching it elsewhere is an error. An underscore name is only a hint.
In a JavaScript class, what does the `static` keyword do — which object does the member live on, and can you reach it from an instance?
basics
~20 sstatic installs a method or field on the class constructor itself instead of on instances. You call it as ClassName.member; reading it from an instance gives undefined, because the constructor is not on the instance's prototype chain.
In a JavaScript class that uses `extends`, why must the derived constructor call `super()` before it reads or writes `this`, and what happens if it doesn't?
basics
~20 sA derived constructor does not create its own this: the parent constructor allocates the instance, and super() is what runs it. Until super() returns, this is uninitialized, so reading or writing it throws a ReferenceError.
In a JavaScript class body, where do a field declaration like count = 0 and a method declaration like inc() {} each end up at runtime, and what practical differences follow?
basics
~20 sA class field becomes an own, writable, enumerable, configurable property created on every instance during construction. A method goes once onto the prototype and is shared. So fields appear in Object.keys, spread and JSON output; methods do not.
In JavaScript, what do the `get` and `set` keywords do when written inside an object literal or a class body, and how does calling code use the property they create?
basics
~20 sget and set define an accessor property: functions the engine runs when code reads or assigns the property with ordinary dot syntax. The getter takes no arguments and returns the value; the setter takes exactly one argument.
In JavaScript, which property keys does a `for...in` loop visit that `Object.keys(obj)` does not return, and how do you guard a `for...in` loop against them?
basics
~20 sfor...in walks the prototype chain and visits inherited enumerable string keys as well as own ones; Object.keys returns only the object's own enumerable string keys. Guard each iteration with Object.hasOwn(obj, key), or iterate Object.keys instead.
In JavaScript, what does each of Object.preventExtensions(), Object.seal() and Object.freeze() block on an object, and how do the three relate to one another?
basics
~10 sObject.preventExtensions blocks adding properties; Object.seal also blocks deleting and reconfiguring them; Object.freeze additionally blocks writing existing values. Each level includes the previous one, and all three are shallow — nested objects stay mutable.
In JavaScript, what does `Object.getOwnPropertyDescriptor(obj, key)` return for a data property versus an accessor property, and which attributes can the two kinds never share?
basics
~10 sA data property's descriptor has value, writable, enumerable and configurable. An accessor property's has get, set, enumerable and configurable. Every property is exactly one kind, so value/writable and get/set can never appear together.
Object.freeze() is described as shallow. What does that mean concretely, and how would you implement a deep freeze that handles an object graph containing cycles?
basics
~20 sShallow means only the object's own properties are locked; objects those properties point at stay fully mutable. A deep freeze recurses over own keys and freezes each object value, tracking already-visited objects so a cycle does not recurse forever.
In JavaScript, what can wrapping an object in a Proxy do that plain getters and setters cannot, and which real use cases does that unlock?
basics
~20 sA Proxy intercepts operations on property names that do not exist yet, plus deletes, in-checks, key enumeration and calls, for any target including arrays and functions. Getters and setters only cover properties you declared in advance.
JavaScript's Reflect namespace duplicates work that Object.* methods and operators like `in`, `delete` and `new` already do. What is Reflect for, and how does it actually differ from those older APIs?
basics
~20 sReflect is a plain namespace object holding one function per internal object operation, matching the Proxy trap list one for one. Unlike the Object.* helpers and operators it mirrors, its methods report failure by returning false and never coerce primitive arguments.
In JavaScript, what does `new Proxy(target, handler)` create, what is a trap, and what happens for an operation the handler defines no trap for?
basics
~20 snew Proxy(target, handler) returns a new object that routes fundamental operations — property reads, writes, deletes, key listing, calls — to matching handler methods called traps. Any operation whose trap is missing falls through to the target unchanged.
A JavaScript Proxy's handler defines an `ownKeys` trap that returns `['a', 'b']`, yet `Object.keys(proxy)` returns an empty array. Which other trap is involved, and why does the result come back empty?
basics
~20 sObject.keys also calls the getOwnPropertyDescriptor trap for every key that ownKeys reported, to test enumerability. With that trap absent it forwards to the target, which has no such properties, so each key returns undefined and is filtered out.
You want arr[-1] to return the last element by wrapping a JavaScript array in a Proxy. What must the get handler do with the property key it receives, and what must it still forward?
basics
~20 sProperty keys reach a get trap as strings or symbols, never numbers, so the handler must convert the key to a number, verify it is a negative integer, and translate it to length plus that index. Everything else must be forwarded unchanged.