[{"data":1,"prerenderedAt":3908},["ShallowReactive",2],{"page-\u002Fjs\u002F02-variables-and-data-types":3},{"id":4,"title":5,"body":6,"description":3901,"extension":3902,"meta":3903,"navigation":74,"path":3904,"seo":3905,"stem":3906,"__hash__":3907},"content\u002Fjs\u002F02-variables-and-data-types.md","JavaScript 02 — Variable Binding, TDZ Internals & Type Coercion Engine",{"type":7,"value":8,"toc":3887},"minimark",[9,14,30,536,543,811,815,1246,1250,1656,1660,2019,2023,2518,2522,3079,3083,3469,3473,3720,3724,3728,3803,3883],[10,11,13],"h1",{"id":12},"_02-variable-binding-tdz-internals-type-coercion-engine","02 — Variable Binding, TDZ Internals & Type Coercion Engine",[15,16,18,22,23,22,26,29],"h2",{"id":17},"let-const-var-scope-and-hoisting-internals",[19,20,21],"code",{},"let"," \u002F ",[19,24,25],{},"const",[19,27,28],{},"var",": Scope and Hoisting Internals",[31,32,34],"code-wrapper",{"language":33},"javascript",[35,36,40],"pre",{"className":37,"code":38,"language":33,"meta":39,"style":39},"language-javascript shiki shiki-themes github-light github-dark","\u002F\u002F ── All three are hoisted — the difference is initialization ──\n\u002F\u002F var:   hoisted + initialized to undefined (accessible before declaration, value is undefined)\n\u002F\u002F let:   hoisted but NOT initialized → Temporal Dead Zone (TDZ) → ReferenceError if accessed early\n\u002F\u002F const: same as let, but the binding is immutable (can't reassign the variable)\n\n\u002F\u002F ── var: function-scoped (or global) — not block-scoped ──\nfunction varScope() {\n    if (true) {\n        var x = 10;  \u002F\u002F function-scoped: x exists in entire function\n    }\n    console.log(x);  \u002F\u002F 10 — var leaks out of the block\n}\n\u002F\u002F var x is visible from the point of declaration to the END of the function\n\u002F\u002F (not just the block it's declared in)\n\n\u002F\u002F ── let\u002Fconst: block-scoped (lexical block scope) ──\nfunction letScope() {\n    if (true) {\n        let y = 20;  \u002F\u002F block-scoped: y only exists in this if-block\n    }\n    console.log(y);  \u002F\u002F ReferenceError: y is not defined\n}\n\n\u002F\u002F ── Hoisting: all declarations are moved to the top of their scope ──\n\u002F\u002F But let\u002Fconst go into the TDZ (not initialized):\nconsole.log(v);  \u002F\u002F undefined (var is hoisted + initialized to undefined)\nvar v = 5;\n\nconsole.log(l);  \u002F\u002F ReferenceError: Cannot access 'l' before initialization (TDZ!)\nlet l = 5;\n\n\u002F\u002F ── The TDZ is a region from the start of the scope to the declaration ──\n{\n    \u002F\u002F TDZ for x starts here (block opening)\n    console.log(x);  \u002F\u002F ReferenceError — in the TDZ\n    let x = 10;       \u002F\u002F TDZ ends — x is now accessible\n    console.log(x);  \u002F\u002F 10\n}\n\n\u002F\u002F ── const: immutable binding, not immutable value ──\nconst obj = { x: 1 };\nobj.x = 2;        \u002F\u002F ✓ the object is mutable — const only prevents reassignment\n\u002F\u002F obj = { x: 3 };  \u002F\u002F ✗ TypeError: Assignment to constant variable\nconsole.log(obj.x);  \u002F\u002F 2\n\n\u002F\u002F ── var in the global scope creates a property on the global object ──\nvar globalVar = 10;\nconsole.log(globalThis.globalVar);  \u002F\u002F 10 — var on global scope → window\u002FglobalThis property\n\nlet globalLet = 20;\nconsole.log(globalThis.globalLet);  \u002F\u002F undefined — let\u002Fconst do NOT create global properties\n","",[19,41,42,51,57,63,69,76,82,97,113,134,140,155,161,167,173,178,184,194,205,224,229,242,247,252,258,264,278,294,299,312,326,331,337,343,349,361,379,391,396,401,407,427,444,453,466,471,477,491,504,509,523],{"__ignoreMap":39},[43,44,47],"span",{"class":45,"line":46},"line",1,[43,48,50],{"class":49},"sdCPZ","\u002F\u002F ── All three are hoisted — the difference is initialization ──\n",[43,52,54],{"class":45,"line":53},2,[43,55,56],{"class":49},"\u002F\u002F var:   hoisted + initialized to undefined (accessible before declaration, value is undefined)\n",[43,58,60],{"class":45,"line":59},3,[43,61,62],{"class":49},"\u002F\u002F let:   hoisted but NOT initialized → Temporal Dead Zone (TDZ) → ReferenceError if accessed early\n",[43,64,66],{"class":45,"line":65},4,[43,67,68],{"class":49},"\u002F\u002F const: same as let, but the binding is immutable (can't reassign the variable)\n",[43,70,72],{"class":45,"line":71},5,[43,73,75],{"emptyLinePlaceholder":74},true,"\n",[43,77,79],{"class":45,"line":78},6,[43,80,81],{"class":49},"\u002F\u002F ── var: function-scoped (or global) — not block-scoped ──\n",[43,83,85,89,93],{"class":45,"line":84},7,[43,86,88],{"class":87},"svdQ7","function",[43,90,92],{"class":91},"sIsaT"," varScope",[43,94,96],{"class":95},"ssxIu","() {\n",[43,98,100,103,106,110],{"class":45,"line":99},8,[43,101,102],{"class":87},"    if",[43,104,105],{"class":95}," (",[43,107,109],{"class":108},"snvgF","true",[43,111,112],{"class":95},") {\n",[43,114,116,119,122,125,128,131],{"class":45,"line":115},9,[43,117,118],{"class":87},"        var",[43,120,121],{"class":95}," x ",[43,123,124],{"class":87},"=",[43,126,127],{"class":108}," 10",[43,129,130],{"class":95},";  ",[43,132,133],{"class":49},"\u002F\u002F function-scoped: x exists in entire function\n",[43,135,137],{"class":45,"line":136},10,[43,138,139],{"class":95},"    }\n",[43,141,143,146,149,152],{"class":45,"line":142},11,[43,144,145],{"class":95},"    console.",[43,147,148],{"class":91},"log",[43,150,151],{"class":95},"(x);  ",[43,153,154],{"class":49},"\u002F\u002F 10 — var leaks out of the block\n",[43,156,158],{"class":45,"line":157},12,[43,159,160],{"class":95},"}\n",[43,162,164],{"class":45,"line":163},13,[43,165,166],{"class":49},"\u002F\u002F var x is visible from the point of declaration to the END of the function\n",[43,168,170],{"class":45,"line":169},14,[43,171,172],{"class":49},"\u002F\u002F (not just the block it's declared in)\n",[43,174,176],{"class":45,"line":175},15,[43,177,75],{"emptyLinePlaceholder":74},[43,179,181],{"class":45,"line":180},16,[43,182,183],{"class":49},"\u002F\u002F ── let\u002Fconst: block-scoped (lexical block scope) ──\n",[43,185,187,189,192],{"class":45,"line":186},17,[43,188,88],{"class":87},[43,190,191],{"class":91}," letScope",[43,193,96],{"class":95},[43,195,197,199,201,203],{"class":45,"line":196},18,[43,198,102],{"class":87},[43,200,105],{"class":95},[43,202,109],{"class":108},[43,204,112],{"class":95},[43,206,208,211,214,216,219,221],{"class":45,"line":207},19,[43,209,210],{"class":87},"        let",[43,212,213],{"class":95}," y ",[43,215,124],{"class":87},[43,217,218],{"class":108}," 20",[43,220,130],{"class":95},[43,222,223],{"class":49},"\u002F\u002F block-scoped: y only exists in this if-block\n",[43,225,227],{"class":45,"line":226},20,[43,228,139],{"class":95},[43,230,232,234,236,239],{"class":45,"line":231},21,[43,233,145],{"class":95},[43,235,148],{"class":91},[43,237,238],{"class":95},"(y);  ",[43,240,241],{"class":49},"\u002F\u002F ReferenceError: y is not defined\n",[43,243,245],{"class":45,"line":244},22,[43,246,160],{"class":95},[43,248,250],{"class":45,"line":249},23,[43,251,75],{"emptyLinePlaceholder":74},[43,253,255],{"class":45,"line":254},24,[43,256,257],{"class":49},"\u002F\u002F ── Hoisting: all declarations are moved to the top of their scope ──\n",[43,259,261],{"class":45,"line":260},25,[43,262,263],{"class":49},"\u002F\u002F But let\u002Fconst go into the TDZ (not initialized):\n",[43,265,267,270,272,275],{"class":45,"line":266},26,[43,268,269],{"class":95},"console.",[43,271,148],{"class":91},[43,273,274],{"class":95},"(v);  ",[43,276,277],{"class":49},"\u002F\u002F undefined (var is hoisted + initialized to undefined)\n",[43,279,281,283,286,288,291],{"class":45,"line":280},27,[43,282,28],{"class":87},[43,284,285],{"class":95}," v ",[43,287,124],{"class":87},[43,289,290],{"class":108}," 5",[43,292,293],{"class":95},";\n",[43,295,297],{"class":45,"line":296},28,[43,298,75],{"emptyLinePlaceholder":74},[43,300,302,304,306,309],{"class":45,"line":301},29,[43,303,269],{"class":95},[43,305,148],{"class":91},[43,307,308],{"class":95},"(l);  ",[43,310,311],{"class":49},"\u002F\u002F ReferenceError: Cannot access 'l' before initialization (TDZ!)\n",[43,313,315,317,320,322,324],{"class":45,"line":314},30,[43,316,21],{"class":87},[43,318,319],{"class":95}," l ",[43,321,124],{"class":87},[43,323,290],{"class":108},[43,325,293],{"class":95},[43,327,329],{"class":45,"line":328},31,[43,330,75],{"emptyLinePlaceholder":74},[43,332,334],{"class":45,"line":333},32,[43,335,336],{"class":49},"\u002F\u002F ── The TDZ is a region from the start of the scope to the declaration ──\n",[43,338,340],{"class":45,"line":339},33,[43,341,342],{"class":95},"{\n",[43,344,346],{"class":45,"line":345},34,[43,347,348],{"class":49},"    \u002F\u002F TDZ for x starts here (block opening)\n",[43,350,352,354,356,358],{"class":45,"line":351},35,[43,353,145],{"class":95},[43,355,148],{"class":91},[43,357,151],{"class":95},[43,359,360],{"class":49},"\u002F\u002F ReferenceError — in the TDZ\n",[43,362,364,367,369,371,373,376],{"class":45,"line":363},36,[43,365,366],{"class":87},"    let",[43,368,121],{"class":95},[43,370,124],{"class":87},[43,372,127],{"class":108},[43,374,375],{"class":95},";       ",[43,377,378],{"class":49},"\u002F\u002F TDZ ends — x is now accessible\n",[43,380,382,384,386,388],{"class":45,"line":381},37,[43,383,145],{"class":95},[43,385,148],{"class":91},[43,387,151],{"class":95},[43,389,390],{"class":49},"\u002F\u002F 10\n",[43,392,394],{"class":45,"line":393},38,[43,395,160],{"class":95},[43,397,399],{"class":45,"line":398},39,[43,400,75],{"emptyLinePlaceholder":74},[43,402,404],{"class":45,"line":403},40,[43,405,406],{"class":49},"\u002F\u002F ── const: immutable binding, not immutable value ──\n",[43,408,410,412,415,418,421,424],{"class":45,"line":409},41,[43,411,25],{"class":87},[43,413,414],{"class":108}," obj",[43,416,417],{"class":87}," =",[43,419,420],{"class":95}," { x: ",[43,422,423],{"class":108},"1",[43,425,426],{"class":95}," };\n",[43,428,430,433,435,438,441],{"class":45,"line":429},42,[43,431,432],{"class":95},"obj.x ",[43,434,124],{"class":87},[43,436,437],{"class":108}," 2",[43,439,440],{"class":95},";        ",[43,442,443],{"class":49},"\u002F\u002F ✓ the object is mutable — const only prevents reassignment\n",[43,445,447,450],{"class":45,"line":446},43,[43,448,449],{"class":49},"\u002F\u002F obj = { x: 3 };",[43,451,452],{"class":49},"  \u002F\u002F ✗ TypeError: Assignment to constant variable\n",[43,454,456,458,460,463],{"class":45,"line":455},44,[43,457,269],{"class":95},[43,459,148],{"class":91},[43,461,462],{"class":95},"(obj.x);  ",[43,464,465],{"class":49},"\u002F\u002F 2\n",[43,467,469],{"class":45,"line":468},45,[43,470,75],{"emptyLinePlaceholder":74},[43,472,474],{"class":45,"line":473},46,[43,475,476],{"class":49},"\u002F\u002F ── var in the global scope creates a property on the global object ──\n",[43,478,480,482,485,487,489],{"class":45,"line":479},47,[43,481,28],{"class":87},[43,483,484],{"class":95}," globalVar ",[43,486,124],{"class":87},[43,488,127],{"class":108},[43,490,293],{"class":95},[43,492,494,496,498,501],{"class":45,"line":493},48,[43,495,269],{"class":95},[43,497,148],{"class":91},[43,499,500],{"class":95},"(globalThis.globalVar);  ",[43,502,503],{"class":49},"\u002F\u002F 10 — var on global scope → window\u002FglobalThis property\n",[43,505,507],{"class":45,"line":506},49,[43,508,75],{"emptyLinePlaceholder":74},[43,510,512,514,517,519,521],{"class":45,"line":511},50,[43,513,21],{"class":87},[43,515,516],{"class":95}," globalLet ",[43,518,124],{"class":87},[43,520,218],{"class":108},[43,522,293],{"class":95},[43,524,526,528,530,533],{"class":45,"line":525},51,[43,527,269],{"class":95},[43,529,148],{"class":91},[43,531,532],{"class":95},"(globalThis.globalLet);  ",[43,534,535],{"class":49},"\u002F\u002F undefined — let\u002Fconst do NOT create global properties\n",[15,537,539,540,542],{"id":538},"anti-pattern-var-in-loops-closure-capture-bug","Anti-Pattern: ",[19,541,28],{}," in Loops (Closure Capture Bug)",[31,544,545],{"language":33},[35,546,548],{"className":37,"code":547,"language":33,"meta":39,"style":39},"\u002F\u002F ❌ NAIVE — var is function-scoped, so the closure captures the SAME variable\nfor (var i = 0; i \u003C 3; i++) {\n    setTimeout(() => console.log(i), 0);\n}\n\u002F\u002F Output: 3, 3, 3 — all closures share the SAME i (function-scoped, final value is 3)\n\n\u002F\u002F ✅ CORRECT — let is block-scoped, each iteration gets its own binding\nfor (let i = 0; i \u003C 3; i++) {\n    setTimeout(() => console.log(i), 0);\n}\n\u002F\u002F Output: 0, 1, 2 — each iteration's let creates a new binding (per-iteration scope)\n\n\u002F\u002F ✅ IIFE workaround (pre-ES6, when let didn't exist)\nfor (var i = 0; i \u003C 3; i++) {\n    (function(j) {          \u002F\u002F IIFE creates a new scope, captures the current value\n        setTimeout(() => console.log(j), 0);\n    })(i);                  \u002F\u002F pass current i as argument → j is a copy\n}\n\u002F\u002F Output: 0, 1, 2\n\n\u002F\u002F ── How let in loops actually works ──\n\u002F\u002F `for (let i = 0; i \u003C 3; i++)` is desugared to create a NEW binding per iteration:\n\u002F\u002F   { let i = 0; setTimeout(() => console.log(i), 0); }\n\u002F\u002F   { let i = 1; setTimeout(() => console.log(i), 0); }\n\u002F\u002F   { let i = 2; setTimeout(() => console.log(i), 0); }\n\u002F\u002F Each iteration has its own `i` in its own scope.\n",[19,549,550,555,589,614,618,623,627,632,658,676,680,685,689,694,720,740,760,768,772,777,781,786,791,796,801,806],{"__ignoreMap":39},[43,551,552],{"class":45,"line":46},[43,553,554],{"class":49},"\u002F\u002F ❌ NAIVE — var is function-scoped, so the closure captures the SAME variable\n",[43,556,557,560,562,564,567,569,572,575,578,581,584,587],{"class":45,"line":53},[43,558,559],{"class":87},"for",[43,561,105],{"class":95},[43,563,28],{"class":87},[43,565,566],{"class":95}," i ",[43,568,124],{"class":87},[43,570,571],{"class":108}," 0",[43,573,574],{"class":95},"; i ",[43,576,577],{"class":87},"\u003C",[43,579,580],{"class":108}," 3",[43,582,583],{"class":95},"; i",[43,585,586],{"class":87},"++",[43,588,112],{"class":95},[43,590,591,594,597,600,603,605,608,611],{"class":45,"line":59},[43,592,593],{"class":91},"    setTimeout",[43,595,596],{"class":95},"(() ",[43,598,599],{"class":87},"=>",[43,601,602],{"class":95}," console.",[43,604,148],{"class":91},[43,606,607],{"class":95},"(i), ",[43,609,610],{"class":108},"0",[43,612,613],{"class":95},");\n",[43,615,616],{"class":45,"line":65},[43,617,160],{"class":95},[43,619,620],{"class":45,"line":71},[43,621,622],{"class":49},"\u002F\u002F Output: 3, 3, 3 — all closures share the SAME i (function-scoped, final value is 3)\n",[43,624,625],{"class":45,"line":78},[43,626,75],{"emptyLinePlaceholder":74},[43,628,629],{"class":45,"line":84},[43,630,631],{"class":49},"\u002F\u002F ✅ CORRECT — let is block-scoped, each iteration gets its own binding\n",[43,633,634,636,638,640,642,644,646,648,650,652,654,656],{"class":45,"line":99},[43,635,559],{"class":87},[43,637,105],{"class":95},[43,639,21],{"class":87},[43,641,566],{"class":95},[43,643,124],{"class":87},[43,645,571],{"class":108},[43,647,574],{"class":95},[43,649,577],{"class":87},[43,651,580],{"class":108},[43,653,583],{"class":95},[43,655,586],{"class":87},[43,657,112],{"class":95},[43,659,660,662,664,666,668,670,672,674],{"class":45,"line":115},[43,661,593],{"class":91},[43,663,596],{"class":95},[43,665,599],{"class":87},[43,667,602],{"class":95},[43,669,148],{"class":91},[43,671,607],{"class":95},[43,673,610],{"class":108},[43,675,613],{"class":95},[43,677,678],{"class":45,"line":136},[43,679,160],{"class":95},[43,681,682],{"class":45,"line":142},[43,683,684],{"class":49},"\u002F\u002F Output: 0, 1, 2 — each iteration's let creates a new binding (per-iteration scope)\n",[43,686,687],{"class":45,"line":157},[43,688,75],{"emptyLinePlaceholder":74},[43,690,691],{"class":45,"line":163},[43,692,693],{"class":49},"\u002F\u002F ✅ IIFE workaround (pre-ES6, when let didn't exist)\n",[43,695,696,698,700,702,704,706,708,710,712,714,716,718],{"class":45,"line":169},[43,697,559],{"class":87},[43,699,105],{"class":95},[43,701,28],{"class":87},[43,703,566],{"class":95},[43,705,124],{"class":87},[43,707,571],{"class":108},[43,709,574],{"class":95},[43,711,577],{"class":87},[43,713,580],{"class":108},[43,715,583],{"class":95},[43,717,586],{"class":87},[43,719,112],{"class":95},[43,721,722,725,727,730,734,737],{"class":45,"line":175},[43,723,724],{"class":95},"    (",[43,726,88],{"class":87},[43,728,729],{"class":95},"(",[43,731,733],{"class":732},"sCrzJ","j",[43,735,736],{"class":95},") {          ",[43,738,739],{"class":49},"\u002F\u002F IIFE creates a new scope, captures the current value\n",[43,741,742,745,747,749,751,753,756,758],{"class":45,"line":180},[43,743,744],{"class":91},"        setTimeout",[43,746,596],{"class":95},[43,748,599],{"class":87},[43,750,602],{"class":95},[43,752,148],{"class":91},[43,754,755],{"class":95},"(j), ",[43,757,610],{"class":108},[43,759,613],{"class":95},[43,761,762,765],{"class":45,"line":186},[43,763,764],{"class":95},"    })(i);                  ",[43,766,767],{"class":49},"\u002F\u002F pass current i as argument → j is a copy\n",[43,769,770],{"class":45,"line":196},[43,771,160],{"class":95},[43,773,774],{"class":45,"line":207},[43,775,776],{"class":49},"\u002F\u002F Output: 0, 1, 2\n",[43,778,779],{"class":45,"line":226},[43,780,75],{"emptyLinePlaceholder":74},[43,782,783],{"class":45,"line":231},[43,784,785],{"class":49},"\u002F\u002F ── How let in loops actually works ──\n",[43,787,788],{"class":45,"line":244},[43,789,790],{"class":49},"\u002F\u002F `for (let i = 0; i \u003C 3; i++)` is desugared to create a NEW binding per iteration:\n",[43,792,793],{"class":45,"line":249},[43,794,795],{"class":49},"\u002F\u002F   { let i = 0; setTimeout(() => console.log(i), 0); }\n",[43,797,798],{"class":45,"line":254},[43,799,800],{"class":49},"\u002F\u002F   { let i = 1; setTimeout(() => console.log(i), 0); }\n",[43,802,803],{"class":45,"line":260},[43,804,805],{"class":49},"\u002F\u002F   { let i = 2; setTimeout(() => console.log(i), 0); }\n",[43,807,808],{"class":45,"line":266},[43,809,810],{"class":49},"\u002F\u002F Each iteration has its own `i` in its own scope.\n",[15,812,814],{"id":813},"primitive-vs-reference-memory-model","Primitive vs Reference: Memory Model",[31,816,817],{"language":33},[35,818,820],{"className":37,"code":819,"language":33,"meta":39,"style":39},"\u002F\u002F ── 7 primitive types (stored by value, immutable) ──\n\u002F\u002F string, number, boolean, null, undefined, symbol, bigint\n\u002F\u002F Primitives are copied by value — each variable gets its own copy.\n\nlet str = \"hello\";\nlet strCopy = str;  \u002F\u002F copy: strCopy is a separate \"hello\"\nstr = \"world\";\nconsole.log(strCopy);  \u002F\u002F \"hello\" — unchanged (primitives are immutable copies)\n\nlet num = 42;\nlet numCopy = num;\nnum = 99;\nconsole.log(numCopy);  \u002F\u002F 42 — unchanged\n\n\u002F\u002F ── Reference types (stored by reference, mutable) ──\n\u002F\u002F Object, Array, Function, Date, RegExp, Map, Set, etc.\n\u002F\u002F References point to heap-allocated objects — copying a reference shares the object.\n\nconst arr = [1, 2, 3];\nconst arrRef = arr;     \u002F\u002F arrRef points to the SAME array (copy of the reference)\narr.push(4);\nconsole.log(arrRef);    \u002F\u002F [1, 2, 3, 4] — shared mutation\n\n\u002F\u002F ── Passing to functions: primitives copy value, references share object ──\nfunction modifyPrim(n) { n = 99; }  \u002F\u002F n is a copy — modifying it doesn't affect caller\nfunction modifyRef(o) { o.x = 99; } \u002F\u002F o is a reference — mutating the object affects caller\n\nlet x = 10;\nmodifyPrim(x);\nconsole.log(x);  \u002F\u002F 10 — unchanged (primitive was copied)\n\nlet obj = { x: 10 };\nmodifyRef(obj);\nconsole.log(obj.x);  \u002F\u002F 99 — changed (shared object was mutated)\n\n\u002F\u002F ── Reassigning a reference inside a function does NOT affect the caller ──\nfunction reassign(o) { o = { x: 99 }; }  \u002F\u002F o is a local reference, now points to a NEW object\nlet myObj = { x: 10 };\nreassign(myObj);\nconsole.log(myObj.x);  \u002F\u002F 10 — unchanged (the local o was reassigned, not the caller's variable)\n",[19,821,822,827,832,837,841,856,871,883,895,899,913,925,937,949,953,958,963,968,972,1000,1015,1030,1042,1046,1051,1076,1101,1105,1117,1125,1136,1140,1156,1164,1175,1179,1184,1211,1226,1234],{"__ignoreMap":39},[43,823,824],{"class":45,"line":46},[43,825,826],{"class":49},"\u002F\u002F ── 7 primitive types (stored by value, immutable) ──\n",[43,828,829],{"class":45,"line":53},[43,830,831],{"class":49},"\u002F\u002F string, number, boolean, null, undefined, symbol, bigint\n",[43,833,834],{"class":45,"line":59},[43,835,836],{"class":49},"\u002F\u002F Primitives are copied by value — each variable gets its own copy.\n",[43,838,839],{"class":45,"line":65},[43,840,75],{"emptyLinePlaceholder":74},[43,842,843,845,848,850,854],{"class":45,"line":71},[43,844,21],{"class":87},[43,846,847],{"class":95}," str ",[43,849,124],{"class":87},[43,851,853],{"class":852},"sJ6F3"," \"hello\"",[43,855,293],{"class":95},[43,857,858,860,863,865,868],{"class":45,"line":78},[43,859,21],{"class":87},[43,861,862],{"class":95}," strCopy ",[43,864,124],{"class":87},[43,866,867],{"class":95}," str;  ",[43,869,870],{"class":49},"\u002F\u002F copy: strCopy is a separate \"hello\"\n",[43,872,873,876,878,881],{"class":45,"line":84},[43,874,875],{"class":95},"str ",[43,877,124],{"class":87},[43,879,880],{"class":852}," \"world\"",[43,882,293],{"class":95},[43,884,885,887,889,892],{"class":45,"line":99},[43,886,269],{"class":95},[43,888,148],{"class":91},[43,890,891],{"class":95},"(strCopy);  ",[43,893,894],{"class":49},"\u002F\u002F \"hello\" — unchanged (primitives are immutable copies)\n",[43,896,897],{"class":45,"line":115},[43,898,75],{"emptyLinePlaceholder":74},[43,900,901,903,906,908,911],{"class":45,"line":136},[43,902,21],{"class":87},[43,904,905],{"class":95}," num ",[43,907,124],{"class":87},[43,909,910],{"class":108}," 42",[43,912,293],{"class":95},[43,914,915,917,920,922],{"class":45,"line":142},[43,916,21],{"class":87},[43,918,919],{"class":95}," numCopy ",[43,921,124],{"class":87},[43,923,924],{"class":95}," num;\n",[43,926,927,930,932,935],{"class":45,"line":157},[43,928,929],{"class":95},"num ",[43,931,124],{"class":87},[43,933,934],{"class":108}," 99",[43,936,293],{"class":95},[43,938,939,941,943,946],{"class":45,"line":163},[43,940,269],{"class":95},[43,942,148],{"class":91},[43,944,945],{"class":95},"(numCopy);  ",[43,947,948],{"class":49},"\u002F\u002F 42 — unchanged\n",[43,950,951],{"class":45,"line":169},[43,952,75],{"emptyLinePlaceholder":74},[43,954,955],{"class":45,"line":175},[43,956,957],{"class":49},"\u002F\u002F ── Reference types (stored by reference, mutable) ──\n",[43,959,960],{"class":45,"line":180},[43,961,962],{"class":49},"\u002F\u002F Object, Array, Function, Date, RegExp, Map, Set, etc.\n",[43,964,965],{"class":45,"line":186},[43,966,967],{"class":49},"\u002F\u002F References point to heap-allocated objects — copying a reference shares the object.\n",[43,969,970],{"class":45,"line":196},[43,971,75],{"emptyLinePlaceholder":74},[43,973,974,976,979,981,984,986,989,992,994,997],{"class":45,"line":207},[43,975,25],{"class":87},[43,977,978],{"class":108}," arr",[43,980,417],{"class":87},[43,982,983],{"class":95}," [",[43,985,423],{"class":108},[43,987,988],{"class":95},", ",[43,990,991],{"class":108},"2",[43,993,988],{"class":95},[43,995,996],{"class":108},"3",[43,998,999],{"class":95},"];\n",[43,1001,1002,1004,1007,1009,1012],{"class":45,"line":226},[43,1003,25],{"class":87},[43,1005,1006],{"class":108}," arrRef",[43,1008,417],{"class":87},[43,1010,1011],{"class":95}," arr;     ",[43,1013,1014],{"class":49},"\u002F\u002F arrRef points to the SAME array (copy of the reference)\n",[43,1016,1017,1020,1023,1025,1028],{"class":45,"line":231},[43,1018,1019],{"class":95},"arr.",[43,1021,1022],{"class":91},"push",[43,1024,729],{"class":95},[43,1026,1027],{"class":108},"4",[43,1029,613],{"class":95},[43,1031,1032,1034,1036,1039],{"class":45,"line":244},[43,1033,269],{"class":95},[43,1035,148],{"class":91},[43,1037,1038],{"class":95},"(arrRef);    ",[43,1040,1041],{"class":49},"\u002F\u002F [1, 2, 3, 4] — shared mutation\n",[43,1043,1044],{"class":45,"line":249},[43,1045,75],{"emptyLinePlaceholder":74},[43,1047,1048],{"class":45,"line":254},[43,1049,1050],{"class":49},"\u002F\u002F ── Passing to functions: primitives copy value, references share object ──\n",[43,1052,1053,1055,1058,1060,1063,1066,1068,1070,1073],{"class":45,"line":260},[43,1054,88],{"class":87},[43,1056,1057],{"class":91}," modifyPrim",[43,1059,729],{"class":95},[43,1061,1062],{"class":732},"n",[43,1064,1065],{"class":95},") { n ",[43,1067,124],{"class":87},[43,1069,934],{"class":108},[43,1071,1072],{"class":95},"; }  ",[43,1074,1075],{"class":49},"\u002F\u002F n is a copy — modifying it doesn't affect caller\n",[43,1077,1078,1080,1083,1085,1088,1091,1093,1095,1098],{"class":45,"line":266},[43,1079,88],{"class":87},[43,1081,1082],{"class":91}," modifyRef",[43,1084,729],{"class":95},[43,1086,1087],{"class":732},"o",[43,1089,1090],{"class":95},") { o.x ",[43,1092,124],{"class":87},[43,1094,934],{"class":108},[43,1096,1097],{"class":95},"; } ",[43,1099,1100],{"class":49},"\u002F\u002F o is a reference — mutating the object affects caller\n",[43,1102,1103],{"class":45,"line":280},[43,1104,75],{"emptyLinePlaceholder":74},[43,1106,1107,1109,1111,1113,1115],{"class":45,"line":296},[43,1108,21],{"class":87},[43,1110,121],{"class":95},[43,1112,124],{"class":87},[43,1114,127],{"class":108},[43,1116,293],{"class":95},[43,1118,1119,1122],{"class":45,"line":301},[43,1120,1121],{"class":91},"modifyPrim",[43,1123,1124],{"class":95},"(x);\n",[43,1126,1127,1129,1131,1133],{"class":45,"line":314},[43,1128,269],{"class":95},[43,1130,148],{"class":91},[43,1132,151],{"class":95},[43,1134,1135],{"class":49},"\u002F\u002F 10 — unchanged (primitive was copied)\n",[43,1137,1138],{"class":45,"line":328},[43,1139,75],{"emptyLinePlaceholder":74},[43,1141,1142,1144,1147,1149,1151,1154],{"class":45,"line":333},[43,1143,21],{"class":87},[43,1145,1146],{"class":95}," obj ",[43,1148,124],{"class":87},[43,1150,420],{"class":95},[43,1152,1153],{"class":108},"10",[43,1155,426],{"class":95},[43,1157,1158,1161],{"class":45,"line":339},[43,1159,1160],{"class":91},"modifyRef",[43,1162,1163],{"class":95},"(obj);\n",[43,1165,1166,1168,1170,1172],{"class":45,"line":345},[43,1167,269],{"class":95},[43,1169,148],{"class":91},[43,1171,462],{"class":95},[43,1173,1174],{"class":49},"\u002F\u002F 99 — changed (shared object was mutated)\n",[43,1176,1177],{"class":45,"line":351},[43,1178,75],{"emptyLinePlaceholder":74},[43,1180,1181],{"class":45,"line":363},[43,1182,1183],{"class":49},"\u002F\u002F ── Reassigning a reference inside a function does NOT affect the caller ──\n",[43,1185,1186,1188,1191,1193,1195,1198,1200,1202,1205,1208],{"class":45,"line":381},[43,1187,88],{"class":87},[43,1189,1190],{"class":91}," reassign",[43,1192,729],{"class":95},[43,1194,1087],{"class":732},[43,1196,1197],{"class":95},") { o ",[43,1199,124],{"class":87},[43,1201,420],{"class":95},[43,1203,1204],{"class":108},"99",[43,1206,1207],{"class":95}," }; }  ",[43,1209,1210],{"class":49},"\u002F\u002F o is a local reference, now points to a NEW object\n",[43,1212,1213,1215,1218,1220,1222,1224],{"class":45,"line":393},[43,1214,21],{"class":87},[43,1216,1217],{"class":95}," myObj ",[43,1219,124],{"class":87},[43,1221,420],{"class":95},[43,1223,1153],{"class":108},[43,1225,426],{"class":95},[43,1227,1228,1231],{"class":45,"line":398},[43,1229,1230],{"class":91},"reassign",[43,1232,1233],{"class":95},"(myObj);\n",[43,1235,1236,1238,1240,1243],{"class":45,"line":403},[43,1237,269],{"class":95},[43,1239,148],{"class":91},[43,1241,1242],{"class":95},"(myObj.x);  ",[43,1244,1245],{"class":49},"\u002F\u002F 10 — unchanged (the local o was reassigned, not the caller's variable)\n",[15,1247,1249],{"id":1248},"type-coercion-the-abstract-equality-algorithm","Type Coercion: The Abstract Equality Algorithm",[31,1251,1252],{"language":33},[35,1253,1255],{"className":37,"code":1254,"language":33,"meta":39,"style":39},"\u002F\u002F ── `==` triggers type coercion; `===` checks type first ──\n\u002F\u002F The Abstract Equality Algorithm (ECMA-262 §7.2.15) has ~20 rules.\n\u002F\u002F Key rules (the most surprising ones):\n\n\u002F\u002F Rule 1: number ↔ string → string is coerced to number\n1 == \"1\";       \u002F\u002F true — \"1\" → 1 (ToNumber(\"1\") = 1)\n0 == \"\";        \u002F\u002F true — \"\" → 0 (ToNumber(\"\") = 0)\n0 == \"0\";       \u002F\u002F true — \"0\" → 0\n\n\u002F\u002F Rule 2: boolean → number (true → 1, false → 0)\n1 == true;      \u002F\u002F true — true → 1\n0 == false;    \u002F\u002F true — false → 0\n\"\" == false;   \u002F\u002F true — \"\" → 0, false → 0 → 0 == 0\n\n\u002F\u002F Rule 3: null == undefined (special case — only each other)\nnull == undefined;  \u002F\u002F true (special rule — they're \"loosely equal\")\nnull == 0;           \u002F\u002F false (null is NOT coerced to 0 for ==)\nnull == false;       \u002F\u002F false\n\n\u002F\u002F Rule 4: object → primitive (via ToPrimitive, which calls valueOf\u002FtoString)\n\"[object Object]\" == {};       \u002F\u002F true — {} → \"[object Object]\"\n\"1,2,3\" == [1, 2, 3];         \u002F\u002F true — array → \"1,2,3\" → \"1,2,3\" == \"1,2,3\"\n\"1\" == [1];                    \u002F\u002F true — [1] → \"1\" → 1 == 1\n\n\u002F\u002F ── NaN: the only value not equal to itself ──\nNaN == NaN;   \u002F\u002F false\nNaN === NaN;  \u002F\u002F false\nNumber.isNaN(NaN);  \u002F\u002F true (correct — doesn't coerce)\n\n\u002F\u002F ── `===` is always safer: no coercion, checks type first ──\n1 === \"1\";     \u002F\u002F false (different types — immediate false)\nnull === undefined;  \u002F\u002F false (different types)\n\n\u002F\u002F ── Object.is: the \"truly correct\" equality (handles NaN and -0) ──\nObject.is(NaN, NaN);    \u002F\u002F true (unlike == and ===)\nObject.is(-0, 0);       \u002F\u002F false (unlike === which says -0 === 0 → true)\nObject.is(0, 0);       \u002F\u002F true\n",[19,1256,1257,1262,1267,1272,1276,1281,1296,1310,1324,1328,1333,1348,1363,1378,1382,1387,1402,1416,1429,1433,1438,1451,1476,1493,1497,1502,1516,1529,1547,1551,1556,1570,1583,1587,1592,1614,1637],{"__ignoreMap":39},[43,1258,1259],{"class":45,"line":46},[43,1260,1261],{"class":49},"\u002F\u002F ── `==` triggers type coercion; `===` checks type first ──\n",[43,1263,1264],{"class":45,"line":53},[43,1265,1266],{"class":49},"\u002F\u002F The Abstract Equality Algorithm (ECMA-262 §7.2.15) has ~20 rules.\n",[43,1268,1269],{"class":45,"line":59},[43,1270,1271],{"class":49},"\u002F\u002F Key rules (the most surprising ones):\n",[43,1273,1274],{"class":45,"line":65},[43,1275,75],{"emptyLinePlaceholder":74},[43,1277,1278],{"class":45,"line":71},[43,1279,1280],{"class":49},"\u002F\u002F Rule 1: number ↔ string → string is coerced to number\n",[43,1282,1283,1285,1288,1291,1293],{"class":45,"line":78},[43,1284,423],{"class":108},[43,1286,1287],{"class":87}," ==",[43,1289,1290],{"class":852}," \"1\"",[43,1292,375],{"class":95},[43,1294,1295],{"class":49},"\u002F\u002F true — \"1\" → 1 (ToNumber(\"1\") = 1)\n",[43,1297,1298,1300,1302,1305,1307],{"class":45,"line":84},[43,1299,610],{"class":108},[43,1301,1287],{"class":87},[43,1303,1304],{"class":852}," \"\"",[43,1306,440],{"class":95},[43,1308,1309],{"class":49},"\u002F\u002F true — \"\" → 0 (ToNumber(\"\") = 0)\n",[43,1311,1312,1314,1316,1319,1321],{"class":45,"line":99},[43,1313,610],{"class":108},[43,1315,1287],{"class":87},[43,1317,1318],{"class":852}," \"0\"",[43,1320,375],{"class":95},[43,1322,1323],{"class":49},"\u002F\u002F true — \"0\" → 0\n",[43,1325,1326],{"class":45,"line":115},[43,1327,75],{"emptyLinePlaceholder":74},[43,1329,1330],{"class":45,"line":136},[43,1331,1332],{"class":49},"\u002F\u002F Rule 2: boolean → number (true → 1, false → 0)\n",[43,1334,1335,1337,1339,1342,1345],{"class":45,"line":142},[43,1336,423],{"class":108},[43,1338,1287],{"class":87},[43,1340,1341],{"class":108}," true",[43,1343,1344],{"class":95},";      ",[43,1346,1347],{"class":49},"\u002F\u002F true — true → 1\n",[43,1349,1350,1352,1354,1357,1360],{"class":45,"line":157},[43,1351,610],{"class":108},[43,1353,1287],{"class":87},[43,1355,1356],{"class":108}," false",[43,1358,1359],{"class":95},";    ",[43,1361,1362],{"class":49},"\u002F\u002F true — false → 0\n",[43,1364,1365,1368,1370,1372,1375],{"class":45,"line":163},[43,1366,1367],{"class":852},"\"\"",[43,1369,1287],{"class":87},[43,1371,1356],{"class":108},[43,1373,1374],{"class":95},";   ",[43,1376,1377],{"class":49},"\u002F\u002F true — \"\" → 0, false → 0 → 0 == 0\n",[43,1379,1380],{"class":45,"line":169},[43,1381,75],{"emptyLinePlaceholder":74},[43,1383,1384],{"class":45,"line":175},[43,1385,1386],{"class":49},"\u002F\u002F Rule 3: null == undefined (special case — only each other)\n",[43,1388,1389,1392,1394,1397,1399],{"class":45,"line":180},[43,1390,1391],{"class":108},"null",[43,1393,1287],{"class":87},[43,1395,1396],{"class":108}," undefined",[43,1398,130],{"class":95},[43,1400,1401],{"class":49},"\u002F\u002F true (special rule — they're \"loosely equal\")\n",[43,1403,1404,1406,1408,1410,1413],{"class":45,"line":186},[43,1405,1391],{"class":108},[43,1407,1287],{"class":87},[43,1409,571],{"class":108},[43,1411,1412],{"class":95},";           ",[43,1414,1415],{"class":49},"\u002F\u002F false (null is NOT coerced to 0 for ==)\n",[43,1417,1418,1420,1422,1424,1426],{"class":45,"line":196},[43,1419,1391],{"class":108},[43,1421,1287],{"class":87},[43,1423,1356],{"class":108},[43,1425,375],{"class":95},[43,1427,1428],{"class":49},"\u002F\u002F false\n",[43,1430,1431],{"class":45,"line":207},[43,1432,75],{"emptyLinePlaceholder":74},[43,1434,1435],{"class":45,"line":226},[43,1436,1437],{"class":49},"\u002F\u002F Rule 4: object → primitive (via ToPrimitive, which calls valueOf\u002FtoString)\n",[43,1439,1440,1443,1445,1448],{"class":45,"line":231},[43,1441,1442],{"class":852},"\"[object Object]\"",[43,1444,1287],{"class":87},[43,1446,1447],{"class":95}," {};       ",[43,1449,1450],{"class":49},"\u002F\u002F true — {} → \"[object Object]\"\n",[43,1452,1453,1456,1458,1460,1462,1464,1466,1468,1470,1473],{"class":45,"line":244},[43,1454,1455],{"class":852},"\"1,2,3\"",[43,1457,1287],{"class":87},[43,1459,983],{"class":95},[43,1461,423],{"class":108},[43,1463,988],{"class":95},[43,1465,991],{"class":108},[43,1467,988],{"class":95},[43,1469,996],{"class":108},[43,1471,1472],{"class":95},"];         ",[43,1474,1475],{"class":49},"\u002F\u002F true — array → \"1,2,3\" → \"1,2,3\" == \"1,2,3\"\n",[43,1477,1478,1481,1483,1485,1487,1490],{"class":45,"line":249},[43,1479,1480],{"class":852},"\"1\"",[43,1482,1287],{"class":87},[43,1484,983],{"class":95},[43,1486,423],{"class":108},[43,1488,1489],{"class":95},"];                    ",[43,1491,1492],{"class":49},"\u002F\u002F true — [1] → \"1\" → 1 == 1\n",[43,1494,1495],{"class":45,"line":254},[43,1496,75],{"emptyLinePlaceholder":74},[43,1498,1499],{"class":45,"line":260},[43,1500,1501],{"class":49},"\u002F\u002F ── NaN: the only value not equal to itself ──\n",[43,1503,1504,1507,1509,1512,1514],{"class":45,"line":266},[43,1505,1506],{"class":108},"NaN",[43,1508,1287],{"class":87},[43,1510,1511],{"class":108}," NaN",[43,1513,1374],{"class":95},[43,1515,1428],{"class":49},[43,1517,1518,1520,1523,1525,1527],{"class":45,"line":280},[43,1519,1506],{"class":108},[43,1521,1522],{"class":87}," ===",[43,1524,1511],{"class":108},[43,1526,130],{"class":95},[43,1528,1428],{"class":49},[43,1530,1531,1534,1537,1539,1541,1544],{"class":45,"line":296},[43,1532,1533],{"class":95},"Number.",[43,1535,1536],{"class":91},"isNaN",[43,1538,729],{"class":95},[43,1540,1506],{"class":108},[43,1542,1543],{"class":95},");  ",[43,1545,1546],{"class":49},"\u002F\u002F true (correct — doesn't coerce)\n",[43,1548,1549],{"class":45,"line":301},[43,1550,75],{"emptyLinePlaceholder":74},[43,1552,1553],{"class":45,"line":314},[43,1554,1555],{"class":49},"\u002F\u002F ── `===` is always safer: no coercion, checks type first ──\n",[43,1557,1558,1560,1562,1564,1567],{"class":45,"line":328},[43,1559,423],{"class":108},[43,1561,1522],{"class":87},[43,1563,1290],{"class":852},[43,1565,1566],{"class":95},";     ",[43,1568,1569],{"class":49},"\u002F\u002F false (different types — immediate false)\n",[43,1571,1572,1574,1576,1578,1580],{"class":45,"line":333},[43,1573,1391],{"class":108},[43,1575,1522],{"class":87},[43,1577,1396],{"class":108},[43,1579,130],{"class":95},[43,1581,1582],{"class":49},"\u002F\u002F false (different types)\n",[43,1584,1585],{"class":45,"line":339},[43,1586,75],{"emptyLinePlaceholder":74},[43,1588,1589],{"class":45,"line":345},[43,1590,1591],{"class":49},"\u002F\u002F ── Object.is: the \"truly correct\" equality (handles NaN and -0) ──\n",[43,1593,1594,1597,1600,1602,1604,1606,1608,1611],{"class":45,"line":351},[43,1595,1596],{"class":95},"Object.",[43,1598,1599],{"class":91},"is",[43,1601,729],{"class":95},[43,1603,1506],{"class":108},[43,1605,988],{"class":95},[43,1607,1506],{"class":108},[43,1609,1610],{"class":95},");    ",[43,1612,1613],{"class":49},"\u002F\u002F true (unlike == and ===)\n",[43,1615,1616,1618,1620,1622,1625,1627,1629,1631,1634],{"class":45,"line":363},[43,1617,1596],{"class":95},[43,1619,1599],{"class":91},[43,1621,729],{"class":95},[43,1623,1624],{"class":87},"-",[43,1626,610],{"class":108},[43,1628,988],{"class":95},[43,1630,610],{"class":108},[43,1632,1633],{"class":95},");       ",[43,1635,1636],{"class":49},"\u002F\u002F false (unlike === which says -0 === 0 → true)\n",[43,1638,1639,1641,1643,1645,1647,1649,1651,1653],{"class":45,"line":381},[43,1640,1596],{"class":95},[43,1642,1599],{"class":91},[43,1644,729],{"class":95},[43,1646,610],{"class":108},[43,1648,988],{"class":95},[43,1650,610],{"class":108},[43,1652,1633],{"class":95},[43,1654,1655],{"class":49},"\u002F\u002F true\n",[15,1657,1659],{"id":1658},"anti-pattern-implicit-coercion-in-conditionals","Anti-Pattern: Implicit Coercion in Conditionals",[31,1661,1662],{"language":33},[35,1663,1665],{"className":37,"code":1664,"language":33,"meta":39,"style":39},"\u002F\u002F ❌ NAIVE — relies on implicit coercion (surprising results)\nfunction process(data) {\n    if (data) {            \u002F\u002F empty array [] is truthy! empty string \"\" is falsy\n        doWork(data);\n    }\n}\nprocess([]);  \u002F\u002F [] is truthy — doWork runs with empty array (probably not intended)\nprocess(\"\");  \u002F\u002F \"\" is falsy — doWork doesn't run (maybe intended, maybe not)\n\n\u002F\u002F ✅ CORRECT — explicit checks\nfunction processSafe(data) {\n    if (data != null && typeof data === \"object\" && data.length > 0) {\n        doWork(data);  \u002F\u002F explicit: not null, is object, has elements\n    }\n}\n\n\u002F\u002F ── The 8 falsy values ──\n\u002F\u002F false, 0, -0, 0n, \"\", null, undefined, NaN\n\u002F\u002F Everything else is truthy (including [], {}, \"0\", \"false\", Infinity)\n\n\u002F\u002F ── ⚠️ `0` and `\"\"` are falsy — `??` vs `||` matters ──\nlet count = 0;\nlet default1 = count || 10;    \u002F\u002F 10 — || treats 0 as falsy, uses default\nlet default2 = count ?? 10;   \u002F\u002F 0 — ?? only uses default for null\u002Fundefined\n\nlet name = \"\";\nlet n1 = name || \"Anonymous\";  \u002F\u002F \"Anonymous\" — || treats \"\" as falsy\nlet n2 = name ?? \"Anonymous\"; \u002F\u002F \"\" — ?? keeps empty string\n\n\u002F\u002F ── `??` (nullish coalescing) only triggers on null\u002Fundefined ──\n\u002F\u002F Use ?? for \"optional with fallback\"; use || for \"falsy with fallback\"\nlet port = config.port ?? 3000;  \u002F\u002F 3000 only if config.port is null\u002Fundefined\nlet mode = config.mode || \"prod\"; \u002F\u002F \"prod\" if config.mode is any falsy value\n",[19,1666,1667,1672,1686,1696,1704,1708,1712,1723,1736,1740,1745,1758,1801,1811,1815,1819,1823,1828,1833,1838,1842,1847,1860,1881,1902,1906,1919,1940,1961,1965,1970,1975,1997],{"__ignoreMap":39},[43,1668,1669],{"class":45,"line":46},[43,1670,1671],{"class":49},"\u002F\u002F ❌ NAIVE — relies on implicit coercion (surprising results)\n",[43,1673,1674,1676,1679,1681,1684],{"class":45,"line":53},[43,1675,88],{"class":87},[43,1677,1678],{"class":91}," process",[43,1680,729],{"class":95},[43,1682,1683],{"class":732},"data",[43,1685,112],{"class":95},[43,1687,1688,1690,1693],{"class":45,"line":59},[43,1689,102],{"class":87},[43,1691,1692],{"class":95}," (data) {            ",[43,1694,1695],{"class":49},"\u002F\u002F empty array [] is truthy! empty string \"\" is falsy\n",[43,1697,1698,1701],{"class":45,"line":65},[43,1699,1700],{"class":91},"        doWork",[43,1702,1703],{"class":95},"(data);\n",[43,1705,1706],{"class":45,"line":71},[43,1707,139],{"class":95},[43,1709,1710],{"class":45,"line":78},[43,1711,160],{"class":95},[43,1713,1714,1717,1720],{"class":45,"line":84},[43,1715,1716],{"class":91},"process",[43,1718,1719],{"class":95},"([]);  ",[43,1721,1722],{"class":49},"\u002F\u002F [] is truthy — doWork runs with empty array (probably not intended)\n",[43,1724,1725,1727,1729,1731,1733],{"class":45,"line":99},[43,1726,1716],{"class":91},[43,1728,729],{"class":95},[43,1730,1367],{"class":852},[43,1732,1543],{"class":95},[43,1734,1735],{"class":49},"\u002F\u002F \"\" is falsy — doWork doesn't run (maybe intended, maybe not)\n",[43,1737,1738],{"class":45,"line":115},[43,1739,75],{"emptyLinePlaceholder":74},[43,1741,1742],{"class":45,"line":136},[43,1743,1744],{"class":49},"\u002F\u002F ✅ CORRECT — explicit checks\n",[43,1746,1747,1749,1752,1754,1756],{"class":45,"line":142},[43,1748,88],{"class":87},[43,1750,1751],{"class":91}," processSafe",[43,1753,729],{"class":95},[43,1755,1683],{"class":732},[43,1757,112],{"class":95},[43,1759,1760,1762,1765,1768,1771,1774,1777,1780,1783,1786,1788,1791,1794,1797,1799],{"class":45,"line":157},[43,1761,102],{"class":87},[43,1763,1764],{"class":95}," (data ",[43,1766,1767],{"class":87},"!=",[43,1769,1770],{"class":108}," null",[43,1772,1773],{"class":87}," &&",[43,1775,1776],{"class":87}," typeof",[43,1778,1779],{"class":95}," data ",[43,1781,1782],{"class":87},"===",[43,1784,1785],{"class":852}," \"object\"",[43,1787,1773],{"class":87},[43,1789,1790],{"class":95}," data.",[43,1792,1793],{"class":108},"length",[43,1795,1796],{"class":87}," >",[43,1798,571],{"class":108},[43,1800,112],{"class":95},[43,1802,1803,1805,1808],{"class":45,"line":163},[43,1804,1700],{"class":91},[43,1806,1807],{"class":95},"(data);  ",[43,1809,1810],{"class":49},"\u002F\u002F explicit: not null, is object, has elements\n",[43,1812,1813],{"class":45,"line":169},[43,1814,139],{"class":95},[43,1816,1817],{"class":45,"line":175},[43,1818,160],{"class":95},[43,1820,1821],{"class":45,"line":180},[43,1822,75],{"emptyLinePlaceholder":74},[43,1824,1825],{"class":45,"line":186},[43,1826,1827],{"class":49},"\u002F\u002F ── The 8 falsy values ──\n",[43,1829,1830],{"class":45,"line":196},[43,1831,1832],{"class":49},"\u002F\u002F false, 0, -0, 0n, \"\", null, undefined, NaN\n",[43,1834,1835],{"class":45,"line":207},[43,1836,1837],{"class":49},"\u002F\u002F Everything else is truthy (including [], {}, \"0\", \"false\", Infinity)\n",[43,1839,1840],{"class":45,"line":226},[43,1841,75],{"emptyLinePlaceholder":74},[43,1843,1844],{"class":45,"line":231},[43,1845,1846],{"class":49},"\u002F\u002F ── ⚠️ `0` and `\"\"` are falsy — `??` vs `||` matters ──\n",[43,1848,1849,1851,1854,1856,1858],{"class":45,"line":244},[43,1850,21],{"class":87},[43,1852,1853],{"class":95}," count ",[43,1855,124],{"class":87},[43,1857,571],{"class":108},[43,1859,293],{"class":95},[43,1861,1862,1864,1867,1869,1871,1874,1876,1878],{"class":45,"line":249},[43,1863,21],{"class":87},[43,1865,1866],{"class":95}," default1 ",[43,1868,124],{"class":87},[43,1870,1853],{"class":95},[43,1872,1873],{"class":87},"||",[43,1875,127],{"class":108},[43,1877,1359],{"class":95},[43,1879,1880],{"class":49},"\u002F\u002F 10 — || treats 0 as falsy, uses default\n",[43,1882,1883,1885,1888,1890,1892,1895,1897,1899],{"class":45,"line":254},[43,1884,21],{"class":87},[43,1886,1887],{"class":95}," default2 ",[43,1889,124],{"class":87},[43,1891,1853],{"class":95},[43,1893,1894],{"class":87},"??",[43,1896,127],{"class":108},[43,1898,1374],{"class":95},[43,1900,1901],{"class":49},"\u002F\u002F 0 — ?? only uses default for null\u002Fundefined\n",[43,1903,1904],{"class":45,"line":260},[43,1905,75],{"emptyLinePlaceholder":74},[43,1907,1908,1910,1913,1915,1917],{"class":45,"line":266},[43,1909,21],{"class":87},[43,1911,1912],{"class":95}," name ",[43,1914,124],{"class":87},[43,1916,1304],{"class":852},[43,1918,293],{"class":95},[43,1920,1921,1923,1926,1928,1930,1932,1935,1937],{"class":45,"line":280},[43,1922,21],{"class":87},[43,1924,1925],{"class":95}," n1 ",[43,1927,124],{"class":87},[43,1929,1912],{"class":95},[43,1931,1873],{"class":87},[43,1933,1934],{"class":852}," \"Anonymous\"",[43,1936,130],{"class":95},[43,1938,1939],{"class":49},"\u002F\u002F \"Anonymous\" — || treats \"\" as falsy\n",[43,1941,1942,1944,1947,1949,1951,1953,1955,1958],{"class":45,"line":296},[43,1943,21],{"class":87},[43,1945,1946],{"class":95}," n2 ",[43,1948,124],{"class":87},[43,1950,1912],{"class":95},[43,1952,1894],{"class":87},[43,1954,1934],{"class":852},[43,1956,1957],{"class":95},"; ",[43,1959,1960],{"class":49},"\u002F\u002F \"\" — ?? keeps empty string\n",[43,1962,1963],{"class":45,"line":301},[43,1964,75],{"emptyLinePlaceholder":74},[43,1966,1967],{"class":45,"line":314},[43,1968,1969],{"class":49},"\u002F\u002F ── `??` (nullish coalescing) only triggers on null\u002Fundefined ──\n",[43,1971,1972],{"class":45,"line":328},[43,1973,1974],{"class":49},"\u002F\u002F Use ?? for \"optional with fallback\"; use || for \"falsy with fallback\"\n",[43,1976,1977,1979,1982,1984,1987,1989,1992,1994],{"class":45,"line":333},[43,1978,21],{"class":87},[43,1980,1981],{"class":95}," port ",[43,1983,124],{"class":87},[43,1985,1986],{"class":95}," config.port ",[43,1988,1894],{"class":87},[43,1990,1991],{"class":108}," 3000",[43,1993,130],{"class":95},[43,1995,1996],{"class":49},"\u002F\u002F 3000 only if config.port is null\u002Fundefined\n",[43,1998,1999,2001,2004,2006,2009,2011,2014,2016],{"class":45,"line":339},[43,2000,21],{"class":87},[43,2002,2003],{"class":95}," mode ",[43,2005,124],{"class":87},[43,2007,2008],{"class":95}," config.mode ",[43,2010,1873],{"class":87},[43,2012,2013],{"class":852}," \"prod\"",[43,2015,1957],{"class":95},[43,2017,2018],{"class":49},"\u002F\u002F \"prod\" if config.mode is any falsy value\n",[15,2020,2022],{"id":2021},"primitive-type-checking-the-reliable-way","Primitive Type Checking: The Reliable Way",[31,2024,2025],{"language":33},[35,2026,2028],{"className":37,"code":2027,"language":33,"meta":39,"style":39},"\u002F\u002F ── typeof: works for primitives, unreliable for objects ──\ntypeof \"str\";        \u002F\u002F \"string\"\ntypeof 42;           \u002F\u002F \"number\"\ntypeof true;         \u002F\u002F \"boolean\"\ntypeof undefined;    \u002F\u002F \"undefined\"\ntypeof null;         \u002F\u002F \"object\" ⚠️ BUG (null is primitive, not object)\ntypeof Symbol();    \u002F\u002F \"symbol\"\ntypeof 42n;         \u002F\u002F \"bigint\"\n\ntypeof {};           \u002F\u002F \"object\"\ntypeof [];           \u002F\u002F \"object\" ⚠️ arrays are objects\ntypeof function(){}; \u002F\u002F \"function\"\ntypeof null;         \u002F\u002F \"object\" ⚠️ legendary bug\n\n\u002F\u002F ── Reliable type checks ──\nconst type = (val) => {\n    if (val === null) return \"null\";\n    if (Array.isArray(val)) return \"array\";\n    return typeof val;\n};\n\ntype(null);     \u002F\u002F \"null\"\ntype([]);       \u002F\u002F \"array\"\ntype({});       \u002F\u002F \"object\"\ntype(42);       \u002F\u002F \"number\"\n\n\u002F\u002F ── Object.prototype.toString (the most reliable) ──\nObject.prototype.toString.call(\"\");      \u002F\u002F \"[object String]\"\nObject.prototype.toString.call([]);      \u002F\u002F \"[object Array]\"\nObject.prototype.toString.call(null);    \u002F\u002F \"[object Null]\"\nObject.prototype.toString.call(new Map()); \u002F\u002F \"[object Map]\"\nObject.prototype.toString.call(async function(){}); \u002F\u002F \"[object AsyncFunction]\"\n\n\u002F\u002F ── instanceof: checks the prototype chain (reference types only) ──\n[] instanceof Array;     \u002F\u002F true\n[] instanceof Object;    \u002F\u002F true (Array extends Object — prototype chain)\n({}) instanceof Object;  \u002F\u002F true\nnew Map() instanceof Map; \u002F\u002F true\n\n\u002F\u002F ⚠️ instanceof breaks across realms (iframes, worker threads)\n\u002F\u002F Each realm has its own copy of Array → an array from an iframe is NOT instanceof Array\n\u002F\u002F Use Array.isArray() for arrays — works across realms\n",[19,2029,2030,2035,2048,2059,2071,2082,2093,2106,2119,2123,2133,2143,2156,2167,2171,2176,2198,2219,2239,2249,2254,2258,2273,2283,2292,2305,2309,2314,2341,2359,2380,2406,2431,2435,2440,2455,2469,2482,2499,2503,2508,2513],{"__ignoreMap":39},[43,2031,2032],{"class":45,"line":46},[43,2033,2034],{"class":49},"\u002F\u002F ── typeof: works for primitives, unreliable for objects ──\n",[43,2036,2037,2040,2043,2045],{"class":45,"line":53},[43,2038,2039],{"class":87},"typeof",[43,2041,2042],{"class":852}," \"str\"",[43,2044,440],{"class":95},[43,2046,2047],{"class":49},"\u002F\u002F \"string\"\n",[43,2049,2050,2052,2054,2056],{"class":45,"line":59},[43,2051,2039],{"class":87},[43,2053,910],{"class":108},[43,2055,1412],{"class":95},[43,2057,2058],{"class":49},"\u002F\u002F \"number\"\n",[43,2060,2061,2063,2065,2068],{"class":45,"line":65},[43,2062,2039],{"class":87},[43,2064,1341],{"class":108},[43,2066,2067],{"class":95},";         ",[43,2069,2070],{"class":49},"\u002F\u002F \"boolean\"\n",[43,2072,2073,2075,2077,2079],{"class":45,"line":71},[43,2074,2039],{"class":87},[43,2076,1396],{"class":108},[43,2078,1359],{"class":95},[43,2080,2081],{"class":49},"\u002F\u002F \"undefined\"\n",[43,2083,2084,2086,2088,2090],{"class":45,"line":78},[43,2085,2039],{"class":87},[43,2087,1770],{"class":108},[43,2089,2067],{"class":95},[43,2091,2092],{"class":49},"\u002F\u002F \"object\" ⚠️ BUG (null is primitive, not object)\n",[43,2094,2095,2097,2100,2103],{"class":45,"line":84},[43,2096,2039],{"class":87},[43,2098,2099],{"class":91}," Symbol",[43,2101,2102],{"class":95},"();    ",[43,2104,2105],{"class":49},"\u002F\u002F \"symbol\"\n",[43,2107,2108,2110,2112,2114,2116],{"class":45,"line":99},[43,2109,2039],{"class":87},[43,2111,910],{"class":108},[43,2113,1062],{"class":87},[43,2115,2067],{"class":95},[43,2117,2118],{"class":49},"\u002F\u002F \"bigint\"\n",[43,2120,2121],{"class":45,"line":115},[43,2122,75],{"emptyLinePlaceholder":74},[43,2124,2125,2127,2130],{"class":45,"line":136},[43,2126,2039],{"class":87},[43,2128,2129],{"class":95}," {};           ",[43,2131,2132],{"class":49},"\u002F\u002F \"object\"\n",[43,2134,2135,2137,2140],{"class":45,"line":142},[43,2136,2039],{"class":87},[43,2138,2139],{"class":95}," [];           ",[43,2141,2142],{"class":49},"\u002F\u002F \"object\" ⚠️ arrays are objects\n",[43,2144,2145,2147,2150,2153],{"class":45,"line":157},[43,2146,2039],{"class":87},[43,2148,2149],{"class":87}," function",[43,2151,2152],{"class":95},"(){}; ",[43,2154,2155],{"class":49},"\u002F\u002F \"function\"\n",[43,2157,2158,2160,2162,2164],{"class":45,"line":163},[43,2159,2039],{"class":87},[43,2161,1770],{"class":108},[43,2163,2067],{"class":95},[43,2165,2166],{"class":49},"\u002F\u002F \"object\" ⚠️ legendary bug\n",[43,2168,2169],{"class":45,"line":169},[43,2170,75],{"emptyLinePlaceholder":74},[43,2172,2173],{"class":45,"line":175},[43,2174,2175],{"class":49},"\u002F\u002F ── Reliable type checks ──\n",[43,2177,2178,2180,2183,2185,2187,2190,2193,2195],{"class":45,"line":180},[43,2179,25],{"class":87},[43,2181,2182],{"class":91}," type",[43,2184,417],{"class":87},[43,2186,105],{"class":95},[43,2188,2189],{"class":732},"val",[43,2191,2192],{"class":95},") ",[43,2194,599],{"class":87},[43,2196,2197],{"class":95}," {\n",[43,2199,2200,2202,2205,2207,2209,2211,2214,2217],{"class":45,"line":186},[43,2201,102],{"class":87},[43,2203,2204],{"class":95}," (val ",[43,2206,1782],{"class":87},[43,2208,1770],{"class":108},[43,2210,2192],{"class":95},[43,2212,2213],{"class":87},"return",[43,2215,2216],{"class":852}," \"null\"",[43,2218,293],{"class":95},[43,2220,2221,2223,2226,2229,2232,2234,2237],{"class":45,"line":196},[43,2222,102],{"class":87},[43,2224,2225],{"class":95}," (Array.",[43,2227,2228],{"class":91},"isArray",[43,2230,2231],{"class":95},"(val)) ",[43,2233,2213],{"class":87},[43,2235,2236],{"class":852}," \"array\"",[43,2238,293],{"class":95},[43,2240,2241,2244,2246],{"class":45,"line":207},[43,2242,2243],{"class":87},"    return",[43,2245,1776],{"class":87},[43,2247,2248],{"class":95}," val;\n",[43,2250,2251],{"class":45,"line":226},[43,2252,2253],{"class":95},"};\n",[43,2255,2256],{"class":45,"line":231},[43,2257,75],{"emptyLinePlaceholder":74},[43,2259,2260,2263,2265,2267,2270],{"class":45,"line":244},[43,2261,2262],{"class":91},"type",[43,2264,729],{"class":95},[43,2266,1391],{"class":108},[43,2268,2269],{"class":95},");     ",[43,2271,2272],{"class":49},"\u002F\u002F \"null\"\n",[43,2274,2275,2277,2280],{"class":45,"line":249},[43,2276,2262],{"class":91},[43,2278,2279],{"class":95},"([]);       ",[43,2281,2282],{"class":49},"\u002F\u002F \"array\"\n",[43,2284,2285,2287,2290],{"class":45,"line":254},[43,2286,2262],{"class":91},[43,2288,2289],{"class":95},"({});       ",[43,2291,2132],{"class":49},[43,2293,2294,2296,2298,2301,2303],{"class":45,"line":260},[43,2295,2262],{"class":91},[43,2297,729],{"class":95},[43,2299,2300],{"class":108},"42",[43,2302,1633],{"class":95},[43,2304,2058],{"class":49},[43,2306,2307],{"class":45,"line":266},[43,2308,75],{"emptyLinePlaceholder":74},[43,2310,2311],{"class":45,"line":280},[43,2312,2313],{"class":49},"\u002F\u002F ── Object.prototype.toString (the most reliable) ──\n",[43,2315,2316,2319,2322,2325,2328,2331,2333,2335,2338],{"class":45,"line":296},[43,2317,2318],{"class":108},"Object",[43,2320,2321],{"class":95},".",[43,2323,2324],{"class":108},"prototype",[43,2326,2327],{"class":95},".toString.",[43,2329,2330],{"class":91},"call",[43,2332,729],{"class":95},[43,2334,1367],{"class":852},[43,2336,2337],{"class":95},");      ",[43,2339,2340],{"class":49},"\u002F\u002F \"[object String]\"\n",[43,2342,2343,2345,2347,2349,2351,2353,2356],{"class":45,"line":301},[43,2344,2318],{"class":108},[43,2346,2321],{"class":95},[43,2348,2324],{"class":108},[43,2350,2327],{"class":95},[43,2352,2330],{"class":91},[43,2354,2355],{"class":95},"([]);      ",[43,2357,2358],{"class":49},"\u002F\u002F \"[object Array]\"\n",[43,2360,2361,2363,2365,2367,2369,2371,2373,2375,2377],{"class":45,"line":314},[43,2362,2318],{"class":108},[43,2364,2321],{"class":95},[43,2366,2324],{"class":108},[43,2368,2327],{"class":95},[43,2370,2330],{"class":91},[43,2372,729],{"class":95},[43,2374,1391],{"class":108},[43,2376,1610],{"class":95},[43,2378,2379],{"class":49},"\u002F\u002F \"[object Null]\"\n",[43,2381,2382,2384,2386,2388,2390,2392,2394,2397,2400,2403],{"class":45,"line":328},[43,2383,2318],{"class":108},[43,2385,2321],{"class":95},[43,2387,2324],{"class":108},[43,2389,2327],{"class":95},[43,2391,2330],{"class":91},[43,2393,729],{"class":95},[43,2395,2396],{"class":87},"new",[43,2398,2399],{"class":91}," Map",[43,2401,2402],{"class":95},"()); ",[43,2404,2405],{"class":49},"\u002F\u002F \"[object Map]\"\n",[43,2407,2408,2410,2412,2414,2416,2418,2420,2423,2425,2428],{"class":45,"line":333},[43,2409,2318],{"class":108},[43,2411,2321],{"class":95},[43,2413,2324],{"class":108},[43,2415,2327],{"class":95},[43,2417,2330],{"class":91},[43,2419,729],{"class":95},[43,2421,2422],{"class":87},"async",[43,2424,2149],{"class":87},[43,2426,2427],{"class":95},"(){}); ",[43,2429,2430],{"class":49},"\u002F\u002F \"[object AsyncFunction]\"\n",[43,2432,2433],{"class":45,"line":339},[43,2434,75],{"emptyLinePlaceholder":74},[43,2436,2437],{"class":45,"line":345},[43,2438,2439],{"class":49},"\u002F\u002F ── instanceof: checks the prototype chain (reference types only) ──\n",[43,2441,2442,2445,2448,2451,2453],{"class":45,"line":351},[43,2443,2444],{"class":95},"[] ",[43,2446,2447],{"class":87},"instanceof",[43,2449,2450],{"class":91}," Array",[43,2452,1566],{"class":95},[43,2454,1655],{"class":49},[43,2456,2457,2459,2461,2464,2466],{"class":45,"line":363},[43,2458,2444],{"class":95},[43,2460,2447],{"class":87},[43,2462,2463],{"class":91}," Object",[43,2465,1359],{"class":95},[43,2467,2468],{"class":49},"\u002F\u002F true (Array extends Object — prototype chain)\n",[43,2470,2471,2474,2476,2478,2480],{"class":45,"line":381},[43,2472,2473],{"class":95},"({}) ",[43,2475,2447],{"class":87},[43,2477,2463],{"class":91},[43,2479,130],{"class":95},[43,2481,1655],{"class":49},[43,2483,2484,2486,2488,2491,2493,2495,2497],{"class":45,"line":393},[43,2485,2396],{"class":87},[43,2487,2399],{"class":91},[43,2489,2490],{"class":95},"() ",[43,2492,2447],{"class":87},[43,2494,2399],{"class":91},[43,2496,1957],{"class":95},[43,2498,1655],{"class":49},[43,2500,2501],{"class":45,"line":398},[43,2502,75],{"emptyLinePlaceholder":74},[43,2504,2505],{"class":45,"line":403},[43,2506,2507],{"class":49},"\u002F\u002F ⚠️ instanceof breaks across realms (iframes, worker threads)\n",[43,2509,2510],{"class":45,"line":409},[43,2511,2512],{"class":49},"\u002F\u002F Each realm has its own copy of Array → an array from an iframe is NOT instanceof Array\n",[43,2514,2515],{"class":45,"line":429},[43,2516,2517],{"class":49},"\u002F\u002F Use Array.isArray() for arrays — works across realms\n",[15,2519,2521],{"id":2520},"number-internals-ieee-754-double-precision","Number Internals: IEEE 754 Double Precision",[31,2523,2524],{"language":33},[35,2525,2527],{"className":37,"code":2526,"language":33,"meta":39,"style":39},"\u002F\u002F ── JS numbers are IEEE 754 double-precision floats (64-bit) ──\n\u002F\u002F 1 bit sign, 11 bits exponent, 52 bits mantissa (53-bit significand)\n\u002F\u002F Safe integer range: -(2^53 - 1) to (2^53 - 1) = -9007199254740991 to 9007199254740991\n\nconsole.log(Number.MAX_SAFE_INTEGER);  \u002F\u002F 9007199254740991 (2^53 - 1)\nconsole.log(Number.MIN_SAFE_INTEGER);  \u002F\u002F -9007199254740991\nconsole.log(Number.MAX_VALUE);         \u002F\u002F 1.7976931348623157e+308\nconsole.log(Number.EPSILON);           \u002F\u002F 2.220446049250313e-16\n\n\u002F\u002F ── Precision loss beyond MAX_SAFE_INTEGER ──\nconsole.log(9007199254740991 + 1);  \u002F\u002F 9007199254740992 (correct)\nconsole.log(9007199254740991 + 2);  \u002F\u002F 9007199254740992 (WRONG! precision lost)\nconsole.log(9007199254740993 === 9007199254740992);  \u002F\u002F true (can't distinguish)\n\n\u002F\u002F ── 0.1 + 0.2 !== 0.3 (classic floating-point bug) ──\nconsole.log(0.1 + 0.2);          \u002F\u002F 0.30000000000000004\nconsole.log(0.1 + 0.2 === 0.3);  \u002F\u002F false\n\n\u002F\u002F ✅ Fix: use Number.EPSILON for comparison\nfunction approxEqual(a, b, eps = Number.EPSILON) {\n    return Math.abs(a - b) \u003C eps;\n}\nconsole.log(approxEqual(0.1 + 0.2, 0.3));  \u002F\u002F true\n\n\u002F\u002F ✅ Fix for money: use integer cents or BigDecimal library\nfunction addMoney(a, b) {\n    return (Math.round(a * 100) + Math.round(b * 100)) \u002F 100;  \u002F\u002F work in cents\n}\nconsole.log(addMoney(0.1, 0.2));  \u002F\u002F 0.3\n\n\u002F\u002F ── BigInt: arbitrary-precision integers (no precision loss) ──\nconst big = 9007199254740993n;  \u002F\u002F n suffix → BigInt\nconsole.log(big + 1n);          \u002F\u002F 9007199254740994n (correct!)\n\u002F\u002F ⚠️ BigInt can't mix with regular numbers: big + 1 → TypeError\n\u002F\u002F BigInt is for integers only — no decimals: 1n \u002F 2n → 0n (truncated)\n\n\u002F\u002F ── -0 exists (negative zero) ──\nconsole.log(-0 === 0);         \u002F\u002F true (=== can't distinguish)\nconsole.log(Object.is(-0, 0)); \u002F\u002F false (Object.is can)\nconsole.log(1 \u002F -0);           \u002F\u002F -Infinity (negative zero matters for division)\nconsole.log(Math.sign(-0));   \u002F\u002F -1 (Math.sign distinguishes -0)\n",[19,2528,2529,2534,2539,2544,2548,2560,2572,2584,2596,2600,2605,2627,2646,2667,2671,2676,2698,2721,2725,2730,2757,2780,2784,2813,2817,2822,2839,2886,2890,2915,2919,2924,2943,2963,2968,2973,2977,2982,3004,3031,3055],{"__ignoreMap":39},[43,2530,2531],{"class":45,"line":46},[43,2532,2533],{"class":49},"\u002F\u002F ── JS numbers are IEEE 754 double-precision floats (64-bit) ──\n",[43,2535,2536],{"class":45,"line":53},[43,2537,2538],{"class":49},"\u002F\u002F 1 bit sign, 11 bits exponent, 52 bits mantissa (53-bit significand)\n",[43,2540,2541],{"class":45,"line":59},[43,2542,2543],{"class":49},"\u002F\u002F Safe integer range: -(2^53 - 1) to (2^53 - 1) = -9007199254740991 to 9007199254740991\n",[43,2545,2546],{"class":45,"line":65},[43,2547,75],{"emptyLinePlaceholder":74},[43,2549,2550,2552,2554,2557],{"class":45,"line":71},[43,2551,269],{"class":95},[43,2553,148],{"class":91},[43,2555,2556],{"class":95},"(Number.MAX_SAFE_INTEGER);  ",[43,2558,2559],{"class":49},"\u002F\u002F 9007199254740991 (2^53 - 1)\n",[43,2561,2562,2564,2566,2569],{"class":45,"line":78},[43,2563,269],{"class":95},[43,2565,148],{"class":91},[43,2567,2568],{"class":95},"(Number.MIN_SAFE_INTEGER);  ",[43,2570,2571],{"class":49},"\u002F\u002F -9007199254740991\n",[43,2573,2574,2576,2578,2581],{"class":45,"line":84},[43,2575,269],{"class":95},[43,2577,148],{"class":91},[43,2579,2580],{"class":95},"(Number.MAX_VALUE);         ",[43,2582,2583],{"class":49},"\u002F\u002F 1.7976931348623157e+308\n",[43,2585,2586,2588,2590,2593],{"class":45,"line":99},[43,2587,269],{"class":95},[43,2589,148],{"class":91},[43,2591,2592],{"class":95},"(Number.EPSILON);           ",[43,2594,2595],{"class":49},"\u002F\u002F 2.220446049250313e-16\n",[43,2597,2598],{"class":45,"line":115},[43,2599,75],{"emptyLinePlaceholder":74},[43,2601,2602],{"class":45,"line":136},[43,2603,2604],{"class":49},"\u002F\u002F ── Precision loss beyond MAX_SAFE_INTEGER ──\n",[43,2606,2607,2609,2611,2613,2616,2619,2622,2624],{"class":45,"line":142},[43,2608,269],{"class":95},[43,2610,148],{"class":91},[43,2612,729],{"class":95},[43,2614,2615],{"class":108},"9007199254740991",[43,2617,2618],{"class":87}," +",[43,2620,2621],{"class":108}," 1",[43,2623,1543],{"class":95},[43,2625,2626],{"class":49},"\u002F\u002F 9007199254740992 (correct)\n",[43,2628,2629,2631,2633,2635,2637,2639,2641,2643],{"class":45,"line":157},[43,2630,269],{"class":95},[43,2632,148],{"class":91},[43,2634,729],{"class":95},[43,2636,2615],{"class":108},[43,2638,2618],{"class":87},[43,2640,437],{"class":108},[43,2642,1543],{"class":95},[43,2644,2645],{"class":49},"\u002F\u002F 9007199254740992 (WRONG! precision lost)\n",[43,2647,2648,2650,2652,2654,2657,2659,2662,2664],{"class":45,"line":163},[43,2649,269],{"class":95},[43,2651,148],{"class":91},[43,2653,729],{"class":95},[43,2655,2656],{"class":108},"9007199254740993",[43,2658,1522],{"class":87},[43,2660,2661],{"class":108}," 9007199254740992",[43,2663,1543],{"class":95},[43,2665,2666],{"class":49},"\u002F\u002F true (can't distinguish)\n",[43,2668,2669],{"class":45,"line":169},[43,2670,75],{"emptyLinePlaceholder":74},[43,2672,2673],{"class":45,"line":175},[43,2674,2675],{"class":49},"\u002F\u002F ── 0.1 + 0.2 !== 0.3 (classic floating-point bug) ──\n",[43,2677,2678,2680,2682,2684,2687,2689,2692,2695],{"class":45,"line":180},[43,2679,269],{"class":95},[43,2681,148],{"class":91},[43,2683,729],{"class":95},[43,2685,2686],{"class":108},"0.1",[43,2688,2618],{"class":87},[43,2690,2691],{"class":108}," 0.2",[43,2693,2694],{"class":95},");          ",[43,2696,2697],{"class":49},"\u002F\u002F 0.30000000000000004\n",[43,2699,2700,2702,2704,2706,2708,2710,2712,2714,2717,2719],{"class":45,"line":186},[43,2701,269],{"class":95},[43,2703,148],{"class":91},[43,2705,729],{"class":95},[43,2707,2686],{"class":108},[43,2709,2618],{"class":87},[43,2711,2691],{"class":108},[43,2713,1522],{"class":87},[43,2715,2716],{"class":108}," 0.3",[43,2718,1543],{"class":95},[43,2720,1428],{"class":49},[43,2722,2723],{"class":45,"line":196},[43,2724,75],{"emptyLinePlaceholder":74},[43,2726,2727],{"class":45,"line":207},[43,2728,2729],{"class":49},"\u002F\u002F ✅ Fix: use Number.EPSILON for comparison\n",[43,2731,2732,2734,2737,2739,2742,2744,2747,2749,2752,2754],{"class":45,"line":226},[43,2733,88],{"class":87},[43,2735,2736],{"class":91}," approxEqual",[43,2738,729],{"class":95},[43,2740,2741],{"class":732},"a",[43,2743,988],{"class":95},[43,2745,2746],{"class":732},"b",[43,2748,988],{"class":95},[43,2750,2751],{"class":732},"eps",[43,2753,417],{"class":87},[43,2755,2756],{"class":95}," Number.EPSILON) {\n",[43,2758,2759,2761,2764,2767,2770,2772,2775,2777],{"class":45,"line":231},[43,2760,2243],{"class":87},[43,2762,2763],{"class":95}," Math.",[43,2765,2766],{"class":91},"abs",[43,2768,2769],{"class":95},"(a ",[43,2771,1624],{"class":87},[43,2773,2774],{"class":95}," b) ",[43,2776,577],{"class":87},[43,2778,2779],{"class":95}," eps;\n",[43,2781,2782],{"class":45,"line":244},[43,2783,160],{"class":95},[43,2785,2786,2788,2790,2792,2795,2797,2799,2801,2803,2805,2808,2811],{"class":45,"line":249},[43,2787,269],{"class":95},[43,2789,148],{"class":91},[43,2791,729],{"class":95},[43,2793,2794],{"class":91},"approxEqual",[43,2796,729],{"class":95},[43,2798,2686],{"class":108},[43,2800,2618],{"class":87},[43,2802,2691],{"class":108},[43,2804,988],{"class":95},[43,2806,2807],{"class":108},"0.3",[43,2809,2810],{"class":95},"));  ",[43,2812,1655],{"class":49},[43,2814,2815],{"class":45,"line":254},[43,2816,75],{"emptyLinePlaceholder":74},[43,2818,2819],{"class":45,"line":260},[43,2820,2821],{"class":49},"\u002F\u002F ✅ Fix for money: use integer cents or BigDecimal library\n",[43,2823,2824,2826,2829,2831,2833,2835,2837],{"class":45,"line":266},[43,2825,88],{"class":87},[43,2827,2828],{"class":91}," addMoney",[43,2830,729],{"class":95},[43,2832,2741],{"class":732},[43,2834,988],{"class":95},[43,2836,2746],{"class":732},[43,2838,112],{"class":95},[43,2840,2841,2843,2846,2849,2851,2854,2857,2859,2862,2864,2866,2869,2871,2873,2876,2879,2881,2883],{"class":45,"line":280},[43,2842,2243],{"class":87},[43,2844,2845],{"class":95}," (Math.",[43,2847,2848],{"class":91},"round",[43,2850,2769],{"class":95},[43,2852,2853],{"class":87},"*",[43,2855,2856],{"class":108}," 100",[43,2858,2192],{"class":95},[43,2860,2861],{"class":87},"+",[43,2863,2763],{"class":95},[43,2865,2848],{"class":91},[43,2867,2868],{"class":95},"(b ",[43,2870,2853],{"class":87},[43,2872,2856],{"class":108},[43,2874,2875],{"class":95},")) ",[43,2877,2878],{"class":87},"\u002F",[43,2880,2856],{"class":108},[43,2882,130],{"class":95},[43,2884,2885],{"class":49},"\u002F\u002F work in cents\n",[43,2887,2888],{"class":45,"line":296},[43,2889,160],{"class":95},[43,2891,2892,2894,2896,2898,2901,2903,2905,2907,2910,2912],{"class":45,"line":301},[43,2893,269],{"class":95},[43,2895,148],{"class":91},[43,2897,729],{"class":95},[43,2899,2900],{"class":91},"addMoney",[43,2902,729],{"class":95},[43,2904,2686],{"class":108},[43,2906,988],{"class":95},[43,2908,2909],{"class":108},"0.2",[43,2911,2810],{"class":95},[43,2913,2914],{"class":49},"\u002F\u002F 0.3\n",[43,2916,2917],{"class":45,"line":314},[43,2918,75],{"emptyLinePlaceholder":74},[43,2920,2921],{"class":45,"line":328},[43,2922,2923],{"class":49},"\u002F\u002F ── BigInt: arbitrary-precision integers (no precision loss) ──\n",[43,2925,2926,2928,2931,2933,2936,2938,2940],{"class":45,"line":333},[43,2927,25],{"class":87},[43,2929,2930],{"class":108}," big",[43,2932,417],{"class":87},[43,2934,2935],{"class":108}," 9007199254740993",[43,2937,1062],{"class":87},[43,2939,130],{"class":95},[43,2941,2942],{"class":49},"\u002F\u002F n suffix → BigInt\n",[43,2944,2945,2947,2949,2952,2954,2956,2958,2960],{"class":45,"line":339},[43,2946,269],{"class":95},[43,2948,148],{"class":91},[43,2950,2951],{"class":95},"(big ",[43,2953,2861],{"class":87},[43,2955,2621],{"class":108},[43,2957,1062],{"class":87},[43,2959,2694],{"class":95},[43,2961,2962],{"class":49},"\u002F\u002F 9007199254740994n (correct!)\n",[43,2964,2965],{"class":45,"line":345},[43,2966,2967],{"class":49},"\u002F\u002F ⚠️ BigInt can't mix with regular numbers: big + 1 → TypeError\n",[43,2969,2970],{"class":45,"line":351},[43,2971,2972],{"class":49},"\u002F\u002F BigInt is for integers only — no decimals: 1n \u002F 2n → 0n (truncated)\n",[43,2974,2975],{"class":45,"line":363},[43,2976,75],{"emptyLinePlaceholder":74},[43,2978,2979],{"class":45,"line":381},[43,2980,2981],{"class":49},"\u002F\u002F ── -0 exists (negative zero) ──\n",[43,2983,2984,2986,2988,2990,2992,2994,2996,2998,3001],{"class":45,"line":393},[43,2985,269],{"class":95},[43,2987,148],{"class":91},[43,2989,729],{"class":95},[43,2991,1624],{"class":87},[43,2993,610],{"class":108},[43,2995,1522],{"class":87},[43,2997,571],{"class":108},[43,2999,3000],{"class":95},");         ",[43,3002,3003],{"class":49},"\u002F\u002F true (=== can't distinguish)\n",[43,3005,3006,3008,3010,3013,3015,3017,3019,3021,3023,3025,3028],{"class":45,"line":398},[43,3007,269],{"class":95},[43,3009,148],{"class":91},[43,3011,3012],{"class":95},"(Object.",[43,3014,1599],{"class":91},[43,3016,729],{"class":95},[43,3018,1624],{"class":87},[43,3020,610],{"class":108},[43,3022,988],{"class":95},[43,3024,610],{"class":108},[43,3026,3027],{"class":95},")); ",[43,3029,3030],{"class":49},"\u002F\u002F false (Object.is can)\n",[43,3032,3033,3035,3037,3039,3041,3044,3047,3049,3052],{"class":45,"line":403},[43,3034,269],{"class":95},[43,3036,148],{"class":91},[43,3038,729],{"class":95},[43,3040,423],{"class":108},[43,3042,3043],{"class":87}," \u002F",[43,3045,3046],{"class":87}," -",[43,3048,610],{"class":108},[43,3050,3051],{"class":95},");           ",[43,3053,3054],{"class":49},"\u002F\u002F -Infinity (negative zero matters for division)\n",[43,3056,3057,3059,3061,3064,3067,3069,3071,3073,3076],{"class":45,"line":409},[43,3058,269],{"class":95},[43,3060,148],{"class":91},[43,3062,3063],{"class":95},"(Math.",[43,3065,3066],{"class":91},"sign",[43,3068,729],{"class":95},[43,3070,1624],{"class":87},[43,3072,610],{"class":108},[43,3074,3075],{"class":95},"));   ",[43,3077,3078],{"class":49},"\u002F\u002F -1 (Math.sign distinguishes -0)\n",[15,3080,3082],{"id":3081},"tips-tricks","💡 Tips & Tricks",[31,3084,3085],{"language":33},[35,3086,3088],{"className":37,"code":3087,"language":33,"meta":39,"style":39},"\u002F\u002F ── Swap variables with destructuring (no temp needed) ──\nlet a = 1, b = 2;\n[a, b] = [b, a];  \u002F\u002F a=2, b=1\n\n\u002F\u002F ── Optional chaining with nullish coalescing for deep defaults ──\nconst port = config?.server?.port ?? 3000;  \u002F\u002F 3000 if any part is null\u002Fundefined\n\n\u002F\u002F ── Comma operator: evaluate multiple expressions, return last ──\nconst result = (console.log(\"side effect\"), 42);  \u002F\u002F logs, then result = 42\n\u002F\u002F Use sparingly — can be confusing. Useful in for-loop init: for (let i = 0, j = 10; ...)\n\n\u002F\u002F ── Numeric separators (ES2021) for readability ──\nconst billion = 1_000_000_000;  \u002F\u002F underscores ignored — same as 1000000000\nconst bytes = 0xff_ff;           \u002F\u002F hex with separators\nconst binary = 0b1010_1010;     \u002F\u002F binary with separators\n\n\u002F\u002F ── Tagged template literals for safe HTML\u002FSQL ──\nfunction html(strings, ...values) {\n    return strings.reduce((acc, str, i) =>\n        acc + str + (i \u003C values.length ? String(values[i]).replace(\u002F[\u003C>&]\u002Fg, c =>\n            ({'\u003C':'&lt;','>':'&gt;','&':'&amp;'}[c])) : ''), '');\n}\nconst userInput = \"\u003Cscript>alert('xss')\u003C\u002Fscript>\";\nconst safe = html`\u003Cdiv>${userInput}\u003C\u002Fdiv>`;  \u002F\u002F escaped: &lt;script&gt;...\n",[19,3089,3090,3095,3115,3128,3132,3137,3158,3162,3167,3196,3201,3205,3210,3227,3244,3261,3265,3270,3292,3323,3376,3426,3430,3444],{"__ignoreMap":39},[43,3091,3092],{"class":45,"line":46},[43,3093,3094],{"class":49},"\u002F\u002F ── Swap variables with destructuring (no temp needed) ──\n",[43,3096,3097,3099,3102,3104,3106,3109,3111,3113],{"class":45,"line":53},[43,3098,21],{"class":87},[43,3100,3101],{"class":95}," a ",[43,3103,124],{"class":87},[43,3105,2621],{"class":108},[43,3107,3108],{"class":95},", b ",[43,3110,124],{"class":87},[43,3112,437],{"class":108},[43,3114,293],{"class":95},[43,3116,3117,3120,3122,3125],{"class":45,"line":59},[43,3118,3119],{"class":95},"[a, b] ",[43,3121,124],{"class":87},[43,3123,3124],{"class":95}," [b, a];  ",[43,3126,3127],{"class":49},"\u002F\u002F a=2, b=1\n",[43,3129,3130],{"class":45,"line":65},[43,3131,75],{"emptyLinePlaceholder":74},[43,3133,3134],{"class":45,"line":71},[43,3135,3136],{"class":49},"\u002F\u002F ── Optional chaining with nullish coalescing for deep defaults ──\n",[43,3138,3139,3141,3144,3146,3149,3151,3153,3155],{"class":45,"line":78},[43,3140,25],{"class":87},[43,3142,3143],{"class":108}," port",[43,3145,417],{"class":87},[43,3147,3148],{"class":95}," config?.server?.port ",[43,3150,1894],{"class":87},[43,3152,1991],{"class":108},[43,3154,130],{"class":95},[43,3156,3157],{"class":49},"\u002F\u002F 3000 if any part is null\u002Fundefined\n",[43,3159,3160],{"class":45,"line":84},[43,3161,75],{"emptyLinePlaceholder":74},[43,3163,3164],{"class":45,"line":99},[43,3165,3166],{"class":49},"\u002F\u002F ── Comma operator: evaluate multiple expressions, return last ──\n",[43,3168,3169,3171,3174,3176,3179,3181,3183,3186,3189,3191,3193],{"class":45,"line":115},[43,3170,25],{"class":87},[43,3172,3173],{"class":108}," result",[43,3175,417],{"class":87},[43,3177,3178],{"class":95}," (console.",[43,3180,148],{"class":91},[43,3182,729],{"class":95},[43,3184,3185],{"class":852},"\"side effect\"",[43,3187,3188],{"class":95},"), ",[43,3190,2300],{"class":108},[43,3192,1543],{"class":95},[43,3194,3195],{"class":49},"\u002F\u002F logs, then result = 42\n",[43,3197,3198],{"class":45,"line":136},[43,3199,3200],{"class":49},"\u002F\u002F Use sparingly — can be confusing. Useful in for-loop init: for (let i = 0, j = 10; ...)\n",[43,3202,3203],{"class":45,"line":142},[43,3204,75],{"emptyLinePlaceholder":74},[43,3206,3207],{"class":45,"line":157},[43,3208,3209],{"class":49},"\u002F\u002F ── Numeric separators (ES2021) for readability ──\n",[43,3211,3212,3214,3217,3219,3222,3224],{"class":45,"line":163},[43,3213,25],{"class":87},[43,3215,3216],{"class":108}," billion",[43,3218,417],{"class":87},[43,3220,3221],{"class":108}," 1_000_000_000",[43,3223,130],{"class":95},[43,3225,3226],{"class":49},"\u002F\u002F underscores ignored — same as 1000000000\n",[43,3228,3229,3231,3234,3236,3239,3241],{"class":45,"line":169},[43,3230,25],{"class":87},[43,3232,3233],{"class":108}," bytes",[43,3235,417],{"class":87},[43,3237,3238],{"class":108}," 0xff_ff",[43,3240,1412],{"class":95},[43,3242,3243],{"class":49},"\u002F\u002F hex with separators\n",[43,3245,3246,3248,3251,3253,3256,3258],{"class":45,"line":175},[43,3247,25],{"class":87},[43,3249,3250],{"class":108}," binary",[43,3252,417],{"class":87},[43,3254,3255],{"class":108}," 0b1010_1010",[43,3257,1566],{"class":95},[43,3259,3260],{"class":49},"\u002F\u002F binary with separators\n",[43,3262,3263],{"class":45,"line":180},[43,3264,75],{"emptyLinePlaceholder":74},[43,3266,3267],{"class":45,"line":186},[43,3268,3269],{"class":49},"\u002F\u002F ── Tagged template literals for safe HTML\u002FSQL ──\n",[43,3271,3272,3274,3277,3279,3282,3284,3287,3290],{"class":45,"line":196},[43,3273,88],{"class":87},[43,3275,3276],{"class":91}," html",[43,3278,729],{"class":95},[43,3280,3281],{"class":732},"strings",[43,3283,988],{"class":95},[43,3285,3286],{"class":87},"...",[43,3288,3289],{"class":732},"values",[43,3291,112],{"class":95},[43,3293,3294,3296,3299,3302,3305,3308,3310,3313,3315,3318,3320],{"class":45,"line":207},[43,3295,2243],{"class":87},[43,3297,3298],{"class":95}," strings.",[43,3300,3301],{"class":91},"reduce",[43,3303,3304],{"class":95},"((",[43,3306,3307],{"class":732},"acc",[43,3309,988],{"class":95},[43,3311,3312],{"class":732},"str",[43,3314,988],{"class":95},[43,3316,3317],{"class":732},"i",[43,3319,2192],{"class":95},[43,3321,3322],{"class":87},"=>\n",[43,3324,3325,3328,3330,3332,3334,3337,3339,3342,3344,3347,3350,3353,3356,3358,3360,3363,3365,3368,3370,3373],{"class":45,"line":226},[43,3326,3327],{"class":95},"        acc ",[43,3329,2861],{"class":87},[43,3331,847],{"class":95},[43,3333,2861],{"class":87},[43,3335,3336],{"class":95}," (i ",[43,3338,577],{"class":87},[43,3340,3341],{"class":95}," values.",[43,3343,1793],{"class":108},[43,3345,3346],{"class":87}," ?",[43,3348,3349],{"class":91}," String",[43,3351,3352],{"class":95},"(values[i]).",[43,3354,3355],{"class":91},"replace",[43,3357,729],{"class":95},[43,3359,2878],{"class":852},[43,3361,3362],{"class":108},"[\u003C>&]",[43,3364,2878],{"class":852},[43,3366,3367],{"class":87},"g",[43,3369,988],{"class":95},[43,3371,3372],{"class":732},"c",[43,3374,3375],{"class":87}," =>\n",[43,3377,3378,3381,3384,3387,3390,3393,3396,3398,3401,3403,3406,3408,3411,3414,3416,3419,3421,3424],{"class":45,"line":231},[43,3379,3380],{"class":95},"            ({",[43,3382,3383],{"class":852},"'\u003C'",[43,3385,3386],{"class":95},":",[43,3388,3389],{"class":852},"'&lt;'",[43,3391,3392],{"class":95},",",[43,3394,3395],{"class":852},"'>'",[43,3397,3386],{"class":95},[43,3399,3400],{"class":852},"'&gt;'",[43,3402,3392],{"class":95},[43,3404,3405],{"class":852},"'&'",[43,3407,3386],{"class":95},[43,3409,3410],{"class":852},"'&amp;'",[43,3412,3413],{"class":95},"}[c])) ",[43,3415,3386],{"class":87},[43,3417,3418],{"class":852}," ''",[43,3420,3188],{"class":95},[43,3422,3423],{"class":852},"''",[43,3425,613],{"class":95},[43,3427,3428],{"class":45,"line":244},[43,3429,160],{"class":95},[43,3431,3432,3434,3437,3439,3442],{"class":45,"line":249},[43,3433,25],{"class":87},[43,3435,3436],{"class":108}," userInput",[43,3438,417],{"class":87},[43,3440,3441],{"class":852}," \"\u003Cscript>alert('xss')\u003C\u002Fscript>\"",[43,3443,293],{"class":95},[43,3445,3446,3448,3451,3453,3455,3458,3461,3464,3466],{"class":45,"line":254},[43,3447,25],{"class":87},[43,3449,3450],{"class":108}," safe",[43,3452,417],{"class":87},[43,3454,3276],{"class":91},[43,3456,3457],{"class":852},"`\u003Cdiv>${",[43,3459,3460],{"class":95},"userInput",[43,3462,3463],{"class":852},"}\u003C\u002Fdiv>`",[43,3465,130],{"class":95},[43,3467,3468],{"class":49},"\u002F\u002F escaped: &lt;script&gt;...\n",[15,3470,3472],{"id":3471},"️-edge-cases-gotchas","⚠️ Edge Cases & Gotchas",[31,3474,3475],{"language":33},[35,3476,3478],{"className":37,"code":3477,"language":33,"meta":39,"style":39},"\u002F\u002F ── `typeof` for undeclared variables doesn't throw (but let\u002Fconst in TDZ does) ──\nconsole.log(typeof undeclaredVar);  \u002F\u002F \"undefined\" (no error — typeof is safe for undeclared)\n\u002F\u002F console.log(typeof tdzVar);      \u002F\u002F ReferenceError if tdzVar is in TDZ (let\u002Fconst)\n\n\u002F\u002F ── `const` with arrays\u002Fobjects: the binding is frozen, the value isn't ──\nconst arr = [1, 2, 3];\narr.push(4);  \u002F\u002F ✓ mutates the array (const only prevents reassigning `arr`)\n\u002F\u002F arr = [];  \u002F\u002F ✗ TypeError: Assignment to constant variable\n\n\u002F\u002F ── `let` in the global scope does NOT create a global object property ──\nlet x = 10;\nconsole.log(window.x);  \u002F\u002F undefined (let doesn't create window property)\nvar y = 10;\nconsole.log(window.y);  \u002F\u002F 10 (var creates window property)\n\n\u002F\u002F ── Re-declaration: var allows it, let\u002Fconst don't ──\nvar a = 1;\nvar a = 2;  \u002F\u002F ✓ var allows re-declaration\nlet b = 1;\n\u002F\u002F let b = 2;  \u002F\u002F ✗ SyntaxError: Identifier 'b' has already been declared\n\n\u002F\u002F ── `0.1 + 0.2` and the `toFixed` trap ──\n(0.1 + 0.2).toFixed(2);  \u002F\u002F \"0.30\" (toFixed rounds to string)\n\u002F\u002F ⚠️ toFixed returns a STRING, not a number\n\u002F\u002F ⚠️ toFixed has rounding issues: (1.005).toFixed(2) → \"1.00\" (not \"1.01\"!)\n",[19,3479,3480,3485,3501,3509,3513,3518,3540,3555,3562,3566,3571,3583,3595,3607,3619,3623,3628,3640,3655,3668,3676,3680,3685,3710,3715],{"__ignoreMap":39},[43,3481,3482],{"class":45,"line":46},[43,3483,3484],{"class":49},"\u002F\u002F ── `typeof` for undeclared variables doesn't throw (but let\u002Fconst in TDZ does) ──\n",[43,3486,3487,3489,3491,3493,3495,3498],{"class":45,"line":53},[43,3488,269],{"class":95},[43,3490,148],{"class":91},[43,3492,729],{"class":95},[43,3494,2039],{"class":87},[43,3496,3497],{"class":95}," undeclaredVar);  ",[43,3499,3500],{"class":49},"\u002F\u002F \"undefined\" (no error — typeof is safe for undeclared)\n",[43,3502,3503,3506],{"class":45,"line":59},[43,3504,3505],{"class":49},"\u002F\u002F console.log(typeof tdzVar);",[43,3507,3508],{"class":49},"      \u002F\u002F ReferenceError if tdzVar is in TDZ (let\u002Fconst)\n",[43,3510,3511],{"class":45,"line":65},[43,3512,75],{"emptyLinePlaceholder":74},[43,3514,3515],{"class":45,"line":71},[43,3516,3517],{"class":49},"\u002F\u002F ── `const` with arrays\u002Fobjects: the binding is frozen, the value isn't ──\n",[43,3519,3520,3522,3524,3526,3528,3530,3532,3534,3536,3538],{"class":45,"line":78},[43,3521,25],{"class":87},[43,3523,978],{"class":108},[43,3525,417],{"class":87},[43,3527,983],{"class":95},[43,3529,423],{"class":108},[43,3531,988],{"class":95},[43,3533,991],{"class":108},[43,3535,988],{"class":95},[43,3537,996],{"class":108},[43,3539,999],{"class":95},[43,3541,3542,3544,3546,3548,3550,3552],{"class":45,"line":84},[43,3543,1019],{"class":95},[43,3545,1022],{"class":91},[43,3547,729],{"class":95},[43,3549,1027],{"class":108},[43,3551,1543],{"class":95},[43,3553,3554],{"class":49},"\u002F\u002F ✓ mutates the array (const only prevents reassigning `arr`)\n",[43,3556,3557,3560],{"class":45,"line":99},[43,3558,3559],{"class":49},"\u002F\u002F arr = [];",[43,3561,452],{"class":49},[43,3563,3564],{"class":45,"line":115},[43,3565,75],{"emptyLinePlaceholder":74},[43,3567,3568],{"class":45,"line":136},[43,3569,3570],{"class":49},"\u002F\u002F ── `let` in the global scope does NOT create a global object property ──\n",[43,3572,3573,3575,3577,3579,3581],{"class":45,"line":142},[43,3574,21],{"class":87},[43,3576,121],{"class":95},[43,3578,124],{"class":87},[43,3580,127],{"class":108},[43,3582,293],{"class":95},[43,3584,3585,3587,3589,3592],{"class":45,"line":157},[43,3586,269],{"class":95},[43,3588,148],{"class":91},[43,3590,3591],{"class":95},"(window.x);  ",[43,3593,3594],{"class":49},"\u002F\u002F undefined (let doesn't create window property)\n",[43,3596,3597,3599,3601,3603,3605],{"class":45,"line":163},[43,3598,28],{"class":87},[43,3600,213],{"class":95},[43,3602,124],{"class":87},[43,3604,127],{"class":108},[43,3606,293],{"class":95},[43,3608,3609,3611,3613,3616],{"class":45,"line":169},[43,3610,269],{"class":95},[43,3612,148],{"class":91},[43,3614,3615],{"class":95},"(window.y);  ",[43,3617,3618],{"class":49},"\u002F\u002F 10 (var creates window property)\n",[43,3620,3621],{"class":45,"line":175},[43,3622,75],{"emptyLinePlaceholder":74},[43,3624,3625],{"class":45,"line":180},[43,3626,3627],{"class":49},"\u002F\u002F ── Re-declaration: var allows it, let\u002Fconst don't ──\n",[43,3629,3630,3632,3634,3636,3638],{"class":45,"line":186},[43,3631,28],{"class":87},[43,3633,3101],{"class":95},[43,3635,124],{"class":87},[43,3637,2621],{"class":108},[43,3639,293],{"class":95},[43,3641,3642,3644,3646,3648,3650,3652],{"class":45,"line":196},[43,3643,28],{"class":87},[43,3645,3101],{"class":95},[43,3647,124],{"class":87},[43,3649,437],{"class":108},[43,3651,130],{"class":95},[43,3653,3654],{"class":49},"\u002F\u002F ✓ var allows re-declaration\n",[43,3656,3657,3659,3662,3664,3666],{"class":45,"line":207},[43,3658,21],{"class":87},[43,3660,3661],{"class":95}," b ",[43,3663,124],{"class":87},[43,3665,2621],{"class":108},[43,3667,293],{"class":95},[43,3669,3670,3673],{"class":45,"line":226},[43,3671,3672],{"class":49},"\u002F\u002F let b = 2;",[43,3674,3675],{"class":49},"  \u002F\u002F ✗ SyntaxError: Identifier 'b' has already been declared\n",[43,3677,3678],{"class":45,"line":231},[43,3679,75],{"emptyLinePlaceholder":74},[43,3681,3682],{"class":45,"line":244},[43,3683,3684],{"class":49},"\u002F\u002F ── `0.1 + 0.2` and the `toFixed` trap ──\n",[43,3686,3687,3689,3691,3693,3695,3698,3701,3703,3705,3707],{"class":45,"line":249},[43,3688,729],{"class":95},[43,3690,2686],{"class":108},[43,3692,2618],{"class":87},[43,3694,2691],{"class":108},[43,3696,3697],{"class":95},").",[43,3699,3700],{"class":91},"toFixed",[43,3702,729],{"class":95},[43,3704,991],{"class":108},[43,3706,1543],{"class":95},[43,3708,3709],{"class":49},"\u002F\u002F \"0.30\" (toFixed rounds to string)\n",[43,3711,3712],{"class":45,"line":254},[43,3713,3714],{"class":49},"\u002F\u002F ⚠️ toFixed returns a STRING, not a number\n",[43,3716,3717],{"class":45,"line":260},[43,3718,3719],{"class":49},"\u002F\u002F ⚠️ toFixed has rounding issues: (1.005).toFixed(2) → \"1.00\" (not \"1.01\"!)\n",[15,3721,3723],{"id":3722},"quick-quiz","🧠 Quick Quiz",[3725,3726,3727],"p",{},"What does this output?",[31,3729,3730],{"language":33},[35,3731,3733],{"className":37,"code":3732,"language":33,"meta":39,"style":39},"let x = 1;\nfunction check() {\n    if (false) {\n        let x = 2;\n    }\n    console.log(x);\n}\ncheck();\n",[19,3734,3735,3747,3756,3767,3779,3783,3791,3795],{"__ignoreMap":39},[43,3736,3737,3739,3741,3743,3745],{"class":45,"line":46},[43,3738,21],{"class":87},[43,3740,121],{"class":95},[43,3742,124],{"class":87},[43,3744,2621],{"class":108},[43,3746,293],{"class":95},[43,3748,3749,3751,3754],{"class":45,"line":53},[43,3750,88],{"class":87},[43,3752,3753],{"class":91}," check",[43,3755,96],{"class":95},[43,3757,3758,3760,3762,3765],{"class":45,"line":59},[43,3759,102],{"class":87},[43,3761,105],{"class":95},[43,3763,3764],{"class":108},"false",[43,3766,112],{"class":95},[43,3768,3769,3771,3773,3775,3777],{"class":45,"line":65},[43,3770,210],{"class":87},[43,3772,121],{"class":95},[43,3774,124],{"class":87},[43,3776,437],{"class":108},[43,3778,293],{"class":95},[43,3780,3781],{"class":45,"line":71},[43,3782,139],{"class":95},[43,3784,3785,3787,3789],{"class":45,"line":78},[43,3786,145],{"class":95},[43,3788,148],{"class":91},[43,3790,1124],{"class":95},[43,3792,3793],{"class":45,"line":84},[43,3794,160],{"class":95},[43,3796,3797,3800],{"class":45,"line":99},[43,3798,3799],{"class":91},"check",[43,3801,3802],{"class":95},"();\n",[3804,3805,3806,3810,3814,3842,3862],"details",{},[3807,3808,3809],"summary",{},"Answer",[3725,3811,3812],{},[19,3813,423],{},[3725,3815,3816,3817,3820,3821,3824,3825,3828,3829,3831,3832,3835,3836,3838,3839,2321],{},"The ",[19,3818,3819],{},"let x = 2"," inside the ",[19,3822,3823],{},"if (false)"," block is block-scoped to that ",[19,3826,3827],{},"if"," block. Even though the block never executes, the ",[19,3830,21],{}," declaration still creates a binding in that block's scope (in the TDZ). But since ",[19,3833,3834],{},"console.log(x)"," is in the function scope (outside the ",[19,3837,3827],{}," block), it accesses the outer ",[19,3840,3841],{},"let x = 1",[3725,3843,3844,3845,3847,3848,3850,3851,3853,3854,3857,3858,3861],{},"If the ",[19,3846,3834],{}," were inside the ",[19,3849,3827],{}," block (before the ",[19,3852,3819],{},"), it would throw ",[19,3855,3856],{},"ReferenceError"," (TDZ — accessing ",[19,3859,3860],{},"x"," before its declaration in the same block).",[3725,3863,3864,3868,3869,2878,3871,3873,3874,3876,3877,3879,3880,3882],{},[3865,3866,3867],"strong",{},"The lesson",": ",[19,3870,21],{},[19,3872,25],{}," are block-scoped. A ",[19,3875,21],{}," inside an ",[19,3878,3823],{}," block still creates a binding in that block's scope — but only that block. The outer ",[19,3881,3860],{}," is unaffected.",[3884,3885,3886],"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 .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}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}",{"title":39,"searchDepth":53,"depth":53,"links":3888},[3889,3891,3893,3894,3895,3896,3897,3898,3899,3900],{"id":17,"depth":53,"text":3890},"let \u002F const \u002F var: Scope and Hoisting Internals",{"id":538,"depth":53,"text":3892},"Anti-Pattern: var in Loops (Closure Capture Bug)",{"id":813,"depth":53,"text":814},{"id":1248,"depth":53,"text":1249},{"id":1658,"depth":53,"text":1659},{"id":2021,"depth":53,"text":2022},{"id":2520,"depth":53,"text":2521},{"id":3081,"depth":53,"text":3082},{"id":3471,"depth":53,"text":3472},{"id":3722,"depth":53,"text":3723},"Deep-dive into JavaScript variable mechanics: let\u002Fconst\u002Fvar scope and hoisting internals, the Temporal Dead Zone (TDZ), primitive vs reference memory model, and the abstract type coercion algorithm. Code-first reference for senior engineers.","md",{},"\u002Fjs\u002F02-variables-and-data-types",{"title":5,"description":3901},"js\u002F02-variables-and-data-types","6_i_Y2knnGiGfyTcstZdbJzTf2LOI-6gDueOIkv6q5w",1789924648851]