[{"data":1,"prerenderedAt":3182},["ShallowReactive",2],{"page-\u002Fjs\u002F11-this-keyword":3},{"id":4,"title":5,"body":6,"description":3175,"extension":3176,"meta":3177,"navigation":80,"path":3178,"seo":3179,"stem":3180,"__hash__":3181},"content\u002Fjs\u002F11-this-keyword.md","JavaScript 11 — `this` Binding Rules: Call Site, Arrow Lexical & Explicit Binding",{"type":7,"value":8,"toc":3161},"minimark",[9,19,24,515,522,877,884,1297,1308,1700,1707,2079,2083,2498,2502,2897,2901,2905,3027,3157],[10,11,13,14,18],"h1",{"id":12},"_11-this-binding-rules-call-site-arrow-lexical-explicit-binding","11 — ",[15,16,17],"code",{},"this"," Binding Rules: Call Site, Arrow Lexical & Explicit Binding",[20,21,23],"h2",{"id":22},"the-four-binding-rules","The Four Binding Rules",[25,26,28],"code-wrapper",{"language":27},"javascript",[29,30,34],"pre",{"className":31,"code":32,"language":27,"meta":33,"style":33},"language-javascript shiki shiki-themes github-light github-dark","\u002F\u002F ── `this` is determined by the CALL SITE (how the function is called), not the definition ──\n\u002F\u002F Four rules, in order of precedence (highest wins):\n\u002F\u002F 1. `new` binding: this = the new object being created\n\u002F\u002F 2. Explicit binding: call\u002Fapply\u002Fbind — this = the first argument\n\u002F\u002F 3. Implicit binding: obj.method() — this = obj (the receiver before the dot)\n\u002F\u002F 4. Default binding: this = global (or undefined in strict mode)\n\n\u002F\u002F ── Rule 4: Default binding (standalone function call) ──\nfunction showThis() { console.log(this); }\nshowThis();  \u002F\u002F global object (window\u002FglobalThis) in sloppy mode; undefined in strict mode\n\u002F\u002F `this` is the global object because there's no receiver (no obj.method() pattern)\n\n\u002F\u002F ── Rule 3: Implicit binding (method call — the receiver) ──\nconst obj = {\n    name: \"Alice\",\n    greet() { console.log(`Hello, ${this.name}`); }\n};\nobj.greet();  \u002F\u002F \"Hello, Alice\" — `this` is obj (the receiver before the dot)\n\u002F\u002F The call site is `obj.greet()` — `obj` is the implicit `this`\n\n\u002F\u002F ── ⚠️ Implicit binding is LOST when the method is detached ──\nconst greet = obj.greet;  \u002F\u002F assign the method to a variable (detached from obj)\ngreet();  \u002F\u002F \"Hello, undefined\" — `this` is the global\u002Fundefined (default binding!)\n\u002F\u002F The call site is `greet()` (no receiver) → default binding\n\u002F\u002F This is the #1 `this` bug: passing a method as a callback loses its receiver.\n\n\u002F\u002F ── Rule 2: Explicit binding (call\u002Fapply\u002Fbind) ──\nfunction greet2(greeting) { return `${greeting}, ${this.name}`; }\nconst user = { name: \"Bob\" };\ngreet2.call(user, \"Hi\");     \u002F\u002F \"Hi, Bob\" — call: this=user, args passed individually\ngreet2.apply(user, [\"Hi\"]);  \u002F\u002F \"Hi, Bob\" — apply: this=user, args as array\nconst bound = greet2.bind(user);  \u002F\u002F bind: creates a NEW function with this permanently set\nbound(\"Hello\");  \u002F\u002F \"Hello, Bob\" — this is always user (can't be changed)\n\n\u002F\u002F ── Rule 1: `new` binding (constructor call) ──\nfunction Person(name) {\n    this.name = name;  \u002F\u002F `this` is the newly created object\n}\nconst alice = new Person(\"Alice\");\nconsole.log(alice.name);  \u002F\u002F \"Alice\" — `this` was the new object created by `new`\n\u002F\u002F `new` creates a fresh object, calls Person with `this` = that object, returns it\n","",[15,35,36,45,51,57,63,69,75,82,88,115,127,133,138,144,159,172,200,206,220,226,231,237,253,263,269,275,280,286,325,344,365,384,406,423,428,434,449,467,473,495,509],{"__ignoreMap":33},[37,38,41],"span",{"class":39,"line":40},"line",1,[37,42,44],{"class":43},"sdCPZ","\u002F\u002F ── `this` is determined by the CALL SITE (how the function is called), not the definition ──\n",[37,46,48],{"class":39,"line":47},2,[37,49,50],{"class":43},"\u002F\u002F Four rules, in order of precedence (highest wins):\n",[37,52,54],{"class":39,"line":53},3,[37,55,56],{"class":43},"\u002F\u002F 1. `new` binding: this = the new object being created\n",[37,58,60],{"class":39,"line":59},4,[37,61,62],{"class":43},"\u002F\u002F 2. Explicit binding: call\u002Fapply\u002Fbind — this = the first argument\n",[37,64,66],{"class":39,"line":65},5,[37,67,68],{"class":43},"\u002F\u002F 3. Implicit binding: obj.method() — this = obj (the receiver before the dot)\n",[37,70,72],{"class":39,"line":71},6,[37,73,74],{"class":43},"\u002F\u002F 4. Default binding: this = global (or undefined in strict mode)\n",[37,76,78],{"class":39,"line":77},7,[37,79,81],{"emptyLinePlaceholder":80},true,"\n",[37,83,85],{"class":39,"line":84},8,[37,86,87],{"class":43},"\u002F\u002F ── Rule 4: Default binding (standalone function call) ──\n",[37,89,91,95,99,103,106,109,112],{"class":39,"line":90},9,[37,92,94],{"class":93},"svdQ7","function",[37,96,98],{"class":97},"sIsaT"," showThis",[37,100,102],{"class":101},"ssxIu","() { console.",[37,104,105],{"class":97},"log",[37,107,108],{"class":101},"(",[37,110,17],{"class":111},"snvgF",[37,113,114],{"class":101},"); }\n",[37,116,118,121,124],{"class":39,"line":117},10,[37,119,120],{"class":97},"showThis",[37,122,123],{"class":101},"();  ",[37,125,126],{"class":43},"\u002F\u002F global object (window\u002FglobalThis) in sloppy mode; undefined in strict mode\n",[37,128,130],{"class":39,"line":129},11,[37,131,132],{"class":43},"\u002F\u002F `this` is the global object because there's no receiver (no obj.method() pattern)\n",[37,134,136],{"class":39,"line":135},12,[37,137,81],{"emptyLinePlaceholder":80},[37,139,141],{"class":39,"line":140},13,[37,142,143],{"class":43},"\u002F\u002F ── Rule 3: Implicit binding (method call — the receiver) ──\n",[37,145,147,150,153,156],{"class":39,"line":146},14,[37,148,149],{"class":93},"const",[37,151,152],{"class":111}," obj",[37,154,155],{"class":93}," =",[37,157,158],{"class":101}," {\n",[37,160,162,165,169],{"class":39,"line":161},15,[37,163,164],{"class":101},"    name: ",[37,166,168],{"class":167},"sJ6F3","\"Alice\"",[37,170,171],{"class":101},",\n",[37,173,175,178,180,182,184,187,189,192,195,198],{"class":39,"line":174},16,[37,176,177],{"class":97},"    greet",[37,179,102],{"class":101},[37,181,105],{"class":97},[37,183,108],{"class":101},[37,185,186],{"class":167},"`Hello, ${",[37,188,17],{"class":111},[37,190,191],{"class":167},".",[37,193,194],{"class":101},"name",[37,196,197],{"class":167},"}`",[37,199,114],{"class":101},[37,201,203],{"class":39,"line":202},17,[37,204,205],{"class":101},"};\n",[37,207,209,212,215,217],{"class":39,"line":208},18,[37,210,211],{"class":101},"obj.",[37,213,214],{"class":97},"greet",[37,216,123],{"class":101},[37,218,219],{"class":43},"\u002F\u002F \"Hello, Alice\" — `this` is obj (the receiver before the dot)\n",[37,221,223],{"class":39,"line":222},19,[37,224,225],{"class":43},"\u002F\u002F The call site is `obj.greet()` — `obj` is the implicit `this`\n",[37,227,229],{"class":39,"line":228},20,[37,230,81],{"emptyLinePlaceholder":80},[37,232,234],{"class":39,"line":233},21,[37,235,236],{"class":43},"\u002F\u002F ── ⚠️ Implicit binding is LOST when the method is detached ──\n",[37,238,240,242,245,247,250],{"class":39,"line":239},22,[37,241,149],{"class":93},[37,243,244],{"class":111}," greet",[37,246,155],{"class":93},[37,248,249],{"class":101}," obj.greet;  ",[37,251,252],{"class":43},"\u002F\u002F assign the method to a variable (detached from obj)\n",[37,254,256,258,260],{"class":39,"line":255},23,[37,257,214],{"class":97},[37,259,123],{"class":101},[37,261,262],{"class":43},"\u002F\u002F \"Hello, undefined\" — `this` is the global\u002Fundefined (default binding!)\n",[37,264,266],{"class":39,"line":265},24,[37,267,268],{"class":43},"\u002F\u002F The call site is `greet()` (no receiver) → default binding\n",[37,270,272],{"class":39,"line":271},25,[37,273,274],{"class":43},"\u002F\u002F This is the #1 `this` bug: passing a method as a callback loses its receiver.\n",[37,276,278],{"class":39,"line":277},26,[37,279,81],{"emptyLinePlaceholder":80},[37,281,283],{"class":39,"line":282},27,[37,284,285],{"class":43},"\u002F\u002F ── Rule 2: Explicit binding (call\u002Fapply\u002Fbind) ──\n",[37,287,289,291,294,296,300,303,306,309,311,314,316,318,320,322],{"class":39,"line":288},28,[37,290,94],{"class":93},[37,292,293],{"class":97}," greet2",[37,295,108],{"class":101},[37,297,299],{"class":298},"sCrzJ","greeting",[37,301,302],{"class":101},") { ",[37,304,305],{"class":93},"return",[37,307,308],{"class":167}," `${",[37,310,299],{"class":101},[37,312,313],{"class":167},"}, ${",[37,315,17],{"class":111},[37,317,191],{"class":167},[37,319,194],{"class":101},[37,321,197],{"class":167},[37,323,324],{"class":101},"; }\n",[37,326,328,330,333,335,338,341],{"class":39,"line":327},29,[37,329,149],{"class":93},[37,331,332],{"class":111}," user",[37,334,155],{"class":93},[37,336,337],{"class":101}," { name: ",[37,339,340],{"class":167},"\"Bob\"",[37,342,343],{"class":101}," };\n",[37,345,347,350,353,356,359,362],{"class":39,"line":346},30,[37,348,349],{"class":101},"greet2.",[37,351,352],{"class":97},"call",[37,354,355],{"class":101},"(user, ",[37,357,358],{"class":167},"\"Hi\"",[37,360,361],{"class":101},");     ",[37,363,364],{"class":43},"\u002F\u002F \"Hi, Bob\" — call: this=user, args passed individually\n",[37,366,368,370,373,376,378,381],{"class":39,"line":367},31,[37,369,349],{"class":101},[37,371,372],{"class":97},"apply",[37,374,375],{"class":101},"(user, [",[37,377,358],{"class":167},[37,379,380],{"class":101},"]);  ",[37,382,383],{"class":43},"\u002F\u002F \"Hi, Bob\" — apply: this=user, args as array\n",[37,385,387,389,392,394,397,400,403],{"class":39,"line":386},32,[37,388,149],{"class":93},[37,390,391],{"class":111}," bound",[37,393,155],{"class":93},[37,395,396],{"class":101}," greet2.",[37,398,399],{"class":97},"bind",[37,401,402],{"class":101},"(user);  ",[37,404,405],{"class":43},"\u002F\u002F bind: creates a NEW function with this permanently set\n",[37,407,409,412,414,417,420],{"class":39,"line":408},33,[37,410,411],{"class":97},"bound",[37,413,108],{"class":101},[37,415,416],{"class":167},"\"Hello\"",[37,418,419],{"class":101},");  ",[37,421,422],{"class":43},"\u002F\u002F \"Hello, Bob\" — this is always user (can't be changed)\n",[37,424,426],{"class":39,"line":425},34,[37,427,81],{"emptyLinePlaceholder":80},[37,429,431],{"class":39,"line":430},35,[37,432,433],{"class":43},"\u002F\u002F ── Rule 1: `new` binding (constructor call) ──\n",[37,435,437,439,442,444,446],{"class":39,"line":436},36,[37,438,94],{"class":93},[37,440,441],{"class":97}," Person",[37,443,108],{"class":101},[37,445,194],{"class":298},[37,447,448],{"class":101},") {\n",[37,450,452,455,458,461,464],{"class":39,"line":451},37,[37,453,454],{"class":111},"    this",[37,456,457],{"class":101},".name ",[37,459,460],{"class":93},"=",[37,462,463],{"class":101}," name;  ",[37,465,466],{"class":43},"\u002F\u002F `this` is the newly created object\n",[37,468,470],{"class":39,"line":469},38,[37,471,472],{"class":101},"}\n",[37,474,476,478,481,483,486,488,490,492],{"class":39,"line":475},39,[37,477,149],{"class":93},[37,479,480],{"class":111}," alice",[37,482,155],{"class":93},[37,484,485],{"class":93}," new",[37,487,441],{"class":97},[37,489,108],{"class":101},[37,491,168],{"class":167},[37,493,494],{"class":101},");\n",[37,496,498,501,503,506],{"class":39,"line":497},40,[37,499,500],{"class":101},"console.",[37,502,105],{"class":97},[37,504,505],{"class":101},"(alice.name);  ",[37,507,508],{"class":43},"\u002F\u002F \"Alice\" — `this` was the new object created by `new`\n",[37,510,512],{"class":39,"line":511},41,[37,513,514],{"class":43},"\u002F\u002F `new` creates a fresh object, calls Person with `this` = that object, returns it\n",[20,516,518,519,521],{"id":517},"arrow-functions-lexical-this-not-affected-by-the-four-rules","Arrow Functions: Lexical ",[15,520,17],{}," (Not Affected by the Four Rules)",[25,523,524],{"language":27},[29,525,527],{"className":31,"code":526,"language":27,"meta":33,"style":33},"\u002F\u002F ── Arrow functions DON'T have their own `this` — they inherit from the enclosing scope ──\n\u002F\u002F The four binding rules do NOT apply to arrows.\n\u002F\u002F Arrow `this` is determined at DEFINITION time (lexical), not at call time (dynamic).\n\nconst obj = {\n    name: \"Alice\",\n    \u002F\u002F Regular function: dynamic `this` (rule 3 — implicit binding)\n    regularGreet() { console.log(`Hello, ${this.name}`); },\n\n    \u002F\u002F Arrow function: lexical `this` (inherits from obj's scope → the module scope)\n    arrowGreet: () => console.log(`Hello, ${this.name}`),  \u002F\u002F this.name is undefined!\n    \u002F\u002F The arrow's `this` is the enclosing scope's `this` — which is the module\u002Fglobal scope.\n    \u002F\u002F The module scope's `this` is undefined (strict mode) or global object (sloppy).\n    \u002F\u002F obj is NOT the enclosing scope — obj is an object literal, not a function scope.\n};\n\nobj.regularGreet();  \u002F\u002F \"Hello, Alice\" — this = obj (implicit binding)\nobj.arrowGreet();    \u002F\u002F \"Hello, undefined\" — this = enclosing scope (lexical, NOT obj)\n\n\u002F\u002F ── Where arrows ARE useful: callbacks inside methods ──\nconst counter = {\n    count: 0,\n    increment() {\n        \u002F\u002F `this` here is counter (implicit binding via method call)\n        [1, 2, 3].forEach(() => {\n            this.count++;  \u002F\u002F ✓ arrow inherits `this` from increment() → counter\n            \u002F\u002F If this were a regular function, `this` would be lost (default binding)\n        });\n    },\n};\ncounter.increment();\nconsole.log(counter.count);  \u002F\u002F 3\n\n\u002F\u002F ── Arrow `this` can't be overridden by call\u002Fapply\u002Fbind ──\nconst arrow = () => console.log(this);\narrow.call({ name: \"forced\" });  \u002F\u002F `this` is STILL the lexical scope (ignored call's first arg)\n\u002F\u002F Arrows ignore explicit binding — their `this` is permanently lexical.\n",[15,528,529,534,539,544,548,558,566,571,595,599,604,638,643,648,653,657,661,673,686,690,695,706,716,724,729,761,778,783,788,793,797,808,820,824,829,853,872],{"__ignoreMap":33},[37,530,531],{"class":39,"line":40},[37,532,533],{"class":43},"\u002F\u002F ── Arrow functions DON'T have their own `this` — they inherit from the enclosing scope ──\n",[37,535,536],{"class":39,"line":47},[37,537,538],{"class":43},"\u002F\u002F The four binding rules do NOT apply to arrows.\n",[37,540,541],{"class":39,"line":53},[37,542,543],{"class":43},"\u002F\u002F Arrow `this` is determined at DEFINITION time (lexical), not at call time (dynamic).\n",[37,545,546],{"class":39,"line":59},[37,547,81],{"emptyLinePlaceholder":80},[37,549,550,552,554,556],{"class":39,"line":65},[37,551,149],{"class":93},[37,553,152],{"class":111},[37,555,155],{"class":93},[37,557,158],{"class":101},[37,559,560,562,564],{"class":39,"line":71},[37,561,164],{"class":101},[37,563,168],{"class":167},[37,565,171],{"class":101},[37,567,568],{"class":39,"line":77},[37,569,570],{"class":43},"    \u002F\u002F Regular function: dynamic `this` (rule 3 — implicit binding)\n",[37,572,573,576,578,580,582,584,586,588,590,592],{"class":39,"line":84},[37,574,575],{"class":97},"    regularGreet",[37,577,102],{"class":101},[37,579,105],{"class":97},[37,581,108],{"class":101},[37,583,186],{"class":167},[37,585,17],{"class":111},[37,587,191],{"class":167},[37,589,194],{"class":101},[37,591,197],{"class":167},[37,593,594],{"class":101},"); },\n",[37,596,597],{"class":39,"line":90},[37,598,81],{"emptyLinePlaceholder":80},[37,600,601],{"class":39,"line":117},[37,602,603],{"class":43},"    \u002F\u002F Arrow function: lexical `this` (inherits from obj's scope → the module scope)\n",[37,605,606,609,612,615,618,620,622,624,626,628,630,632,635],{"class":39,"line":129},[37,607,608],{"class":97},"    arrowGreet",[37,610,611],{"class":101},": () ",[37,613,614],{"class":93},"=>",[37,616,617],{"class":101}," console.",[37,619,105],{"class":97},[37,621,108],{"class":101},[37,623,186],{"class":167},[37,625,17],{"class":111},[37,627,191],{"class":167},[37,629,194],{"class":101},[37,631,197],{"class":167},[37,633,634],{"class":101},"),  ",[37,636,637],{"class":43},"\u002F\u002F this.name is undefined!\n",[37,639,640],{"class":39,"line":135},[37,641,642],{"class":43},"    \u002F\u002F The arrow's `this` is the enclosing scope's `this` — which is the module\u002Fglobal scope.\n",[37,644,645],{"class":39,"line":140},[37,646,647],{"class":43},"    \u002F\u002F The module scope's `this` is undefined (strict mode) or global object (sloppy).\n",[37,649,650],{"class":39,"line":146},[37,651,652],{"class":43},"    \u002F\u002F obj is NOT the enclosing scope — obj is an object literal, not a function scope.\n",[37,654,655],{"class":39,"line":161},[37,656,205],{"class":101},[37,658,659],{"class":39,"line":174},[37,660,81],{"emptyLinePlaceholder":80},[37,662,663,665,668,670],{"class":39,"line":202},[37,664,211],{"class":101},[37,666,667],{"class":97},"regularGreet",[37,669,123],{"class":101},[37,671,672],{"class":43},"\u002F\u002F \"Hello, Alice\" — this = obj (implicit binding)\n",[37,674,675,677,680,683],{"class":39,"line":208},[37,676,211],{"class":101},[37,678,679],{"class":97},"arrowGreet",[37,681,682],{"class":101},"();    ",[37,684,685],{"class":43},"\u002F\u002F \"Hello, undefined\" — this = enclosing scope (lexical, NOT obj)\n",[37,687,688],{"class":39,"line":222},[37,689,81],{"emptyLinePlaceholder":80},[37,691,692],{"class":39,"line":228},[37,693,694],{"class":43},"\u002F\u002F ── Where arrows ARE useful: callbacks inside methods ──\n",[37,696,697,699,702,704],{"class":39,"line":233},[37,698,149],{"class":93},[37,700,701],{"class":111}," counter",[37,703,155],{"class":93},[37,705,158],{"class":101},[37,707,708,711,714],{"class":39,"line":239},[37,709,710],{"class":101},"    count: ",[37,712,713],{"class":111},"0",[37,715,171],{"class":101},[37,717,718,721],{"class":39,"line":255},[37,719,720],{"class":97},"    increment",[37,722,723],{"class":101},"() {\n",[37,725,726],{"class":39,"line":265},[37,727,728],{"class":43},"        \u002F\u002F `this` here is counter (implicit binding via method call)\n",[37,730,731,734,737,740,743,745,748,751,754,757,759],{"class":39,"line":271},[37,732,733],{"class":101},"        [",[37,735,736],{"class":111},"1",[37,738,739],{"class":101},", ",[37,741,742],{"class":111},"2",[37,744,739],{"class":101},[37,746,747],{"class":111},"3",[37,749,750],{"class":101},"].",[37,752,753],{"class":97},"forEach",[37,755,756],{"class":101},"(() ",[37,758,614],{"class":93},[37,760,158],{"class":101},[37,762,763,766,769,772,775],{"class":39,"line":277},[37,764,765],{"class":111},"            this",[37,767,768],{"class":101},".count",[37,770,771],{"class":93},"++",[37,773,774],{"class":101},";  ",[37,776,777],{"class":43},"\u002F\u002F ✓ arrow inherits `this` from increment() → counter\n",[37,779,780],{"class":39,"line":282},[37,781,782],{"class":43},"            \u002F\u002F If this were a regular function, `this` would be lost (default binding)\n",[37,784,785],{"class":39,"line":288},[37,786,787],{"class":101},"        });\n",[37,789,790],{"class":39,"line":327},[37,791,792],{"class":101},"    },\n",[37,794,795],{"class":39,"line":346},[37,796,205],{"class":101},[37,798,799,802,805],{"class":39,"line":367},[37,800,801],{"class":101},"counter.",[37,803,804],{"class":97},"increment",[37,806,807],{"class":101},"();\n",[37,809,810,812,814,817],{"class":39,"line":386},[37,811,500],{"class":101},[37,813,105],{"class":97},[37,815,816],{"class":101},"(counter.count);  ",[37,818,819],{"class":43},"\u002F\u002F 3\n",[37,821,822],{"class":39,"line":408},[37,823,81],{"emptyLinePlaceholder":80},[37,825,826],{"class":39,"line":425},[37,827,828],{"class":43},"\u002F\u002F ── Arrow `this` can't be overridden by call\u002Fapply\u002Fbind ──\n",[37,830,831,833,836,838,841,843,845,847,849,851],{"class":39,"line":430},[37,832,149],{"class":93},[37,834,835],{"class":97}," arrow",[37,837,155],{"class":93},[37,839,840],{"class":101}," () ",[37,842,614],{"class":93},[37,844,617],{"class":101},[37,846,105],{"class":97},[37,848,108],{"class":101},[37,850,17],{"class":111},[37,852,494],{"class":101},[37,854,855,858,860,863,866,869],{"class":39,"line":436},[37,856,857],{"class":101},"arrow.",[37,859,352],{"class":97},[37,861,862],{"class":101},"({ name: ",[37,864,865],{"class":167},"\"forced\"",[37,867,868],{"class":101}," });  ",[37,870,871],{"class":43},"\u002F\u002F `this` is STILL the lexical scope (ignored call's first arg)\n",[37,873,874],{"class":39,"line":451},[37,875,876],{"class":43},"\u002F\u002F Arrows ignore explicit binding — their `this` is permanently lexical.\n",[20,878,880,881,883],{"id":879},"anti-pattern-lost-this-in-callbacks","Anti-Pattern: Lost ",[15,882,17],{}," in Callbacks",[25,885,886],{"language":27},[29,887,889],{"className":31,"code":888,"language":27,"meta":33,"style":33},"\u002F\u002F ❌ NAIVE — regular function as callback loses `this`\nclass Timer {\n    constructor() {\n        this.seconds = 0;\n    }\n    start() {\n        setInterval(function() {\n            this.seconds++;  \u002F\u002F ✗ `this` is NOT the Timer instance (default binding → global)\n            \u002F\u002F In a regular function passed to setInterval, `this` is the global object\n            console.log(this.seconds);  \u002F\u002F NaN (global.seconds is undefined → undefined+1 = NaN)\n        }, 1000);\n    }\n}\n\u002F\u002F new Timer().start();  \u002F\u002F logs NaN every second (this.seconds is undefined)\n\n\u002F\u002F ✅ CORRECT — arrow function preserves `this` (lexical binding)\nclass Timer2 {\n    constructor() { this.seconds = 0; }\n    start() {\n        setInterval(() => {\n            this.seconds++;  \u002F\u002F ✓ `this` is the Timer2 instance (lexical from start())\n            console.log(this.seconds);\n        }, 1000);\n    }\n}\n\n\u002F\u002F ✅ ALSO CORRECT — bind the regular function\nclass Timer3 {\n    constructor() { this.seconds = 0; }\n    start() {\n        setInterval(function() {\n            this.seconds++;\n        }.bind(this), 1000);  \u002F\u002F bind creates a new function with `this` permanently set\n    }\n}\n\n\u002F\u002F ✅ ALSO CORRECT — save `this` to a variable (pre-ES6 pattern)\nclass Timer4 {\n    constructor() { this.seconds = 0; }\n    start() {\n        const self = this;  \u002F\u002F save reference to `this`\n        setInterval(function() {\n            self.seconds++;  \u002F\u002F use self (closure captures the outer this)\n        }, 1000);\n    }\n}\n",[15,890,891,896,906,913,929,934,941,952,966,971,988,998,1002,1006,1014,1018,1023,1032,1049,1055,1065,1078,1091,1099,1103,1107,1111,1116,1125,1141,1147,1157,1167,1188,1192,1196,1200,1205,1214,1230,1236,1254,1265,1278,1287,1292],{"__ignoreMap":33},[37,892,893],{"class":39,"line":40},[37,894,895],{"class":43},"\u002F\u002F ❌ NAIVE — regular function as callback loses `this`\n",[37,897,898,901,904],{"class":39,"line":47},[37,899,900],{"class":93},"class",[37,902,903],{"class":97}," Timer",[37,905,158],{"class":101},[37,907,908,911],{"class":39,"line":53},[37,909,910],{"class":93},"    constructor",[37,912,723],{"class":101},[37,914,915,918,921,923,926],{"class":39,"line":59},[37,916,917],{"class":111},"        this",[37,919,920],{"class":101},".seconds ",[37,922,460],{"class":93},[37,924,925],{"class":111}," 0",[37,927,928],{"class":101},";\n",[37,930,931],{"class":39,"line":65},[37,932,933],{"class":101},"    }\n",[37,935,936,939],{"class":39,"line":71},[37,937,938],{"class":97},"    start",[37,940,723],{"class":101},[37,942,943,946,948,950],{"class":39,"line":77},[37,944,945],{"class":97},"        setInterval",[37,947,108],{"class":101},[37,949,94],{"class":93},[37,951,723],{"class":101},[37,953,954,956,959,961,963],{"class":39,"line":84},[37,955,765],{"class":111},[37,957,958],{"class":101},".seconds",[37,960,771],{"class":93},[37,962,774],{"class":101},[37,964,965],{"class":43},"\u002F\u002F ✗ `this` is NOT the Timer instance (default binding → global)\n",[37,967,968],{"class":39,"line":90},[37,969,970],{"class":43},"            \u002F\u002F In a regular function passed to setInterval, `this` is the global object\n",[37,972,973,976,978,980,982,985],{"class":39,"line":117},[37,974,975],{"class":101},"            console.",[37,977,105],{"class":97},[37,979,108],{"class":101},[37,981,17],{"class":111},[37,983,984],{"class":101},".seconds);  ",[37,986,987],{"class":43},"\u002F\u002F NaN (global.seconds is undefined → undefined+1 = NaN)\n",[37,989,990,993,996],{"class":39,"line":129},[37,991,992],{"class":101},"        }, ",[37,994,995],{"class":111},"1000",[37,997,494],{"class":101},[37,999,1000],{"class":39,"line":135},[37,1001,933],{"class":101},[37,1003,1004],{"class":39,"line":140},[37,1005,472],{"class":101},[37,1007,1008,1011],{"class":39,"line":146},[37,1009,1010],{"class":43},"\u002F\u002F new Timer().start();",[37,1012,1013],{"class":43},"  \u002F\u002F logs NaN every second (this.seconds is undefined)\n",[37,1015,1016],{"class":39,"line":161},[37,1017,81],{"emptyLinePlaceholder":80},[37,1019,1020],{"class":39,"line":174},[37,1021,1022],{"class":43},"\u002F\u002F ✅ CORRECT — arrow function preserves `this` (lexical binding)\n",[37,1024,1025,1027,1030],{"class":39,"line":202},[37,1026,900],{"class":93},[37,1028,1029],{"class":97}," Timer2",[37,1031,158],{"class":101},[37,1033,1034,1036,1039,1041,1043,1045,1047],{"class":39,"line":208},[37,1035,910],{"class":93},[37,1037,1038],{"class":101},"() { ",[37,1040,17],{"class":111},[37,1042,920],{"class":101},[37,1044,460],{"class":93},[37,1046,925],{"class":111},[37,1048,324],{"class":101},[37,1050,1051,1053],{"class":39,"line":222},[37,1052,938],{"class":97},[37,1054,723],{"class":101},[37,1056,1057,1059,1061,1063],{"class":39,"line":228},[37,1058,945],{"class":97},[37,1060,756],{"class":101},[37,1062,614],{"class":93},[37,1064,158],{"class":101},[37,1066,1067,1069,1071,1073,1075],{"class":39,"line":233},[37,1068,765],{"class":111},[37,1070,958],{"class":101},[37,1072,771],{"class":93},[37,1074,774],{"class":101},[37,1076,1077],{"class":43},"\u002F\u002F ✓ `this` is the Timer2 instance (lexical from start())\n",[37,1079,1080,1082,1084,1086,1088],{"class":39,"line":239},[37,1081,975],{"class":101},[37,1083,105],{"class":97},[37,1085,108],{"class":101},[37,1087,17],{"class":111},[37,1089,1090],{"class":101},".seconds);\n",[37,1092,1093,1095,1097],{"class":39,"line":255},[37,1094,992],{"class":101},[37,1096,995],{"class":111},[37,1098,494],{"class":101},[37,1100,1101],{"class":39,"line":265},[37,1102,933],{"class":101},[37,1104,1105],{"class":39,"line":271},[37,1106,472],{"class":101},[37,1108,1109],{"class":39,"line":277},[37,1110,81],{"emptyLinePlaceholder":80},[37,1112,1113],{"class":39,"line":282},[37,1114,1115],{"class":43},"\u002F\u002F ✅ ALSO CORRECT — bind the regular function\n",[37,1117,1118,1120,1123],{"class":39,"line":288},[37,1119,900],{"class":93},[37,1121,1122],{"class":97}," Timer3",[37,1124,158],{"class":101},[37,1126,1127,1129,1131,1133,1135,1137,1139],{"class":39,"line":327},[37,1128,910],{"class":93},[37,1130,1038],{"class":101},[37,1132,17],{"class":111},[37,1134,920],{"class":101},[37,1136,460],{"class":93},[37,1138,925],{"class":111},[37,1140,324],{"class":101},[37,1142,1143,1145],{"class":39,"line":346},[37,1144,938],{"class":97},[37,1146,723],{"class":101},[37,1148,1149,1151,1153,1155],{"class":39,"line":367},[37,1150,945],{"class":97},[37,1152,108],{"class":101},[37,1154,94],{"class":93},[37,1156,723],{"class":101},[37,1158,1159,1161,1163,1165],{"class":39,"line":386},[37,1160,765],{"class":111},[37,1162,958],{"class":101},[37,1164,771],{"class":93},[37,1166,928],{"class":101},[37,1168,1169,1172,1174,1176,1178,1181,1183,1185],{"class":39,"line":408},[37,1170,1171],{"class":101},"        }.",[37,1173,399],{"class":97},[37,1175,108],{"class":101},[37,1177,17],{"class":111},[37,1179,1180],{"class":101},"), ",[37,1182,995],{"class":111},[37,1184,419],{"class":101},[37,1186,1187],{"class":43},"\u002F\u002F bind creates a new function with `this` permanently set\n",[37,1189,1190],{"class":39,"line":425},[37,1191,933],{"class":101},[37,1193,1194],{"class":39,"line":430},[37,1195,472],{"class":101},[37,1197,1198],{"class":39,"line":436},[37,1199,81],{"emptyLinePlaceholder":80},[37,1201,1202],{"class":39,"line":451},[37,1203,1204],{"class":43},"\u002F\u002F ✅ ALSO CORRECT — save `this` to a variable (pre-ES6 pattern)\n",[37,1206,1207,1209,1212],{"class":39,"line":469},[37,1208,900],{"class":93},[37,1210,1211],{"class":97}," Timer4",[37,1213,158],{"class":101},[37,1215,1216,1218,1220,1222,1224,1226,1228],{"class":39,"line":475},[37,1217,910],{"class":93},[37,1219,1038],{"class":101},[37,1221,17],{"class":111},[37,1223,920],{"class":101},[37,1225,460],{"class":93},[37,1227,925],{"class":111},[37,1229,324],{"class":101},[37,1231,1232,1234],{"class":39,"line":497},[37,1233,938],{"class":97},[37,1235,723],{"class":101},[37,1237,1238,1241,1244,1246,1249,1251],{"class":39,"line":511},[37,1239,1240],{"class":93},"        const",[37,1242,1243],{"class":111}," self",[37,1245,155],{"class":93},[37,1247,1248],{"class":111}," this",[37,1250,774],{"class":101},[37,1252,1253],{"class":43},"\u002F\u002F save reference to `this`\n",[37,1255,1257,1259,1261,1263],{"class":39,"line":1256},42,[37,1258,945],{"class":97},[37,1260,108],{"class":101},[37,1262,94],{"class":93},[37,1264,723],{"class":101},[37,1266,1268,1271,1273,1275],{"class":39,"line":1267},43,[37,1269,1270],{"class":101},"            self.seconds",[37,1272,771],{"class":93},[37,1274,774],{"class":101},[37,1276,1277],{"class":43},"\u002F\u002F use self (closure captures the outer this)\n",[37,1279,1281,1283,1285],{"class":39,"line":1280},44,[37,1282,992],{"class":101},[37,1284,995],{"class":111},[37,1286,494],{"class":101},[37,1288,1290],{"class":39,"line":1289},45,[37,1291,933],{"class":101},[37,1293,1295],{"class":39,"line":1294},46,[37,1296,472],{"class":101},[20,1298,1300,739,1302,1304,1305,1307],{"id":1299},"call-apply-and-bind-internals",[15,1301,352],{},[15,1303,372],{},", and ",[15,1306,399],{}," Internals",[25,1309,1310],{"language":27},[29,1311,1313],{"className":31,"code":1312,"language":27,"meta":33,"style":33},"\u002F\u002F ── call: invoke with this and individual args ──\nfunction introduce(greeting, punctuation) {\n    return `${greeting}, I'm ${this.name}${punctuation}`;\n}\nintroduce.call({ name: \"Alice\" }, \"Hello\", \"!\");  \u002F\u002F \"Hello, I'm Alice!\"\n\n\u002F\u002F ── apply: invoke with this and args as array ──\nintroduce.apply({ name: \"Bob\" }, [\"Hi\", \"?\"]);  \u002F\u002F \"Hi, I'm Bob?\"\n\n\u002F\u002F ── bind: create a new function with permanent this (and optional pre-filled args) ──\nconst aliceIntroduce = introduce.bind({ name: \"Charlie\" }, \"Hey\");\naliceIntroduce(\".\");  \u002F\u002F \"Hey, I'm Charlie.\" (greeting pre-filled, punctuation passed at call)\n\u002F\u002F bind doesn't invoke immediately — it returns a new function\n\n\u002F\u002F ── Partial application with bind (pre-fill args) ──\nfunction add(a, b, c) { return a + b + c; }\nconst add5 = add.bind(null, 5);  \u002F\u002F first arg = 5 (null for this — don't care)\nadd5(10, 20);  \u002F\u002F 35 (5 + 10 + 20)\n\n\u002F\u002F ── Borrowing methods (use another object's method on your object) ──\nconst arrayLike = { 0: \"a\", 1: \"b\", length: 2 };\n\u002F\u002F arrayLike doesn't have .join, but Array.prototype does:\nArray.prototype.join.call(arrayLike, \"-\");  \u002F\u002F \"a-b\" (borrows Array.join, this = arrayLike)\n\n\u002F\u002F ── Hard binding (bind can't be undone) ──\nconst bound = introduce.bind({ name: \"Hard\" });\n\u002F\u002F bound.call({ name: \"Override\" });  \u002F\u002F `this` is STILL { name: \"Hard\" } (bind is permanent)\n\u002F\u002F bind creates a wrapper function that ignores the call's `this` and uses the bound one.\n",[15,1314,1315,1320,1338,1365,1369,1395,1399,1404,1429,1433,1438,1464,1479,1484,1488,1493,1533,1562,1582,1586,1591,1627,1632,1658,1662,1667,1687,1695],{"__ignoreMap":33},[37,1316,1317],{"class":39,"line":40},[37,1318,1319],{"class":43},"\u002F\u002F ── call: invoke with this and individual args ──\n",[37,1321,1322,1324,1327,1329,1331,1333,1336],{"class":39,"line":47},[37,1323,94],{"class":93},[37,1325,1326],{"class":97}," introduce",[37,1328,108],{"class":101},[37,1330,299],{"class":298},[37,1332,739],{"class":101},[37,1334,1335],{"class":298},"punctuation",[37,1337,448],{"class":101},[37,1339,1340,1343,1345,1347,1350,1352,1354,1356,1359,1361,1363],{"class":39,"line":53},[37,1341,1342],{"class":93},"    return",[37,1344,308],{"class":167},[37,1346,299],{"class":101},[37,1348,1349],{"class":167},"}, I'm ${",[37,1351,17],{"class":111},[37,1353,191],{"class":167},[37,1355,194],{"class":101},[37,1357,1358],{"class":167},"}${",[37,1360,1335],{"class":101},[37,1362,197],{"class":167},[37,1364,928],{"class":101},[37,1366,1367],{"class":39,"line":59},[37,1368,472],{"class":101},[37,1370,1371,1374,1376,1378,1380,1383,1385,1387,1390,1392],{"class":39,"line":65},[37,1372,1373],{"class":101},"introduce.",[37,1375,352],{"class":97},[37,1377,862],{"class":101},[37,1379,168],{"class":167},[37,1381,1382],{"class":101}," }, ",[37,1384,416],{"class":167},[37,1386,739],{"class":101},[37,1388,1389],{"class":167},"\"!\"",[37,1391,419],{"class":101},[37,1393,1394],{"class":43},"\u002F\u002F \"Hello, I'm Alice!\"\n",[37,1396,1397],{"class":39,"line":71},[37,1398,81],{"emptyLinePlaceholder":80},[37,1400,1401],{"class":39,"line":77},[37,1402,1403],{"class":43},"\u002F\u002F ── apply: invoke with this and args as array ──\n",[37,1405,1406,1408,1410,1412,1414,1417,1419,1421,1424,1426],{"class":39,"line":84},[37,1407,1373],{"class":101},[37,1409,372],{"class":97},[37,1411,862],{"class":101},[37,1413,340],{"class":167},[37,1415,1416],{"class":101}," }, [",[37,1418,358],{"class":167},[37,1420,739],{"class":101},[37,1422,1423],{"class":167},"\"?\"",[37,1425,380],{"class":101},[37,1427,1428],{"class":43},"\u002F\u002F \"Hi, I'm Bob?\"\n",[37,1430,1431],{"class":39,"line":90},[37,1432,81],{"emptyLinePlaceholder":80},[37,1434,1435],{"class":39,"line":117},[37,1436,1437],{"class":43},"\u002F\u002F ── bind: create a new function with permanent this (and optional pre-filled args) ──\n",[37,1439,1440,1442,1445,1447,1450,1452,1454,1457,1459,1462],{"class":39,"line":129},[37,1441,149],{"class":93},[37,1443,1444],{"class":111}," aliceIntroduce",[37,1446,155],{"class":93},[37,1448,1449],{"class":101}," introduce.",[37,1451,399],{"class":97},[37,1453,862],{"class":101},[37,1455,1456],{"class":167},"\"Charlie\"",[37,1458,1382],{"class":101},[37,1460,1461],{"class":167},"\"Hey\"",[37,1463,494],{"class":101},[37,1465,1466,1469,1471,1474,1476],{"class":39,"line":135},[37,1467,1468],{"class":97},"aliceIntroduce",[37,1470,108],{"class":101},[37,1472,1473],{"class":167},"\".\"",[37,1475,419],{"class":101},[37,1477,1478],{"class":43},"\u002F\u002F \"Hey, I'm Charlie.\" (greeting pre-filled, punctuation passed at call)\n",[37,1480,1481],{"class":39,"line":140},[37,1482,1483],{"class":43},"\u002F\u002F bind doesn't invoke immediately — it returns a new function\n",[37,1485,1486],{"class":39,"line":146},[37,1487,81],{"emptyLinePlaceholder":80},[37,1489,1490],{"class":39,"line":161},[37,1491,1492],{"class":43},"\u002F\u002F ── Partial application with bind (pre-fill args) ──\n",[37,1494,1495,1497,1500,1502,1505,1507,1510,1512,1515,1517,1519,1522,1525,1528,1530],{"class":39,"line":174},[37,1496,94],{"class":93},[37,1498,1499],{"class":97}," add",[37,1501,108],{"class":101},[37,1503,1504],{"class":298},"a",[37,1506,739],{"class":101},[37,1508,1509],{"class":298},"b",[37,1511,739],{"class":101},[37,1513,1514],{"class":298},"c",[37,1516,302],{"class":101},[37,1518,305],{"class":93},[37,1520,1521],{"class":101}," a ",[37,1523,1524],{"class":93},"+",[37,1526,1527],{"class":101}," b ",[37,1529,1524],{"class":93},[37,1531,1532],{"class":101}," c; }\n",[37,1534,1535,1537,1540,1542,1545,1547,1549,1552,1554,1557,1559],{"class":39,"line":202},[37,1536,149],{"class":93},[37,1538,1539],{"class":111}," add5",[37,1541,155],{"class":93},[37,1543,1544],{"class":101}," add.",[37,1546,399],{"class":97},[37,1548,108],{"class":101},[37,1550,1551],{"class":111},"null",[37,1553,739],{"class":101},[37,1555,1556],{"class":111},"5",[37,1558,419],{"class":101},[37,1560,1561],{"class":43},"\u002F\u002F first arg = 5 (null for this — don't care)\n",[37,1563,1564,1567,1569,1572,1574,1577,1579],{"class":39,"line":208},[37,1565,1566],{"class":97},"add5",[37,1568,108],{"class":101},[37,1570,1571],{"class":111},"10",[37,1573,739],{"class":101},[37,1575,1576],{"class":111},"20",[37,1578,419],{"class":101},[37,1580,1581],{"class":43},"\u002F\u002F 35 (5 + 10 + 20)\n",[37,1583,1584],{"class":39,"line":222},[37,1585,81],{"emptyLinePlaceholder":80},[37,1587,1588],{"class":39,"line":228},[37,1589,1590],{"class":43},"\u002F\u002F ── Borrowing methods (use another object's method on your object) ──\n",[37,1592,1593,1595,1598,1600,1603,1605,1608,1611,1613,1615,1617,1620,1623,1625],{"class":39,"line":233},[37,1594,149],{"class":93},[37,1596,1597],{"class":111}," arrayLike",[37,1599,155],{"class":93},[37,1601,1602],{"class":101}," { ",[37,1604,713],{"class":111},[37,1606,1607],{"class":101},": ",[37,1609,1610],{"class":167},"\"a\"",[37,1612,739],{"class":101},[37,1614,736],{"class":111},[37,1616,1607],{"class":101},[37,1618,1619],{"class":167},"\"b\"",[37,1621,1622],{"class":101},", length: ",[37,1624,742],{"class":111},[37,1626,343],{"class":101},[37,1628,1629],{"class":39,"line":239},[37,1630,1631],{"class":43},"\u002F\u002F arrayLike doesn't have .join, but Array.prototype does:\n",[37,1633,1634,1637,1639,1642,1645,1647,1650,1653,1655],{"class":39,"line":255},[37,1635,1636],{"class":111},"Array",[37,1638,191],{"class":101},[37,1640,1641],{"class":111},"prototype",[37,1643,1644],{"class":101},".join.",[37,1646,352],{"class":97},[37,1648,1649],{"class":101},"(arrayLike, ",[37,1651,1652],{"class":167},"\"-\"",[37,1654,419],{"class":101},[37,1656,1657],{"class":43},"\u002F\u002F \"a-b\" (borrows Array.join, this = arrayLike)\n",[37,1659,1660],{"class":39,"line":265},[37,1661,81],{"emptyLinePlaceholder":80},[37,1663,1664],{"class":39,"line":271},[37,1665,1666],{"class":43},"\u002F\u002F ── Hard binding (bind can't be undone) ──\n",[37,1668,1669,1671,1673,1675,1677,1679,1681,1684],{"class":39,"line":277},[37,1670,149],{"class":93},[37,1672,391],{"class":111},[37,1674,155],{"class":93},[37,1676,1449],{"class":101},[37,1678,399],{"class":97},[37,1680,862],{"class":101},[37,1682,1683],{"class":167},"\"Hard\"",[37,1685,1686],{"class":101}," });\n",[37,1688,1689,1692],{"class":39,"line":282},[37,1690,1691],{"class":43},"\u002F\u002F bound.call({ name: \"Override\" });",[37,1693,1694],{"class":43},"  \u002F\u002F `this` is STILL { name: \"Hard\" } (bind is permanent)\n",[37,1696,1697],{"class":39,"line":288},[37,1698,1699],{"class":43},"\u002F\u002F bind creates a wrapper function that ignores the call's `this` and uses the bound one.\n",[20,1701,1703,1704,1706],{"id":1702},"production-pattern-event-handler-this-management","Production Pattern: Event Handler ",[15,1705,17],{}," Management",[25,1708,1709],{"language":27},[29,1710,1712],{"className":31,"code":1711,"language":27,"meta":33,"style":33},"\u002F\u002F ── In event handlers, `this` is the element that triggered the event ──\n\u002F\u002F ── Arrow function event handlers: `this` is NOT the element (lexical!) ──\n\nclass ButtonController {\n    constructor(button) {\n        this.button = button;\n        this.clickCount = 0;\n\n        \u002F\u002F ❌ Regular function: `this` is the button element (not the controller)\n        \u002F\u002F this.button.addEventListener(\"click\", function() {\n        \u002F\u002F     this.clickCount++;  \u002F\u002F ✗ this is the button, not the controller\n        \u002F\u002F });\n\n        \u002F\u002F ✅ Arrow function: `this` is the controller (lexical)\n        this.button.addEventListener(\"click\", () => {\n            this.clickCount++;  \u002F\u002F ✓ this is the controller\n            this.updateLabel();\n        });\n\n        \u002F\u002F ✅ Alternative: bind the regular function\n        this.button.addEventListener(\"click\", this.handleClick.bind(this));\n    }\n\n    handleClick() {\n        this.clickCount++;  \u002F\u002F this is the controller (bound)\n        \u002F\u002F Note: `this.button` inside is the controller's button, not the event target\n        \u002F\u002F If you need the event target: use event.currentTarget\n    }\n\n    updateLabel() {\n        this.button.textContent = `Clicked ${this.clickCount} times`;\n    }\n}\n\n\u002F\u002F ── When you DO need `this` to be the element (e.g., accessing dataset) ──\ndocument.querySelectorAll(\".item\").forEach(function(el) {\n    \u002F\u002F Regular function in forEach: `this` is undefined\u002Fglobal (NOT el)\n    el.addEventListener(\"click\", function(event) {\n        \u002F\u002F `this` is the clicked element (event handler binding)\n        console.log(this.dataset.id);  \u002F\u002F ✓ this is the element\n    });\n});\n",[15,1713,1714,1719,1724,1728,1737,1748,1760,1773,1777,1782,1787,1795,1800,1804,1809,1831,1845,1856,1860,1864,1869,1897,1901,1905,1912,1925,1930,1935,1939,1943,1950,1974,1978,1982,1986,1991,2020,2025,2047,2052,2069,2074],{"__ignoreMap":33},[37,1715,1716],{"class":39,"line":40},[37,1717,1718],{"class":43},"\u002F\u002F ── In event handlers, `this` is the element that triggered the event ──\n",[37,1720,1721],{"class":39,"line":47},[37,1722,1723],{"class":43},"\u002F\u002F ── Arrow function event handlers: `this` is NOT the element (lexical!) ──\n",[37,1725,1726],{"class":39,"line":53},[37,1727,81],{"emptyLinePlaceholder":80},[37,1729,1730,1732,1735],{"class":39,"line":59},[37,1731,900],{"class":93},[37,1733,1734],{"class":97}," ButtonController",[37,1736,158],{"class":101},[37,1738,1739,1741,1743,1746],{"class":39,"line":65},[37,1740,910],{"class":93},[37,1742,108],{"class":101},[37,1744,1745],{"class":298},"button",[37,1747,448],{"class":101},[37,1749,1750,1752,1755,1757],{"class":39,"line":71},[37,1751,917],{"class":111},[37,1753,1754],{"class":101},".button ",[37,1756,460],{"class":93},[37,1758,1759],{"class":101}," button;\n",[37,1761,1762,1764,1767,1769,1771],{"class":39,"line":77},[37,1763,917],{"class":111},[37,1765,1766],{"class":101},".clickCount ",[37,1768,460],{"class":93},[37,1770,925],{"class":111},[37,1772,928],{"class":101},[37,1774,1775],{"class":39,"line":84},[37,1776,81],{"emptyLinePlaceholder":80},[37,1778,1779],{"class":39,"line":90},[37,1780,1781],{"class":43},"        \u002F\u002F ❌ Regular function: `this` is the button element (not the controller)\n",[37,1783,1784],{"class":39,"line":117},[37,1785,1786],{"class":43},"        \u002F\u002F this.button.addEventListener(\"click\", function() {\n",[37,1788,1789,1792],{"class":39,"line":129},[37,1790,1791],{"class":43},"        \u002F\u002F     this.clickCount++;",[37,1793,1794],{"class":43},"  \u002F\u002F ✗ this is the button, not the controller\n",[37,1796,1797],{"class":39,"line":135},[37,1798,1799],{"class":43},"        \u002F\u002F });\n",[37,1801,1802],{"class":39,"line":140},[37,1803,81],{"emptyLinePlaceholder":80},[37,1805,1806],{"class":39,"line":146},[37,1807,1808],{"class":43},"        \u002F\u002F ✅ Arrow function: `this` is the controller (lexical)\n",[37,1810,1811,1813,1816,1819,1821,1824,1827,1829],{"class":39,"line":161},[37,1812,917],{"class":111},[37,1814,1815],{"class":101},".button.",[37,1817,1818],{"class":97},"addEventListener",[37,1820,108],{"class":101},[37,1822,1823],{"class":167},"\"click\"",[37,1825,1826],{"class":101},", () ",[37,1828,614],{"class":93},[37,1830,158],{"class":101},[37,1832,1833,1835,1838,1840,1842],{"class":39,"line":174},[37,1834,765],{"class":111},[37,1836,1837],{"class":101},".clickCount",[37,1839,771],{"class":93},[37,1841,774],{"class":101},[37,1843,1844],{"class":43},"\u002F\u002F ✓ this is the controller\n",[37,1846,1847,1849,1851,1854],{"class":39,"line":202},[37,1848,765],{"class":111},[37,1850,191],{"class":101},[37,1852,1853],{"class":97},"updateLabel",[37,1855,807],{"class":101},[37,1857,1858],{"class":39,"line":208},[37,1859,787],{"class":101},[37,1861,1862],{"class":39,"line":222},[37,1863,81],{"emptyLinePlaceholder":80},[37,1865,1866],{"class":39,"line":228},[37,1867,1868],{"class":43},"        \u002F\u002F ✅ Alternative: bind the regular function\n",[37,1870,1871,1873,1875,1877,1879,1881,1883,1885,1888,1890,1892,1894],{"class":39,"line":233},[37,1872,917],{"class":111},[37,1874,1815],{"class":101},[37,1876,1818],{"class":97},[37,1878,108],{"class":101},[37,1880,1823],{"class":167},[37,1882,739],{"class":101},[37,1884,17],{"class":111},[37,1886,1887],{"class":101},".handleClick.",[37,1889,399],{"class":97},[37,1891,108],{"class":101},[37,1893,17],{"class":111},[37,1895,1896],{"class":101},"));\n",[37,1898,1899],{"class":39,"line":239},[37,1900,933],{"class":101},[37,1902,1903],{"class":39,"line":255},[37,1904,81],{"emptyLinePlaceholder":80},[37,1906,1907,1910],{"class":39,"line":265},[37,1908,1909],{"class":97},"    handleClick",[37,1911,723],{"class":101},[37,1913,1914,1916,1918,1920,1922],{"class":39,"line":271},[37,1915,917],{"class":111},[37,1917,1837],{"class":101},[37,1919,771],{"class":93},[37,1921,774],{"class":101},[37,1923,1924],{"class":43},"\u002F\u002F this is the controller (bound)\n",[37,1926,1927],{"class":39,"line":277},[37,1928,1929],{"class":43},"        \u002F\u002F Note: `this.button` inside is the controller's button, not the event target\n",[37,1931,1932],{"class":39,"line":282},[37,1933,1934],{"class":43},"        \u002F\u002F If you need the event target: use event.currentTarget\n",[37,1936,1937],{"class":39,"line":288},[37,1938,933],{"class":101},[37,1940,1941],{"class":39,"line":327},[37,1942,81],{"emptyLinePlaceholder":80},[37,1944,1945,1948],{"class":39,"line":346},[37,1946,1947],{"class":97},"    updateLabel",[37,1949,723],{"class":101},[37,1951,1952,1954,1957,1959,1962,1964,1966,1969,1972],{"class":39,"line":367},[37,1953,917],{"class":111},[37,1955,1956],{"class":101},".button.textContent ",[37,1958,460],{"class":93},[37,1960,1961],{"class":167}," `Clicked ${",[37,1963,17],{"class":111},[37,1965,191],{"class":167},[37,1967,1968],{"class":101},"clickCount",[37,1970,1971],{"class":167},"} times`",[37,1973,928],{"class":101},[37,1975,1976],{"class":39,"line":386},[37,1977,933],{"class":101},[37,1979,1980],{"class":39,"line":408},[37,1981,472],{"class":101},[37,1983,1984],{"class":39,"line":425},[37,1985,81],{"emptyLinePlaceholder":80},[37,1987,1988],{"class":39,"line":430},[37,1989,1990],{"class":43},"\u002F\u002F ── When you DO need `this` to be the element (e.g., accessing dataset) ──\n",[37,1992,1993,1996,1999,2001,2004,2007,2009,2011,2013,2015,2018],{"class":39,"line":436},[37,1994,1995],{"class":101},"document.",[37,1997,1998],{"class":97},"querySelectorAll",[37,2000,108],{"class":101},[37,2002,2003],{"class":167},"\".item\"",[37,2005,2006],{"class":101},").",[37,2008,753],{"class":97},[37,2010,108],{"class":101},[37,2012,94],{"class":93},[37,2014,108],{"class":101},[37,2016,2017],{"class":298},"el",[37,2019,448],{"class":101},[37,2021,2022],{"class":39,"line":451},[37,2023,2024],{"class":43},"    \u002F\u002F Regular function in forEach: `this` is undefined\u002Fglobal (NOT el)\n",[37,2026,2027,2030,2032,2034,2036,2038,2040,2042,2045],{"class":39,"line":469},[37,2028,2029],{"class":101},"    el.",[37,2031,1818],{"class":97},[37,2033,108],{"class":101},[37,2035,1823],{"class":167},[37,2037,739],{"class":101},[37,2039,94],{"class":93},[37,2041,108],{"class":101},[37,2043,2044],{"class":298},"event",[37,2046,448],{"class":101},[37,2048,2049],{"class":39,"line":475},[37,2050,2051],{"class":43},"        \u002F\u002F `this` is the clicked element (event handler binding)\n",[37,2053,2054,2057,2059,2061,2063,2066],{"class":39,"line":497},[37,2055,2056],{"class":101},"        console.",[37,2058,105],{"class":97},[37,2060,108],{"class":101},[37,2062,17],{"class":111},[37,2064,2065],{"class":101},".dataset.id);  ",[37,2067,2068],{"class":43},"\u002F\u002F ✓ this is the element\n",[37,2070,2071],{"class":39,"line":511},[37,2072,2073],{"class":101},"    });\n",[37,2075,2076],{"class":39,"line":1256},[37,2077,2078],{"class":101},"});\n",[20,2080,2082],{"id":2081},"tips-tricks","💡 Tips & Tricks",[25,2084,2085],{"language":27},[29,2086,2088],{"className":31,"code":2087,"language":27,"meta":33,"style":33},"\u002F\u002F ── `this` in class fields: arrow vs regular method ──\nclass Counter {\n    count = 0;\n\n    \u002F\u002F Regular method: `this` is dynamic (depends on call site)\n    increment() { this.count++; }\n\n    \u002F\u002F Class field arrow: `this` is bound to the instance (lexical, permanent)\n    \u002F\u002F Useful for callbacks: `button.onclick = counter.incrementArrow`\n    incrementArrow = () => { this.count++; };\n}\nconst c = new Counter();\nconst detached = c.increment;\n\u002F\u002F detached();  \u002F\u002F ✗ TypeError: this is undefined (lost the receiver)\nconst detachedArrow = c.incrementArrow;\ndetachedArrow();  \u002F\u002F ✓ works (arrow has permanent this = c)\n\n\u002F\u002F ── `this.constructor` for accessing the class from an instance ──\nclass Animal {\n    reproduce() { return new this.constructor(); }  \u002F\u002F creates same type as the instance\n}\nclass Dog extends Animal {}\nconst puppy = new Dog().reproduce();  \u002F\u002F puppy is a Dog (this.constructor = Dog)\n\n\u002F\u002F ── `new.target` for detecting constructor calls ──\nfunction Base() {\n    if (!new.target) throw new Error(\"must call with new\");\n    \u002F\u002F new.target is undefined if called without `new`\n    \u002F\u002F new.target is the constructor if called with `new`\n}\n\u002F\u002F Base();  \u002F\u002F throws\nnew Base();  \u002F\u002F works\n\n\u002F\u002F ── Avoid `this` entirely with arrow functions and closures ──\nconst createCounter = () => {\n    let count = 0;  \u002F\u002F private state (closure)\n    return {\n        increment: () => ++count,   \u002F\u002F arrow — no `this` needed\n        get count() { return count; },  \u002F\u002F getter\n    };\n};\n",[15,2089,2090,2095,2104,2115,2119,2124,2138,2142,2147,2152,2174,2178,2193,2205,2213,2225,2235,2239,2244,2253,2277,2281,2296,2320,2324,2329,2338,2372,2377,2382,2386,2394,2406,2410,2415,2430,2447,2453,2471,2489,2494],{"__ignoreMap":33},[37,2091,2092],{"class":39,"line":40},[37,2093,2094],{"class":43},"\u002F\u002F ── `this` in class fields: arrow vs regular method ──\n",[37,2096,2097,2099,2102],{"class":39,"line":47},[37,2098,900],{"class":93},[37,2100,2101],{"class":97}," Counter",[37,2103,158],{"class":101},[37,2105,2106,2109,2111,2113],{"class":39,"line":53},[37,2107,2108],{"class":298},"    count",[37,2110,155],{"class":93},[37,2112,925],{"class":111},[37,2114,928],{"class":101},[37,2116,2117],{"class":39,"line":59},[37,2118,81],{"emptyLinePlaceholder":80},[37,2120,2121],{"class":39,"line":65},[37,2122,2123],{"class":43},"    \u002F\u002F Regular method: `this` is dynamic (depends on call site)\n",[37,2125,2126,2128,2130,2132,2134,2136],{"class":39,"line":71},[37,2127,720],{"class":97},[37,2129,1038],{"class":101},[37,2131,17],{"class":111},[37,2133,768],{"class":101},[37,2135,771],{"class":93},[37,2137,324],{"class":101},[37,2139,2140],{"class":39,"line":77},[37,2141,81],{"emptyLinePlaceholder":80},[37,2143,2144],{"class":39,"line":84},[37,2145,2146],{"class":43},"    \u002F\u002F Class field arrow: `this` is bound to the instance (lexical, permanent)\n",[37,2148,2149],{"class":39,"line":90},[37,2150,2151],{"class":43},"    \u002F\u002F Useful for callbacks: `button.onclick = counter.incrementArrow`\n",[37,2153,2154,2157,2159,2161,2163,2165,2167,2169,2171],{"class":39,"line":117},[37,2155,2156],{"class":97},"    incrementArrow",[37,2158,155],{"class":93},[37,2160,840],{"class":101},[37,2162,614],{"class":93},[37,2164,1602],{"class":101},[37,2166,17],{"class":111},[37,2168,768],{"class":101},[37,2170,771],{"class":93},[37,2172,2173],{"class":101},"; };\n",[37,2175,2176],{"class":39,"line":129},[37,2177,472],{"class":101},[37,2179,2180,2182,2185,2187,2189,2191],{"class":39,"line":135},[37,2181,149],{"class":93},[37,2183,2184],{"class":111}," c",[37,2186,155],{"class":93},[37,2188,485],{"class":93},[37,2190,2101],{"class":97},[37,2192,807],{"class":101},[37,2194,2195,2197,2200,2202],{"class":39,"line":140},[37,2196,149],{"class":93},[37,2198,2199],{"class":111}," detached",[37,2201,155],{"class":93},[37,2203,2204],{"class":101}," c.increment;\n",[37,2206,2207,2210],{"class":39,"line":146},[37,2208,2209],{"class":43},"\u002F\u002F detached();",[37,2211,2212],{"class":43},"  \u002F\u002F ✗ TypeError: this is undefined (lost the receiver)\n",[37,2214,2215,2217,2220,2222],{"class":39,"line":161},[37,2216,149],{"class":93},[37,2218,2219],{"class":111}," detachedArrow",[37,2221,155],{"class":93},[37,2223,2224],{"class":101}," c.incrementArrow;\n",[37,2226,2227,2230,2232],{"class":39,"line":174},[37,2228,2229],{"class":97},"detachedArrow",[37,2231,123],{"class":101},[37,2233,2234],{"class":43},"\u002F\u002F ✓ works (arrow has permanent this = c)\n",[37,2236,2237],{"class":39,"line":202},[37,2238,81],{"emptyLinePlaceholder":80},[37,2240,2241],{"class":39,"line":208},[37,2242,2243],{"class":43},"\u002F\u002F ── `this.constructor` for accessing the class from an instance ──\n",[37,2245,2246,2248,2251],{"class":39,"line":222},[37,2247,900],{"class":93},[37,2249,2250],{"class":97}," Animal",[37,2252,158],{"class":101},[37,2254,2255,2258,2260,2262,2264,2266,2268,2271,2274],{"class":39,"line":228},[37,2256,2257],{"class":97},"    reproduce",[37,2259,1038],{"class":101},[37,2261,305],{"class":93},[37,2263,485],{"class":93},[37,2265,1248],{"class":111},[37,2267,191],{"class":101},[37,2269,2270],{"class":97},"constructor",[37,2272,2273],{"class":101},"(); }  ",[37,2275,2276],{"class":43},"\u002F\u002F creates same type as the instance\n",[37,2278,2279],{"class":39,"line":233},[37,2280,472],{"class":101},[37,2282,2283,2285,2288,2291,2293],{"class":39,"line":239},[37,2284,900],{"class":93},[37,2286,2287],{"class":97}," Dog",[37,2289,2290],{"class":93}," extends",[37,2292,2250],{"class":97},[37,2294,2295],{"class":101}," {}\n",[37,2297,2298,2300,2303,2305,2307,2309,2312,2315,2317],{"class":39,"line":255},[37,2299,149],{"class":93},[37,2301,2302],{"class":111}," puppy",[37,2304,155],{"class":93},[37,2306,485],{"class":93},[37,2308,2287],{"class":97},[37,2310,2311],{"class":101},"().",[37,2313,2314],{"class":97},"reproduce",[37,2316,123],{"class":101},[37,2318,2319],{"class":43},"\u002F\u002F puppy is a Dog (this.constructor = Dog)\n",[37,2321,2322],{"class":39,"line":265},[37,2323,81],{"emptyLinePlaceholder":80},[37,2325,2326],{"class":39,"line":271},[37,2327,2328],{"class":43},"\u002F\u002F ── `new.target` for detecting constructor calls ──\n",[37,2330,2331,2333,2336],{"class":39,"line":277},[37,2332,94],{"class":93},[37,2334,2335],{"class":97}," Base",[37,2337,723],{"class":101},[37,2339,2340,2343,2346,2349,2351,2354,2357,2360,2362,2365,2367,2370],{"class":39,"line":282},[37,2341,2342],{"class":93},"    if",[37,2344,2345],{"class":101}," (",[37,2347,2348],{"class":93},"!new",[37,2350,191],{"class":101},[37,2352,2353],{"class":111},"target",[37,2355,2356],{"class":101},") ",[37,2358,2359],{"class":93},"throw",[37,2361,485],{"class":93},[37,2363,2364],{"class":97}," Error",[37,2366,108],{"class":101},[37,2368,2369],{"class":167},"\"must call with new\"",[37,2371,494],{"class":101},[37,2373,2374],{"class":39,"line":288},[37,2375,2376],{"class":43},"    \u002F\u002F new.target is undefined if called without `new`\n",[37,2378,2379],{"class":39,"line":327},[37,2380,2381],{"class":43},"    \u002F\u002F new.target is the constructor if called with `new`\n",[37,2383,2384],{"class":39,"line":346},[37,2385,472],{"class":101},[37,2387,2388,2391],{"class":39,"line":367},[37,2389,2390],{"class":43},"\u002F\u002F Base();",[37,2392,2393],{"class":43},"  \u002F\u002F throws\n",[37,2395,2396,2399,2401,2403],{"class":39,"line":386},[37,2397,2398],{"class":93},"new",[37,2400,2335],{"class":97},[37,2402,123],{"class":101},[37,2404,2405],{"class":43},"\u002F\u002F works\n",[37,2407,2408],{"class":39,"line":408},[37,2409,81],{"emptyLinePlaceholder":80},[37,2411,2412],{"class":39,"line":425},[37,2413,2414],{"class":43},"\u002F\u002F ── Avoid `this` entirely with arrow functions and closures ──\n",[37,2416,2417,2419,2422,2424,2426,2428],{"class":39,"line":430},[37,2418,149],{"class":93},[37,2420,2421],{"class":97}," createCounter",[37,2423,155],{"class":93},[37,2425,840],{"class":101},[37,2427,614],{"class":93},[37,2429,158],{"class":101},[37,2431,2432,2435,2438,2440,2442,2444],{"class":39,"line":436},[37,2433,2434],{"class":93},"    let",[37,2436,2437],{"class":101}," count ",[37,2439,460],{"class":93},[37,2441,925],{"class":111},[37,2443,774],{"class":101},[37,2445,2446],{"class":43},"\u002F\u002F private state (closure)\n",[37,2448,2449,2451],{"class":39,"line":451},[37,2450,1342],{"class":93},[37,2452,158],{"class":101},[37,2454,2455,2458,2460,2462,2465,2468],{"class":39,"line":469},[37,2456,2457],{"class":97},"        increment",[37,2459,611],{"class":101},[37,2461,614],{"class":93},[37,2463,2464],{"class":93}," ++",[37,2466,2467],{"class":101},"count,   ",[37,2469,2470],{"class":43},"\u002F\u002F arrow — no `this` needed\n",[37,2472,2473,2476,2479,2481,2483,2486],{"class":39,"line":475},[37,2474,2475],{"class":93},"        get",[37,2477,2478],{"class":97}," count",[37,2480,1038],{"class":101},[37,2482,305],{"class":93},[37,2484,2485],{"class":101}," count; },  ",[37,2487,2488],{"class":43},"\u002F\u002F getter\n",[37,2490,2491],{"class":39,"line":497},[37,2492,2493],{"class":101},"    };\n",[37,2495,2496],{"class":39,"line":511},[37,2497,205],{"class":101},[20,2499,2501],{"id":2500},"️-edge-cases-gotchas","⚠️ Edge Cases & Gotchas",[25,2503,2504],{"language":27},[29,2505,2507],{"className":31,"code":2506,"language":27,"meta":33,"style":33},"\u002F\u002F ── `this` in a standalone regular function is global (sloppy) or undefined (strict) ──\nfunction test() { return this; }\ntest();  \u002F\u002F window\u002FglobalThis (sloppy), undefined (strict)\n\n\u002F\u002F ── `this` in an arrow function is the ENCLOSING scope's `this` ──\nconst obj = { method: () => this };\nobj.method();  \u002F\u002F `this` is the module scope (NOT obj — arrows don't get implicit binding)\n\n\u002F\u002F ── `this` in a class constructor is the new instance ──\nclass C { constructor() { console.log(this); } }\nnew C();  \u002F\u002F C {} (the new instance)\n\n\u002F\u002F ── `this` in static methods is the class itself ──\nclass D {\n    static method() { console.log(this); }\n}\nD.method();  \u002F\u002F class D (this = the class, not an instance)\n\n\u002F\u002F ── Implicit binding is lost when detached (passed as callback) ──\nconst obj = { greet() { console.log(this); } };\nsetTimeout(obj.greet, 0);  \u002F\u002F `this` is global\u002Fundefined (detached — no receiver)\n\n\u002F\u002F ── `bind` is permanent (can't be overridden) ──\nconst bound = obj.greet.bind({ name: \"bound\" });\nbound.call({ name: \"override\" });  \u002F\u002F `this` is STILL { name: \"bound\" }\n\n\u002F\u002F ── Arrow function `this` can't be changed ──\nconst arrow = () => console.log(this);\narrow.call({ forced: true });  \u002F\u002F `this` is still the lexical scope (call ignored)\n\n\u002F\u002F ── `this` in `setTimeout` callback is global (not the enclosing object) ──\nconst obj2 = {\n    delay: 1000,\n    run() {\n        setTimeout(function() {\n            \u002F\u002F `this` here is the global object, NOT obj2\n            \u002F\u002F console.log(this.delay);  \u002F\u002F undefined\n        }, this.delay);  \u002F\u002F ✓ this is obj2 here (in the run() method scope)\n    },\n};\n",[15,2508,2509,2514,2529,2539,2543,2548,2569,2580,2584,2589,2611,2622,2626,2631,2640,2658,2662,2676,2680,2685,2708,2723,2727,2732,2752,2769,2773,2778,2800,2817,2821,2826,2837,2846,2853,2864,2869,2877,2889,2893],{"__ignoreMap":33},[37,2510,2511],{"class":39,"line":40},[37,2512,2513],{"class":43},"\u002F\u002F ── `this` in a standalone regular function is global (sloppy) or undefined (strict) ──\n",[37,2515,2516,2518,2521,2523,2525,2527],{"class":39,"line":47},[37,2517,94],{"class":93},[37,2519,2520],{"class":97}," test",[37,2522,1038],{"class":101},[37,2524,305],{"class":93},[37,2526,1248],{"class":111},[37,2528,324],{"class":101},[37,2530,2531,2534,2536],{"class":39,"line":53},[37,2532,2533],{"class":97},"test",[37,2535,123],{"class":101},[37,2537,2538],{"class":43},"\u002F\u002F window\u002FglobalThis (sloppy), undefined (strict)\n",[37,2540,2541],{"class":39,"line":59},[37,2542,81],{"emptyLinePlaceholder":80},[37,2544,2545],{"class":39,"line":65},[37,2546,2547],{"class":43},"\u002F\u002F ── `this` in an arrow function is the ENCLOSING scope's `this` ──\n",[37,2549,2550,2552,2554,2556,2558,2561,2563,2565,2567],{"class":39,"line":71},[37,2551,149],{"class":93},[37,2553,152],{"class":111},[37,2555,155],{"class":93},[37,2557,1602],{"class":101},[37,2559,2560],{"class":97},"method",[37,2562,611],{"class":101},[37,2564,614],{"class":93},[37,2566,1248],{"class":111},[37,2568,343],{"class":101},[37,2570,2571,2573,2575,2577],{"class":39,"line":77},[37,2572,211],{"class":101},[37,2574,2560],{"class":97},[37,2576,123],{"class":101},[37,2578,2579],{"class":43},"\u002F\u002F `this` is the module scope (NOT obj — arrows don't get implicit binding)\n",[37,2581,2582],{"class":39,"line":84},[37,2583,81],{"emptyLinePlaceholder":80},[37,2585,2586],{"class":39,"line":90},[37,2587,2588],{"class":43},"\u002F\u002F ── `this` in a class constructor is the new instance ──\n",[37,2590,2591,2593,2596,2598,2600,2602,2604,2606,2608],{"class":39,"line":117},[37,2592,900],{"class":93},[37,2594,2595],{"class":97}," C",[37,2597,1602],{"class":101},[37,2599,2270],{"class":93},[37,2601,102],{"class":101},[37,2603,105],{"class":97},[37,2605,108],{"class":101},[37,2607,17],{"class":111},[37,2609,2610],{"class":101},"); } }\n",[37,2612,2613,2615,2617,2619],{"class":39,"line":129},[37,2614,2398],{"class":93},[37,2616,2595],{"class":97},[37,2618,123],{"class":101},[37,2620,2621],{"class":43},"\u002F\u002F C {} (the new instance)\n",[37,2623,2624],{"class":39,"line":135},[37,2625,81],{"emptyLinePlaceholder":80},[37,2627,2628],{"class":39,"line":140},[37,2629,2630],{"class":43},"\u002F\u002F ── `this` in static methods is the class itself ──\n",[37,2632,2633,2635,2638],{"class":39,"line":146},[37,2634,900],{"class":93},[37,2636,2637],{"class":97}," D",[37,2639,158],{"class":101},[37,2641,2642,2645,2648,2650,2652,2654,2656],{"class":39,"line":161},[37,2643,2644],{"class":93},"    static",[37,2646,2647],{"class":97}," method",[37,2649,102],{"class":101},[37,2651,105],{"class":97},[37,2653,108],{"class":101},[37,2655,17],{"class":111},[37,2657,114],{"class":101},[37,2659,2660],{"class":39,"line":174},[37,2661,472],{"class":101},[37,2663,2664,2667,2669,2671,2673],{"class":39,"line":202},[37,2665,2666],{"class":111},"D",[37,2668,191],{"class":101},[37,2670,2560],{"class":97},[37,2672,123],{"class":101},[37,2674,2675],{"class":43},"\u002F\u002F class D (this = the class, not an instance)\n",[37,2677,2678],{"class":39,"line":208},[37,2679,81],{"emptyLinePlaceholder":80},[37,2681,2682],{"class":39,"line":222},[37,2683,2684],{"class":43},"\u002F\u002F ── Implicit binding is lost when detached (passed as callback) ──\n",[37,2686,2687,2689,2691,2693,2695,2697,2699,2701,2703,2705],{"class":39,"line":228},[37,2688,149],{"class":93},[37,2690,152],{"class":111},[37,2692,155],{"class":93},[37,2694,1602],{"class":101},[37,2696,214],{"class":97},[37,2698,102],{"class":101},[37,2700,105],{"class":97},[37,2702,108],{"class":101},[37,2704,17],{"class":111},[37,2706,2707],{"class":101},"); } };\n",[37,2709,2710,2713,2716,2718,2720],{"class":39,"line":233},[37,2711,2712],{"class":97},"setTimeout",[37,2714,2715],{"class":101},"(obj.greet, ",[37,2717,713],{"class":111},[37,2719,419],{"class":101},[37,2721,2722],{"class":43},"\u002F\u002F `this` is global\u002Fundefined (detached — no receiver)\n",[37,2724,2725],{"class":39,"line":239},[37,2726,81],{"emptyLinePlaceholder":80},[37,2728,2729],{"class":39,"line":255},[37,2730,2731],{"class":43},"\u002F\u002F ── `bind` is permanent (can't be overridden) ──\n",[37,2733,2734,2736,2738,2740,2743,2745,2747,2750],{"class":39,"line":265},[37,2735,149],{"class":93},[37,2737,391],{"class":111},[37,2739,155],{"class":93},[37,2741,2742],{"class":101}," obj.greet.",[37,2744,399],{"class":97},[37,2746,862],{"class":101},[37,2748,2749],{"class":167},"\"bound\"",[37,2751,1686],{"class":101},[37,2753,2754,2757,2759,2761,2764,2766],{"class":39,"line":271},[37,2755,2756],{"class":101},"bound.",[37,2758,352],{"class":97},[37,2760,862],{"class":101},[37,2762,2763],{"class":167},"\"override\"",[37,2765,868],{"class":101},[37,2767,2768],{"class":43},"\u002F\u002F `this` is STILL { name: \"bound\" }\n",[37,2770,2771],{"class":39,"line":277},[37,2772,81],{"emptyLinePlaceholder":80},[37,2774,2775],{"class":39,"line":282},[37,2776,2777],{"class":43},"\u002F\u002F ── Arrow function `this` can't be changed ──\n",[37,2779,2780,2782,2784,2786,2788,2790,2792,2794,2796,2798],{"class":39,"line":288},[37,2781,149],{"class":93},[37,2783,835],{"class":97},[37,2785,155],{"class":93},[37,2787,840],{"class":101},[37,2789,614],{"class":93},[37,2791,617],{"class":101},[37,2793,105],{"class":97},[37,2795,108],{"class":101},[37,2797,17],{"class":111},[37,2799,494],{"class":101},[37,2801,2802,2804,2806,2809,2812,2814],{"class":39,"line":327},[37,2803,857],{"class":101},[37,2805,352],{"class":97},[37,2807,2808],{"class":101},"({ forced: ",[37,2810,2811],{"class":111},"true",[37,2813,868],{"class":101},[37,2815,2816],{"class":43},"\u002F\u002F `this` is still the lexical scope (call ignored)\n",[37,2818,2819],{"class":39,"line":346},[37,2820,81],{"emptyLinePlaceholder":80},[37,2822,2823],{"class":39,"line":367},[37,2824,2825],{"class":43},"\u002F\u002F ── `this` in `setTimeout` callback is global (not the enclosing object) ──\n",[37,2827,2828,2830,2833,2835],{"class":39,"line":386},[37,2829,149],{"class":93},[37,2831,2832],{"class":111}," obj2",[37,2834,155],{"class":93},[37,2836,158],{"class":101},[37,2838,2839,2842,2844],{"class":39,"line":408},[37,2840,2841],{"class":101},"    delay: ",[37,2843,995],{"class":111},[37,2845,171],{"class":101},[37,2847,2848,2851],{"class":39,"line":425},[37,2849,2850],{"class":97},"    run",[37,2852,723],{"class":101},[37,2854,2855,2858,2860,2862],{"class":39,"line":430},[37,2856,2857],{"class":97},"        setTimeout",[37,2859,108],{"class":101},[37,2861,94],{"class":93},[37,2863,723],{"class":101},[37,2865,2866],{"class":39,"line":436},[37,2867,2868],{"class":43},"            \u002F\u002F `this` here is the global object, NOT obj2\n",[37,2870,2871,2874],{"class":39,"line":451},[37,2872,2873],{"class":43},"            \u002F\u002F console.log(this.delay);",[37,2875,2876],{"class":43},"  \u002F\u002F undefined\n",[37,2878,2879,2881,2883,2886],{"class":39,"line":469},[37,2880,992],{"class":101},[37,2882,17],{"class":111},[37,2884,2885],{"class":101},".delay);  ",[37,2887,2888],{"class":43},"\u002F\u002F ✓ this is obj2 here (in the run() method scope)\n",[37,2890,2891],{"class":39,"line":475},[37,2892,792],{"class":101},[37,2894,2895],{"class":39,"line":497},[37,2896,205],{"class":101},[20,2898,2900],{"id":2899},"quick-quiz","🧠 Quick Quiz",[2902,2903,2904],"p",{},"What does this output?",[25,2906,2907],{"language":27},[29,2908,2910],{"className":31,"code":2909,"language":27,"meta":33,"style":33},"const obj = {\n    name: \"Alice\",\n    regular() { return this.name; },\n    arrow: () => this.name,\n    bound: (function() { return this.name; }).bind({ name: \"Bob\" }),\n};\nconsole.log(obj.regular());\nconsole.log(obj.arrow());\nconsole.log(obj.bound());\n",[15,2911,2912,2922,2930,2944,2958,2983,2987,3002,3015],{"__ignoreMap":33},[37,2913,2914,2916,2918,2920],{"class":39,"line":40},[37,2915,149],{"class":93},[37,2917,152],{"class":111},[37,2919,155],{"class":93},[37,2921,158],{"class":101},[37,2923,2924,2926,2928],{"class":39,"line":47},[37,2925,164],{"class":101},[37,2927,168],{"class":167},[37,2929,171],{"class":101},[37,2931,2932,2935,2937,2939,2941],{"class":39,"line":53},[37,2933,2934],{"class":97},"    regular",[37,2936,1038],{"class":101},[37,2938,305],{"class":93},[37,2940,1248],{"class":111},[37,2942,2943],{"class":101},".name; },\n",[37,2945,2946,2949,2951,2953,2955],{"class":39,"line":59},[37,2947,2948],{"class":97},"    arrow",[37,2950,611],{"class":101},[37,2952,614],{"class":93},[37,2954,1248],{"class":111},[37,2956,2957],{"class":101},".name,\n",[37,2959,2960,2963,2965,2967,2969,2971,2974,2976,2978,2980],{"class":39,"line":65},[37,2961,2962],{"class":101},"    bound: (",[37,2964,94],{"class":93},[37,2966,1038],{"class":101},[37,2968,305],{"class":93},[37,2970,1248],{"class":111},[37,2972,2973],{"class":101},".name; }).",[37,2975,399],{"class":97},[37,2977,862],{"class":101},[37,2979,340],{"class":167},[37,2981,2982],{"class":101}," }),\n",[37,2984,2985],{"class":39,"line":71},[37,2986,205],{"class":101},[37,2988,2989,2991,2993,2996,2999],{"class":39,"line":77},[37,2990,500],{"class":101},[37,2992,105],{"class":97},[37,2994,2995],{"class":101},"(obj.",[37,2997,2998],{"class":97},"regular",[37,3000,3001],{"class":101},"());\n",[37,3003,3004,3006,3008,3010,3013],{"class":39,"line":84},[37,3005,500],{"class":101},[37,3007,105],{"class":97},[37,3009,2995],{"class":101},[37,3011,3012],{"class":97},"arrow",[37,3014,3001],{"class":101},[37,3016,3017,3019,3021,3023,3025],{"class":39,"line":90},[37,3018,500],{"class":101},[37,3020,105],{"class":97},[37,3022,2995],{"class":101},[37,3024,411],{"class":97},[37,3026,3001],{"class":101},[3028,3029,3030,3034,3061,3142],"details",{},[3031,3032,3033],"summary",{},"Answer",[29,3035,3037],{"className":31,"code":3036,"language":27,"meta":33,"style":33},"\"Alice\"   \u002F\u002F regular(): implicit binding — this = obj (obj.regular())\n\"undefined\" \u002F\u002F arrow(): lexical `this` — the module\u002Fglobal scope (NOT obj)\n\"Bob\"     \u002F\u002F bound(): the function was bound to { name: \"Bob\" } at definition time\n",[15,3038,3039,3046,3054],{"__ignoreMap":33},[37,3040,3041,3043],{"class":39,"line":40},[37,3042,168],{"class":167},[37,3044,3045],{"class":43},"   \u002F\u002F regular(): implicit binding — this = obj (obj.regular())\n",[37,3047,3048,3051],{"class":39,"line":47},[37,3049,3050],{"class":167},"\"undefined\"",[37,3052,3053],{"class":43}," \u002F\u002F arrow(): lexical `this` — the module\u002Fglobal scope (NOT obj)\n",[37,3055,3056,3058],{"class":39,"line":53},[37,3057,340],{"class":167},[37,3059,3060],{"class":43},"     \u002F\u002F bound(): the function was bound to { name: \"Bob\" } at definition time\n",[3062,3063,3064,3083,3112],"ul",{},[3065,3066,3067,3070,3071,3073,3074,3076,3077,3080,3081,191],"li",{},[15,3068,3069],{},"obj.regular()",": called as ",[15,3072,3069],{}," — implicit binding, ",[15,3075,17],{}," is ",[15,3078,3079],{},"obj",", returns ",[15,3082,168],{},[3065,3084,3085,3088,3089,3091,3092,3094,3095,3097,3098,3102,3103,3105,3106,3076,3109,191],{},[15,3086,3087],{},"obj.arrow()",": arrow function — ",[15,3090,17],{}," is lexical (the enclosing scope's ",[15,3093,17],{},"). ",[15,3096,3079],{}," is an object literal, not a function scope, so the arrow inherits the ",[3099,3100,3101],"strong",{},"module scope's"," ",[15,3104,17],{}," (undefined in strict mode, global in sloppy). ",[15,3107,3108],{},"this.name",[15,3110,3111],{},"undefined",[3065,3113,3114,3117,3118,3121,3122,3125,3126,3128,3129,3132,3133,3135,3136,3076,3138,3080,3140,191],{},[15,3115,3116],{},"obj.bound()",": the function expression ",[15,3119,3120],{},"(function() { return this.name; })"," is immediately ",[15,3123,3124],{},".bind({ name: \"Bob\" })",". The bind permanently sets ",[15,3127,17],{}," to ",[15,3130,3131],{},"{ name: \"Bob\" }",". When called as ",[15,3134,3116],{},", the bind overrides implicit binding — ",[15,3137,17],{},[15,3139,3131],{},[15,3141,340],{},[2902,3143,3144,3147,3148,3150,3151,3153,3154,3156],{},[3099,3145,3146],{},"The lesson",": regular functions get ",[15,3149,17],{}," from the call site (dynamic). Arrow functions get ",[15,3152,17],{}," from the definition scope (lexical). Bound functions have ",[15,3155,17],{}," permanently set (bind is irreversible).",[3158,3159,3160],"style",{},"html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}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 .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}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);}",{"title":33,"searchDepth":47,"depth":47,"links":3162},[3163,3164,3166,3168,3170,3172,3173,3174],{"id":22,"depth":47,"text":23},{"id":517,"depth":47,"text":3165},"Arrow Functions: Lexical this (Not Affected by the Four Rules)",{"id":879,"depth":47,"text":3167},"Anti-Pattern: Lost this in Callbacks",{"id":1299,"depth":47,"text":3169},"call, apply, and bind Internals",{"id":1702,"depth":47,"text":3171},"Production Pattern: Event Handler this Management",{"id":2081,"depth":47,"text":2082},{"id":2500,"depth":47,"text":2501},{"id":2899,"depth":47,"text":2900},"Deep-dive into JavaScript `this` binding: the four binding rules (default, implicit, explicit, new), arrow function lexical binding, call\u002Fapply\u002Fbind internals, and the call-site determination model. Code-first reference for senior engineers.","md",{},"\u002Fjs\u002F11-this-keyword",{"title":5,"description":3175},"js\u002F11-this-keyword","LvSJNqUUB5WuhJDq-q2Q6VqvkRv38uJ2l9XBQbXHs5M",1789924649218]