[{"data":1,"prerenderedAt":4843},["ShallowReactive",2],{"page-\u002Fjs\u002F10-classes-and-prototypes":3},{"id":4,"title":5,"body":6,"description":177,"extension":4837,"meta":4838,"navigation":39,"path":4839,"seo":4840,"stem":4841,"__hash__":4842},"content\u002Fjs\u002F10-classes-and-prototypes.md","10 — Classes & Prototypes",{"type":7,"value":8,"toc":4813},"minimark",[9,13,162,454,685,1013,1285,1523,1793,2027,2234,2439,2651,2852,3112,3298,3513,3812,4091,4319,4715,4809],[10,11,5],"h1",{"id":12},"_10-classes-prototypes",[14,15,16,26,104],"question-wrapper",{},[17,18,20,21,25],"h3",{"id":19},"q1-which-statement-best-describes-the-relationship-between-javascript-class-syntax-and-prototypes","Q1. Which statement best describes the relationship between JavaScript ",[22,23,24],"code",{},"class"," syntax and prototypes?",[27,28,31,61,72,84],"ul",{"className":29},[30],"contains-task-list",[32,33,36,41,42,45,46,49,50,53,54,57,58],"li",{"className":34},[35],"task-list-item",[37,38],"input",{"disabled":39,"type":40},true,"checkbox"," ",[22,43,44],{},"class Foo {}"," is just syntactic sugar — it creates an ordinary function ",[22,47,48],{},"Foo"," whose ",[22,51,52],{},".prototype"," object holds the instance methods, the same underlying mechanism as manually writing ",[22,55,56],{},"function Foo() {}"," and assigning methods onto ",[22,59,60],{},"Foo.prototype",[32,62,64,41,66,68,69,71],{"className":63},[35],[37,65],{"disabled":39,"type":40},[22,67,24],{}," introduces a completely new object model separate from prototypes — classes do not have a ",[22,70,52],{}," property at all",[32,73,75,41,77,79,80,83],{"className":74},[35],[37,76],{"disabled":39,"type":40},[22,78,24],{}," methods are copied onto every instance individually when ",[22,81,82],{},"new"," is called, so no prototype chain lookup is involved",[32,85,87,41,89,91,92,95,96,99,100,103],{"className":86},[35],[37,88],{"disabled":39,"type":40},[22,90,24],{}," syntax only works for built-in types like ",[22,93,94],{},"Array"," and ",[22,97,98],{},"Map","; user-defined types must still use ",[22,101,102],{},"function"," constructors",[105,106,107,111,129],"details",{},[108,109,110],"summary",{},"Show Answer",[112,113,114,118,119,45,121,49,123,53,125,57,127],"p",{},[115,116,117],"strong",{},"Answer:"," A — ",[22,120,44],{},[22,122,48],{},[22,124,52],{},[22,126,56],{},[22,128,60],{},[112,130,131,134,135,137,138,141,142,144,145,147,148,151,152,154,155,158,159,161],{},[115,132,133],{},"Explanation:"," Under the hood, a ",[22,136,24],{}," declaration still produces a function value (",[22,139,140],{},"typeof Foo === \"function\"","), and every method written in the class body is installed onto ",[22,143,60],{},", exactly like the pre-ES6 pattern of ",[22,146,56],{}," plus ",[22,149,150],{},"Foo.prototype.method = ...",". Classes add stricter syntax (mandatory ",[22,153,82],{},", real inheritance via ",[22,156,157],{},"extends",", TDZ, always-strict-mode bodies), but the runtime object model — functions with a ",[22,160,52],{}," object shared by instances — is unchanged. B, C, and D all describe a different object model than the one JS actually uses.",[14,163,165,169,348,406],{"language":164},"javascript",[17,166,168],{"id":167},"q2-what-does-this-log","Q2. What does this log?",[170,171,172],"code-wrapper",{"language":164},[173,174,178],"pre",{"className":175,"code":176,"language":164,"meta":177,"style":177},"language-javascript shiki shiki-themes github-light github-dark","class Animal {\n  speak() {\n    return \"...\";\n  }\n}\n\nfunction LegacyAnimal() {}\nLegacyAnimal.prototype.speak = function () {\n  return \"...\";\n};\n\nconsole.log(typeof Animal, typeof Animal.prototype.speak);\nconsole.log(typeof LegacyAnimal, typeof LegacyAnimal.prototype.speak);\n","",[22,179,180,196,205,218,224,230,236,247,274,284,290,295,324],{"__ignoreMap":177},[181,182,185,188,192],"span",{"class":183,"line":184},"line",1,[181,186,24],{"class":187},"svdQ7",[181,189,191],{"class":190},"sIsaT"," Animal",[181,193,195],{"class":194},"ssxIu"," {\n",[181,197,199,202],{"class":183,"line":198},2,[181,200,201],{"class":190},"  speak",[181,203,204],{"class":194},"() {\n",[181,206,208,211,215],{"class":183,"line":207},3,[181,209,210],{"class":187},"    return",[181,212,214],{"class":213},"sJ6F3"," \"...\"",[181,216,217],{"class":194},";\n",[181,219,221],{"class":183,"line":220},4,[181,222,223],{"class":194},"  }\n",[181,225,227],{"class":183,"line":226},5,[181,228,229],{"class":194},"}\n",[181,231,233],{"class":183,"line":232},6,[181,234,235],{"emptyLinePlaceholder":39},"\n",[181,237,239,241,244],{"class":183,"line":238},7,[181,240,102],{"class":187},[181,242,243],{"class":190}," LegacyAnimal",[181,245,246],{"class":194},"() {}\n",[181,248,250,254,257,260,262,265,268,271],{"class":183,"line":249},8,[181,251,253],{"class":252},"snvgF","LegacyAnimal",[181,255,256],{"class":194},".",[181,258,259],{"class":252},"prototype",[181,261,256],{"class":194},[181,263,264],{"class":190},"speak",[181,266,267],{"class":187}," =",[181,269,270],{"class":187}," function",[181,272,273],{"class":194}," () {\n",[181,275,277,280,282],{"class":183,"line":276},9,[181,278,279],{"class":187},"  return",[181,281,214],{"class":213},[181,283,217],{"class":194},[181,285,287],{"class":183,"line":286},10,[181,288,289],{"class":194},"};\n",[181,291,293],{"class":183,"line":292},11,[181,294,235],{"emptyLinePlaceholder":39},[181,296,298,301,304,307,310,313,315,317,319,321],{"class":183,"line":297},12,[181,299,300],{"class":194},"console.",[181,302,303],{"class":190},"log",[181,305,306],{"class":194},"(",[181,308,309],{"class":187},"typeof",[181,311,312],{"class":194}," Animal, ",[181,314,309],{"class":187},[181,316,191],{"class":252},[181,318,256],{"class":194},[181,320,259],{"class":252},[181,322,323],{"class":194},".speak);\n",[181,325,327,329,331,333,335,338,340,342,344,346],{"class":183,"line":326},13,[181,328,300],{"class":194},[181,330,303],{"class":190},[181,332,306],{"class":194},[181,334,309],{"class":187},[181,336,337],{"class":194}," LegacyAnimal, ",[181,339,309],{"class":187},[181,341,243],{"class":252},[181,343,256],{"class":194},[181,345,259],{"class":252},[181,347,323],{"class":194},[27,349,351,367,386,397],{"className":350},[30],[32,352,354,41,356,359,360,363,364,366],{"className":353},[35],[37,355],{"disabled":39,"type":40},[22,357,358],{},"\"function\" \"undefined\""," then ",[22,361,362],{},"\"function\" \"function\""," — only the legacy pattern actually attaches ",[22,365,264],{}," onto the prototype",[32,368,370,41,372,359,374,376,377,379,380,382,383,385],{"className":369},[35],[37,371],{"disabled":39,"type":40},[22,373,362],{},[22,375,362],{}," — a ",[22,378,24],{}," declaration produces an ordinary function value whose methods are installed on ",[22,381,52],{},", exactly like manually building a constructor function and assigning to ",[22,384,52],{}," by hand",[32,387,389,41,391,359,394,396],{"className":388},[35],[37,390],{"disabled":39,"type":40},[22,392,393],{},"\"object\" \"function\"",[22,395,362],{}," — classes are plain objects, not functions",[32,398,400,41,402,359,404],{"className":399},[35],[37,401],{"disabled":39,"type":40},[22,403,362],{},[22,405,393],{},[105,407,408,410,425],{},[108,409,110],{},[112,411,412,414,415,359,417,376,419,379,421,382,423,385],{},[115,413,117],{}," B — ",[22,416,362],{},[22,418,362],{},[22,420,24],{},[22,422,52],{},[22,424,52],{},[112,426,427,41,429,432,433,436,437,439,440,442,443,446,447,450,451,453],{},[115,428,133],{},[115,430,431],{},"Idiom:"," both blocks log identically, which is exactly the point — ",[22,434,435],{},"Animal"," is a function just like ",[22,438,253],{},", and ",[22,441,264],{}," lives on ",[22,444,445],{},"Animal.prototype"," just like it lives on ",[22,448,449],{},"LegacyAnimal.prototype",". The ",[22,452,24],{}," keyword is a more readable, safer syntax for building this same function-plus-prototype structure; it doesn't create a fundamentally different kind of value. Options C and D invent a distinction (class as \"object\") that doesn't exist in JS.",[14,455,456,460,584,639],{"language":164},[17,457,459],{"id":458},"q3-what-happens-when-this-runs","Q3. What happens when this runs?",[170,461,462],{"language":164},[173,463,465],{"className":175,"code":464,"language":164,"meta":177,"style":177},"const p = new Point3D(1, 2, 3);\n\nclass Point3D {\n  constructor(x, y, z) {\n    this.x = x;\n    this.y = y;\n    this.z = z;\n  }\n}\n",[22,466,467,502,506,514,538,552,564,576,580],{"__ignoreMap":177},[181,468,469,472,475,477,480,483,485,488,491,494,496,499],{"class":183,"line":184},[181,470,471],{"class":187},"const",[181,473,474],{"class":252}," p",[181,476,267],{"class":187},[181,478,479],{"class":187}," new",[181,481,482],{"class":190}," Point3D",[181,484,306],{"class":194},[181,486,487],{"class":252},"1",[181,489,490],{"class":194},", ",[181,492,493],{"class":252},"2",[181,495,490],{"class":194},[181,497,498],{"class":252},"3",[181,500,501],{"class":194},");\n",[181,503,504],{"class":183,"line":198},[181,505,235],{"emptyLinePlaceholder":39},[181,507,508,510,512],{"class":183,"line":207},[181,509,24],{"class":187},[181,511,482],{"class":190},[181,513,195],{"class":194},[181,515,516,519,521,525,527,530,532,535],{"class":183,"line":220},[181,517,518],{"class":187},"  constructor",[181,520,306],{"class":194},[181,522,524],{"class":523},"sCrzJ","x",[181,526,490],{"class":194},[181,528,529],{"class":523},"y",[181,531,490],{"class":194},[181,533,534],{"class":523},"z",[181,536,537],{"class":194},") {\n",[181,539,540,543,546,549],{"class":183,"line":226},[181,541,542],{"class":252},"    this",[181,544,545],{"class":194},".x ",[181,547,548],{"class":187},"=",[181,550,551],{"class":194}," x;\n",[181,553,554,556,559,561],{"class":183,"line":232},[181,555,542],{"class":252},[181,557,558],{"class":194},".y ",[181,560,548],{"class":187},[181,562,563],{"class":194}," y;\n",[181,565,566,568,571,573],{"class":183,"line":238},[181,567,542],{"class":252},[181,569,570],{"class":194},".z ",[181,572,548],{"class":187},[181,574,575],{"class":194}," z;\n",[181,577,578],{"class":183,"line":249},[181,579,223],{"class":194},[181,581,582],{"class":183,"line":276},[181,583,229],{"class":194},[27,585,587,593,613,631],{"className":586},[30],[32,588,590,592],{"className":589},[35],[37,591],{"disabled":39,"type":40}," It works fine — classes, like function declarations, are fully hoisted with their implementation",[32,594,596,598,599,602,603,605,606,609,610],{"className":595},[35],[37,597],{"disabled":39,"type":40}," It logs ",[22,600,601],{},"undefined"," when ",[22,604,112],{}," is later inspected, because ",[22,607,608],{},"Point3D"," is hoisted but left uninitialized like a ",[22,611,612],{},"var",[32,614,616,41,618,621,622,624,625,628,629],{"className":615},[35],[37,617],{"disabled":39,"type":40},[22,619,620],{},"ReferenceError: Cannot access 'Point3D' before initialization"," — the class binding is hoisted but stays in the temporal dead zone until the ",[22,623,24],{}," statement itself is evaluated, just like ",[22,626,627],{},"let","\u002F",[22,630,471],{},[32,632,634,41,636],{"className":633},[35],[37,635],{"disabled":39,"type":40},[22,637,638],{},"TypeError: Point3D is not a constructor",[105,640,641,643,656],{},[108,642,110],{},[112,644,645,647,648,621,650,624,652,628,654],{},[115,646,117],{}," C — ",[22,649,620],{},[22,651,24],{},[22,653,627],{},[22,655,471],{},[112,657,658,41,660,663,664,666,667,669,670,672,673,628,675,677,678,680,681,684],{},[115,659,133],{},[115,661,662],{},"Debug:"," unlike function declarations, ",[22,665,24],{}," declarations are not hoisted with their implementation ready to use. The name ",[22,668,608],{}," is hoisted to the top of its scope but remains in the temporal dead zone (TDZ) until the ",[22,671,24],{}," statement's line actually executes, exactly like ",[22,674,627],{},[22,676,471],{},". Referencing it any earlier — even just to call ",[22,679,82],{}," on it — throws a ",[22,682,683],{},"ReferenceError",". This is a common trap for developers used to function declarations being freely callable before their textual position (see quiz 05).",[14,686,687,691,888,942],{"language":164},[17,688,690],{"id":689},"q4-what-does-this-log","Q4. What does this log?",[170,692,693],{"language":164},[173,694,696],{"className":175,"code":695,"language":164,"meta":177,"style":177},"class Point {\n  constructor(x, y) {\n    this.x = x;\n    this.y = y;\n  }\n  distanceFromOrigin() {\n    return Math.sqrt(this.x ** 2 + this.y ** 2);\n  }\n}\n\nconst p = new Point(3, 4);\nconsole.log(Object.getPrototypeOf(p) === Point.prototype);\nconsole.log(p.hasOwnProperty(\"distanceFromOrigin\"));\nconsole.log(p.hasOwnProperty(\"x\"));\n",[22,697,698,707,721,731,741,745,752,789,793,797,801,824,850,870],{"__ignoreMap":177},[181,699,700,702,705],{"class":183,"line":184},[181,701,24],{"class":187},[181,703,704],{"class":190}," Point",[181,706,195],{"class":194},[181,708,709,711,713,715,717,719],{"class":183,"line":198},[181,710,518],{"class":187},[181,712,306],{"class":194},[181,714,524],{"class":523},[181,716,490],{"class":194},[181,718,529],{"class":523},[181,720,537],{"class":194},[181,722,723,725,727,729],{"class":183,"line":207},[181,724,542],{"class":252},[181,726,545],{"class":194},[181,728,548],{"class":187},[181,730,551],{"class":194},[181,732,733,735,737,739],{"class":183,"line":220},[181,734,542],{"class":252},[181,736,558],{"class":194},[181,738,548],{"class":187},[181,740,563],{"class":194},[181,742,743],{"class":183,"line":226},[181,744,223],{"class":194},[181,746,747,750],{"class":183,"line":232},[181,748,749],{"class":190},"  distanceFromOrigin",[181,751,204],{"class":194},[181,753,754,756,759,762,764,767,769,772,775,778,781,783,785,787],{"class":183,"line":238},[181,755,210],{"class":187},[181,757,758],{"class":194}," Math.",[181,760,761],{"class":190},"sqrt",[181,763,306],{"class":194},[181,765,766],{"class":252},"this",[181,768,545],{"class":194},[181,770,771],{"class":187},"**",[181,773,774],{"class":252}," 2",[181,776,777],{"class":187}," +",[181,779,780],{"class":252}," this",[181,782,558],{"class":194},[181,784,771],{"class":187},[181,786,774],{"class":252},[181,788,501],{"class":194},[181,790,791],{"class":183,"line":249},[181,792,223],{"class":194},[181,794,795],{"class":183,"line":276},[181,796,229],{"class":194},[181,798,799],{"class":183,"line":286},[181,800,235],{"emptyLinePlaceholder":39},[181,802,803,805,807,809,811,813,815,817,819,822],{"class":183,"line":292},[181,804,471],{"class":187},[181,806,474],{"class":252},[181,808,267],{"class":187},[181,810,479],{"class":187},[181,812,704],{"class":190},[181,814,306],{"class":194},[181,816,498],{"class":252},[181,818,490],{"class":194},[181,820,821],{"class":252},"4",[181,823,501],{"class":194},[181,825,826,828,830,833,836,839,842,844,846,848],{"class":183,"line":297},[181,827,300],{"class":194},[181,829,303],{"class":190},[181,831,832],{"class":194},"(Object.",[181,834,835],{"class":190},"getPrototypeOf",[181,837,838],{"class":194},"(p) ",[181,840,841],{"class":187},"===",[181,843,704],{"class":252},[181,845,256],{"class":194},[181,847,259],{"class":252},[181,849,501],{"class":194},[181,851,852,854,856,859,862,864,867],{"class":183,"line":326},[181,853,300],{"class":194},[181,855,303],{"class":190},[181,857,858],{"class":194},"(p.",[181,860,861],{"class":190},"hasOwnProperty",[181,863,306],{"class":194},[181,865,866],{"class":213},"\"distanceFromOrigin\"",[181,868,869],{"class":194},"));\n",[181,871,873,875,877,879,881,883,886],{"class":183,"line":872},14,[181,874,300],{"class":194},[181,876,303],{"class":190},[181,878,858],{"class":194},[181,880,861],{"class":190},[181,882,306],{"class":194},[181,884,885],{"class":213},"\"x\"",[181,887,869],{"class":194},[27,889,891,903,915,926],{"className":890},[30],[32,892,894,41,896,490,899,490,901],{"className":893},[35],[37,895],{"disabled":39,"type":40},[22,897,898],{},"true",[22,900,898],{},[22,902,898],{},[32,904,906,41,908,490,911,490,913],{"className":905},[35],[37,907],{"disabled":39,"type":40},[22,909,910],{},"false",[22,912,910],{},[22,914,898],{},[32,916,918,41,920,490,922,490,924],{"className":917},[35],[37,919],{"disabled":39,"type":40},[22,921,898],{},[22,923,910],{},[22,925,910],{},[32,927,929,41,931,490,933,490,935,937,938,941],{"className":928},[35],[37,930],{"disabled":39,"type":40},[22,932,898],{},[22,934,910],{},[22,936,898],{}," — methods defined in a class body live once on the shared prototype, while properties assigned via ",[22,939,940],{},"this.x ="," inside the constructor become the instance's own properties",[105,943,944,946,959],{},[108,945,110],{},[112,947,948,950,951,490,953,490,955,937,957,941],{},[115,949,117],{}," D — ",[22,952,898],{},[22,954,910],{},[22,956,898],{},[22,958,940],{},[112,960,961,41,963,966,967,969,970,973,974,977,978,980,981,984,985,987,988,992,993,995,996,998,999,1001,1002,95,1004,1006,1007,1009,1010,1012],{},[115,962,133],{},[22,964,965],{},"Object.getPrototypeOf(p) === Point.prototype"," confirms that ",[22,968,112],{},"'s internal ",[22,971,972],{},"[[Prototype]]"," link points to ",[22,975,976],{},"Point.prototype",", which is where ",[22,979,82],{}," wires it up. ",[22,982,983],{},"distanceFromOrigin"," was declared as a class method, so it lives once on ",[22,986,976],{}," and is ",[989,990,991],"em",{},"not"," an own property of ",[22,994,112],{}," — ",[22,997,861],{}," correctly reports ",[22,1000,910],{},". ",[22,1003,524],{},[22,1005,529],{},", by contrast, are assigned directly onto ",[22,1008,766],{}," inside the constructor, so they genuinely are own properties of every instance, hence ",[22,1011,898],{},". This is the standard way to verify that instance methods are shared, not duplicated per instance.",[14,1014,1015,1019,1152,1215],{"language":164},[17,1016,1018],{"id":1017},"q5-what-does-this-log","Q5. What does this log?",[170,1020,1021],{"language":164},[173,1022,1024],{"className":175,"code":1023,"language":164,"meta":177,"style":177},"class LivingThing {\n  breathe() {\n    return \"breathing\";\n  }\n}\n\nclass Animal extends LivingThing {}\nclass Dog extends Animal {}\n\nconst rex = new Dog();\nconsole.log(rex.breathe());\nconsole.log(Object.getPrototypeOf(Object.getPrototypeOf(rex)) === Animal.prototype);\n",[22,1025,1026,1035,1042,1051,1055,1059,1063,1077,1090,1094,1110,1125],{"__ignoreMap":177},[181,1027,1028,1030,1033],{"class":183,"line":184},[181,1029,24],{"class":187},[181,1031,1032],{"class":190}," LivingThing",[181,1034,195],{"class":194},[181,1036,1037,1040],{"class":183,"line":198},[181,1038,1039],{"class":190},"  breathe",[181,1041,204],{"class":194},[181,1043,1044,1046,1049],{"class":183,"line":207},[181,1045,210],{"class":187},[181,1047,1048],{"class":213}," \"breathing\"",[181,1050,217],{"class":194},[181,1052,1053],{"class":183,"line":220},[181,1054,223],{"class":194},[181,1056,1057],{"class":183,"line":226},[181,1058,229],{"class":194},[181,1060,1061],{"class":183,"line":232},[181,1062,235],{"emptyLinePlaceholder":39},[181,1064,1065,1067,1069,1072,1074],{"class":183,"line":238},[181,1066,24],{"class":187},[181,1068,191],{"class":190},[181,1070,1071],{"class":187}," extends",[181,1073,1032],{"class":190},[181,1075,1076],{"class":194}," {}\n",[181,1078,1079,1081,1084,1086,1088],{"class":183,"line":249},[181,1080,24],{"class":187},[181,1082,1083],{"class":190}," Dog",[181,1085,1071],{"class":187},[181,1087,191],{"class":190},[181,1089,1076],{"class":194},[181,1091,1092],{"class":183,"line":276},[181,1093,235],{"emptyLinePlaceholder":39},[181,1095,1096,1098,1101,1103,1105,1107],{"class":183,"line":286},[181,1097,471],{"class":187},[181,1099,1100],{"class":252}," rex",[181,1102,267],{"class":187},[181,1104,479],{"class":187},[181,1106,1083],{"class":190},[181,1108,1109],{"class":194},"();\n",[181,1111,1112,1114,1116,1119,1122],{"class":183,"line":292},[181,1113,300],{"class":194},[181,1115,303],{"class":190},[181,1117,1118],{"class":194},"(rex.",[181,1120,1121],{"class":190},"breathe",[181,1123,1124],{"class":194},"());\n",[181,1126,1127,1129,1131,1133,1135,1137,1139,1142,1144,1146,1148,1150],{"class":183,"line":297},[181,1128,300],{"class":194},[181,1130,303],{"class":190},[181,1132,832],{"class":194},[181,1134,835],{"class":190},[181,1136,832],{"class":194},[181,1138,835],{"class":190},[181,1140,1141],{"class":194},"(rex)) ",[181,1143,841],{"class":187},[181,1145,191],{"class":252},[181,1147,256],{"class":194},[181,1149,259],{"class":252},[181,1151,501],{"class":194},[27,1153,1155,1182,1197,1206],{"className":1154},[30],[32,1156,1158,41,1160,359,1163,995,1165,1167,1168,1171,1172,1174,1175,1177,1178,1181],{"className":1157},[35],[37,1159],{"disabled":39,"type":40},[22,1161,1162],{},"\"breathing\"",[22,1164,898],{},[22,1166,1121],{}," isn't found on ",[22,1169,1170],{},"Dog.prototype"," or ",[22,1173,445],{},", so the engine keeps walking up the ",[22,1176,972],{}," chain until it reaches ",[22,1179,1180],{},"LivingThing.prototype",", where the method is finally found",[32,1183,1185,41,1187,1190,1191,1193,1194],{"className":1184},[35],[37,1186],{"disabled":39,"type":40},[22,1188,1189],{},"TypeError: rex.breathe is not a function",", because ",[22,1192,1121],{}," is defined two inheritance levels above ",[22,1195,1196],{},"Dog",[32,1198,1200,41,1202,359,1204],{"className":1199},[35],[37,1201],{"disabled":39,"type":40},[22,1203,1162],{},[22,1205,910],{},[32,1207,1209,41,1211,359,1213],{"className":1208},[35],[37,1210],{"disabled":39,"type":40},[22,1212,601],{},[22,1214,898],{},[105,1216,1217,1219,1237],{},[108,1218,110],{},[112,1220,1221,118,1223,359,1225,995,1227,1167,1229,1171,1231,1174,1233,1177,1235,1181],{},[115,1222,117],{},[22,1224,1162],{},[22,1226,898],{},[22,1228,1121],{},[22,1230,1170],{},[22,1232,445],{},[22,1234,972],{},[22,1236,1180],{},[112,1238,1239,1241,1242,1245,1246,1249,1250,1252,1253,1255,1256,1252,1258,1255,1260,1252,1262,1264,1265,1001,1268,1271,1272,439,1274,1271,1277,1279,1280,1282,1283,256],{},[115,1240,133],{}," Property\u002Fmethod lookup in JS is never limited to an object's own prototype — when ",[22,1243,1244],{},"rex.breathe()"," is called, the engine checks ",[22,1247,1248],{},"rex"," itself (no ",[22,1251,1121],{},"), then ",[22,1254,1170],{}," (no ",[22,1257,1121],{},[22,1259,445],{},[22,1261,1121],{},[22,1263,1180],{}," (found), and stops there. This walk continues until a match is found or the chain terminates at ",[22,1266,1267],{},"null",[22,1269,1270],{},"Object.getPrototypeOf(rex)"," is ",[22,1273,1170],{},[22,1275,1276],{},"Object.getPrototypeOf(Dog.prototype)",[22,1278,445],{}," — exactly what ",[22,1281,157],{}," wires up — so the equality check is ",[22,1284,898],{},[14,1286,1287,1291,1427,1468],{"language":164},[17,1288,1290],{"id":1289},"q6-what-happens-when-this-runs","Q6. What happens when this runs?",[170,1292,1293],{"language":164},[173,1294,1296],{"className":175,"code":1295,"language":164,"meta":177,"style":177},"class Vehicle {\n  constructor(make) {\n    this.make = make;\n  }\n}\n\nclass Car extends Vehicle {\n  constructor(make, model) {\n    this.model = model;\n    super(make);\n  }\n}\n\nconst c = new Car(\"Toyota\", \"Corolla\");\n",[22,1297,1298,1307,1318,1330,1334,1338,1342,1355,1370,1382,1390,1394,1398,1402],{"__ignoreMap":177},[181,1299,1300,1302,1305],{"class":183,"line":184},[181,1301,24],{"class":187},[181,1303,1304],{"class":190}," Vehicle",[181,1306,195],{"class":194},[181,1308,1309,1311,1313,1316],{"class":183,"line":198},[181,1310,518],{"class":187},[181,1312,306],{"class":194},[181,1314,1315],{"class":523},"make",[181,1317,537],{"class":194},[181,1319,1320,1322,1325,1327],{"class":183,"line":207},[181,1321,542],{"class":252},[181,1323,1324],{"class":194},".make ",[181,1326,548],{"class":187},[181,1328,1329],{"class":194}," make;\n",[181,1331,1332],{"class":183,"line":220},[181,1333,223],{"class":194},[181,1335,1336],{"class":183,"line":226},[181,1337,229],{"class":194},[181,1339,1340],{"class":183,"line":232},[181,1341,235],{"emptyLinePlaceholder":39},[181,1343,1344,1346,1349,1351,1353],{"class":183,"line":238},[181,1345,24],{"class":187},[181,1347,1348],{"class":190}," Car",[181,1350,1071],{"class":187},[181,1352,1304],{"class":190},[181,1354,195],{"class":194},[181,1356,1357,1359,1361,1363,1365,1368],{"class":183,"line":249},[181,1358,518],{"class":187},[181,1360,306],{"class":194},[181,1362,1315],{"class":523},[181,1364,490],{"class":194},[181,1366,1367],{"class":523},"model",[181,1369,537],{"class":194},[181,1371,1372,1374,1377,1379],{"class":183,"line":276},[181,1373,542],{"class":252},[181,1375,1376],{"class":194},".model ",[181,1378,548],{"class":187},[181,1380,1381],{"class":194}," model;\n",[181,1383,1384,1387],{"class":183,"line":286},[181,1385,1386],{"class":252},"    super",[181,1388,1389],{"class":194},"(make);\n",[181,1391,1392],{"class":183,"line":292},[181,1393,223],{"class":194},[181,1395,1396],{"class":183,"line":297},[181,1397,229],{"class":194},[181,1399,1400],{"class":183,"line":326},[181,1401,235],{"emptyLinePlaceholder":39},[181,1403,1404,1406,1409,1411,1413,1415,1417,1420,1422,1425],{"class":183,"line":872},[181,1405,471],{"class":187},[181,1407,1408],{"class":252}," c",[181,1410,267],{"class":187},[181,1412,479],{"class":187},[181,1414,1348],{"class":190},[181,1416,306],{"class":194},[181,1418,1419],{"class":213},"\"Toyota\"",[181,1421,490],{"class":194},[181,1423,1424],{"class":213},"\"Corolla\"",[181,1426,501],{"class":194},[27,1428,1430,1441,1449,1457],{"className":1429},[30],[32,1431,1433,1435,1436,95,1438,1440],{"className":1432},[35],[37,1434],{"disabled":39,"type":40}," It creates the car normally, with both ",[22,1437,1315],{},[22,1439,1367],{}," set",[32,1442,1444,41,1446],{"className":1443},[35],[37,1445],{"disabled":39,"type":40},[22,1447,1448],{},"ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor",[32,1450,1452,41,1454],{"className":1451},[35],[37,1453],{"disabled":39,"type":40},[22,1455,1456],{},"TypeError: Cannot set property 'model' of undefined",[32,1458,1460,1462,1463,1465,1466],{"className":1459},[35],[37,1461],{"disabled":39,"type":40}," It works, but ",[22,1464,1315],{}," ends up ",[22,1467,601],{},[105,1469,1470,1472,1478],{},[108,1471,110],{},[112,1473,1474,414,1476],{},[115,1475,117],{},[22,1477,1448],{},[112,1479,1480,41,1482,1485,1486,1488,1489,1492,1493,1496,1497,41,1500,1503,1504,1507,1508,1510,1511,1513,1514,1516,1517,1519,1520,1522],{},[115,1481,133],{},[115,1483,1484],{},"Safety:"," in a derived class, ",[22,1487,766],{}," doesn't exist until ",[22,1490,1491],{},"super()"," has run — the parent constructor is what actually allocates and initializes the object. ",[22,1494,1495],{},"Car","'s constructor tries to write ",[22,1498,1499],{},"this.model = model",[989,1501,1502],{},"before"," calling ",[22,1505,1506],{},"super(make)",", so it touches ",[22,1509,766],{}," while it's still uninitialized, and the engine throws immediately. The fix is to call ",[22,1512,1506],{}," first and only then assign ",[22,1515,1499],{},". This rule has no equivalent in base (non-",[22,1518,157],{},") classes, where ",[22,1521,766],{}," is available from the start of the constructor.",[14,1524,1525,1529,1691,1736],{"language":164},[17,1526,1528],{"id":1527},"q7-what-does-this-log","Q7. What does this log?",[170,1530,1531],{"language":164},[173,1532,1534],{"className":175,"code":1533,"language":164,"meta":177,"style":177},"class AnimalBase {\n  constructor(name) {\n    this.name = name;\n  }\n  speak() {\n    return `${this.name} makes a sound`;\n  }\n}\n\nclass Cat extends AnimalBase {\n  speak() {\n    return `${this.name} meows`;\n  }\n}\n\nconst c = new Cat(\"Whiskers\");\nconsole.log(c.name, c.speak());\n",[22,1535,1536,1545,1556,1568,1572,1578,1596,1600,1604,1608,1621,1627,1644,1648,1652,1657,1677],{"__ignoreMap":177},[181,1537,1538,1540,1543],{"class":183,"line":184},[181,1539,24],{"class":187},[181,1541,1542],{"class":190}," AnimalBase",[181,1544,195],{"class":194},[181,1546,1547,1549,1551,1554],{"class":183,"line":198},[181,1548,518],{"class":187},[181,1550,306],{"class":194},[181,1552,1553],{"class":523},"name",[181,1555,537],{"class":194},[181,1557,1558,1560,1563,1565],{"class":183,"line":207},[181,1559,542],{"class":252},[181,1561,1562],{"class":194},".name ",[181,1564,548],{"class":187},[181,1566,1567],{"class":194}," name;\n",[181,1569,1570],{"class":183,"line":220},[181,1571,223],{"class":194},[181,1573,1574,1576],{"class":183,"line":226},[181,1575,201],{"class":190},[181,1577,204],{"class":194},[181,1579,1580,1582,1585,1587,1589,1591,1594],{"class":183,"line":232},[181,1581,210],{"class":187},[181,1583,1584],{"class":213}," `${",[181,1586,766],{"class":252},[181,1588,256],{"class":213},[181,1590,1553],{"class":194},[181,1592,1593],{"class":213},"} makes a sound`",[181,1595,217],{"class":194},[181,1597,1598],{"class":183,"line":238},[181,1599,223],{"class":194},[181,1601,1602],{"class":183,"line":249},[181,1603,229],{"class":194},[181,1605,1606],{"class":183,"line":276},[181,1607,235],{"emptyLinePlaceholder":39},[181,1609,1610,1612,1615,1617,1619],{"class":183,"line":286},[181,1611,24],{"class":187},[181,1613,1614],{"class":190}," Cat",[181,1616,1071],{"class":187},[181,1618,1542],{"class":190},[181,1620,195],{"class":194},[181,1622,1623,1625],{"class":183,"line":292},[181,1624,201],{"class":190},[181,1626,204],{"class":194},[181,1628,1629,1631,1633,1635,1637,1639,1642],{"class":183,"line":297},[181,1630,210],{"class":187},[181,1632,1584],{"class":213},[181,1634,766],{"class":252},[181,1636,256],{"class":213},[181,1638,1553],{"class":194},[181,1640,1641],{"class":213},"} meows`",[181,1643,217],{"class":194},[181,1645,1646],{"class":183,"line":326},[181,1647,223],{"class":194},[181,1649,1650],{"class":183,"line":872},[181,1651,229],{"class":194},[181,1653,1655],{"class":183,"line":1654},15,[181,1656,235],{"emptyLinePlaceholder":39},[181,1658,1660,1662,1664,1666,1668,1670,1672,1675],{"class":183,"line":1659},16,[181,1661,471],{"class":187},[181,1663,1408],{"class":252},[181,1665,267],{"class":187},[181,1667,479],{"class":187},[181,1669,1614],{"class":190},[181,1671,306],{"class":194},[181,1673,1674],{"class":213},"\"Whiskers\"",[181,1676,501],{"class":194},[181,1678,1680,1682,1684,1687,1689],{"class":183,"line":1679},17,[181,1681,300],{"class":194},[181,1683,303],{"class":190},[181,1685,1686],{"class":194},"(c.name, c.",[181,1688,264],{"class":190},[181,1690,1124],{"class":194},[27,1692,1694,1706,1714,1727],{"className":1693},[30],[32,1695,1697,41,1699,1702,1703,1705],{"className":1696},[35],[37,1698],{"disabled":39,"type":40},[22,1700,1701],{},"undefined \"undefined meows\""," — without an explicit constructor, ",[22,1704,1553],{}," never gets assigned",[32,1707,1709,41,1711],{"className":1708},[35],[37,1710],{"disabled":39,"type":40},[22,1712,1713],{},"TypeError: Cannot read properties of undefined",[32,1715,1717,41,1719,1722,1723,1726],{"className":1716},[35],[37,1718],{"disabled":39,"type":40},[22,1720,1721],{},"\"Whiskers\" \"Whiskers meows\""," — omitting the constructor doesn't skip initialization; JS auto-generates ",[22,1724,1725],{},"constructor(...args) { super(...args); }"," for any subclass that doesn't define its own, forwarding every argument straight to the parent constructor",[32,1728,1730,41,1732,1735],{"className":1729},[35],[37,1731],{"disabled":39,"type":40},[22,1733,1734],{},"\"Whiskers\" \"Whiskers makes a sound\""," — subclass method overrides only apply if a constructor is explicitly defined",[105,1737,1738,1740,1748],{},[108,1739,110],{},[112,1741,1742,647,1744,1722,1746,1726],{},[115,1743,117],{},[22,1745,1721],{},[22,1747,1725],{},[112,1749,1750,41,1752,1755,1756,1759,1760,1763,1764,1767,1768,1771,1772,1774,1775,1778,1779,1781,1782,1785,1786,1788,1789,1792],{},[115,1751,133],{},[22,1753,1754],{},"Cat"," has no explicit ",[22,1757,1758],{},"constructor",", so the spec supplies a default one that simply forwards all arguments to ",[22,1761,1762],{},"super",". That means ",[22,1765,1766],{},"new Cat(\"Whiskers\")"," still runs ",[22,1769,1770],{},"AnimalBase","'s constructor with ",[22,1773,1674],{},", correctly setting ",[22,1776,1777],{},"this.name",". Method overriding is completely independent of whether a constructor was written — ",[22,1780,264],{}," resolves to ",[22,1783,1784],{},"Cat.prototype.speak"," via normal prototype lookup regardless, so the answer combines the parent-initialized ",[22,1787,1553],{}," with the overridden ",[22,1790,1791],{},"meows"," behavior.",[14,1794,1795,1799,1915,1977],{"language":164},[17,1796,1798],{"id":1797},"q8-what-does-this-log","Q8. What does this log?",[170,1800,1801],{"language":164},[173,1802,1804],{"className":175,"code":1803,"language":164,"meta":177,"style":177},"class Employee {\n  describe() {\n    return \"an employee\";\n  }\n}\n\nclass Manager extends Employee {\n  describe() {\n    return `a manager (${super.describe()})`;\n  }\n}\n\nconsole.log(new Manager().describe());\n",[22,1805,1806,1815,1822,1831,1835,1839,1843,1856,1862,1884,1888,1892,1896],{"__ignoreMap":177},[181,1807,1808,1810,1813],{"class":183,"line":184},[181,1809,24],{"class":187},[181,1811,1812],{"class":190}," Employee",[181,1814,195],{"class":194},[181,1816,1817,1820],{"class":183,"line":198},[181,1818,1819],{"class":190},"  describe",[181,1821,204],{"class":194},[181,1823,1824,1826,1829],{"class":183,"line":207},[181,1825,210],{"class":187},[181,1827,1828],{"class":213}," \"an employee\"",[181,1830,217],{"class":194},[181,1832,1833],{"class":183,"line":220},[181,1834,223],{"class":194},[181,1836,1837],{"class":183,"line":226},[181,1838,229],{"class":194},[181,1840,1841],{"class":183,"line":232},[181,1842,235],{"emptyLinePlaceholder":39},[181,1844,1845,1847,1850,1852,1854],{"class":183,"line":238},[181,1846,24],{"class":187},[181,1848,1849],{"class":190}," Manager",[181,1851,1071],{"class":187},[181,1853,1812],{"class":190},[181,1855,195],{"class":194},[181,1857,1858,1860],{"class":183,"line":249},[181,1859,1819],{"class":190},[181,1861,204],{"class":194},[181,1863,1864,1866,1869,1871,1873,1876,1879,1882],{"class":183,"line":276},[181,1865,210],{"class":187},[181,1867,1868],{"class":213}," `a manager (${",[181,1870,1762],{"class":252},[181,1872,256],{"class":213},[181,1874,1875],{"class":190},"describe",[181,1877,1878],{"class":213},"()",[181,1880,1881],{"class":213},"})`",[181,1883,217],{"class":194},[181,1885,1886],{"class":183,"line":286},[181,1887,223],{"class":194},[181,1889,1890],{"class":183,"line":292},[181,1891,229],{"class":194},[181,1893,1894],{"class":183,"line":297},[181,1895,235],{"emptyLinePlaceholder":39},[181,1897,1898,1900,1902,1904,1906,1908,1911,1913],{"class":183,"line":326},[181,1899,300],{"class":194},[181,1901,303],{"class":190},[181,1903,306],{"class":194},[181,1905,82],{"class":187},[181,1907,1849],{"class":190},[181,1909,1910],{"class":194},"().",[181,1912,1875],{"class":190},[181,1914,1124],{"class":194},[27,1916,1918,1926,1945,1953],{"className":1917},[30],[32,1919,1921,41,1923],{"className":1920},[35],[37,1922],{"disabled":39,"type":40},[22,1924,1925],{},"\"an employee\"",[32,1927,1929,41,1931,995,1934,1937,1938,1941,1942,1944],{"className":1928},[35],[37,1930],{"disabled":39,"type":40},[22,1932,1933],{},"\"a manager (a manager (an employee))\"",[22,1935,1936],{},"super.describe()"," re-invokes ",[22,1939,1940],{},"Manager","'s own ",[22,1943,1875],{},", causing infinite-looking recursion",[32,1946,1948,41,1950],{"className":1947},[35],[37,1949],{"disabled":39,"type":40},[22,1951,1952],{},"TypeError: super.describe is not a function",[32,1954,1956,41,1958,995,1961,1963,1964,1966,1967,1970,1971,1973,1974,1976],{"className":1955},[35],[37,1957],{"disabled":39,"type":40},[22,1959,1960],{},"\"a manager (an employee)\"",[22,1962,1875],{}," is overridden in ",[22,1965,1940],{},", shadowing ",[22,1968,1969],{},"Employee","'s version for normal calls, but ",[22,1972,1936],{}," explicitly reaches one level up the prototype chain to invoke ",[22,1975,1969],{},"'s original implementation",[105,1978,1979,1981,1997],{},[108,1980,110],{},[112,1982,1983,950,1985,995,1987,1963,1989,1966,1991,1970,1993,1973,1995,1976],{},[115,1984,117],{},[22,1986,1960],{},[22,1988,1875],{},[22,1990,1940],{},[22,1992,1969],{},[22,1994,1936],{},[22,1996,1969],{},[112,1998,1999,2001,2002,2005,2006,2009,2010,2012,2013,2015,2016,2019,2020,2023,2024,2026],{},[115,2000,133],{}," Overriding a method in a subclass shadows the parent's version for ordinary calls (",[22,2003,2004],{},"instance.describe()"," always finds ",[22,2007,2008],{},"Manager.prototype.describe"," first). ",[22,2011,1936],{}," bypasses that shadowing on purpose — it's a special reference that looks up ",[22,2014,1875],{}," starting from ",[22,2017,2018],{},"Employee.prototype"," instead of ",[22,2021,2022],{},"Manager.prototype",", invoking the parent's original implementation without re-entering ",[22,2025,1940],{},"'s override. There's no recursion here at all, ruling out option B.",[14,2028,2029,2033,2140,2185],{"language":164},[17,2030,2032],{"id":2031},"q9-what-does-this-log","Q9. What does this log?",[170,2034,2035],{"language":164},[173,2036,2038],{"className":175,"code":2037,"language":164,"meta":177,"style":177},"class MathUtils {\n  static square(n) {\n    return n * n;\n  }\n}\n\nconst m = new MathUtils();\nconsole.log(MathUtils.square(5));\nconsole.log(m.square(5));\n",[22,2039,2040,2049,2064,2077,2081,2085,2089,2104,2123],{"__ignoreMap":177},[181,2041,2042,2044,2047],{"class":183,"line":184},[181,2043,24],{"class":187},[181,2045,2046],{"class":190}," MathUtils",[181,2048,195],{"class":194},[181,2050,2051,2054,2057,2059,2062],{"class":183,"line":198},[181,2052,2053],{"class":187},"  static",[181,2055,2056],{"class":190}," square",[181,2058,306],{"class":194},[181,2060,2061],{"class":523},"n",[181,2063,537],{"class":194},[181,2065,2066,2068,2071,2074],{"class":183,"line":207},[181,2067,210],{"class":187},[181,2069,2070],{"class":194}," n ",[181,2072,2073],{"class":187},"*",[181,2075,2076],{"class":194}," n;\n",[181,2078,2079],{"class":183,"line":220},[181,2080,223],{"class":194},[181,2082,2083],{"class":183,"line":226},[181,2084,229],{"class":194},[181,2086,2087],{"class":183,"line":232},[181,2088,235],{"emptyLinePlaceholder":39},[181,2090,2091,2093,2096,2098,2100,2102],{"class":183,"line":238},[181,2092,471],{"class":187},[181,2094,2095],{"class":252}," m",[181,2097,267],{"class":187},[181,2099,479],{"class":187},[181,2101,2046],{"class":190},[181,2103,1109],{"class":194},[181,2105,2106,2108,2110,2113,2116,2118,2121],{"class":183,"line":249},[181,2107,300],{"class":194},[181,2109,303],{"class":190},[181,2111,2112],{"class":194},"(MathUtils.",[181,2114,2115],{"class":190},"square",[181,2117,306],{"class":194},[181,2119,2120],{"class":252},"5",[181,2122,869],{"class":194},[181,2124,2125,2127,2129,2132,2134,2136,2138],{"class":183,"line":276},[181,2126,300],{"class":194},[181,2128,303],{"class":190},[181,2130,2131],{"class":194},"(m.",[181,2133,2115],{"class":190},[181,2135,306],{"class":194},[181,2137,2120],{"class":252},[181,2139,869],{"class":194},[27,2141,2143,2158,2167,2176],{"className":2142},[30],[32,2144,2146,41,2148,359,2151,2154,2155,2157],{"className":2145},[35],[37,2147],{"disabled":39,"type":40},[22,2149,2150],{},"25",[22,2152,2153],{},"TypeError: m.square is not a function"," — static methods are installed directly on the class\u002Fconstructor object itself, never on ",[22,2156,52],{},", so instances have no access to them at all",[32,2159,2161,41,2163,359,2165],{"className":2160},[35],[37,2162],{"disabled":39,"type":40},[22,2164,2150],{},[22,2166,2150],{},[32,2168,2170,41,2172,2175],{"className":2169},[35],[37,2171],{"disabled":39,"type":40},[22,2173,2174],{},"TypeError"," on the very first line, because a class with only static methods cannot be instantiated",[32,2177,2179,41,2181,359,2183],{"className":2178},[35],[37,2180],{"disabled":39,"type":40},[22,2182,2150],{},[22,2184,601],{},[105,2186,2187,2189,2199],{},[108,2188,110],{},[112,2190,2191,118,2193,359,2195,2154,2197,2157],{},[115,2192,117],{},[22,2194,2150],{},[22,2196,2153],{},[22,2198,52],{},[112,2200,2201,41,2203,2206,2207,2210,2211,2214,2215,2217,2218,2220,2221,2223,2224,2227,2228,1001,2230,2233],{},[115,2202,133],{},[22,2204,2205],{},"static"," methods and properties belong to the class object (",[22,2208,2209],{},"MathUtils",") itself, not to ",[22,2212,2213],{},"MathUtils.prototype",". Since instance property\u002Fmethod lookup only ever walks the ",[22,2216,972],{}," chain starting from the instance, and ",[22,2219,2213],{}," is never part of that chain that leads to ",[22,2222,2209],{}," itself, ",[22,2225,2226],{},"m.square"," simply doesn't resolve to anything — calling it throws a ",[22,2229,2174],{},[22,2231,2232],{},"MathUtils.square(5)"," works because it's called directly on the class object where the static method actually lives.",[14,2235,2236,2240,2317,2372],{"language":164},[17,2237,2239],{"id":2238},"q10-what-does-this-log","Q10. What does this log?",[170,2241,2242],{"language":164},[173,2243,2245],{"className":175,"code":2244,"language":164,"meta":177,"style":177},"class Base {\n  static create() {\n    return \"created via Base.create\";\n  }\n}\n\nclass Derived extends Base {}\n\nconsole.log(Derived.create());\n",[22,2246,2247,2256,2265,2274,2278,2282,2286,2299,2303],{"__ignoreMap":177},[181,2248,2249,2251,2254],{"class":183,"line":184},[181,2250,24],{"class":187},[181,2252,2253],{"class":190}," Base",[181,2255,195],{"class":194},[181,2257,2258,2260,2263],{"class":183,"line":198},[181,2259,2053],{"class":187},[181,2261,2262],{"class":190}," create",[181,2264,204],{"class":194},[181,2266,2267,2269,2272],{"class":183,"line":207},[181,2268,210],{"class":187},[181,2270,2271],{"class":213}," \"created via Base.create\"",[181,2273,217],{"class":194},[181,2275,2276],{"class":183,"line":220},[181,2277,223],{"class":194},[181,2279,2280],{"class":183,"line":226},[181,2281,229],{"class":194},[181,2283,2284],{"class":183,"line":232},[181,2285,235],{"emptyLinePlaceholder":39},[181,2287,2288,2290,2293,2295,2297],{"class":183,"line":238},[181,2289,24],{"class":187},[181,2291,2292],{"class":190}," Derived",[181,2294,1071],{"class":187},[181,2296,2253],{"class":190},[181,2298,1076],{"class":194},[181,2300,2301],{"class":183,"line":249},[181,2302,235],{"emptyLinePlaceholder":39},[181,2304,2305,2307,2309,2312,2315],{"class":183,"line":276},[181,2306,300],{"class":194},[181,2308,303],{"class":190},[181,2310,2311],{"class":194},"(Derived.",[181,2313,2314],{"class":190},"create",[181,2316,1124],{"class":194},[27,2318,2320,2328,2357,2364],{"className":2319},[30],[32,2321,2323,41,2325],{"className":2322},[35],[37,2324],{"disabled":39,"type":40},[22,2326,2327],{},"TypeError: Derived.create is not a function",[32,2329,2331,41,2333,995,2336,2338,2339,2342,2343,2346,2347,2350,2351,2354,2355],{"className":2330},[35],[37,2332],{"disabled":39,"type":40},[22,2334,2335],{},"\"created via Base.create\"",[22,2337,157],{}," links not just ",[22,2340,2341],{},"Derived.prototype"," to ",[22,2344,2345],{},"Base.prototype",", but also ",[22,2348,2349],{},"Derived"," itself to ",[22,2352,2353],{},"Base",", so static members are inherited by the subclass too, the same way instance methods are inherited via ",[22,2356,52],{},[32,2358,2360,41,2362],{"className":2359},[35],[37,2361],{"disabled":39,"type":40},[22,2363,601],{},[32,2365,2367,41,2369],{"className":2366},[35],[37,2368],{"disabled":39,"type":40},[22,2370,2371],{},"ReferenceError: create is not defined",[105,2373,2374,2376,2394],{},[108,2375,110],{},[112,2377,2378,414,2380,995,2382,2338,2384,2342,2386,2346,2388,2350,2390,2354,2392],{},[115,2379,117],{},[22,2381,2335],{},[22,2383,157],{},[22,2385,2341],{},[22,2387,2345],{},[22,2389,2349],{},[22,2391,2353],{},[22,2393,52],{},[112,2395,2396,41,2398,41,2400,2402,2403,2405,2406,2408,2409,2411,2412,41,2415,1941,2417,2408,2419,2421,2422,2425,2426,2428,2429,2431,2432,2434,2435,2438],{},[115,2397,133],{},[115,2399,431],{},[22,2401,157],{}," sets up two parallel prototype links: ",[22,2404,2341],{},"'s ",[22,2407,972],{}," becomes ",[22,2410,2345],{}," (for instance methods), ",[989,2413,2414],{},"and",[22,2416,2349],{},[22,2418,972],{},[22,2420,2353],{}," (for static members). So looking up ",[22,2423,2424],{},"Derived.create"," walks from ",[22,2427,2349],{}," up to ",[22,2430,2353],{},", finds the static method there, and it runs successfully. This surprises developers who assume ",[22,2433,2205],{}," members are entirely non-inherited — they're excluded from ",[989,2436,2437],{},"instances",", but not from subclasses.",[14,2440,2441,2445,2572,2612],{"language":164},[17,2442,2444],{"id":2443},"q11-what-happens-when-this-runs","Q11. What happens when this runs?",[170,2446,2447],{"language":164},[173,2448,2450],{"className":175,"code":2449,"language":164,"meta":177,"style":177},"class BankAccount {\n  #balance = 0;\n  deposit(amount) {\n    this.#balance += amount;\n  }\n  get balance() {\n    return this.#balance;\n  }\n}\n\nconst acct = new BankAccount();\nacct.deposit(100);\nconsole.log(acct.#balance);\n",[22,2451,2452,2461,2473,2485,2498,2502,2512,2521,2525,2529,2533,2548,2563],{"__ignoreMap":177},[181,2453,2454,2456,2459],{"class":183,"line":184},[181,2455,24],{"class":187},[181,2457,2458],{"class":190}," BankAccount",[181,2460,195],{"class":194},[181,2462,2463,2466,2468,2471],{"class":183,"line":198},[181,2464,2465],{"class":523},"  #balance",[181,2467,267],{"class":187},[181,2469,2470],{"class":252}," 0",[181,2472,217],{"class":194},[181,2474,2475,2478,2480,2483],{"class":183,"line":207},[181,2476,2477],{"class":190},"  deposit",[181,2479,306],{"class":194},[181,2481,2482],{"class":523},"amount",[181,2484,537],{"class":194},[181,2486,2487,2489,2492,2495],{"class":183,"line":220},[181,2488,542],{"class":252},[181,2490,2491],{"class":194},".#balance ",[181,2493,2494],{"class":187},"+=",[181,2496,2497],{"class":194}," amount;\n",[181,2499,2500],{"class":183,"line":226},[181,2501,223],{"class":194},[181,2503,2504,2507,2510],{"class":183,"line":232},[181,2505,2506],{"class":187},"  get",[181,2508,2509],{"class":190}," balance",[181,2511,204],{"class":194},[181,2513,2514,2516,2518],{"class":183,"line":238},[181,2515,210],{"class":187},[181,2517,780],{"class":252},[181,2519,2520],{"class":194},".#balance;\n",[181,2522,2523],{"class":183,"line":249},[181,2524,223],{"class":194},[181,2526,2527],{"class":183,"line":276},[181,2528,229],{"class":194},[181,2530,2531],{"class":183,"line":286},[181,2532,235],{"emptyLinePlaceholder":39},[181,2534,2535,2537,2540,2542,2544,2546],{"class":183,"line":292},[181,2536,471],{"class":187},[181,2538,2539],{"class":252}," acct",[181,2541,267],{"class":187},[181,2543,479],{"class":187},[181,2545,2458],{"class":190},[181,2547,1109],{"class":194},[181,2549,2550,2553,2556,2558,2561],{"class":183,"line":297},[181,2551,2552],{"class":194},"acct.",[181,2554,2555],{"class":190},"deposit",[181,2557,306],{"class":194},[181,2559,2560],{"class":252},"100",[181,2562,501],{"class":194},[181,2564,2565,2567,2569],{"class":183,"line":326},[181,2566,300],{"class":194},[181,2568,303],{"class":190},[181,2570,2571],{"class":194},"(acct.#balance);\n",[27,2573,2575,2583,2590,2604],{"className":2574},[30],[32,2576,2578,2580,2581],{"className":2577},[35],[37,2579],{"disabled":39,"type":40}," Logs ",[22,2582,2560],{},[32,2584,2586,2580,2588],{"className":2585},[35],[37,2587],{"disabled":39,"type":40},[22,2589,601],{},[32,2591,2593,2595,2596,2599,2600,2603],{"className":2592},[35],[37,2594],{"disabled":39,"type":40}," Throws ",[22,2597,2598],{},"SyntaxError: Private field '#balance' must be declared in an enclosing class"," at parse time — nothing in the file executes at all, not even the earlier ",[22,2601,2602],{},"acct.deposit(100)"," call, because the whole script fails to parse before any code runs",[32,2605,2607,2595,2609],{"className":2606},[35],[37,2608],{"disabled":39,"type":40},[22,2610,2611],{},"TypeError: acct.#balance is not accessible outside class BankAccount",[105,2613,2614,2616,2625],{},[108,2615,110],{},[112,2617,2618,2620,2621,2599,2623,2603],{},[115,2619,117],{}," C — Throws ",[22,2622,2598],{},[22,2624,2602],{},[112,2626,2627,41,2629,2631,2632,2635,2636,2639,2640,2643,2644,2647,2648,2650],{},[115,2628,133],{},[115,2630,1484],{}," unlike an unenforced ",[22,2633,2634],{},"_balance"," naming convention, a true private field (",[22,2637,2638],{},"#balance",") is enforced at the language level. The ",[22,2641,2642],{},".#name"," syntax is only legal lexically inside a class body that declares that exact private name — writing ",[22,2645,2646],{},"acct.#balance"," anywhere else isn't just a runtime access violation, it's not valid syntax at all, so the engine rejects the entire script before executing a single line. This is stricter than a runtime ",[22,2649,2174],{}," (option D): the failure happens at parse time, not when the line would run.",[14,2652,2653,2657,2744,2804],{"language":164},[17,2654,2656],{"id":2655},"q12-what-does-this-log","Q12. What does this log?",[170,2658,2659],{"language":164},[173,2660,2662],{"className":175,"code":2661,"language":164,"meta":177,"style":177},"class Wallet {\n  _cash = 50;\n  #pin = \"1234\";\n}\n\nconst w = new Wallet();\nconsole.log(w._cash);\nconsole.log(w[\"#pin\"]);\n",[22,2663,2664,2673,2685,2697,2701,2705,2720,2729],{"__ignoreMap":177},[181,2665,2666,2668,2671],{"class":183,"line":184},[181,2667,24],{"class":187},[181,2669,2670],{"class":190}," Wallet",[181,2672,195],{"class":194},[181,2674,2675,2678,2680,2683],{"class":183,"line":198},[181,2676,2677],{"class":523},"  _cash",[181,2679,267],{"class":187},[181,2681,2682],{"class":252}," 50",[181,2684,217],{"class":194},[181,2686,2687,2690,2692,2695],{"class":183,"line":207},[181,2688,2689],{"class":523},"  #pin",[181,2691,267],{"class":187},[181,2693,2694],{"class":213}," \"1234\"",[181,2696,217],{"class":194},[181,2698,2699],{"class":183,"line":220},[181,2700,229],{"class":194},[181,2702,2703],{"class":183,"line":226},[181,2704,235],{"emptyLinePlaceholder":39},[181,2706,2707,2709,2712,2714,2716,2718],{"class":183,"line":232},[181,2708,471],{"class":187},[181,2710,2711],{"class":252}," w",[181,2713,267],{"class":187},[181,2715,479],{"class":187},[181,2717,2670],{"class":190},[181,2719,1109],{"class":194},[181,2721,2722,2724,2726],{"class":183,"line":238},[181,2723,300],{"class":194},[181,2725,303],{"class":190},[181,2727,2728],{"class":194},"(w._cash);\n",[181,2730,2731,2733,2735,2738,2741],{"class":183,"line":249},[181,2732,300],{"class":194},[181,2734,303],{"class":190},[181,2736,2737],{"class":194},"(w[",[181,2739,2740],{"class":213},"\"#pin\"",[181,2742,2743],{"class":194},"]);\n",[27,2745,2747,2759,2768,2778],{"className":2746},[30],[32,2748,2750,41,2752,359,2755,2758],{"className":2749},[35],[37,2751],{"disabled":39,"type":40},[22,2753,2754],{},"50",[22,2756,2757],{},"1234"," — bracket notation is a valid way to reach private fields from outside a class",[32,2760,2762,41,2764,359,2766],{"className":2761},[35],[37,2763],{"disabled":39,"type":40},[22,2765,601],{},[22,2767,601],{},[32,2769,2771,2773,2774,2777],{"className":2770},[35],[37,2772],{"disabled":39,"type":40}," It throws a ",[22,2775,2776],{},"SyntaxError"," on the second line",[32,2779,2781,41,2783,359,2785,995,2787,2790,2791,2794,2795,2798,2799,2801,2802],{"className":2780},[35],[37,2782],{"disabled":39,"type":40},[22,2784,2754],{},[22,2786,601],{},[22,2788,2789],{},"_cash"," is only a naming convention, so it's freely readable from outside; ",[22,2792,2793],{},"#pin"," is a genuinely private field, and ",[22,2796,2797],{},"w[\"#pin\"]"," doesn't reach it at all — it's just an ordinary bracket lookup for a property literally named the four characters ",[22,2800,2740],{},", which was never set, so it returns ",[22,2803,601],{},[105,2805,2806,2808,2826],{},[108,2807,110],{},[112,2809,2810,950,2812,359,2814,995,2816,2790,2818,2794,2820,2798,2822,2801,2824],{},[115,2811,117],{},[22,2813,2754],{},[22,2815,601],{},[22,2817,2789],{},[22,2819,2793],{},[22,2821,2797],{},[22,2823,2740],{},[22,2825,601],{},[112,2827,2828,41,2830,2832,2833,2835,2836,2839,2840,2842,2843,2845,2846,2848,2849,2851],{},[115,2829,133],{},[115,2831,662],{}," the leading underscore in ",[22,2834,2789],{}," communicates \"please don't touch this from outside,\" but the engine does nothing to enforce it — ",[22,2837,2838],{},"w._cash"," reads it just like any other property. ",[22,2841,2793],{}," is different in kind, not just convention: private fields are never accessible via bracket\u002Fcomputed notation at all, even from inside the class. ",[22,2844,2797],{}," doesn't parse as a private-field access — the string ",[22,2847,2740],{}," is just an ordinary property key, and since no property with that literal name was ever set, the lookup quietly returns ",[22,2850,601],{}," instead of exposing the private value or throwing.",[14,2853,2854,2858,3006,3063],{"language":164},[17,2855,2857],{"id":2856},"q13-what-does-this-log","Q13. What does this log?",[170,2859,2860],{"language":164},[173,2861,2863],{"className":175,"code":2862,"language":164,"meta":177,"style":177},"class Rectangle {\n  constructor(width, height) {\n    this.width = width;\n    this.height = height;\n  }\n  get area() {\n    return this.width * this.height;\n  }\n}\n\nconst r = new Rectangle(4, 5);\nconsole.log(r.area);\nr.width = 10;\nconsole.log(r.area);\n",[22,2864,2865,2874,2890,2902,2914,2918,2927,2942,2946,2950,2954,2977,2986,2998],{"__ignoreMap":177},[181,2866,2867,2869,2872],{"class":183,"line":184},[181,2868,24],{"class":187},[181,2870,2871],{"class":190}," Rectangle",[181,2873,195],{"class":194},[181,2875,2876,2878,2880,2883,2885,2888],{"class":183,"line":198},[181,2877,518],{"class":187},[181,2879,306],{"class":194},[181,2881,2882],{"class":523},"width",[181,2884,490],{"class":194},[181,2886,2887],{"class":523},"height",[181,2889,537],{"class":194},[181,2891,2892,2894,2897,2899],{"class":183,"line":207},[181,2893,542],{"class":252},[181,2895,2896],{"class":194},".width ",[181,2898,548],{"class":187},[181,2900,2901],{"class":194}," width;\n",[181,2903,2904,2906,2909,2911],{"class":183,"line":220},[181,2905,542],{"class":252},[181,2907,2908],{"class":194},".height ",[181,2910,548],{"class":187},[181,2912,2913],{"class":194}," height;\n",[181,2915,2916],{"class":183,"line":226},[181,2917,223],{"class":194},[181,2919,2920,2922,2925],{"class":183,"line":232},[181,2921,2506],{"class":187},[181,2923,2924],{"class":190}," area",[181,2926,204],{"class":194},[181,2928,2929,2931,2933,2935,2937,2939],{"class":183,"line":238},[181,2930,210],{"class":187},[181,2932,780],{"class":252},[181,2934,2896],{"class":194},[181,2936,2073],{"class":187},[181,2938,780],{"class":252},[181,2940,2941],{"class":194},".height;\n",[181,2943,2944],{"class":183,"line":249},[181,2945,223],{"class":194},[181,2947,2948],{"class":183,"line":276},[181,2949,229],{"class":194},[181,2951,2952],{"class":183,"line":286},[181,2953,235],{"emptyLinePlaceholder":39},[181,2955,2956,2958,2961,2963,2965,2967,2969,2971,2973,2975],{"class":183,"line":292},[181,2957,471],{"class":187},[181,2959,2960],{"class":252}," r",[181,2962,267],{"class":187},[181,2964,479],{"class":187},[181,2966,2871],{"class":190},[181,2968,306],{"class":194},[181,2970,821],{"class":252},[181,2972,490],{"class":194},[181,2974,2120],{"class":252},[181,2976,501],{"class":194},[181,2978,2979,2981,2983],{"class":183,"line":297},[181,2980,300],{"class":194},[181,2982,303],{"class":190},[181,2984,2985],{"class":194},"(r.area);\n",[181,2987,2988,2991,2993,2996],{"class":183,"line":326},[181,2989,2990],{"class":194},"r.width ",[181,2992,548],{"class":187},[181,2994,2995],{"class":252}," 10",[181,2997,217],{"class":194},[181,2999,3000,3002,3004],{"class":183,"line":872},[181,3001,300],{"class":194},[181,3003,303],{"class":190},[181,3005,2985],{"class":194},[27,3007,3009,3031,3043,3053],{"className":3008},[30],[32,3010,3012,41,3014,359,3017,3019,3020,3022,3023,3026,3027,628,3029],{"className":3011},[35],[37,3013],{"disabled":39,"type":40},[22,3015,3016],{},"20",[22,3018,2754],{}," — a getter runs its body fresh on every access; nothing caches the earlier result, so once ",[22,3021,2882],{}," changes, the next read of ",[22,3024,3025],{},"area"," recomputes from the current ",[22,3028,2882],{},[22,3030,2887],{},[32,3032,3034,41,3036,359,3038,995,3040,3042],{"className":3033},[35],[37,3035],{"disabled":39,"type":40},[22,3037,3016],{},[22,3039,3016],{},[22,3041,3025],{}," is computed once at first access and then cached like a regular property",[32,3044,3046,41,3048,359,3051],{"className":3045},[35],[37,3047],{"disabled":39,"type":40},[22,3049,3050],{},"NaN",[22,3052,3050],{},[32,3054,3056,41,3058,359,3060],{"className":3055},[35],[37,3057],{"disabled":39,"type":40},[22,3059,3016],{},[22,3061,3062],{},"TypeError: Cannot set property 'width'",[105,3064,3065,3067,3083],{},[108,3066,110],{},[112,3068,3069,118,3071,359,3073,3019,3075,3022,3077,3026,3079,628,3081],{},[115,3070,117],{},[22,3072,3016],{},[22,3074,2754],{},[22,3076,2882],{},[22,3078,3025],{},[22,3080,2882],{},[22,3082,2887],{},[112,3084,3085,3087,3088,3091,3092,3095,3096,3099,3100,3103,3104,3107,3108,3111],{},[115,3086,133],{}," A ",[22,3089,3090],{},"get"," accessor in a class is a function that runs every single time ",[22,3093,3094],{},"instance.prop"," is read — it's transparent property syntax over a method call, not a stored value. Nothing about ",[22,3097,3098],{},"r.area"," is memoized, so the first read computes ",[22,3101,3102],{},"4 * 5 = 20",", and after ",[22,3105,3106],{},"r.width = 10",", the second read recomputes ",[22,3109,3110],{},"10 * 5 = 50"," from the current field values. Assuming the result gets cached (option B) is a common but incorrect mental model — that's not how getters work unless you explicitly build caching yourself.",[14,3113,3114,3118,3234,3273],{"language":164},[17,3115,3117],{"id":3116},"q14-what-happens-when-this-runs","Q14. What happens when this runs?",[170,3119,3120],{"language":164},[173,3121,3123],{"className":175,"code":3122,"language":164,"meta":177,"style":177},"class Temperature {\n  #celsius = 0;\n  get fahrenheit() {\n    return (this.#celsius * 9) \u002F 5 + 32;\n  }\n}\n\nconst t = new Temperature();\nt.fahrenheit = 100;\nconsole.log(t.fahrenheit);\n",[22,3124,3125,3134,3145,3154,3186,3190,3194,3198,3213,3225],{"__ignoreMap":177},[181,3126,3127,3129,3132],{"class":183,"line":184},[181,3128,24],{"class":187},[181,3130,3131],{"class":190}," Temperature",[181,3133,195],{"class":194},[181,3135,3136,3139,3141,3143],{"class":183,"line":198},[181,3137,3138],{"class":523},"  #celsius",[181,3140,267],{"class":187},[181,3142,2470],{"class":252},[181,3144,217],{"class":194},[181,3146,3147,3149,3152],{"class":183,"line":207},[181,3148,2506],{"class":187},[181,3150,3151],{"class":190}," fahrenheit",[181,3153,204],{"class":194},[181,3155,3156,3158,3161,3163,3166,3168,3171,3174,3176,3179,3181,3184],{"class":183,"line":220},[181,3157,210],{"class":187},[181,3159,3160],{"class":194}," (",[181,3162,766],{"class":252},[181,3164,3165],{"class":194},".#celsius ",[181,3167,2073],{"class":187},[181,3169,3170],{"class":252}," 9",[181,3172,3173],{"class":194},") ",[181,3175,628],{"class":187},[181,3177,3178],{"class":252}," 5",[181,3180,777],{"class":187},[181,3182,3183],{"class":252}," 32",[181,3185,217],{"class":194},[181,3187,3188],{"class":183,"line":226},[181,3189,223],{"class":194},[181,3191,3192],{"class":183,"line":232},[181,3193,229],{"class":194},[181,3195,3196],{"class":183,"line":238},[181,3197,235],{"emptyLinePlaceholder":39},[181,3199,3200,3202,3205,3207,3209,3211],{"class":183,"line":249},[181,3201,471],{"class":187},[181,3203,3204],{"class":252}," t",[181,3206,267],{"class":187},[181,3208,479],{"class":187},[181,3210,3131],{"class":190},[181,3212,1109],{"class":194},[181,3214,3215,3218,3220,3223],{"class":183,"line":276},[181,3216,3217],{"class":194},"t.fahrenheit ",[181,3219,548],{"class":187},[181,3221,3222],{"class":252}," 100",[181,3224,217],{"class":194},[181,3226,3227,3229,3231],{"class":183,"line":286},[181,3228,300],{"class":194},[181,3230,303],{"class":190},[181,3232,3233],{"class":194},"(t.fahrenheit);\n",[27,3235,3237,3246,3259,3266],{"className":3236},[30],[32,3238,3240,2580,3242,3245],{"className":3239},[35],[37,3241],{"disabled":39,"type":40},[22,3243,3244],{},"32"," — the assignment is silently ignored because there's no setter",[32,3247,3249,41,3251,3254,3255,3258],{"className":3248},[35],[37,3250],{"disabled":39,"type":40},[22,3252,3253],{},"TypeError: Cannot set property fahrenheit of #\u003CTemperature> which has only a getter"," — class bodies (including field initializers and methods) always execute in strict mode, even without a ",[22,3256,3257],{},"\"use strict\""," pragma, so assigning to a getter-only property throws rather than failing silently",[32,3260,3262,2580,3264],{"className":3261},[35],[37,3263],{"disabled":39,"type":40},[22,3265,2560],{},[32,3267,3269,2580,3271],{"className":3268},[35],[37,3270],{"disabled":39,"type":40},[22,3272,3050],{},[105,3274,3275,3277,3285],{},[108,3276,110],{},[112,3278,3279,414,3281,3254,3283,3258],{},[115,3280,117],{},[22,3282,3253],{},[22,3284,3257],{},[112,3286,3287,41,3289,3291,3292,3294,3295,3297],{},[115,3288,133],{},[115,3290,1484],{}," JS class bodies are implicitly strict mode, no ",[22,3293,3257],{}," needed. In strict mode, assigning to a property that only has a getter (no setter defined) throws a ",[22,3296,2174],{}," instead of silently doing nothing. This is a meaningful difference from a plain object literal in a non-strict script, where the same kind of assignment can fail silently — classes fail loudly by default, which is generally the safer behavior for catching bugs early.",[14,3299,3300,3304,3421,3471],{"language":164},[17,3301,3303],{"id":3302},"q15-what-does-this-log-in-order","Q15. What does this log, in order?",[170,3305,3306],{"language":164},[173,3307,3309],{"className":175,"code":3308,"language":164,"meta":177,"style":177},"class Counter {\n  count = this.logStart();\n\n  constructor() {\n    console.log(\"constructor body runs, count =\", this.count);\n  }\n\n  logStart() {\n    console.log(\"field initializer runs\");\n    return 0;\n  }\n}\n\nnew Counter();\n",[22,3310,3311,3320,3336,3340,3346,3365,3369,3373,3380,3393,3401,3405,3409,3413],{"__ignoreMap":177},[181,3312,3313,3315,3318],{"class":183,"line":184},[181,3314,24],{"class":187},[181,3316,3317],{"class":190}," Counter",[181,3319,195],{"class":194},[181,3321,3322,3325,3327,3329,3331,3334],{"class":183,"line":198},[181,3323,3324],{"class":523},"  count",[181,3326,267],{"class":187},[181,3328,780],{"class":252},[181,3330,256],{"class":194},[181,3332,3333],{"class":190},"logStart",[181,3335,1109],{"class":194},[181,3337,3338],{"class":183,"line":207},[181,3339,235],{"emptyLinePlaceholder":39},[181,3341,3342,3344],{"class":183,"line":220},[181,3343,518],{"class":187},[181,3345,204],{"class":194},[181,3347,3348,3351,3353,3355,3358,3360,3362],{"class":183,"line":226},[181,3349,3350],{"class":194},"    console.",[181,3352,303],{"class":190},[181,3354,306],{"class":194},[181,3356,3357],{"class":213},"\"constructor body runs, count =\"",[181,3359,490],{"class":194},[181,3361,766],{"class":252},[181,3363,3364],{"class":194},".count);\n",[181,3366,3367],{"class":183,"line":232},[181,3368,223],{"class":194},[181,3370,3371],{"class":183,"line":238},[181,3372,235],{"emptyLinePlaceholder":39},[181,3374,3375,3378],{"class":183,"line":249},[181,3376,3377],{"class":190},"  logStart",[181,3379,204],{"class":194},[181,3381,3382,3384,3386,3388,3391],{"class":183,"line":276},[181,3383,3350],{"class":194},[181,3385,303],{"class":190},[181,3387,306],{"class":194},[181,3389,3390],{"class":213},"\"field initializer runs\"",[181,3392,501],{"class":194},[181,3394,3395,3397,3399],{"class":183,"line":286},[181,3396,210],{"class":187},[181,3398,2470],{"class":252},[181,3400,217],{"class":194},[181,3402,3403],{"class":183,"line":292},[181,3404,223],{"class":194},[181,3406,3407],{"class":183,"line":297},[181,3408,229],{"class":194},[181,3410,3411],{"class":183,"line":326},[181,3412,235],{"emptyLinePlaceholder":39},[181,3414,3415,3417,3419],{"class":183,"line":872},[181,3416,82],{"class":187},[181,3418,3317],{"class":190},[181,3420,1109],{"class":194},[27,3422,3424,3434,3444,3462],{"className":3423},[30],[32,3425,3427,41,3429,359,3432],{"className":3426},[35],[37,3428],{"disabled":39,"type":40},[22,3430,3431],{},"\"constructor body runs, count = 0\"",[22,3433,3390],{},[32,3435,3437,41,3439,359,3441],{"className":3436},[35],[37,3438],{"disabled":39,"type":40},[22,3440,3390],{},[22,3442,3443],{},"\"constructor body runs, count = undefined\"",[32,3445,3447,41,3449,359,3451,3453,3454,3457,3458,3461],{"className":3446},[35],[37,3448],{"disabled":39,"type":40},[22,3450,3390],{},[22,3452,3431],{}," — public class fields are initialized per-instance before the constructor body executes, so ",[22,3455,3456],{},"count","'s initializer (and the method call inside it) runs first, and by the time the constructor body logs, ",[22,3459,3460],{},"this.count"," is already set",[32,3463,3465,41,3467,3470],{"className":3464},[35],[37,3466],{"disabled":39,"type":40},[22,3468,3469],{},"TypeError: this.logStart is not a function",", because instance methods aren't available yet during field initialization",[105,3472,3473,3475,3487],{},[108,3474,110],{},[112,3476,3477,647,3479,359,3481,3453,3483,3457,3485,3461],{},[115,3478,117],{},[22,3480,3390],{},[22,3482,3431],{},[22,3484,3456],{},[22,3486,3460],{},[112,3488,3489,3491,3492,3494,3495,3497,3498,3500,3501,3503,3504,3507,3508,3510,3511,256],{},[115,3490,133],{}," Public instance fields declared with ",[22,3493,548],{}," at the class body level are set up per-instance as part of construction, and for a base (non-",[22,3496,157],{},") class that happens ",[989,3499,1502],{}," the explicit constructor body runs. So ",[22,3502,3456],{},"'s initializer executes first — calling ",[22,3505,3506],{},"this.logStart()"," (which is already available on the prototype at that point, ruling out option D) and logging ",[22,3509,3390],{}," — and only afterward does the constructor body run and log the now-initialized ",[22,3512,3460],{},[14,3514,3515,3519,3657,3734],{"language":164},[17,3516,3518],{"id":3517},"q16-what-does-this-log","Q16. What does this log?",[170,3520,3521],{"language":164},[173,3522,3524],{"className":175,"code":3523,"language":164,"meta":177,"style":177},"class Shape {\n  constructor() {\n    console.log(this.describe());\n  }\n  describe() {\n    return \"a shape\";\n  }\n}\n\nclass Circle extends Shape {\n  radius = 5;\n  describe() {\n    return `a circle with radius ${this.radius}`;\n  }\n}\n\nnew Circle();\n",[22,3525,3526,3535,3541,3557,3561,3567,3576,3580,3584,3588,3601,3612,3618,3637,3641,3645,3649],{"__ignoreMap":177},[181,3527,3528,3530,3533],{"class":183,"line":184},[181,3529,24],{"class":187},[181,3531,3532],{"class":190}," Shape",[181,3534,195],{"class":194},[181,3536,3537,3539],{"class":183,"line":198},[181,3538,518],{"class":187},[181,3540,204],{"class":194},[181,3542,3543,3545,3547,3549,3551,3553,3555],{"class":183,"line":207},[181,3544,3350],{"class":194},[181,3546,303],{"class":190},[181,3548,306],{"class":194},[181,3550,766],{"class":252},[181,3552,256],{"class":194},[181,3554,1875],{"class":190},[181,3556,1124],{"class":194},[181,3558,3559],{"class":183,"line":220},[181,3560,223],{"class":194},[181,3562,3563,3565],{"class":183,"line":226},[181,3564,1819],{"class":190},[181,3566,204],{"class":194},[181,3568,3569,3571,3574],{"class":183,"line":232},[181,3570,210],{"class":187},[181,3572,3573],{"class":213}," \"a shape\"",[181,3575,217],{"class":194},[181,3577,3578],{"class":183,"line":238},[181,3579,223],{"class":194},[181,3581,3582],{"class":183,"line":249},[181,3583,229],{"class":194},[181,3585,3586],{"class":183,"line":276},[181,3587,235],{"emptyLinePlaceholder":39},[181,3589,3590,3592,3595,3597,3599],{"class":183,"line":286},[181,3591,24],{"class":187},[181,3593,3594],{"class":190}," Circle",[181,3596,1071],{"class":187},[181,3598,3532],{"class":190},[181,3600,195],{"class":194},[181,3602,3603,3606,3608,3610],{"class":183,"line":292},[181,3604,3605],{"class":523},"  radius",[181,3607,267],{"class":187},[181,3609,3178],{"class":252},[181,3611,217],{"class":194},[181,3613,3614,3616],{"class":183,"line":297},[181,3615,1819],{"class":190},[181,3617,204],{"class":194},[181,3619,3620,3622,3625,3627,3629,3632,3635],{"class":183,"line":326},[181,3621,210],{"class":187},[181,3623,3624],{"class":213}," `a circle with radius ${",[181,3626,766],{"class":252},[181,3628,256],{"class":213},[181,3630,3631],{"class":194},"radius",[181,3633,3634],{"class":213},"}`",[181,3636,217],{"class":194},[181,3638,3639],{"class":183,"line":872},[181,3640,223],{"class":194},[181,3642,3643],{"class":183,"line":1654},[181,3644,229],{"class":194},[181,3646,3647],{"class":183,"line":1659},[181,3648,235],{"emptyLinePlaceholder":39},[181,3650,3651,3653,3655],{"class":183,"line":1679},[181,3652,82],{"class":187},[181,3654,3594],{"class":190},[181,3656,1109],{"class":194},[27,3658,3660,3668,3676,3684],{"className":3659},[30],[32,3661,3663,41,3665],{"className":3662},[35],[37,3664],{"disabled":39,"type":40},[22,3666,3667],{},"\"a shape\"",[32,3669,3671,41,3673],{"className":3670},[35],[37,3672],{"disabled":39,"type":40},[22,3674,3675],{},"\"a circle with radius 5\"",[32,3677,3679,41,3681],{"className":3678},[35],[37,3680],{"disabled":39,"type":40},[22,3682,3683],{},"ReferenceError: Cannot access 'radius' before initialization",[32,3685,3687,41,3689,3692,3693,3696,3697,3700,3701,3704,3705,3707,3708,3710,3711,3714,3715,41,3718,3720,3721,3723,3724,3726,3727,3730,3731,3733],{"className":3686},[35],[37,3688],{"disabled":39,"type":40},[22,3690,3691],{},"\"a circle with radius undefined\""," — method dispatch always uses the actual (derived) prototype, so ",[22,3694,3695],{},"this.describe()"," inside ",[22,3698,3699],{},"Shape","'s constructor already resolves to ",[22,3702,3703],{},"Circle","'s overridden ",[22,3706,1875],{},"; but ",[22,3709,3703],{},"'s own field initializers (including ",[22,3712,3713],{},"radius = 5",") only run ",[989,3716,3717],{},"after",[22,3719,1491],{}," returns, so at the moment ",[22,3722,1875],{}," runs mid-",[22,3725,1491],{}," call, ",[22,3728,3729],{},"this.radius"," isn't set yet and simply reads as ",[22,3732,601],{}," rather than throwing",[105,3735,3736,3738,3768],{},[108,3737,110],{},[112,3739,3740,950,3742,3692,3744,3696,3746,3700,3748,3704,3750,3707,3752,3710,3754,3714,3756,41,3758,3720,3760,3723,3762,3726,3764,3730,3766,3733],{},[115,3741,117],{},[22,3743,3691],{},[22,3745,3695],{},[22,3747,3699],{},[22,3749,3703],{},[22,3751,1875],{},[22,3753,3703],{},[22,3755,3713],{},[989,3757,3717],{},[22,3759,1491],{},[22,3761,1875],{},[22,3763,1491],{},[22,3765,3729],{},[22,3767,601],{},[112,3769,3770,41,3772,3774,3775,3777,3778,3780,3781,3783,3784,3787,3788,3791,3792,3794,3795,3797,3798,3800,3801,3803,3804,628,3806,3808,3809,3811],{},[115,3771,133],{},[115,3773,662],{}," this combines two rules that interact badly. First, method overriding is resolved dynamically through the prototype chain, so even while ",[22,3776,3699],{},"'s constructor is still running (as part of ",[22,3779,1491],{},"), ",[22,3782,3695],{}," finds ",[22,3785,3786],{},"Circle.prototype.describe",", not ",[22,3789,3790],{},"Shape.prototype.describe",". Second, in a derived class, instance field initializers (like ",[22,3793,3713],{},") only run once ",[22,3796,1491],{}," has returned — they haven't executed yet at the point ",[22,3799,1875],{}," is invoked mid-",[22,3802,1491],{},". Reading a not-yet-set instance property doesn't throw (that's only TDZ behavior for ",[22,3805,627],{},[22,3807,471],{}," bindings); it just returns ",[22,3810,601],{},", since the property genuinely doesn't exist yet anywhere in the chain. This ordering gotcha is a real source of bugs when a base constructor calls an overridable method.",[14,3813,3814,3818,3988,4040],{"language":164},[17,3815,3817],{"id":3816},"q17-what-does-this-log","Q17. What does this log?",[170,3819,3820],{"language":164},[173,3821,3823],{"className":175,"code":3822,"language":164,"meta":177,"style":177},"class Logger {\n  prefix = \"[LOG]\";\n\n  logRegular(msg) {\n    console.log(this.prefix, msg);\n  }\n\n  logArrow = (msg) => {\n    console.log(this.prefix, msg);\n  };\n}\n\nconst a = new Logger();\nconst b = new Logger();\n\nconsole.log(a.logRegular === b.logRegular);\nconsole.log(a.logArrow === b.logArrow);\n",[22,3824,3825,3834,3846,3850,3862,3875,3879,3883,3901,3913,3918,3922,3926,3941,3956,3960,3974],{"__ignoreMap":177},[181,3826,3827,3829,3832],{"class":183,"line":184},[181,3828,24],{"class":187},[181,3830,3831],{"class":190}," Logger",[181,3833,195],{"class":194},[181,3835,3836,3839,3841,3844],{"class":183,"line":198},[181,3837,3838],{"class":523},"  prefix",[181,3840,267],{"class":187},[181,3842,3843],{"class":213}," \"[LOG]\"",[181,3845,217],{"class":194},[181,3847,3848],{"class":183,"line":207},[181,3849,235],{"emptyLinePlaceholder":39},[181,3851,3852,3855,3857,3860],{"class":183,"line":220},[181,3853,3854],{"class":190},"  logRegular",[181,3856,306],{"class":194},[181,3858,3859],{"class":523},"msg",[181,3861,537],{"class":194},[181,3863,3864,3866,3868,3870,3872],{"class":183,"line":226},[181,3865,3350],{"class":194},[181,3867,303],{"class":190},[181,3869,306],{"class":194},[181,3871,766],{"class":252},[181,3873,3874],{"class":194},".prefix, msg);\n",[181,3876,3877],{"class":183,"line":232},[181,3878,223],{"class":194},[181,3880,3881],{"class":183,"line":238},[181,3882,235],{"emptyLinePlaceholder":39},[181,3884,3885,3888,3890,3892,3894,3896,3899],{"class":183,"line":249},[181,3886,3887],{"class":190},"  logArrow",[181,3889,267],{"class":187},[181,3891,3160],{"class":194},[181,3893,3859],{"class":523},[181,3895,3173],{"class":194},[181,3897,3898],{"class":187},"=>",[181,3900,195],{"class":194},[181,3902,3903,3905,3907,3909,3911],{"class":183,"line":276},[181,3904,3350],{"class":194},[181,3906,303],{"class":190},[181,3908,306],{"class":194},[181,3910,766],{"class":252},[181,3912,3874],{"class":194},[181,3914,3915],{"class":183,"line":286},[181,3916,3917],{"class":194},"  };\n",[181,3919,3920],{"class":183,"line":292},[181,3921,229],{"class":194},[181,3923,3924],{"class":183,"line":297},[181,3925,235],{"emptyLinePlaceholder":39},[181,3927,3928,3930,3933,3935,3937,3939],{"class":183,"line":326},[181,3929,471],{"class":187},[181,3931,3932],{"class":252}," a",[181,3934,267],{"class":187},[181,3936,479],{"class":187},[181,3938,3831],{"class":190},[181,3940,1109],{"class":194},[181,3942,3943,3945,3948,3950,3952,3954],{"class":183,"line":872},[181,3944,471],{"class":187},[181,3946,3947],{"class":252}," b",[181,3949,267],{"class":187},[181,3951,479],{"class":187},[181,3953,3831],{"class":190},[181,3955,1109],{"class":194},[181,3957,3958],{"class":183,"line":1654},[181,3959,235],{"emptyLinePlaceholder":39},[181,3961,3962,3964,3966,3969,3971],{"class":183,"line":1659},[181,3963,300],{"class":194},[181,3965,303],{"class":190},[181,3967,3968],{"class":194},"(a.logRegular ",[181,3970,841],{"class":187},[181,3972,3973],{"class":194}," b.logRegular);\n",[181,3975,3976,3978,3980,3983,3985],{"class":183,"line":1679},[181,3977,300],{"class":194},[181,3979,303],{"class":190},[181,3981,3982],{"class":194},"(a.logArrow ",[181,3984,841],{"class":187},[181,3986,3987],{"class":194}," b.logArrow);\n",[27,3989,3991,4013,4022,4031],{"className":3990},[30],[32,3992,3994,41,3996,359,3998,4000,4001,4004,4005,4008,4009,4012],{"className":3993},[35],[37,3995],{"disabled":39,"type":40},[22,3997,898],{},[22,3999,910],{}," — a regular method (",[22,4002,4003],{},"logRegular",") is defined once on ",[22,4006,4007],{},"Logger.prototype"," and shared by every instance, so both instances reference the identical function object; an arrow function class field (",[22,4010,4011],{},"logArrow",") is instead created fresh during each constructor run and assigned as an own property on that specific instance, so two instances never share the same function reference",[32,4014,4016,41,4018,359,4020],{"className":4015},[35],[37,4017],{"disabled":39,"type":40},[22,4019,910],{},[22,4021,910],{},[32,4023,4025,41,4027,359,4029],{"className":4024},[35],[37,4026],{"disabled":39,"type":40},[22,4028,898],{},[22,4030,898],{},[32,4032,4034,41,4036,359,4038],{"className":4033},[35],[37,4035],{"disabled":39,"type":40},[22,4037,910],{},[22,4039,898],{},[105,4041,4042,4044,4058],{},[108,4043,110],{},[112,4045,4046,118,4048,359,4050,4000,4052,4004,4054,4008,4056,4012],{},[115,4047,117],{},[22,4049,898],{},[22,4051,910],{},[22,4053,4003],{},[22,4055,4007],{},[22,4057,4011],{},[112,4059,4060,41,4062,41,4065,4067,4068,4070,4071,1271,4073,1001,4075,4077,4078,4081,4082,4085,4086,3696,4088,4090],{},[115,4061,133],{},[115,4063,4064],{},"Performance:",[22,4066,4003],{}," is ordinary class-method syntax, so it's installed exactly once on ",[22,4069,4007],{}," — every instance looks it up through the prototype chain and gets back the same function object, hence ",[22,4072,841],{},[22,4074,898],{},[22,4076,4011],{}," is a class ",[989,4079,4080],{},"field"," whose value happens to be an arrow function; like any instance field, its initializer runs separately for every ",[22,4083,4084],{},"new Logger()"," call, creating a brand-new closure each time and assigning it as an own property of that instance. That's what makes ",[22,4087,766],{},[22,4089,4011],{}," permanently bound to its own instance — but it comes at a real memory cost (one extra function object per instance) compared to a shared prototype method, which matters for classes instantiated many times.",[14,4092,4093,4097,4182,4242],{"language":164},[17,4094,4096],{"id":4095},"q18-what-does-this-log","Q18. What does this log?",[170,4098,4099],{"language":164},[173,4100,4102],{"className":175,"code":4101,"language":164,"meta":177,"style":177},"class Shape {}\n\nconst s = new Shape();\n\nclass NewShape {}\nShape.prototype = NewShape.prototype;\n\nconsole.log(s instanceof Shape);\n",[22,4103,4104,4112,4116,4131,4135,4144,4162,4166],{"__ignoreMap":177},[181,4105,4106,4108,4110],{"class":183,"line":184},[181,4107,24],{"class":187},[181,4109,3532],{"class":190},[181,4111,1076],{"class":194},[181,4113,4114],{"class":183,"line":198},[181,4115,235],{"emptyLinePlaceholder":39},[181,4117,4118,4120,4123,4125,4127,4129],{"class":183,"line":207},[181,4119,471],{"class":187},[181,4121,4122],{"class":252}," s",[181,4124,267],{"class":187},[181,4126,479],{"class":187},[181,4128,3532],{"class":190},[181,4130,1109],{"class":194},[181,4132,4133],{"class":183,"line":220},[181,4134,235],{"emptyLinePlaceholder":39},[181,4136,4137,4139,4142],{"class":183,"line":226},[181,4138,24],{"class":187},[181,4140,4141],{"class":190}," NewShape",[181,4143,1076],{"class":194},[181,4145,4146,4148,4150,4152,4154,4156,4158,4160],{"class":183,"line":232},[181,4147,3699],{"class":252},[181,4149,256],{"class":194},[181,4151,259],{"class":252},[181,4153,267],{"class":187},[181,4155,4141],{"class":252},[181,4157,256],{"class":194},[181,4159,259],{"class":252},[181,4161,217],{"class":194},[181,4163,4164],{"class":183,"line":238},[181,4165,235],{"emptyLinePlaceholder":39},[181,4167,4168,4170,4172,4175,4178,4180],{"class":183,"line":249},[181,4169,300],{"class":194},[181,4171,303],{"class":190},[181,4173,4174],{"class":194},"(s ",[181,4176,4177],{"class":187},"instanceof",[181,4179,3532],{"class":190},[181,4181,501],{"class":194},[27,4183,4185,4199,4227,4235],{"className":4184},[30],[32,4186,4188,41,4190,995,4192,4195,4196,4198],{"className":4187},[35],[37,4189],{"disabled":39,"type":40},[22,4191,898],{},[22,4193,4194],{},"s"," was created as an instance of ",[22,4197,3699],{},", so it stays an instance forever",[32,4200,4202,41,4204,995,4206,4208,4209,4212,4213,4215,4216,2405,4218,4220,4221,4223,4224],{"className":4201},[35],[37,4203],{"disabled":39,"type":40},[22,4205,910],{},[22,4207,4177],{}," re-reads ",[22,4210,4211],{},"Shape.prototype"," at the moment of the check, not at construction time; since ",[22,4214,4211],{}," now points to a different object than the one actually in ",[22,4217,4194],{},[22,4219,972],{}," chain, the check fails even though ",[22,4222,4194],{}," was legitimately built by ",[22,4225,4226],{},"new Shape()",[32,4228,4230,41,4232],{"className":4229},[35],[37,4231],{"disabled":39,"type":40},[22,4233,4234],{},"TypeError: Right-hand side of 'instanceof' is not callable",[32,4236,4238,41,4240],{"className":4237},[35],[37,4239],{"disabled":39,"type":40},[22,4241,601],{},[105,4243,4244,4246,4266],{},[108,4245,110],{},[112,4247,4248,414,4250,995,4252,4208,4254,4212,4256,4215,4258,2405,4260,4220,4262,4223,4264],{},[115,4249,117],{},[22,4251,910],{},[22,4253,4177],{},[22,4255,4211],{},[22,4257,4211],{},[22,4259,4194],{},[22,4261,972],{},[22,4263,4194],{},[22,4265,4226],{},[112,4267,4268,41,4270,41,4272,4275,4276,2405,4279,4282,4283,2405,4285,4287,4288,4290,4291,4293,4294,4296,4297,4299,4300,4303,4304,4306,4307,4309,4310,4312,4313,4315,4316,4318],{},[115,4269,133],{},[115,4271,662],{},[22,4273,4274],{},"x instanceof C"," works by taking ",[22,4277,4278],{},"C.prototype",[989,4280,4281],{},"current"," value and checking whether it appears anywhere in ",[22,4284,524],{},[22,4286,972],{}," chain — it does not remember what ",[22,4289,4278],{}," was at construction time. ",[22,4292,4194],{}," was built while ",[22,4295,4211],{}," pointed to its original prototype object, so that original object is permanently baked into ",[22,4298,4194],{},"'s chain. Reassigning ",[22,4301,4302],{},"Shape.prototype = NewShape.prototype"," afterward changes what the ",[989,4305,24],{}," currently points to, but does nothing to ",[22,4308,4194],{},"'s existing chain, so the two no longer match and ",[22,4311,4177],{}," reports ",[22,4314,910],{},". Reassigning ",[22,4317,52],{}," after instances already exist is a real footgun for exactly this reason.",[14,4320,4321,4325,4608,4659],{"language":164},[17,4322,4324],{"id":4323},"q19-what-does-this-log","Q19. What does this log?",[170,4326,4327],{"language":164},[173,4328,4330],{"className":175,"code":4329,"language":164,"meta":177,"style":177},"const Serializable = Base => class extends Base {\n  toJSON() {\n    return JSON.stringify(this);\n  }\n};\n\nconst Comparable = Base => class extends Base {\n  equals(other) {\n    return this.toJSON() === other.toJSON();\n  }\n};\n\nclass Point {\n  constructor(x, y) {\n    this.x = x;\n    this.y = y;\n  }\n}\n\nclass ComparablePoint extends Comparable(Serializable(Point)) {}\n\nconst a = new ComparablePoint(1, 2);\nconst b = new ComparablePoint(1, 2);\n\nconsole.log(a.equals(b));\n",[22,4331,4332,4355,4362,4380,4384,4388,4392,4413,4425,4448,4452,4456,4460,4468,4482,4492,4502,4506,4511,4516,4536,4541,4564,4587,4592],{"__ignoreMap":177},[181,4333,4334,4336,4339,4341,4343,4346,4349,4351,4353],{"class":183,"line":184},[181,4335,471],{"class":187},[181,4337,4338],{"class":190}," Serializable",[181,4340,267],{"class":187},[181,4342,2253],{"class":523},[181,4344,4345],{"class":187}," =>",[181,4347,4348],{"class":187}," class",[181,4350,1071],{"class":187},[181,4352,2253],{"class":190},[181,4354,195],{"class":194},[181,4356,4357,4360],{"class":183,"line":198},[181,4358,4359],{"class":190},"  toJSON",[181,4361,204],{"class":194},[181,4363,4364,4366,4369,4371,4374,4376,4378],{"class":183,"line":207},[181,4365,210],{"class":187},[181,4367,4368],{"class":252}," JSON",[181,4370,256],{"class":194},[181,4372,4373],{"class":190},"stringify",[181,4375,306],{"class":194},[181,4377,766],{"class":252},[181,4379,501],{"class":194},[181,4381,4382],{"class":183,"line":220},[181,4383,223],{"class":194},[181,4385,4386],{"class":183,"line":226},[181,4387,289],{"class":194},[181,4389,4390],{"class":183,"line":232},[181,4391,235],{"emptyLinePlaceholder":39},[181,4393,4394,4396,4399,4401,4403,4405,4407,4409,4411],{"class":183,"line":238},[181,4395,471],{"class":187},[181,4397,4398],{"class":190}," Comparable",[181,4400,267],{"class":187},[181,4402,2253],{"class":523},[181,4404,4345],{"class":187},[181,4406,4348],{"class":187},[181,4408,1071],{"class":187},[181,4410,2253],{"class":190},[181,4412,195],{"class":194},[181,4414,4415,4418,4420,4423],{"class":183,"line":249},[181,4416,4417],{"class":190},"  equals",[181,4419,306],{"class":194},[181,4421,4422],{"class":523},"other",[181,4424,537],{"class":194},[181,4426,4427,4429,4431,4433,4436,4439,4441,4444,4446],{"class":183,"line":276},[181,4428,210],{"class":187},[181,4430,780],{"class":252},[181,4432,256],{"class":194},[181,4434,4435],{"class":190},"toJSON",[181,4437,4438],{"class":194},"() ",[181,4440,841],{"class":187},[181,4442,4443],{"class":194}," other.",[181,4445,4435],{"class":190},[181,4447,1109],{"class":194},[181,4449,4450],{"class":183,"line":286},[181,4451,223],{"class":194},[181,4453,4454],{"class":183,"line":292},[181,4455,289],{"class":194},[181,4457,4458],{"class":183,"line":297},[181,4459,235],{"emptyLinePlaceholder":39},[181,4461,4462,4464,4466],{"class":183,"line":326},[181,4463,24],{"class":187},[181,4465,704],{"class":190},[181,4467,195],{"class":194},[181,4469,4470,4472,4474,4476,4478,4480],{"class":183,"line":872},[181,4471,518],{"class":187},[181,4473,306],{"class":194},[181,4475,524],{"class":523},[181,4477,490],{"class":194},[181,4479,529],{"class":523},[181,4481,537],{"class":194},[181,4483,4484,4486,4488,4490],{"class":183,"line":1654},[181,4485,542],{"class":252},[181,4487,545],{"class":194},[181,4489,548],{"class":187},[181,4491,551],{"class":194},[181,4493,4494,4496,4498,4500],{"class":183,"line":1659},[181,4495,542],{"class":252},[181,4497,558],{"class":194},[181,4499,548],{"class":187},[181,4501,563],{"class":194},[181,4503,4504],{"class":183,"line":1679},[181,4505,223],{"class":194},[181,4507,4509],{"class":183,"line":4508},18,[181,4510,229],{"class":194},[181,4512,4514],{"class":183,"line":4513},19,[181,4515,235],{"emptyLinePlaceholder":39},[181,4517,4519,4521,4524,4526,4528,4530,4533],{"class":183,"line":4518},20,[181,4520,24],{"class":187},[181,4522,4523],{"class":190}," ComparablePoint",[181,4525,1071],{"class":187},[181,4527,4398],{"class":190},[181,4529,306],{"class":194},[181,4531,4532],{"class":190},"Serializable",[181,4534,4535],{"class":194},"(Point)) {}\n",[181,4537,4539],{"class":183,"line":4538},21,[181,4540,235],{"emptyLinePlaceholder":39},[181,4542,4544,4546,4548,4550,4552,4554,4556,4558,4560,4562],{"class":183,"line":4543},22,[181,4545,471],{"class":187},[181,4547,3932],{"class":252},[181,4549,267],{"class":187},[181,4551,479],{"class":187},[181,4553,4523],{"class":190},[181,4555,306],{"class":194},[181,4557,487],{"class":252},[181,4559,490],{"class":194},[181,4561,493],{"class":252},[181,4563,501],{"class":194},[181,4565,4567,4569,4571,4573,4575,4577,4579,4581,4583,4585],{"class":183,"line":4566},23,[181,4568,471],{"class":187},[181,4570,3947],{"class":252},[181,4572,267],{"class":187},[181,4574,479],{"class":187},[181,4576,4523],{"class":190},[181,4578,306],{"class":194},[181,4580,487],{"class":252},[181,4582,490],{"class":194},[181,4584,493],{"class":252},[181,4586,501],{"class":194},[181,4588,4590],{"class":183,"line":4589},24,[181,4591,235],{"emptyLinePlaceholder":39},[181,4593,4595,4597,4599,4602,4605],{"class":183,"line":4594},25,[181,4596,300],{"class":194},[181,4598,303],{"class":190},[181,4600,4601],{"class":194},"(a.",[181,4603,4604],{"class":190},"equals",[181,4606,4607],{"class":194},"(b));\n",[27,4609,4611,4619,4636,4651],{"className":4610},[30],[32,4612,4614,41,4616],{"className":4613},[35],[37,4615],{"disabled":39,"type":40},[22,4617,4618],{},"SyntaxError: A class can only extend one expression",[32,4620,4622,41,4624,1190,4626,4628,4629,4631,4632,4635],{"className":4621},[35],[37,4623],{"disabled":39,"type":40},[22,4625,910],{},[22,4627,4435],{}," from ",[22,4630,4532],{}," is shadowed by ",[22,4633,4634],{},"Comparable","'s own method",[32,4637,4639,41,4641,4643,4644,4646,4647,4650],{"className":4638},[35],[37,4640],{"disabled":39,"type":40},[22,4642,898],{}," — since JS classes support only single inheritance via ",[22,4645,157],{},", each mixin is written as a function that takes a base class and returns a new subclass extending it; chaining these calls (",[22,4648,4649],{},"Comparable(Serializable(Point))",") layers multiple independent behaviors onto one class, which is how JS works around not having true multiple inheritance",[32,4652,4654,41,4656],{"className":4653},[35],[37,4655],{"disabled":39,"type":40},[22,4657,4658],{},"TypeError: other.toJSON is not a function",[105,4660,4661,4663,4673],{},[108,4662,110],{},[112,4664,4665,647,4667,4643,4669,4646,4671,4650],{},[115,4666,117],{},[22,4668,898],{},[22,4670,157],{},[22,4672,4649],{},[112,4674,4675,41,4677,41,4679,4681,4682,4685,4686,4689,4690,4692,4693,4696,4697,1001,4699,4702,4703,95,4705,4707,4708,4711,4712,4714],{},[115,4676,133],{},[115,4678,431],{},[22,4680,157],{}," only ever accepts a single expression, but that expression can itself be a function call that returns a class — which is exactly what a mixin function is. ",[22,4683,4684],{},"Serializable(Point)"," returns an anonymous class extending ",[22,4687,4688],{},"Point"," that adds ",[22,4691,4435],{},"; ",[22,4694,4695],{},"Comparable(...)"," wraps that again, adding ",[22,4698,4604],{},[22,4700,4701],{},"ComparablePoint"," ends up with both ",[22,4704,4435],{},[22,4706,4604],{}," available through its prototype chain, with no conflict between them, so ",[22,4709,4710],{},"a.equals(b)"," compares their JSON forms and correctly returns ",[22,4713,898],{},". This composition pattern is JS's standard workaround for the lack of real multiple inheritance.",[14,4716,4717,4739,4776],{},[17,4718,4720,4721,490,4724,439,4727,4730,4731,490,4733,4735,4736,4738],{"id":4719},"q20-a-team-building-a-ui-has-modal-tooltip-and-dropdown-components-all-three-need-identical-positioning-logic-but-positioning-isnt-conceptually-a-kind-of-modal-tooltip-or-dropdown-its-an-unrelated-cross-cutting-concern-whats-the-best-practice-way-to-share-this-behavior","Q20. A team building a UI has ",[22,4722,4723],{},"Modal",[22,4725,4726],{},"Tooltip",[22,4728,4729],{},"Dropdown"," components. All three need identical positioning logic, but \"positioning\" isn't conceptually a kind of ",[22,4732,4723],{},[22,4734,4726],{},", or ",[22,4737,4729],{}," — it's an unrelated, cross-cutting concern. What's the best-practice way to share this behavior?",[27,4740,4742,4752,4758,4767],{"className":4741},[30],[32,4743,4745,4747,4748,4751],{"className":4744},[35],[37,4746],{"disabled":39,"type":40}," Create one deep base class ",[22,4749,4750],{},"PositionableUIElement"," that all three extend, even though they aren't otherwise conceptually related, so the shared logic lives in exactly one place",[32,4753,4755,4757],{"className":4754},[35],[37,4756],{"disabled":39,"type":40}," Copy-paste the positioning code into each of the three components to avoid any coupling between them",[32,4759,4761,4763,4764,4766],{"className":4760},[35],[37,4762],{"disabled":39,"type":40}," Use multiple inheritance by having each component ",[22,4765,157],{}," both a base UI class and a separate positioning class at the same time",[32,4768,4770,4772,4773,4775],{"className":4769},[35],[37,4771],{"disabled":39,"type":40}," Extract the positioning logic into a standalone function\u002Fobject (a composed helper or mixin, as in Q19) that each component uses, since ",[22,4774,157],{}," should model a genuine \"is-a\" relationship — reaching for inheritance purely to share unrelated behavior produces awkward, fragile hierarchies as more cross-cutting concerns pile up",[105,4777,4778,4780,4787],{},[108,4779,110],{},[112,4781,4782,4784,4785,4775],{},[115,4783,117],{}," D — Extract the positioning logic into a standalone function\u002Fobject (a composed helper or mixin, as in Q19) that each component uses, since ",[22,4786,157],{},[112,4788,4789,41,4791,41,4793,4795,4796,490,4798,439,4800,4802,4803,4805,4806,4808],{},[115,4790,133],{},[115,4792,431],{},[22,4794,157],{}," should express \"this really is a specialized version of that,\" not just \"I want to reuse some code.\" Forcing ",[22,4797,4723],{},[22,4799,4726],{},[22,4801,4729],{}," under a shared ",[22,4804,4750],{}," base (option A) works today but becomes fragile the moment a fourth unrelated concern (e.g., \"draggable\") needs sharing too — deep, unrelated hierarchies are hard to reason about and hard to change safely. Copy-pasting (option B) duplicates bugs across three places. Option C isn't even possible — JS's ",[22,4807,157],{}," clause accepts exactly one class expression, though as Q19 showed, that one expression can itself be composed from multiple mixins. Preferring composition (small, focused, combinable units of behavior) over deep inheritance chains is the widely recommended default for sharing behavior that isn't a true \"is-a\" relationship.",[4810,4811,4812],"style",{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}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 .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}",{"title":177,"searchDepth":198,"depth":198,"links":4814},[4815,4817,4818,4819,4820,4821,4822,4823,4824,4825,4826,4827,4828,4829,4830,4831,4832,4833,4834,4835],{"id":19,"depth":207,"text":4816},"Q1. Which statement best describes the relationship between JavaScript class syntax and prototypes?",{"id":167,"depth":207,"text":168},{"id":458,"depth":207,"text":459},{"id":689,"depth":207,"text":690},{"id":1017,"depth":207,"text":1018},{"id":1289,"depth":207,"text":1290},{"id":1527,"depth":207,"text":1528},{"id":1797,"depth":207,"text":1798},{"id":2031,"depth":207,"text":2032},{"id":2238,"depth":207,"text":2239},{"id":2443,"depth":207,"text":2444},{"id":2655,"depth":207,"text":2656},{"id":2856,"depth":207,"text":2857},{"id":3116,"depth":207,"text":3117},{"id":3302,"depth":207,"text":3303},{"id":3517,"depth":207,"text":3518},{"id":3816,"depth":207,"text":3817},{"id":4095,"depth":207,"text":4096},{"id":4323,"depth":207,"text":4324},{"id":4719,"depth":207,"text":4836},"Q20. A team building a UI has Modal, Tooltip, and Dropdown components. All three need identical positioning logic, but \"positioning\" isn't conceptually a kind of Modal, Tooltip, or Dropdown — it's an unrelated, cross-cutting concern. What's the best-practice way to share this behavior?","md",{},"\u002Fjs\u002F10-classes-and-prototypes",{"title":5,"description":177},"js\u002F10-classes-and-prototypes","wCJbrMlNmKaevEMTyrlZlHx1QwR_W9CFu79psIbMZPo",1787335397333]