[{"data":1,"prerenderedAt":1382},["ShallowReactive",2],{"blog-\u002Fblog\u002Fjavascript-prototypal-inheritance-guide":3},{"id":4,"title":5,"body":6,"description":1367,"difficulty":1368,"extension":1369,"framework":1370,"frameworkSlug":1371,"meta":1372,"navigation":131,"order":122,"path":1373,"qaPath":1374,"seo":1375,"stem":1376,"subtopic":1377,"topic":1378,"topicSlug":1379,"updated":1380,"__hash__":1381},"blog\u002Fblog\u002Fjavascript-prototypal-inheritance-guide.md","Prototypal Inheritance in JavaScript — The Complete Practical Guide",{"type":7,"value":8,"toc":1355},"minimark",[9,14,35,42,46,49,196,220,224,227,461,485,489,498,741,771,775,782,853,875,879,882,906,1012,1015,1019,1025,1082,1095,1099,1102,1177,1192,1195,1254,1264,1268,1282,1286,1338,1351],[10,11,13],"h2",{"id":12},"inheritance-without-classes","Inheritance without classes",[15,16,17,18,22,23,26,27,31,32,34],"p",{},"Most languages implement inheritance through classes: a blueprint that other blueprints\nextend. JavaScript takes a different, arguably simpler route — objects inherit directly\nfrom ",[19,20,21],"strong",{},"other objects"," through the prototype chain. This is ",[19,24,25],{},"prototypal inheritance",", and\nit's what ",[28,29,30],"code",{},"class"," quietly compiles down to. Understanding it directly (not just through the\n",[28,33,30],{}," veneer) gives you a much firmer grip on how behavior is shared, overridden, and\nextended in JavaScript.",[15,36,37,38,41],{},"The core idea is ",[19,39,40],{},"delegation",": an object delegates property and method lookups it can't\nsatisfy to its prototype. There's no copying of methods into each object — instances point\nback to shared behavior and borrow it on demand.",[10,43,45],{"id":44},"delegation-the-foundation","Delegation, the foundation",[15,47,48],{},"When an object lacks a property, lookup climbs to its prototype. So if you put shared\nmethods on a prototype object, every object linked to it can use them as if they were its\nown.",[50,51,56],"pre",{"className":52,"code":53,"language":54,"meta":55,"style":55},"language-js shiki shiki-themes github-light github-dark","const animal = {\n  describe() { return `${this.name} is a ${this.type}` }\n}\n\nconst dog = Object.create(animal)\ndog.name = 'Rex'\ndog.type = 'dog'\n\ndog.describe()   \u002F\u002F 'Rex is a dog' method delegated to animal\n","js","",[28,57,58,78,120,126,133,152,164,175,180],{"__ignoreMap":55},[59,60,63,67,71,74],"span",{"class":61,"line":62},"line",1,[59,64,66],{"class":65},"szBVR","const",[59,68,70],{"class":69},"sj4cs"," animal",[59,72,73],{"class":65}," =",[59,75,77],{"class":76},"sVt8B"," {\n",[59,79,81,85,88,91,95,98,101,104,107,109,111,114,117],{"class":61,"line":80},2,[59,82,84],{"class":83},"sScJk","  describe",[59,86,87],{"class":76},"() { ",[59,89,90],{"class":65},"return",[59,92,94],{"class":93},"sZZnC"," `${",[59,96,97],{"class":69},"this",[59,99,100],{"class":93},".",[59,102,103],{"class":76},"name",[59,105,106],{"class":93},"} is a ${",[59,108,97],{"class":69},[59,110,100],{"class":93},[59,112,113],{"class":76},"type",[59,115,116],{"class":93},"}`",[59,118,119],{"class":76}," }\n",[59,121,123],{"class":61,"line":122},3,[59,124,125],{"class":76},"}\n",[59,127,129],{"class":61,"line":128},4,[59,130,132],{"emptyLinePlaceholder":131},true,"\n",[59,134,136,138,141,143,146,149],{"class":61,"line":135},5,[59,137,66],{"class":65},[59,139,140],{"class":69}," dog",[59,142,73],{"class":65},[59,144,145],{"class":76}," Object.",[59,147,148],{"class":83},"create",[59,150,151],{"class":76},"(animal)\n",[59,153,155,158,161],{"class":61,"line":154},6,[59,156,157],{"class":76},"dog.name ",[59,159,160],{"class":65},"=",[59,162,163],{"class":93}," 'Rex'\n",[59,165,167,170,172],{"class":61,"line":166},7,[59,168,169],{"class":76},"dog.type ",[59,171,160],{"class":65},[59,173,174],{"class":93}," 'dog'\n",[59,176,178],{"class":61,"line":177},8,[59,179,132],{"emptyLinePlaceholder":131},[59,181,183,186,189,192],{"class":61,"line":182},9,[59,184,185],{"class":76},"dog.",[59,187,188],{"class":83},"describe",[59,190,191],{"class":76},"()   ",[59,193,195],{"class":194},"sJ8bj","\u002F\u002F 'Rex is a dog' method delegated to animal\n",[15,197,198,199,201,202,204,205,208,209,213,214,217,218,100],{},"Notice ",[28,200,97],{}," inside ",[28,203,188],{}," refers to ",[28,206,207],{},"dog",", the object the method was ",[210,211,212],"em",{},"called on",", not\n",[28,215,216],{},"animal"," where it lives. That's the magic of delegation: one shared method, many objects,\neach supplying its own data through ",[28,219,97],{},[10,221,223],{"id":222},"building-inheritance-with-objectcreate","Building inheritance with Object.create",[15,225,226],{},"The cleanest way to express \"B inherits from A\" with plain objects is to set B's prototype\nto A. You can build multi-level hierarchies this way.",[50,228,230],{"className":52,"code":229,"language":54,"meta":55,"style":55},"const shape = {\n  area() { return 0 },\n  toString() { return `${this.constructor?.name ?? 'Shape'} area=${this.area()}` }\n}\n\nconst rectangle = Object.create(shape)\nrectangle.init = function (w, h) { this.w = w; this.h = h; return this }\nrectangle.area = function () { return this.w * this.h }   \u002F\u002F override\n\nconst r = Object.create(rectangle).init(3, 4)\nr.area()   \u002F\u002F 12 — rectangle's own area\n",[28,231,232,243,258,301,305,309,325,381,411,415,448],{"__ignoreMap":55},[59,233,234,236,239,241],{"class":61,"line":62},[59,235,66],{"class":65},[59,237,238],{"class":69}," shape",[59,240,73],{"class":65},[59,242,77],{"class":76},[59,244,245,248,250,252,255],{"class":61,"line":80},[59,246,247],{"class":83},"  area",[59,249,87],{"class":76},[59,251,90],{"class":65},[59,253,254],{"class":69}," 0",[59,256,257],{"class":76}," },\n",[59,259,260,263,265,267,269,271,273,276,279,281,284,287,289,291,294,297,299],{"class":61,"line":122},[59,261,262],{"class":83},"  toString",[59,264,87],{"class":76},[59,266,90],{"class":65},[59,268,94],{"class":93},[59,270,97],{"class":69},[59,272,100],{"class":93},[59,274,275],{"class":69},"constructor",[59,277,278],{"class":93},"?.",[59,280,103],{"class":76},[59,282,283],{"class":65}," ??",[59,285,286],{"class":93}," 'Shape'} area=${",[59,288,97],{"class":69},[59,290,100],{"class":93},[59,292,293],{"class":83},"area",[59,295,296],{"class":93},"()",[59,298,116],{"class":93},[59,300,119],{"class":76},[59,302,303],{"class":61,"line":128},[59,304,125],{"class":76},[59,306,307],{"class":61,"line":135},[59,308,132],{"emptyLinePlaceholder":131},[59,310,311,313,316,318,320,322],{"class":61,"line":154},[59,312,66],{"class":65},[59,314,315],{"class":69}," rectangle",[59,317,73],{"class":65},[59,319,145],{"class":76},[59,321,148],{"class":83},[59,323,324],{"class":76},"(shape)\n",[59,326,327,330,333,335,338,341,345,348,351,354,356,359,361,364,366,369,371,374,376,379],{"class":61,"line":166},[59,328,329],{"class":76},"rectangle.",[59,331,332],{"class":83},"init",[59,334,73],{"class":65},[59,336,337],{"class":65}," function",[59,339,340],{"class":76}," (",[59,342,344],{"class":343},"s4XuR","w",[59,346,347],{"class":76},", ",[59,349,350],{"class":343},"h",[59,352,353],{"class":76},") { ",[59,355,97],{"class":69},[59,357,358],{"class":76},".w ",[59,360,160],{"class":65},[59,362,363],{"class":76}," w; ",[59,365,97],{"class":69},[59,367,368],{"class":76},".h ",[59,370,160],{"class":65},[59,372,373],{"class":76}," h; ",[59,375,90],{"class":65},[59,377,378],{"class":69}," this",[59,380,119],{"class":76},[59,382,383,385,387,389,391,394,396,398,400,403,405,408],{"class":61,"line":177},[59,384,329],{"class":76},[59,386,293],{"class":83},[59,388,73],{"class":65},[59,390,337],{"class":65},[59,392,393],{"class":76}," () { ",[59,395,90],{"class":65},[59,397,378],{"class":69},[59,399,358],{"class":76},[59,401,402],{"class":65},"*",[59,404,378],{"class":69},[59,406,407],{"class":76},".h }   ",[59,409,410],{"class":194},"\u002F\u002F override\n",[59,412,413],{"class":61,"line":182},[59,414,132],{"emptyLinePlaceholder":131},[59,416,418,420,423,425,427,429,432,434,437,440,442,445],{"class":61,"line":417},10,[59,419,66],{"class":65},[59,421,422],{"class":69}," r",[59,424,73],{"class":65},[59,426,145],{"class":76},[59,428,148],{"class":83},[59,430,431],{"class":76},"(rectangle).",[59,433,332],{"class":83},[59,435,436],{"class":76},"(",[59,438,439],{"class":69},"3",[59,441,347],{"class":76},[59,443,444],{"class":69},"4",[59,446,447],{"class":76},")\n",[59,449,451,454,456,458],{"class":61,"line":450},11,[59,452,453],{"class":76},"r.",[59,455,293],{"class":83},[59,457,191],{"class":76},[59,459,460],{"class":194},"\u002F\u002F 12 — rectangle's own area\n",[15,462,463,464,467,468,471,472,474,475,477,478,481,482,100],{},"Here the chain is ",[28,465,466],{},"r -> rectangle -> shape -> Object.prototype",". ",[28,469,470],{},"r"," borrows ",[28,473,332],{}," and\n",[28,476,293],{}," from ",[28,479,480],{},"rectangle",", which itself delegates anything missing to ",[28,483,484],{},"shape",[10,486,488],{"id":487},"constructor-function-inheritance","Constructor-function inheritance",[15,490,491,492,494,495,497],{},"Before ",[28,493,30],{},", the standard pattern used constructor functions and explicitly wired up the\nprototype chain. It's verbose but worth understanding because ",[28,496,30],{}," does exactly this\nunder the hood.",[50,499,501],{"className":52,"code":500,"language":54,"meta":55,"style":55},"function Animal(name) { this.name = name }\nAnimal.prototype.speak = function () { return `${this.name} makes a sound` }\n\nfunction Dog(name) {\n  Animal.call(this, name)         \u002F\u002F 1. run parent constructor on `this`\n}\nDog.prototype = Object.create(Animal.prototype)  \u002F\u002F 2. link prototypes\nDog.prototype.constructor = Dog                    \u002F\u002F 3. fix the constructor pointer\nDog.prototype.speak = function () { return `${this.name} barks` }  \u002F\u002F override\n\nconst d = new Dog('Rex')\nd.speak()              \u002F\u002F 'Rex barks'\nd instanceof Animal    \u002F\u002F true chain set up correctly\n",[28,502,503,527,563,567,581,599,603,632,652,688,692,713,727],{"__ignoreMap":55},[59,504,505,508,511,513,515,517,519,522,524],{"class":61,"line":62},[59,506,507],{"class":65},"function",[59,509,510],{"class":83}," Animal",[59,512,436],{"class":76},[59,514,103],{"class":343},[59,516,353],{"class":76},[59,518,97],{"class":69},[59,520,521],{"class":76},".name ",[59,523,160],{"class":65},[59,525,526],{"class":76}," name }\n",[59,528,529,532,534,537,539,542,544,546,548,550,552,554,556,558,561],{"class":61,"line":80},[59,530,531],{"class":69},"Animal",[59,533,100],{"class":76},[59,535,536],{"class":69},"prototype",[59,538,100],{"class":76},[59,540,541],{"class":83},"speak",[59,543,73],{"class":65},[59,545,337],{"class":65},[59,547,393],{"class":76},[59,549,90],{"class":65},[59,551,94],{"class":93},[59,553,97],{"class":69},[59,555,100],{"class":93},[59,557,103],{"class":76},[59,559,560],{"class":93},"} makes a sound`",[59,562,119],{"class":76},[59,564,565],{"class":61,"line":122},[59,566,132],{"emptyLinePlaceholder":131},[59,568,569,571,574,576,578],{"class":61,"line":128},[59,570,507],{"class":65},[59,572,573],{"class":83}," Dog",[59,575,436],{"class":76},[59,577,103],{"class":343},[59,579,580],{"class":76},") {\n",[59,582,583,586,589,591,593,596],{"class":61,"line":135},[59,584,585],{"class":76},"  Animal.",[59,587,588],{"class":83},"call",[59,590,436],{"class":76},[59,592,97],{"class":69},[59,594,595],{"class":76},", name)         ",[59,597,598],{"class":194},"\u002F\u002F 1. run parent constructor on `this`\n",[59,600,601],{"class":61,"line":154},[59,602,125],{"class":76},[59,604,605,608,610,612,614,616,618,620,622,624,626,629],{"class":61,"line":166},[59,606,607],{"class":69},"Dog",[59,609,100],{"class":76},[59,611,536],{"class":69},[59,613,73],{"class":65},[59,615,145],{"class":76},[59,617,148],{"class":83},[59,619,436],{"class":76},[59,621,531],{"class":69},[59,623,100],{"class":76},[59,625,536],{"class":69},[59,627,628],{"class":76},")  ",[59,630,631],{"class":194},"\u002F\u002F 2. link prototypes\n",[59,633,634,636,638,640,642,644,646,649],{"class":61,"line":177},[59,635,607],{"class":69},[59,637,100],{"class":76},[59,639,536],{"class":69},[59,641,100],{"class":76},[59,643,275],{"class":69},[59,645,73],{"class":65},[59,647,648],{"class":76}," Dog                    ",[59,650,651],{"class":194},"\u002F\u002F 3. fix the constructor pointer\n",[59,653,654,656,658,660,662,664,666,668,670,672,674,676,678,680,683,686],{"class":61,"line":182},[59,655,607],{"class":69},[59,657,100],{"class":76},[59,659,536],{"class":69},[59,661,100],{"class":76},[59,663,541],{"class":83},[59,665,73],{"class":65},[59,667,337],{"class":65},[59,669,393],{"class":76},[59,671,90],{"class":65},[59,673,94],{"class":93},[59,675,97],{"class":69},[59,677,100],{"class":93},[59,679,103],{"class":76},[59,681,682],{"class":93},"} barks`",[59,684,685],{"class":76}," }  ",[59,687,410],{"class":194},[59,689,690],{"class":61,"line":417},[59,691,132],{"emptyLinePlaceholder":131},[59,693,694,696,699,701,704,706,708,711],{"class":61,"line":450},[59,695,66],{"class":65},[59,697,698],{"class":69}," d",[59,700,73],{"class":65},[59,702,703],{"class":65}," new",[59,705,573],{"class":83},[59,707,436],{"class":76},[59,709,710],{"class":93},"'Rex'",[59,712,447],{"class":76},[59,714,716,719,721,724],{"class":61,"line":715},12,[59,717,718],{"class":76},"d.",[59,720,541],{"class":83},[59,722,723],{"class":76},"()              ",[59,725,726],{"class":194},"\u002F\u002F 'Rex barks'\n",[59,728,730,733,736,738],{"class":61,"line":729},13,[59,731,732],{"class":76},"d ",[59,734,735],{"class":65},"instanceof",[59,737,510],{"class":83},[59,739,740],{"class":194},"    \u002F\u002F true chain set up correctly\n",[15,742,743,744,747,748,751,752,755,756,759,760,763,764,767,768,770],{},"The three steps matter: ",[19,745,746],{},"(1)"," call the parent constructor with ",[28,749,750],{},"Animal.call(this, ...)","\nso instance fields are initialized, ",[19,753,754],{},"(2)"," set ",[28,757,758],{},"Dog.prototype"," to an object that delegates\nto ",[28,761,762],{},"Animal.prototype",", and ",[19,765,766],{},"(3)"," restore ",[28,769,275],{},". Skip any of them and you get\nsubtle bugs.",[10,772,774],{"id":773},"overriding-and-extending-methods","Overriding and extending methods",[15,776,777,778,781],{},"Overriding is just shadowing: define a method with the same name lower in the chain and it\nwins. To ",[210,779,780],{},"extend"," rather than replace the parent's behavior, call up to the parent\nexplicitly.",[50,783,785],{"className":52,"code":784,"language":54,"meta":55,"style":55},"Dog.prototype.speak = function () {\n  const base = Animal.prototype.speak.call(this)  \u002F\u002F reuse parent logic\n  return `${base}, specifically a bark`\n}\n",[28,786,787,806,836,849],{"__ignoreMap":55},[59,788,789,791,793,795,797,799,801,803],{"class":61,"line":62},[59,790,607],{"class":69},[59,792,100],{"class":76},[59,794,536],{"class":69},[59,796,100],{"class":76},[59,798,541],{"class":83},[59,800,73],{"class":65},[59,802,337],{"class":65},[59,804,805],{"class":76}," () {\n",[59,807,808,811,814,816,818,820,822,825,827,829,831,833],{"class":61,"line":80},[59,809,810],{"class":65},"  const",[59,812,813],{"class":69}," base",[59,815,73],{"class":65},[59,817,510],{"class":69},[59,819,100],{"class":76},[59,821,536],{"class":69},[59,823,824],{"class":76},".speak.",[59,826,588],{"class":83},[59,828,436],{"class":76},[59,830,97],{"class":69},[59,832,628],{"class":76},[59,834,835],{"class":194},"\u002F\u002F reuse parent logic\n",[59,837,838,841,843,846],{"class":61,"line":122},[59,839,840],{"class":65},"  return",[59,842,94],{"class":93},[59,844,845],{"class":76},"base",[59,847,848],{"class":93},"}, specifically a bark`\n",[59,850,851],{"class":61,"line":128},[59,852,125],{"class":76},[15,854,855,858,859,861,862,865,866,868,869,347,871,874],{},[28,856,857],{},"Animal.prototype.speak.call(this)"," is the pre-",[28,860,30],{}," equivalent of ",[28,863,864],{},"super.speak()",". You\nfetch the parent method off the parent prototype and invoke it with the current ",[28,867,97],{},".\nWith ",[28,870,30],{},[28,872,873],{},"super"," does this for you — but it's the same mechanism.",[10,876,878],{"id":877},"delegation-vs-concatenation-mixins","Delegation vs concatenation (mixins)",[15,880,881],{},"There are two broad strategies for sharing behavior:",[883,884,885,892],"ul",{},[886,887,888,891],"li",{},[19,889,890],{},"Delegation (prototypal):"," objects link to a shared prototype and borrow methods live.\nOne copy of each method, changes to the prototype are seen instantly by all instances.",[886,893,894,897,898,901,902,905],{},[19,895,896],{},"Concatenation (mixins):"," copy properties from source objects ",[210,899,900],{},"into"," the target with\n",[28,903,904],{},"Object.assign",". Each object gets its own copy; no live link.",[50,907,909],{"className":52,"code":908,"language":54,"meta":55,"style":55},"\u002F\u002F concatenation \u002F mixin\nconst serializable = { toJSON() { return JSON.stringify(this) } }\nconst comparable   = { equals(o) { return this.id === o.id } }\n\nconst entity = Object.assign({}, serializable, comparable, { id: 1 })\n",[28,910,911,916,950,985,989],{"__ignoreMap":55},[59,912,913],{"class":61,"line":62},[59,914,915],{"class":194},"\u002F\u002F concatenation \u002F mixin\n",[59,917,918,920,923,925,928,931,933,935,938,940,943,945,947],{"class":61,"line":80},[59,919,66],{"class":65},[59,921,922],{"class":69}," serializable",[59,924,73],{"class":65},[59,926,927],{"class":76}," { ",[59,929,930],{"class":83},"toJSON",[59,932,87],{"class":76},[59,934,90],{"class":65},[59,936,937],{"class":69}," JSON",[59,939,100],{"class":76},[59,941,942],{"class":83},"stringify",[59,944,436],{"class":76},[59,946,97],{"class":69},[59,948,949],{"class":76},") } }\n",[59,951,952,954,957,960,962,965,967,970,972,974,976,979,982],{"class":61,"line":122},[59,953,66],{"class":65},[59,955,956],{"class":69}," comparable",[59,958,959],{"class":65},"   =",[59,961,927],{"class":76},[59,963,964],{"class":83},"equals",[59,966,436],{"class":76},[59,968,969],{"class":343},"o",[59,971,353],{"class":76},[59,973,90],{"class":65},[59,975,378],{"class":69},[59,977,978],{"class":76},".id ",[59,980,981],{"class":65},"===",[59,983,984],{"class":76}," o.id } }\n",[59,986,987],{"class":61,"line":128},[59,988,132],{"emptyLinePlaceholder":131},[59,990,991,993,996,998,1000,1003,1006,1009],{"class":61,"line":135},[59,992,66],{"class":65},[59,994,995],{"class":69}," entity",[59,997,73],{"class":65},[59,999,145],{"class":76},[59,1001,1002],{"class":83},"assign",[59,1004,1005],{"class":76},"({}, serializable, comparable, { id: ",[59,1007,1008],{"class":69},"1",[59,1010,1011],{"class":76}," })\n",[15,1013,1014],{},"Delegation is memory-efficient and dynamic; concatenation is flat and avoids deep chains.\nReal codebases use both — prototypes for primary inheritance, mixins for cross-cutting\ncapabilities that don't fit a single hierarchy.",[10,1016,1018],{"id":1017},"the-instanceof-relationship","The instanceof relationship",[15,1020,1021,1022,1024],{},"Because inheritance is just chained prototypes, ",[28,1023,735],{}," reflects the whole hierarchy.",[50,1026,1028],{"className":52,"code":1027,"language":54,"meta":55,"style":55},"const d = new Dog('Rex')\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",[28,1029,1030,1048,1059,1070],{"__ignoreMap":55},[59,1031,1032,1034,1036,1038,1040,1042,1044,1046],{"class":61,"line":62},[59,1033,66],{"class":65},[59,1035,698],{"class":69},[59,1037,73],{"class":65},[59,1039,703],{"class":65},[59,1041,573],{"class":83},[59,1043,436],{"class":76},[59,1045,710],{"class":93},[59,1047,447],{"class":76},[59,1049,1050,1052,1054,1056],{"class":61,"line":80},[59,1051,732],{"class":76},[59,1053,735],{"class":65},[59,1055,573],{"class":83},[59,1057,1058],{"class":194},"      \u002F\u002F true\n",[59,1060,1061,1063,1065,1067],{"class":61,"line":122},[59,1062,732],{"class":76},[59,1064,735],{"class":65},[59,1066,510],{"class":83},[59,1068,1069],{"class":194},"   \u002F\u002F true Animal.prototype is in the chain\n",[59,1071,1072,1074,1076,1079],{"class":61,"line":128},[59,1073,732],{"class":76},[59,1075,735],{"class":65},[59,1077,1078],{"class":83}," Object",[59,1080,1081],{"class":194},"   \u002F\u002F true\n",[15,1083,1084,1086,1087,1090,1091,1094],{},[28,1085,735],{}," checks whether the right-hand side's ",[28,1088,1089],{},".prototype"," appears anywhere in the\nleft-hand side's chain — so it naturally returns ",[28,1092,1093],{},"true"," for every ancestor.",[10,1096,1098],{"id":1097},"common-pitfalls","Common pitfalls",[15,1100,1101],{},"A few mistakes recur constantly:",[50,1103,1105],{"className":52,"code":1104,"language":54,"meta":55,"style":55},"\u002F\u002F forgetting Object.create — this points the SAME object, not a copy\nDog.prototype = Animal.prototype\n\u002F\u002F now overriding Dog.prototype.speak also changes Animal's! shared reference\n\n\u002F\u002F forgetting to call the parent constructor\nfunction Dog(name) { \u002F* missing Animal.call(this, name) *\u002F }\nnew Dog('Rex').name   \u002F\u002F undefined — instance never initialized\n",[28,1106,1107,1112,1129,1134,1138,1143,1160],{"__ignoreMap":55},[59,1108,1109],{"class":61,"line":62},[59,1110,1111],{"class":194},"\u002F\u002F forgetting Object.create — this points the SAME object, not a copy\n",[59,1113,1114,1116,1118,1120,1122,1124,1126],{"class":61,"line":80},[59,1115,607],{"class":69},[59,1117,100],{"class":76},[59,1119,536],{"class":69},[59,1121,73],{"class":65},[59,1123,510],{"class":69},[59,1125,100],{"class":76},[59,1127,1128],{"class":69},"prototype\n",[59,1130,1131],{"class":61,"line":122},[59,1132,1133],{"class":194},"\u002F\u002F now overriding Dog.prototype.speak also changes Animal's! shared reference\n",[59,1135,1136],{"class":61,"line":128},[59,1137,132],{"emptyLinePlaceholder":131},[59,1139,1140],{"class":61,"line":135},[59,1141,1142],{"class":194},"\u002F\u002F forgetting to call the parent constructor\n",[59,1144,1145,1147,1149,1151,1153,1155,1158],{"class":61,"line":154},[59,1146,507],{"class":65},[59,1148,573],{"class":83},[59,1150,436],{"class":76},[59,1152,103],{"class":343},[59,1154,353],{"class":76},[59,1156,1157],{"class":194},"\u002F* missing Animal.call(this, name) *\u002F",[59,1159,119],{"class":76},[59,1161,1162,1165,1167,1169,1171,1174],{"class":61,"line":166},[59,1163,1164],{"class":65},"new",[59,1166,573],{"class":83},[59,1168,436],{"class":76},[59,1170,710],{"class":93},[59,1172,1173],{"class":76},").name   ",[59,1175,1176],{"class":194},"\u002F\u002F undefined — instance never initialized\n",[15,1178,1179,1180,1183,1184,1187,1188,1191],{},"The first is the most dangerous: assigning ",[28,1181,1182],{},"Dog.prototype = Animal.prototype"," makes them\nthe ",[210,1185,1186],{},"same object",", so changes leak between parent and child. Always use\n",[28,1189,1190],{},"Object.create(Animal.prototype)"," to get a fresh delegating object. The second leaves\ninstance fields uninitialized because the parent's setup code never ran.",[15,1193,1194],{},"Another subtle one: defining methods on instances instead of the prototype wastes memory and\nbreaks the \"shared behavior\" model.",[50,1196,1198],{"className":52,"code":1197,"language":54,"meta":55,"style":55},"function Cat(name) {\n  this.name = name\n  this.meow = function () { return 'meow' }  \u002F\u002F new function per instance\n}\n",[28,1199,1200,1213,1225,1250],{"__ignoreMap":55},[59,1201,1202,1204,1207,1209,1211],{"class":61,"line":62},[59,1203,507],{"class":65},[59,1205,1206],{"class":83}," Cat",[59,1208,436],{"class":76},[59,1210,103],{"class":343},[59,1212,580],{"class":76},[59,1214,1215,1218,1220,1222],{"class":61,"line":80},[59,1216,1217],{"class":69},"  this",[59,1219,521],{"class":76},[59,1221,160],{"class":65},[59,1223,1224],{"class":76}," name\n",[59,1226,1227,1229,1231,1234,1236,1238,1240,1242,1245,1247],{"class":61,"line":122},[59,1228,1217],{"class":69},[59,1230,100],{"class":76},[59,1232,1233],{"class":83},"meow",[59,1235,73],{"class":65},[59,1237,337],{"class":65},[59,1239,393],{"class":76},[59,1241,90],{"class":65},[59,1243,1244],{"class":93}," 'meow'",[59,1246,685],{"class":76},[59,1248,1249],{"class":194},"\u002F\u002F new function per instance\n",[59,1251,1252],{"class":61,"line":128},[59,1253,125],{"class":76},[15,1255,1256,1257,1259,1260,1263],{},"Move ",[28,1258,1233],{}," to ",[28,1261,1262],{},"Cat.prototype"," so all cats share it.",[10,1265,1267],{"id":1266},"when-prototypal-shines","When prototypal shines",[15,1269,1270,1271,1274,1275,1278,1279,1281],{},"Prototypal inheritance excels when you want ",[19,1272,1273],{},"flexible, runtime-adjustable"," behavior:\nobjects can be composed and re-linked dynamically, behavior can be added to a prototype and\ninstantly seen by all instances, and there's no rigid class hierarchy to fight. It's also\njust ",[210,1276,1277],{},"less machinery"," — objects all the way down. The tradeoff is that the explicit\nconstructor-wiring pattern is verbose, which is exactly why ",[28,1280,30],{}," syntax was added as\nsugar.",[10,1283,1285],{"id":1284},"key-takeaways","Key takeaways",[883,1287,1288,1297,1303,1312,1325,1328],{},[886,1289,1290,1291,1293,1294,1296],{},"JavaScript inheritance is ",[19,1292,40],{},": objects borrow methods from their prototype,\nwith ",[28,1295,97],{}," bound to the calling object.",[886,1298,1299,1302],{},[28,1300,1301],{},"Object.create(proto)"," is the cleanest primitive for \"inherit from this object.\"",[886,1304,1305,1306,1309,1310,100],{},"Constructor inheritance needs three steps: call the parent constructor, link prototypes\nvia ",[28,1307,1308],{},"Object.create",", and restore ",[28,1311,275],{},[886,1313,1314,1315,1318,1319,1321,1322,1324],{},"Override by shadowing; extend by calling the parent method with ",[28,1316,1317],{},".call(this)"," (the\npre-",[28,1320,30],{}," ",[28,1323,873],{},").",[886,1326,1327],{},"Delegation shares one method copy live; concatenation\u002Fmixins copy methods in flat.",[886,1329,1330,1331,1334,1335,100],{},"Never set ",[28,1332,1333],{},"Child.prototype = Parent.prototype"," — use ",[28,1336,1337],{},"Object.create(Parent.prototype)",[15,1339,1340,1341,1343,1344,1347,1348,1350],{},"Everything ",[28,1342,30],{}," does, this model does underneath. Learn it directly and ",[28,1345,1346],{},"extends",",\n",[28,1349,873],{},", and the rest become transparent rather than magical.",[1352,1353,1354],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":55,"searchDepth":80,"depth":80,"links":1356},[1357,1358,1359,1360,1361,1362,1363,1364,1365,1366],{"id":12,"depth":80,"text":13},{"id":44,"depth":80,"text":45},{"id":222,"depth":80,"text":223},{"id":487,"depth":80,"text":488},{"id":773,"depth":80,"text":774},{"id":877,"depth":80,"text":878},{"id":1017,"depth":80,"text":1018},{"id":1097,"depth":80,"text":1098},{"id":1266,"depth":80,"text":1267},{"id":1284,"depth":80,"text":1285},"Learn prototypal inheritance in JavaScript — delegation vs concatenation, Object.create patterns, sharing behavior, overriding methods, and how it differs from classical inheritance.","medium","md","JavaScript","javascript",{},"\u002Fblog\u002Fjavascript-prototypal-inheritance-guide","\u002Fjavascript\u002Fobjects\u002Fprototypal-inheritance",{"title":5,"description":1367},"blog\u002Fjavascript-prototypal-inheritance-guide","Prototypal Inheritance","Objects & Prototypes","objects","2026-06-18","Qs3FXL4McAlk0GMz5FFVbL_L5DYzjMzFx1cHk9Do0qQ",1781808673080]