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