[{"data":1,"prerenderedAt":166},["ShallowReactive",2],{"qa-\u002Fjavascript\u002Fobjects\u002Fprototypes-chain":3},{"page":4,"siblings":149,"blog":163},{"id":5,"title":6,"body":7,"description":11,"difficulty":14,"extension":15,"framework":16,"frameworkSlug":17,"meta":18,"navigation":19,"order":12,"path":20,"questions":21,"related":140,"seo":141,"seoDescription":142,"stem":143,"subtopic":144,"topic":145,"topicSlug":146,"updated":147,"__hash__":148},"qa\u002Fjavascript\u002Fobjects\u002Fprototypes-chain.md","Prototypes Chain",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"hard","md","JavaScript","javascript",{},true,"\u002Fjavascript\u002Fobjects\u002Fprototypes-chain",[22,27,31,35,39,43,47,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136],{"id":23,"difficulty":24,"q":25,"a":26},"what-is-prototype","medium","What is a prototype in JavaScript?","Every object has an internal link to another object called its **prototype**.\nWhen you access a property that the object doesn't have, JavaScript looks it up\non the prototype, then that object's prototype, and so on — the **prototype\nchain**. This is how objects inherit behavior in JavaScript.\n\n```js\nconst arr = [1, 2, 3]\narr.map(x => x)  \u002F\u002F `map` isn't on `arr`; it's found on Array.prototype\n```\n\nPrototypes are how methods are **shared** across many instances without copying\nthem onto each object — the foundation of JavaScript's object model.\n",{"id":28,"difficulty":14,"q":29,"a":30},"proto-vs-prototype","What is the difference between __proto__ and prototype?","They're related but distinct:\n\n- **`prototype`** is a property of **constructor functions** (and classes). It's\n  the object that becomes the prototype of instances created with `new`.\n- **`__proto__`** (or `Object.getPrototypeOf`) is the actual **prototype link**\n  on every object — pointing to the object it inherits from.\n\n```js\nfunction Dog() {}\nconst d = new Dog()\nd.__proto__ === Dog.prototype          \u002F\u002F true\nObject.getPrototypeOf(d) === Dog.prototype \u002F\u002F true (preferred check)\n```\n\nSo `Constructor.prototype` is what *instances* get as their `__proto__`. Use\n`Object.getPrototypeOf`\u002F`setPrototypeOf` instead of the legacy `__proto__`.\n",{"id":32,"difficulty":24,"q":33,"a":34},"prototype-chain-lookup","How does property lookup work along the prototype chain?","When you read `obj.prop`, the engine checks `obj` first; if not found, it\nfollows `obj`'s prototype, then that object's prototype, until it finds the\nproperty or reaches `null` (returning `undefined`).\n\n```js\nconst animal = { eats: true }\nconst dog = Object.create(animal)\ndog.barks = true\ndog.barks   \u002F\u002F true (own)\ndog.eats    \u002F\u002F true (inherited from animal)\ndog.flies   \u002F\u002F undefined (not found anywhere)\n```\n\nWriting a property, by contrast, always creates\u002Fupdates an **own** property on\nthe object itself — it doesn't modify the prototype (unless an inherited setter\nintercepts it).\n",{"id":36,"difficulty":24,"q":37,"a":38},"end-of-chain","What is at the end of the prototype chain?","The chain ends at **`null`**. Most objects inherit from `Object.prototype`,\nwhose prototype is `null`.\n\n```js\nconst obj = {}\nObject.getPrototypeOf(obj) === Object.prototype       \u002F\u002F true\nObject.getPrototypeOf(Object.prototype) === null      \u002F\u002F true\n```\n\n`Object.prototype` provides `toString`, `hasOwnProperty`, `valueOf`, etc., which\nis why nearly every object has them. An object made with `Object.create(null)`\nhas **no** prototype, so its chain is empty.\n",{"id":40,"difficulty":24,"q":41,"a":42},"methods-on-prototype","Why are methods defined on the prototype instead of each instance?","Putting methods on the prototype means **one shared copy** for all instances,\ninstead of a separate function per object — saving memory and allowing methods\nto be updated in one place.\n\n```js\nfunction User(name) { this.name = name }\nUser.prototype.greet = function () { return `Hi, ${this.name}` }\n\nconst a = new User('Ada'), b = new User('Bob')\na.greet === b.greet   \u002F\u002F true — shared method\n```\n\nEach instance holds only its own data (`name`); the behavior lives once on\n`User.prototype`. Classes do this automatically (methods go on the prototype).\n",{"id":44,"difficulty":24,"q":45,"a":46},"hasownproperty","How do you tell own properties from inherited ones?","Use `hasOwnProperty` \u002F `Object.hasOwn`, which check **only own** properties,\nunlike `in` which also sees inherited ones.\n\n```js\nconst dog = Object.create({ eats: true })\ndog.barks = true\n'eats' in dog              \u002F\u002F true (inherited)\nObject.hasOwn(dog, 'eats') \u002F\u002F false (not own)\nObject.hasOwn(dog, 'barks')\u002F\u002F true\n```\n\n`Object.hasOwn` (ES2022) is the modern, robust form — it works even on\n`Object.create(null)` objects and can't be shadowed by an own property named\n`hasOwnProperty`.\n",{"id":48,"difficulty":49,"q":50,"a":51},"getprototypeof","easy","How do you get and set an object's prototype?","Use `Object.getPrototypeOf` to read and `Object.setPrototypeOf` (or\n`Object.create`) to set — prefer these over the legacy `__proto__`.\n\n```js\nconst proto = { greet() { return 'hi' } }\nconst obj = Object.create(proto)        \u002F\u002F create WITH a prototype\nObject.getPrototypeOf(obj) === proto     \u002F\u002F true\nObject.setPrototypeOf(obj, otherProto)   \u002F\u002F change it (slow — avoid in hot code)\n```\n\n`Object.setPrototypeOf` deoptimizes the object and is slow; set the prototype at\ncreation time with `Object.create` or a constructor\u002Fclass instead.\n",{"id":53,"difficulty":24,"q":54,"a":55},"prototype-inheritance-vs-class","How do classes relate to prototypes?","`class` is **syntactic sugar** over prototypes. Class methods are put on the\nconstructor's `prototype`, and `extends` sets up the prototype chain — the same\nmechanism, nicer syntax.\n\n```js\nclass User {\n  constructor(name) { this.name = name }\n  greet() { return `Hi, ${this.name}` }   \u002F\u002F -> User.prototype.greet\n}\ntypeof User              \u002F\u002F 'function'\nUser.prototype.greet     \u002F\u002F the method lives here\n```\n\nUnder the hood there are no \"real\" classes — `class` desugars to constructor\nfunctions + prototype assignment, with some extras (strict mode, non-enumerable\nmethods, `new`-only invocation).\n",{"id":57,"difficulty":24,"q":58,"a":59},"shadowing","What is property shadowing in the prototype chain?","An **own** property with the same name as an inherited one **shadows** (hides)\nthe prototype's version — lookup stops at the own property.\n\n```js\nconst proto = { greet: () => 'from proto' }\nconst obj = Object.create(proto)\nobj.greet = () => 'from obj'\nobj.greet()  \u002F\u002F 'from obj' — shadows the prototype's greet\ndelete obj.greet\nobj.greet()  \u002F\u002F 'from proto' — inherited version reappears\n```\n\nAssigning to an inherited property creates an own one (shadowing); it doesn't\nchange the prototype. Deleting the own property reveals the inherited one again.\n",{"id":61,"difficulty":24,"q":62,"a":63},"instanceof-prototype","How does instanceof use the prototype chain?","`obj instanceof Ctor` checks whether `Ctor.prototype` appears **anywhere** in\n`obj`'s prototype chain.\n\n```js\nclass Animal {}\nclass Dog extends Animal {}\nconst d = new Dog()\nd instanceof Dog     \u002F\u002F true\nd instanceof Animal  \u002F\u002F true (Animal.prototype is in the chain)\nd instanceof Object  \u002F\u002F true\n```\n\nSo it tests prototype-chain membership, not the exact constructor. It can break\nacross realms (iframes) and if you reassign `prototype`; `Symbol.hasInstance`\ncan customize its behavior.\n",{"id":65,"difficulty":14,"q":66,"a":67},"constructor-property","What is the constructor property on the prototype?","Every function's `prototype` object has a `constructor` property pointing back\nto the function. Instances inherit it, so you can find the constructor that made\nan object.\n\n```js\nfunction User() {}\nUser.prototype.constructor === User   \u002F\u002F true\nconst u = new User()\nu.constructor === User                 \u002F\u002F true (inherited)\n```\n\nGotcha: if you **replace** `Prototype` entirely (`User.prototype = {...}`), you\nlose the `constructor` link unless you set it back. It's mostly informational\nand shouldn't be relied on for type checks.\n",{"id":69,"difficulty":14,"q":70,"a":71},"extend-builtin","Can you add methods to built-in prototypes, and should you?","You technically can (`Array.prototype.last = function(){...}`), but you\n**shouldn't** — modifying built-in prototypes (monkey-patching) risks clashing\nwith future language features or other libraries, and breaks `for...in`.\n\n```js\n\u002F\u002F avoid — pollutes every array, may collide with a future Array.prototype\nArray.prototype.last = function () { return this[this.length - 1] }\n```\n\nPrefer standalone utility functions or subclasses. The one time it's acceptable\nis a carefully scoped **polyfill** that implements a standardized method on old\nengines.\n",{"id":73,"difficulty":14,"q":74,"a":75},"prototype-pollution","What is prototype pollution?","A security vulnerability where untrusted input modifies `Object.prototype`,\naffecting **every** object in the program — often via unsafe deep-merge or\nproperty assignment using a `__proto__` key.\n\n```js\n\u002F\u002F attacker payload: { \"__proto__\": { \"isAdmin\": true } }\nmerge({}, JSON.parse(userInput))\n;({}).isAdmin   \u002F\u002F true — every object now \"has\" isAdmin\n```\n\nMitigate by rejecting `__proto__`\u002F`constructor`\u002F`prototype` keys, using\n`Object.create(null)` or `Map` for user data, and `Object.freeze(Object.\nprototype)`. It's a real-world exploit in many libraries.\n",{"id":77,"difficulty":49,"q":78,"a":79},"array-prototype-methods","Where do array and string methods come from?","They live on the built-in prototypes — `Array.prototype`, `String.prototype`,\netc. — and are inherited by every array\u002Fstring via the prototype chain.\n\n```js\n[1, 2].map          === Array.prototype.map     \u002F\u002F true\n'hi'.toUpperCase    === String.prototype.toUpperCase \u002F\u002F true\n```\n\nThat's why all arrays share the same `map`\u002F`filter`. Primitives like strings are\ntemporarily **boxed** into wrapper objects so they can reach their prototype\nmethods, then discarded.\n",{"id":81,"difficulty":14,"q":82,"a":83},"borrow-methods","How do you borrow methods from a prototype?","Use `call`\u002F`apply` to invoke a prototype method with a different `this` — handy\nfor array-like objects that lack array methods.\n\n```js\nfunction sum() {\n  return Array.prototype.reduce.call(arguments, (a, b) => a + b, 0)\n}\nArray.prototype.slice.call(document.querySelectorAll('div')) \u002F\u002F NodeList -> array\n```\n\nMethod borrowing leverages that prototype methods are just functions decoupled\nfrom their objects via `this`. Modern code often uses `Array.from`\u002Fspread\ninstead, but borrowing shows how the chain and `this` interact.\n",{"id":85,"difficulty":24,"q":86,"a":87},"own-vs-inherited-enumeration","Do Object.keys and for...in include inherited properties?","- **`Object.keys`** — own enumerable properties only.\n- **`for...in`** — own **and inherited** enumerable properties.\n\n```js\nconst proto = { inherited: 1 }\nconst obj = Object.create(proto)\nobj.own = 2\nObject.keys(obj)            \u002F\u002F ['own']\nfor (const k in obj) console.log(k)  \u002F\u002F 'own', then 'inherited'\n```\n\nThis is why `for...in` needs a `hasOwn` guard. Built-in prototype methods are\nnon-enumerable, so they don't show up in `for...in` — only your own additions\nto prototypes would.\n",{"id":89,"difficulty":24,"q":90,"a":91},"create-vs-new","What is the difference between Object.create and new?","- **`Object.create(proto)`** sets the new object's prototype to `proto` and runs\n  **no constructor**.\n- **`new Fn()`** creates an object whose prototype is `Fn.prototype`, then runs\n  `Fn` as a constructor (initializing the object).\n\n```js\nconst a = Object.create(protoObj)   \u002F\u002F prototype = protoObj, no init\nconst b = new Ctor(args)            \u002F\u002F prototype = Ctor.prototype, runs Ctor\n```\n\n`Object.create` is lower-level (just sets up the link); `new` is the full\nconstructor flow. `new Ctor()` is roughly `Object.create(Ctor.prototype)` plus\ncalling `Ctor` with the new object as `this`.\n",{"id":93,"difficulty":14,"q":94,"a":95},"differential-inheritance","What is \"differential inheritance\" \u002F delegation?","JavaScript's prototype model is **delegation-based**: objects don't copy\nproperties from a \"class,\" they **delegate** missing property lookups to their\nprototype at runtime. Each object stores only what differs from its prototype.\n\n```js\nconst base = { type: 'shape', area() { return 0 } }\nconst circle = Object.create(base)\ncircle.r = 2\ncircle.area = function () { return Math.PI * this.r ** 2 } \u002F\u002F override only this\n```\n\nChanges to the prototype are immediately visible to all delegating objects (a\nlive link), unlike class-based copying. This is why the model is sometimes\ncalled \"objects linking to other objects\" (OLOO).\n",{"id":97,"difficulty":24,"q":98,"a":99},"prototype-method-update","What happens if you change a prototype after instances exist?","Because the prototype link is **live**, existing instances immediately see\nchanges to their prototype.\n\n```js\nfunction User() {}\nconst u = new User()\nUser.prototype.greet = function () { return 'hi' }\nu.greet()   \u002F\u002F 'hi' — added after u was created, but visible\n```\n\nThis is a consequence of delegation: instances don't copy the prototype, they\nreference it. (Reassigning the whole `prototype` object, however, only affects\n*future* instances — existing ones keep their old prototype.)\n",{"id":101,"difficulty":24,"q":102,"a":103},"typeof-vs-instanceof","When do you use typeof vs instanceof?","- **`typeof`** — for **primitives** and detecting functions (`'string'`,\n  `'number'`, `'function'`, …).\n- **`instanceof`** — for checking whether an object is built by a particular\n  constructor\u002Fclass (prototype-chain membership).\n\n```js\ntypeof 'hi'           \u002F\u002F 'string'\ntypeof []             \u002F\u002F 'object' (useless for arrays)\n[] instanceof Array   \u002F\u002F true\nnew Date instanceof Date \u002F\u002F true\n```\n\n`typeof null` is `'object'` and `typeof []` is `'object'`, so use\n`Array.isArray` for arrays and `instanceof`\u002Fduck-typing for object kinds.\n",{"id":105,"difficulty":14,"q":106,"a":107},"function-prototype","Do arrow functions have a prototype property?","No. Arrow functions **lack a `prototype`** property and can't be used with\n`new`, because they're not designed to be constructors.\n\n```js\nconst arrow = () => {}\narrow.prototype          \u002F\u002F undefined\nnew arrow()              \u002F\u002F TypeError: arrow is not a constructor\n\nfunction regular() {}\nregular.prototype        \u002F\u002F {} — usable as a constructor\n```\n\nOnly regular functions (and classes) have a `prototype` object for building\ninstances. This is one of several reasons arrows are lightweight callbacks, not\ngeneral-purpose functions.\n",{"id":109,"difficulty":14,"q":110,"a":111},"chain-performance","Does a long prototype chain affect performance?","Slightly — each missing-property lookup walks the chain until found or `null`,\nso very deep chains add overhead. In practice engines optimize this heavily\n(inline caches), so it rarely matters for normal depths.\n\n```js\n\u002F\u002F accessing a deeply inherited property walks more links\ndeep.someInheritedMethod()  \u002F\u002F traverses several prototypes\n```\n\nBigger wins come from not reassigning prototypes at runtime\n(`setPrototypeOf` deoptimizes) and keeping object \"shapes\" stable. Don't\nmicro-optimize chain depth; do avoid dynamic prototype mutation in hot paths.\n",{"id":113,"difficulty":14,"q":114,"a":115},"mixin-prototype","How do you mix methods from multiple sources into a prototype?","Since JavaScript has single-prototype inheritance, you compose extra behavior by\n**copying methods** onto a prototype — a mixin.\n\n```js\nconst serializable = { toJSON() { return { ...this } } }\nconst loggable = { log() { console.log(this) } }\n\nclass Model {}\nObject.assign(Model.prototype, serializable, loggable)\nnew Model().log()\n```\n\n`Object.assign(Class.prototype, ...mixins)` adds shared methods without a\nsuperclass — the standard way to share behavior across unrelated classes.\n",{"id":117,"difficulty":24,"q":118,"a":119},"null-prototype-pitfall","What breaks when an object has no prototype?","`Object.create(null)` objects lack `Object.prototype`, so the usual methods\n(`toString`, `hasOwnProperty`, `valueOf`) are missing.\n\n```js\nconst dict = Object.create(null)\ndict.toString()              \u002F\u002F TypeError: not a function\n`${dict}`                    \u002F\u002F throws — can't coerce to string\nObject.keys(dict)            \u002F\u002F static methods still work\ndict.hasOwnProperty          \u002F\u002F undefined -> use Object.hasOwn(dict, k)\n```\n\nUse the **static** `Object.*` methods instead of instance methods. The benefit\n(no inherited keys to collide with) is why they're used as safe maps — but a\n`Map` usually avoids these pitfalls entirely.\n",{"id":121,"difficulty":14,"q":122,"a":123},"setprototypeof-vs-create","Why is Object.setPrototypeOf discouraged?","Changing an existing object's prototype forces engines to **deoptimize** it\n(its hidden class\u002Fshape changes), which is slow and can hurt every later access\nto that object.\n\n```js\n\u002F\u002F slow — mutates an existing object's prototype\nconst obj = {}\nObject.setPrototypeOf(obj, proto)\n\n\u002F\u002F fast — set the prototype at creation\nconst obj2 = Object.create(proto)\n```\n\nSet the prototype **once at creation** (`Object.create`, a class, or a\nconstructor) rather than mutating it later. MDN explicitly warns about\n`setPrototypeOf`'s performance impact.\n",{"id":125,"difficulty":24,"q":126,"a":127},"prototype-vs-composition","Is prototypal inheritance better than composition?","Neither is universally better — they solve different problems. Prototypal\ninheritance shares behavior down an is-a chain; **composition** builds behavior\nby combining small, independent pieces (often favored for flexibility).\n\n```js\n\u002F\u002F composition: assemble capabilities\nconst canFly = (s) => ({ fly: () => `${s.name} flies` })\nconst bird = (name) => { const s = { name }; return { ...s, ...canFly(s) } }\n```\n\nDeep inheritance chains get rigid; composition (mixins, factory functions,\ndelegation) tends to scale better. The common guidance \"favor composition over\ninheritance\" applies in JS too.\n",{"id":129,"difficulty":14,"q":130,"a":131},"getter-on-prototype","Can getters and setters live on a prototype?","Yes — accessor properties defined on a prototype are inherited and run with the\ninstance as `this`, so derived values work per instance.\n\n```js\nclass Circle {\n  constructor(r) { this.r = r }\n  get area() { return Math.PI * this.r ** 2 }  \u002F\u002F on Circle.prototype\n}\nnew Circle(2).area   \u002F\u002F 12.56... — `this` is the instance\n```\n\nClass getters\u002Fsetters live on the prototype (shared definition), but execute\nagainst each instance. You can also add them via\n`Object.defineProperty(proto, 'x', { get, set })`.\n",{"id":133,"difficulty":14,"q":134,"a":135},"realm-instanceof","Why can instanceof fail across iframes or realms?","Each realm (iframe, worker, Node vm) has its **own** built-in constructors and\nprototypes. An array from another frame has a different `Array.prototype`, so\n`arr instanceof Array` is `false` in your realm.\n\n```js\nconst iframeArray = iframe.contentWindow.eval('[1, 2]')\niframeArray instanceof Array   \u002F\u002F false — different Array constructor\nArray.isArray(iframeArray)     \u002F\u002F true — realm-agnostic\n```\n\nPrefer realm-safe checks: `Array.isArray`, `Object.prototype.toString.call(x)`\n(`'[object Array]'`), or duck typing — not `instanceof` — for cross-realm code.\n",{"id":137,"difficulty":14,"q":138,"a":139},"oloo","What is the OLOO pattern?","\"Objects Linking to Other Objects\" — a style (popularized by Kyle Simpson) that\nuses `Object.create` and delegation directly, without constructors, `new`, or\nclasses, embracing JavaScript's prototypal nature.\n\n```js\nconst Widget = {\n  init(w) { this.width = w; return this },\n  render() { return `width: ${this.width}` },\n}\nconst button = Object.create(Widget).init(100)\nbutton.render()  \u002F\u002F 'width: 100'\n```\n\nIt avoids the `new`\u002F`this`\u002F`prototype` ceremony and makes the delegation\nexplicit. It's a minority style — classes are more common — but it clarifies how\nprototypes actually work.\n",null,{"description":11},"JavaScript prototype interview questions — the prototype chain, __proto__ vs prototype, property lookup, inheritance, and how methods are shared.","javascript\u002Fobjects\u002Fprototypes-chain","Prototypes & the Prototype Chain","Objects & Prototypes","objects","2026-06-18","apN3WJNktEDjBw2n8sZQhdM5ksCiMFRiWPSCKdSPYa8",[150,154,155,159],{"subtopic":151,"path":152,"order":153},"Objects & Properties","\u002Fjavascript\u002Fobjects\u002Fobjects-properties",1,{"subtopic":144,"path":20,"order":12},{"subtopic":156,"path":157,"order":158},"Prototypal Inheritance","\u002Fjavascript\u002Fobjects\u002Fprototypal-inheritance",3,{"subtopic":160,"path":161,"order":162},"The new Operator & Constructors","\u002Fjavascript\u002Fobjects\u002Fnew-constructors",4,{"path":164,"title":165},"\u002Fblog\u002Fjavascript-prototypes-prototype-chain-explained","JavaScript Prototypes & the Prototype Chain Explained — A Visual Guide",1781808676075]