[{"data":1,"prerenderedAt":4371},["ShallowReactive",2],{"blog-post-/blogs/javascript-traps-worth-knowing-before-they-bite-you":3,"blog-surround-/blogs/javascript-traps-worth-knowing-before-they-bite-you":4366},{"id":4,"title":5,"body":6,"createdAt":4353,"description":4354,"extension":4355,"image":4356,"lastUpdated":4353,"meta":4357,"navigation":1173,"ogImage":4358,"path":4359,"published":1173,"seo":4360,"stem":4361,"tags":4362,"trending":4364,"__hash__":4365},"content/blogs/javascript-traps-worth-knowing-before-they-bite-you.md","JavaScript Traps Worth Knowing Before They Bite You",{"type":7,"value":8,"toc":4323},"minimark",[9,13,16,35,38,77,80,98,100,153,156,159,162,165,168,171,174,177,180,188,191,221,224,227,233,236,246,249,252,282,285,288,291,294,297,321,324,361,364,367,370,372,379,382,406,413,416,419,422,427,430,439,442,479,482,485,488,491,493,500,503,529,532,535,559,568,571,577,580,635,642,695,702,755,760,762,769,772,780,783,786,789,792,884,887,890,893,974,977,981,984,990,1016,1024,1027,1062,1065,1068,1071,1073,1081,1087,1090,1110,1113,1142,1145,1194,1197,1200,1217,1220,1236,1239,1254,1257,1275,1278,1291,1294,1297,1300,1303,1306,1328,1331,1360,1362,1381,1384,1386,1393,1404,1410,1413,1465,1468,1474,1521,1524,1529,1532,1609,1612,1632,1635,1653,1656,1666,1671,1732,1735,1751,1754,1759,1764,1770,1773,1775,1779,1782,1787,1816,1819,1852,1855,1863,1890,1893,1896,1899,1902,1905,1907,1914,1919,1922,1927,1929,2016,2019,2022,2049,2055,2060,2063,2069,2100,2103,2140,2143,2148,2151,2228,2234,2289,2292,2295,2297,2301,2304,2364,2371,2374,2377,2380,2453,2456,2459,2522,2525,2594,2597,2600,2709,2712,2719,2725,2743,2746,2749,2752,2757,2760,2762,2769,2772,2809,2811,2832,2835,2856,2858,2863,2872,2878,2890,2892,2928,2931,2999,3002,3005,3008,3062,3065,3103,3106,3108,3115,3120,3123,3125,3178,3181,3184,3187,3190,3193,3195,3250,3253,3256,3262,3265,3268,3315,3318,3321,3324,3327,3329,3336,3339,3386,3389,3427,3441,3444,3447,3485,3487,3505,3508,3510,3513,3515,3519,3522,3556,3559,3562,3565,3667,3669,3736,3739,3745,3750,3753,3760,3767,3770,3773,3776,3781,3799,3802,3805,3807,3811,3814,3817,3840,3843,3846,3849,3871,3874,3877,3880,3883,3905,3908,3911,3914,3916,3920,3923,3940,3943,3946,3949,3952,3954,3970,3976,3984,3987,3990,3993,4035,4038,4041,4043,4049,4052,4115,4118,4123,4142,4145,4151,4218,4221,4224,4229,4232,4234,4238,4241,4258,4261,4269,4272,4302,4305,4313,4316,4319],[10,11,12],"p",{},"JavaScript is one of those languages that looks friendly right up until the moment it ruins your evening.",[10,14,15],{},"At first, everything feels simple.",[17,18,19,23,26,29,32],"ul",{},[20,21,22],"li",{},"You write a function.",[20,24,25],{},"You render a button.",[20,27,28],{},"You fetch some JSON.",[20,30,31],{},"You build a small UI.",[20,33,34],{},"You think: “Okay, I get it. JavaScript is not that hard.”",[10,36,37],{},"And then, at some random point, you open the console and see this:",[39,40,45],"pre",{"className":41,"code":42,"language":43,"meta":44,"style":44},"language-js shiki shiki-themes dracula","0.1 + 0.2 === 0.3\n// false\n","js","",[46,47,48,70],"code",{"__ignoreMap":44},[49,50,53,57,61,64,67],"span",{"class":51,"line":52},"line",1,[49,54,56],{"class":55},"sIQBb","0.1",[49,58,60],{"class":59},"s0Tla"," +",[49,62,63],{"class":55}," 0.2",[49,65,66],{"class":59}," ===",[49,68,69],{"class":55}," 0.3\n",[49,71,73],{"class":51,"line":72},2,[49,74,76],{"class":75},"shSDL","// false\n",[10,78,79],{},"Or this:",[39,81,83],{"className":41,"code":82,"language":43,"meta":44,"style":44},"typeof null\n// \"object\"\n",[46,84,85,93],{"__ignoreMap":44},[49,86,87,90],{"class":51,"line":52},[49,88,89],{"class":59},"typeof",[49,91,92],{"class":55}," null\n",[49,94,95],{"class":51,"line":72},[49,96,97],{"class":75},"// \"object\"\n",[10,99,79],{},[39,101,103],{"className":41,"code":102,"language":43,"meta":44,"style":44},"[\"10\", \"10\", \"10\"].map(parseInt)\n// [10, NaN, 2]\n",[46,104,105,148],{"__ignoreMap":44},[49,106,107,111,115,119,121,124,126,128,130,132,134,136,138,141,145],{"class":51,"line":52},[49,108,110],{"class":109},"sCdxs","[",[49,112,114],{"class":113},"seVfx","\"",[49,116,118],{"class":117},"s-mGx","10",[49,120,114],{"class":113},[49,122,123],{"class":109},", ",[49,125,114],{"class":113},[49,127,118],{"class":117},[49,129,114],{"class":113},[49,131,123],{"class":109},[49,133,114],{"class":113},[49,135,118],{"class":117},[49,137,114],{"class":113},[49,139,140],{"class":109},"].",[49,142,144],{"class":143},"sAOxA","map",[49,146,147],{"class":109},"(parseInt)\n",[49,149,150],{"class":51,"line":72},[49,151,152],{"class":75},"// [10, NaN, 2]\n",[10,154,155],{},"And suddenly JavaScript stops looking like a cute scripting language and starts looking like an ancient artifact with cursed rules inside.",[10,157,158],{},"The funny thing is: JavaScript is usually not random.",[10,160,161],{},"Most of its weird behavior comes from legacy decisions, type coercion, floating-point math, browser history, and the fact that the language had to evolve without breaking half of the internet.",[10,163,164],{},"That is what makes JavaScript interesting.",[10,166,167],{},"And sometimes painful.",[10,169,170],{},"This article is not a complete JavaScript textbook. It is a collection of traps that I think every developer should know earlier rather than later.",[10,172,173],{},"Not because you need to memorize them all.",[10,175,176],{},"But because one day you will see one of them in production, and it is better to recognize the monster before it bites.",[178,179],"hr",{},[181,182,184,185],"h2",{"id":183},"the-famous-one-01-02","The Famous One: ",[46,186,187],{},"0.1 + 0.2",[10,189,190],{},"Let’s start with the classic.",[39,192,194],{"className":41,"code":193,"language":43,"meta":44,"style":44},"console.log(0.1 + 0.2)\n// 0.30000000000000004\n",[46,195,196,216],{"__ignoreMap":44},[49,197,198,201,204,207,209,211,213],{"class":51,"line":52},[49,199,200],{"class":109},"console.",[49,202,203],{"class":143},"log",[49,205,206],{"class":109},"(",[49,208,56],{"class":55},[49,210,60],{"class":59},[49,212,63],{"class":55},[49,214,215],{"class":109},")\n",[49,217,218],{"class":51,"line":72},[49,219,220],{"class":75},"// 0.30000000000000004\n",[10,222,223],{},"At some point, every JavaScript developer discovers this example.",[10,225,226],{},"And usually the first reaction is:",[228,229,230],"blockquote",{},[10,231,232],{},"What the hell?",[10,234,235],{},"The problem is not really JavaScript itself. The same thing happens in many other languages because they use binary floating-point numbers.",[10,237,238,239,241,242,245],{},"Computers store numbers in binary. Some decimal numbers, like ",[46,240,56],{}," and ",[46,243,244],{},"0.2",", cannot be represented perfectly in binary form. So JavaScript stores an approximation.",[10,247,248],{},"Usually that approximation is good enough.",[10,250,251],{},"But sometimes it leaks out:",[39,253,255],{"className":41,"code":254,"language":43,"meta":44,"style":44},"console.log(0.1 + 0.2 === 0.3)\n// false\n",[46,256,257,278],{"__ignoreMap":44},[49,258,259,261,263,265,267,269,271,273,276],{"class":51,"line":52},[49,260,200],{"class":109},[49,262,203],{"class":143},[49,264,206],{"class":109},[49,266,56],{"class":55},[49,268,60],{"class":59},[49,270,63],{"class":55},[49,272,66],{"class":59},[49,274,275],{"class":55}," 0.3",[49,277,215],{"class":109},[49,279,280],{"class":51,"line":72},[49,281,76],{"class":75},[10,283,284],{},"This looks stupid, but it is just math under the hood.",[10,286,287],{},"The real lesson is simple:",[10,289,290],{},"Do not use floating-point numbers for things that require exact precision.",[10,292,293],{},"Especially money.",[10,295,296],{},"Bad:",[39,298,300],{"className":41,"code":299,"language":43,"meta":44,"style":44},"const price = 0.1 + 0.2\n",[46,301,302],{"__ignoreMap":44},[49,303,304,307,310,313,316,318],{"class":51,"line":52},[49,305,306],{"class":59},"const",[49,308,309],{"class":109}," price ",[49,311,312],{"class":59},"=",[49,314,315],{"class":55}," 0.1",[49,317,60],{"class":59},[49,319,320],{"class":55}," 0.2\n",[10,322,323],{},"Better:",[39,325,327],{"className":41,"code":326,"language":43,"meta":44,"style":44},"const priceInCents = 10 + 20\nconsole.log(priceInCents)\n// 30\n",[46,328,329,346,355],{"__ignoreMap":44},[49,330,331,333,336,338,341,343],{"class":51,"line":52},[49,332,306],{"class":59},[49,334,335],{"class":109}," priceInCents ",[49,337,312],{"class":59},[49,339,340],{"class":55}," 10",[49,342,60],{"class":59},[49,344,345],{"class":55}," 20\n",[49,347,348,350,352],{"class":51,"line":72},[49,349,200],{"class":109},[49,351,203],{"class":143},[49,353,354],{"class":109},"(priceInCents)\n",[49,356,358],{"class":51,"line":357},3,[49,359,360],{"class":75},"// 30\n",[10,362,363],{},"Store money in cents, kopeks, smallest units, whatever fits your currency.",[10,365,366],{},"If you are building financial software, use a proper decimal library. Do not try to be heroic with floats.",[10,368,369],{},"Heroism in financial calculations usually ends with someone losing money.",[178,371],{},[181,373,375,378],{"id":374},"typeof-null-is-a-historical-scar",[46,376,377],{},"typeof null"," Is a Historical Scar",[10,380,381],{},"This one is beautiful in the worst possible way:",[39,383,385],{"className":41,"code":384,"language":43,"meta":44,"style":44},"console.log(typeof null)\n// \"object\"\n",[46,386,387,402],{"__ignoreMap":44},[49,388,389,391,393,395,397,400],{"class":51,"line":52},[49,390,200],{"class":109},[49,392,203],{"class":143},[49,394,206],{"class":109},[49,396,89],{"class":59},[49,398,399],{"class":55}," null",[49,401,215],{"class":109},[49,403,404],{"class":51,"line":72},[49,405,97],{"class":75},[10,407,408,409,412],{},"Of course, ",[46,410,411],{},"null"," is not an object.",[10,414,415],{},"But JavaScript says it is.",[10,417,418],{},"This behavior comes from an old implementation detail in the early days of the language. And now it cannot be fixed because too much old code depends on it.",[10,420,421],{},"That is one of the recurring themes in JavaScript:",[228,423,424],{},[10,425,426],{},"Some things are not fixed because the web must not break.",[10,428,429],{},"So we live with this forever.",[10,431,432,433,435,436,438],{},"If you need to check for ",[46,434,411],{},", do not use ",[46,437,89],{},".",[10,440,441],{},"Use direct comparison:",[39,443,445],{"className":41,"code":444,"language":43,"meta":44,"style":44},"const value = null\nconsole.log(value === null)\n// true\n",[46,446,447,458,474],{"__ignoreMap":44},[49,448,449,451,454,456],{"class":51,"line":52},[49,450,306],{"class":59},[49,452,453],{"class":109}," value ",[49,455,312],{"class":59},[49,457,92],{"class":55},[49,459,460,462,464,467,470,472],{"class":51,"line":72},[49,461,200],{"class":109},[49,463,203],{"class":143},[49,465,466],{"class":109},"(value ",[49,468,469],{"class":59},"===",[49,471,399],{"class":55},[49,473,215],{"class":109},[49,475,476],{"class":51,"line":357},[49,477,478],{"class":75},"// true\n",[10,480,481],{},"It is boring.",[10,483,484],{},"It is explicit.",[10,486,487],{},"It works.",[10,489,490],{},"And in JavaScript, boring and explicit is often the best strategy.",[178,492],{},[181,494,496,499],{"id":495},"nan-is-not-equal-to-itself",[46,497,498],{},"NaN"," Is Not Equal to Itself",[10,501,502],{},"Another little monster:",[39,504,506],{"className":41,"code":505,"language":43,"meta":44,"style":44},"console.log(NaN === NaN)\n// false\n",[46,507,508,525],{"__ignoreMap":44},[49,509,510,512,514,516,518,520,523],{"class":51,"line":52},[49,511,200],{"class":109},[49,513,203],{"class":143},[49,515,206],{"class":109},[49,517,498],{"class":55},[49,519,66],{"class":59},[49,521,522],{"class":55}," NaN",[49,524,215],{"class":109},[49,526,527],{"class":51,"line":72},[49,528,76],{"class":75},[10,530,531],{},"At first glance, this looks completely insane.",[10,533,534],{},"Even worse:",[39,536,538],{"className":41,"code":537,"language":43,"meta":44,"style":44},"console.log(typeof NaN)\n// \"number\"\n",[46,539,540,554],{"__ignoreMap":44},[49,541,542,544,546,548,550,552],{"class":51,"line":52},[49,543,200],{"class":109},[49,545,203],{"class":143},[49,547,206],{"class":109},[49,549,89],{"class":59},[49,551,522],{"class":55},[49,553,215],{"class":109},[49,555,556],{"class":51,"line":72},[49,557,558],{"class":75},"// \"number\"\n",[10,560,561,562,564,565,438],{},"So ",[46,563,498],{}," means “Not a Number”, but its type is ",[46,566,567],{},"\"number\"",[10,569,570],{},"Welcome to JavaScript.",[10,572,573,574,576],{},"Actually, this also comes from floating-point rules. ",[46,575,498],{}," represents an invalid numeric result, and according to the standard, it is not equal to anything, including itself.",[10,578,579],{},"So this does not work:",[39,581,583],{"className":41,"code":582,"language":43,"meta":44,"style":44},"const value = NaN\nif (value === NaN) {\n  console.log(\"This will never run\")\n}\n",[46,584,585,596,611,629],{"__ignoreMap":44},[49,586,587,589,591,593],{"class":51,"line":52},[49,588,306],{"class":59},[49,590,453],{"class":109},[49,592,312],{"class":59},[49,594,595],{"class":55}," NaN\n",[49,597,598,601,604,606,608],{"class":51,"line":72},[49,599,600],{"class":59},"if",[49,602,603],{"class":109}," (value ",[49,605,469],{"class":59},[49,607,522],{"class":55},[49,609,610],{"class":109},") {\n",[49,612,613,616,618,620,622,625,627],{"class":51,"line":357},[49,614,615],{"class":109},"  console.",[49,617,203],{"class":143},[49,619,206],{"class":109},[49,621,114],{"class":113},[49,623,624],{"class":117},"This will never run",[49,626,114],{"class":113},[49,628,215],{"class":109},[49,630,632],{"class":51,"line":631},4,[49,633,634],{"class":109},"}\n",[10,636,637,638,641],{},"Use ",[46,639,640],{},"Number.isNaN()"," instead:",[39,643,645],{"className":41,"code":644,"language":43,"meta":44,"style":44},"console.log(Number.isNaN(NaN))\n// true\nconsole.log(Number.isNaN(\"hello\"))\n// false\n",[46,646,647,666,670,691],{"__ignoreMap":44},[49,648,649,651,653,656,659,661,663],{"class":51,"line":52},[49,650,200],{"class":109},[49,652,203],{"class":143},[49,654,655],{"class":109},"(Number.",[49,657,658],{"class":143},"isNaN",[49,660,206],{"class":109},[49,662,498],{"class":55},[49,664,665],{"class":109},"))\n",[49,667,668],{"class":51,"line":72},[49,669,478],{"class":75},[49,671,672,674,676,678,680,682,684,687,689],{"class":51,"line":357},[49,673,200],{"class":109},[49,675,203],{"class":143},[49,677,655],{"class":109},[49,679,658],{"class":143},[49,681,206],{"class":109},[49,683,114],{"class":113},[49,685,686],{"class":117},"hello",[49,688,114],{"class":113},[49,690,665],{"class":109},[49,692,693],{"class":51,"line":631},[49,694,76],{"class":75},[10,696,697,698,701],{},"Be careful with the old global ",[46,699,700],{},"isNaN()"," function, because it performs coercion:",[39,703,705],{"className":41,"code":704,"language":43,"meta":44,"style":44},"console.log(isNaN(\"hello\"))\n// true\nconsole.log(Number.isNaN(\"hello\"))\n// false\n",[46,706,707,727,731,751],{"__ignoreMap":44},[49,708,709,711,713,715,717,719,721,723,725],{"class":51,"line":52},[49,710,200],{"class":109},[49,712,203],{"class":143},[49,714,206],{"class":109},[49,716,658],{"class":143},[49,718,206],{"class":109},[49,720,114],{"class":113},[49,722,686],{"class":117},[49,724,114],{"class":113},[49,726,665],{"class":109},[49,728,729],{"class":51,"line":72},[49,730,478],{"class":75},[49,732,733,735,737,739,741,743,745,747,749],{"class":51,"line":357},[49,734,200],{"class":109},[49,736,203],{"class":143},[49,738,655],{"class":109},[49,740,658],{"class":143},[49,742,206],{"class":109},[49,744,114],{"class":113},[49,746,686],{"class":117},[49,748,114],{"class":113},[49,750,665],{"class":109},[49,752,753],{"class":51,"line":631},[49,754,76],{"class":75},[10,756,757,759],{},[46,758,640],{}," is stricter and usually what you actually want.",[178,761],{},[181,763,765,766],{"id":764},"the-problem-with","The Problem With ",[46,767,768],{},"==",[10,770,771],{},"JavaScript has two equality operators:",[39,773,778],{"className":774,"code":776,"language":777,"meta":44},[775],"language-text","==\n===\n","text",[46,779,776],{"__ignoreMap":44},[10,781,782],{},"The first one is loose equality.",[10,784,785],{},"The second one is strict equality.",[10,787,788],{},"Loose equality tries to convert values before comparing them.",[10,790,791],{},"That is how you get this:",[39,793,795],{"className":41,"code":794,"language":43,"meta":44,"style":44},"console.log(0 == false)         // true\nconsole.log(\"\" == false)        // true\nconsole.log(\"5\" == 5)           // true\nconsole.log(null == undefined)  // true\n",[46,796,797,819,839,864],{"__ignoreMap":44},[49,798,799,801,803,805,808,811,814,817],{"class":51,"line":52},[49,800,200],{"class":109},[49,802,203],{"class":143},[49,804,206],{"class":109},[49,806,807],{"class":55},"0",[49,809,810],{"class":59}," ==",[49,812,813],{"class":55}," false",[49,815,816],{"class":109},")         ",[49,818,478],{"class":75},[49,820,821,823,825,827,830,832,834,837],{"class":51,"line":72},[49,822,200],{"class":109},[49,824,203],{"class":143},[49,826,206],{"class":109},[49,828,829],{"class":113},"\"\"",[49,831,810],{"class":59},[49,833,813],{"class":55},[49,835,836],{"class":109},")        ",[49,838,478],{"class":75},[49,840,841,843,845,847,849,852,854,856,859,862],{"class":51,"line":357},[49,842,200],{"class":109},[49,844,203],{"class":143},[49,846,206],{"class":109},[49,848,114],{"class":113},[49,850,851],{"class":117},"5",[49,853,114],{"class":113},[49,855,810],{"class":59},[49,857,858],{"class":55}," 5",[49,860,861],{"class":109},")           ",[49,863,478],{"class":75},[49,865,866,868,870,872,874,876,879,882],{"class":51,"line":631},[49,867,200],{"class":109},[49,869,203],{"class":143},[49,871,206],{"class":109},[49,873,411],{"class":55},[49,875,810],{"class":59},[49,877,878],{"class":55}," undefined",[49,880,881],{"class":109},")  ",[49,883,478],{"class":75},[10,885,886],{},"Sometimes this feels convenient.",[10,888,889],{},"Most of the time it is just a bug waiting for its moment.",[10,891,892],{},"Strict equality does not perform type conversion:",[39,894,896],{"className":41,"code":895,"language":43,"meta":44,"style":44},"console.log(0 === false)         // false\nconsole.log(\"\" === false)        // false\nconsole.log(\"5\" === 5)           // false\nconsole.log(null === undefined)  // false\n",[46,897,898,916,934,956],{"__ignoreMap":44},[49,899,900,902,904,906,908,910,912,914],{"class":51,"line":52},[49,901,200],{"class":109},[49,903,203],{"class":143},[49,905,206],{"class":109},[49,907,807],{"class":55},[49,909,66],{"class":59},[49,911,813],{"class":55},[49,913,816],{"class":109},[49,915,76],{"class":75},[49,917,918,920,922,924,926,928,930,932],{"class":51,"line":72},[49,919,200],{"class":109},[49,921,203],{"class":143},[49,923,206],{"class":109},[49,925,829],{"class":113},[49,927,66],{"class":59},[49,929,813],{"class":55},[49,931,836],{"class":109},[49,933,76],{"class":75},[49,935,936,938,940,942,944,946,948,950,952,954],{"class":51,"line":357},[49,937,200],{"class":109},[49,939,203],{"class":143},[49,941,206],{"class":109},[49,943,114],{"class":113},[49,945,851],{"class":117},[49,947,114],{"class":113},[49,949,66],{"class":59},[49,951,858],{"class":55},[49,953,861],{"class":109},[49,955,76],{"class":75},[49,957,958,960,962,964,966,968,970,972],{"class":51,"line":631},[49,959,200],{"class":109},[49,961,203],{"class":143},[49,963,206],{"class":109},[49,965,411],{"class":55},[49,967,66],{"class":59},[49,969,878],{"class":55},[49,971,881],{"class":109},[49,973,76],{"class":75},[10,975,976],{},"My default rule is simple:",[10,978,637,979,438],{},[46,980,469],{},[10,982,983],{},"Almost always.",[10,985,986,987,989],{},"There is one common pattern where ",[46,988,768],{}," is sometimes used intentionally:",[39,991,993],{"className":41,"code":992,"language":43,"meta":44,"style":44},"if (value == null) {\n  // catches both null and undefined\n}\n",[46,994,995,1007,1012],{"__ignoreMap":44},[49,996,997,999,1001,1003,1005],{"class":51,"line":52},[49,998,600],{"class":59},[49,1000,603],{"class":109},[49,1002,768],{"class":59},[49,1004,399],{"class":55},[49,1006,610],{"class":109},[49,1008,1009],{"class":51,"line":72},[49,1010,1011],{"class":75},"  // catches both null and undefined\n",[49,1013,1014],{"class":51,"line":357},[49,1015,634],{"class":109},[10,1017,1018,1019,241,1021,438],{},"This checks for both ",[46,1020,411],{},[46,1022,1023],{},"undefined",[10,1025,1026],{},"But if you are working in a team, or writing code you want to be extremely clear, I would rather write:",[39,1028,1030],{"className":41,"code":1029,"language":43,"meta":44,"style":44},"if (value === null || value === undefined) {\n  // clear and explicit\n}\n",[46,1031,1032,1053,1058],{"__ignoreMap":44},[49,1033,1034,1036,1038,1040,1042,1045,1047,1049,1051],{"class":51,"line":52},[49,1035,600],{"class":59},[49,1037,603],{"class":109},[49,1039,469],{"class":59},[49,1041,399],{"class":55},[49,1043,1044],{"class":59}," ||",[49,1046,453],{"class":109},[49,1048,469],{"class":59},[49,1050,878],{"class":55},[49,1052,610],{"class":109},[49,1054,1055],{"class":51,"line":72},[49,1056,1057],{"class":75},"  // clear and explicit\n",[49,1059,1060],{"class":51,"line":357},[49,1061,634],{"class":109},[10,1063,1064],{},"Yes, it is longer.",[10,1066,1067],{},"But future you will understand it immediately.",[10,1069,1070],{},"And future you is the person you should be writing code for.",[178,1072],{},[181,1074,1076,1077,1080],{"id":1075},"arrays-objects-and-the-operator","Arrays, Objects, and the ",[46,1078,1079],{},"+"," Operator",[10,1082,1083,1084,1086],{},"The ",[46,1085,1079],{}," operator in JavaScript has two jobs.",[10,1088,1089],{},"It can add numbers:",[39,1091,1093],{"className":41,"code":1092,"language":43,"meta":44,"style":44},"1 + 2\n// 3\n",[46,1094,1095,1105],{"__ignoreMap":44},[49,1096,1097,1100,1102],{"class":51,"line":52},[49,1098,1099],{"class":55},"1",[49,1101,60],{"class":59},[49,1103,1104],{"class":55}," 2\n",[49,1106,1107],{"class":51,"line":72},[49,1108,1109],{"class":75},"// 3\n",[10,1111,1112],{},"And it can concatenate strings:",[39,1114,1116],{"className":41,"code":1115,"language":43,"meta":44,"style":44},"\"hello\" + \" world\"\n// \"hello world\"\n",[46,1117,1118,1137],{"__ignoreMap":44},[49,1119,1120,1122,1124,1126,1128,1131,1134],{"class":51,"line":52},[49,1121,114],{"class":113},[49,1123,686],{"class":117},[49,1125,114],{"class":113},[49,1127,60],{"class":59},[49,1129,1130],{"class":113}," \"",[49,1132,1133],{"class":117}," world",[49,1135,1136],{"class":113},"\"\n",[49,1138,1139],{"class":51,"line":72},[49,1140,1141],{"class":75},"// \"hello world\"\n",[10,1143,1144],{},"The problem starts when you give it arrays or objects.",[39,1146,1148],{"className":41,"code":1147,"language":43,"meta":44,"style":44},"console.log([] + [])\n// \"\"\n\nconsole.log([] + {})\n// \"[object Object]\"\n",[46,1149,1150,1164,1169,1175,1188],{"__ignoreMap":44},[49,1151,1152,1154,1156,1159,1161],{"class":51,"line":52},[49,1153,200],{"class":109},[49,1155,203],{"class":143},[49,1157,1158],{"class":109},"([] ",[49,1160,1079],{"class":59},[49,1162,1163],{"class":109}," [])\n",[49,1165,1166],{"class":51,"line":72},[49,1167,1168],{"class":75},"// \"\"\n",[49,1170,1171],{"class":51,"line":357},[49,1172,1174],{"emptyLinePlaceholder":1173},true,"\n",[49,1176,1177,1179,1181,1183,1185],{"class":51,"line":631},[49,1178,200],{"class":109},[49,1180,203],{"class":143},[49,1182,1158],{"class":109},[49,1184,1079],{"class":59},[49,1186,1187],{"class":109}," {})\n",[49,1189,1191],{"class":51,"line":1190},5,[49,1192,1193],{"class":75},"// \"[object Object]\"\n",[10,1195,1196],{},"This is not magic. JavaScript tries to convert both sides into primitive values.",[10,1198,1199],{},"An empty array becomes an empty string:",[39,1201,1203],{"className":41,"code":1202,"language":43,"meta":44,"style":44},"String([])\n// \"\"\n",[46,1204,1205,1213],{"__ignoreMap":44},[49,1206,1207,1210],{"class":51,"line":52},[49,1208,1209],{"class":143},"String",[49,1211,1212],{"class":109},"([])\n",[49,1214,1215],{"class":51,"line":72},[49,1216,1168],{"class":75},[10,1218,1219],{},"An object becomes this beautiful thing:",[39,1221,1223],{"className":41,"code":1222,"language":43,"meta":44,"style":44},"String({})\n// \"[object Object]\"\n",[46,1224,1225,1232],{"__ignoreMap":44},[49,1226,1227,1229],{"class":51,"line":52},[49,1228,1209],{"class":143},[49,1230,1231],{"class":109},"({})\n",[49,1233,1234],{"class":51,"line":72},[49,1235,1193],{"class":75},[10,1237,1238],{},"So this:",[39,1240,1242],{"className":41,"code":1241,"language":43,"meta":44,"style":44},"[] + {}\n",[46,1243,1244],{"__ignoreMap":44},[49,1245,1246,1249,1251],{"class":51,"line":52},[49,1247,1248],{"class":109},"[] ",[49,1250,1079],{"class":59},[49,1252,1253],{"class":109}," {}\n",[10,1255,1256],{},"becomes roughly this:",[39,1258,1260],{"className":41,"code":1259,"language":43,"meta":44,"style":44},"\"\" + \"[object Object]\"\n",[46,1261,1262],{"__ignoreMap":44},[49,1263,1264,1266,1268,1270,1273],{"class":51,"line":52},[49,1265,829],{"class":113},[49,1267,60],{"class":59},[49,1269,1130],{"class":113},[49,1271,1272],{"class":117},"[object Object]",[49,1274,1136],{"class":113},[10,1276,1277],{},"Result:",[39,1279,1281],{"className":41,"code":1280,"language":43,"meta":44,"style":44},"\"[object Object]\"\n",[46,1282,1283],{"__ignoreMap":44},[49,1284,1285,1287,1289],{"class":51,"line":52},[49,1286,114],{"class":113},[49,1288,1272],{"class":117},[49,1290,1136],{"class":113},[10,1292,1293],{},"You can go very deep into this rabbit hole. There are entire memes about JavaScript coercion.",[10,1295,1296],{},"But the practical lesson is simple:",[10,1298,1299],{},"Do not rely on implicit conversion when your values are not simple primitives.",[10,1301,1302],{},"Write what you mean.",[10,1304,1305],{},"Instead of this:",[39,1307,1309],{"className":41,"code":1308,"language":43,"meta":44,"style":44},"const result = items + \"\"\n",[46,1310,1311],{"__ignoreMap":44},[49,1312,1313,1315,1318,1320,1323,1325],{"class":51,"line":52},[49,1314,306],{"class":59},[49,1316,1317],{"class":109}," result ",[49,1319,312],{"class":59},[49,1321,1322],{"class":109}," items ",[49,1324,1079],{"class":59},[49,1326,1327],{"class":113}," \"\"\n",[10,1329,1330],{},"Write this:",[39,1332,1334],{"className":41,"code":1333,"language":43,"meta":44,"style":44},"const result = items.join(\", \")\n",[46,1335,1336],{"__ignoreMap":44},[49,1337,1338,1340,1342,1344,1347,1350,1352,1354,1356,1358],{"class":51,"line":52},[49,1339,306],{"class":59},[49,1341,1317],{"class":109},[49,1343,312],{"class":59},[49,1345,1346],{"class":109}," items.",[49,1348,1349],{"class":143},"join",[49,1351,206],{"class":109},[49,1353,114],{"class":113},[49,1355,123],{"class":117},[49,1357,114],{"class":113},[49,1359,215],{"class":109},[10,1361,79],{},[39,1363,1365],{"className":41,"code":1364,"language":43,"meta":44,"style":44},"const result = String(value)\n",[46,1366,1367],{"__ignoreMap":44},[49,1368,1369,1371,1373,1375,1378],{"class":51,"line":52},[49,1370,306],{"class":59},[49,1372,1317],{"class":109},[49,1374,312],{"class":59},[49,1376,1377],{"class":143}," String",[49,1379,1380],{"class":109},"(value)\n",[10,1382,1383],{},"Explicit code is less funny in screenshots, but much better in production.",[178,1385],{},[181,1387,1389,1392],{"id":1388},"var-is-not-your-friend",[46,1390,1391],{},"var"," Is Not Your Friend",[10,1394,1395,1396,241,1399,1401,1402,438],{},"Before ",[46,1397,1398],{},"let",[46,1400,306],{},", JavaScript had ",[46,1403,1391],{},[10,1405,1406,1407,1409],{},"And ",[46,1408,1391],{}," has one big problem: it is function-scoped, not block-scoped.",[10,1411,1412],{},"Example:",[39,1414,1416],{"className":41,"code":1415,"language":43,"meta":44,"style":44},"if (true) {\n  var name = \"Ravy\"\n}\nconsole.log(name)\n// \"Ravy\"\n",[46,1417,1418,1430,1447,1451,1460],{"__ignoreMap":44},[49,1419,1420,1422,1425,1428],{"class":51,"line":52},[49,1421,600],{"class":59},[49,1423,1424],{"class":109}," (",[49,1426,1427],{"class":55},"true",[49,1429,610],{"class":109},[49,1431,1432,1435,1438,1440,1442,1445],{"class":51,"line":72},[49,1433,1434],{"class":59},"  var",[49,1436,1437],{"class":109}," name ",[49,1439,312],{"class":59},[49,1441,1130],{"class":113},[49,1443,1444],{"class":117},"Ravy",[49,1446,1136],{"class":113},[49,1448,1449],{"class":51,"line":357},[49,1450,634],{"class":109},[49,1452,1453,1455,1457],{"class":51,"line":631},[49,1454,200],{"class":109},[49,1456,203],{"class":143},[49,1458,1459],{"class":109},"(name)\n",[49,1461,1462],{"class":51,"line":1190},[49,1463,1464],{"class":75},"// \"Ravy\"\n",[10,1466,1467],{},"That variable escaped from the block.",[10,1469,1470,1471,1473],{},"With ",[46,1472,1398],{},", this would fail:",[39,1475,1477],{"className":41,"code":1476,"language":43,"meta":44,"style":44},"if (true) {\n  let name = \"Ravy\"\n}\nconsole.log(name)\n// ReferenceError\n",[46,1478,1479,1489,1504,1508,1516],{"__ignoreMap":44},[49,1480,1481,1483,1485,1487],{"class":51,"line":52},[49,1482,600],{"class":59},[49,1484,1424],{"class":109},[49,1486,1427],{"class":55},[49,1488,610],{"class":109},[49,1490,1491,1494,1496,1498,1500,1502],{"class":51,"line":72},[49,1492,1493],{"class":59},"  let",[49,1495,1437],{"class":109},[49,1497,312],{"class":59},[49,1499,1130],{"class":113},[49,1501,1444],{"class":117},[49,1503,1136],{"class":113},[49,1505,1506],{"class":51,"line":357},[49,1507,634],{"class":109},[49,1509,1510,1512,1514],{"class":51,"line":631},[49,1511,200],{"class":109},[49,1513,203],{"class":143},[49,1515,1459],{"class":109},[49,1517,1518],{"class":51,"line":1190},[49,1519,1520],{"class":75},"// ReferenceError\n",[10,1522,1523],{},"This is how most modern developers expect variables to behave.",[10,1525,1526,1528],{},[46,1527,1391],{}," also creates confusing behavior with loops and closures.",[10,1530,1531],{},"Classic example:",[39,1533,1535],{"className":41,"code":1534,"language":43,"meta":44,"style":44},"for (var i = 0; i \u003C 3; i++) {\n  setTimeout(() => {\n    console.log(i)\n  }, 100)\n}\n",[46,1536,1537,1571,1585,1595,1605],{"__ignoreMap":44},[49,1538,1539,1542,1544,1546,1549,1551,1554,1557,1560,1563,1566,1569],{"class":51,"line":52},[49,1540,1541],{"class":59},"for",[49,1543,1424],{"class":109},[49,1545,1391],{"class":59},[49,1547,1548],{"class":109}," i ",[49,1550,312],{"class":59},[49,1552,1553],{"class":55}," 0",[49,1555,1556],{"class":109},"; i ",[49,1558,1559],{"class":59},"\u003C",[49,1561,1562],{"class":55}," 3",[49,1564,1565],{"class":109},"; i",[49,1567,1568],{"class":59},"++",[49,1570,610],{"class":109},[49,1572,1573,1576,1579,1582],{"class":51,"line":72},[49,1574,1575],{"class":143},"  setTimeout",[49,1577,1578],{"class":109},"(() ",[49,1580,1581],{"class":59},"=>",[49,1583,1584],{"class":109}," {\n",[49,1586,1587,1590,1592],{"class":51,"line":357},[49,1588,1589],{"class":109},"    console.",[49,1591,203],{"class":143},[49,1593,1594],{"class":109},"(i)\n",[49,1596,1597,1600,1603],{"class":51,"line":631},[49,1598,1599],{"class":109},"  }, ",[49,1601,1602],{"class":55},"100",[49,1604,215],{"class":109},[49,1606,1607],{"class":51,"line":1190},[49,1608,634],{"class":109},[10,1610,1611],{},"You might expect:",[39,1613,1615],{"className":41,"code":1614,"language":43,"meta":44,"style":44},"0\n1\n2\n",[46,1616,1617,1622,1627],{"__ignoreMap":44},[49,1618,1619],{"class":51,"line":52},[49,1620,1621],{"class":55},"0\n",[49,1623,1624],{"class":51,"line":72},[49,1625,1626],{"class":55},"1\n",[49,1628,1629],{"class":51,"line":357},[49,1630,1631],{"class":55},"2\n",[10,1633,1634],{},"But you get:",[39,1636,1638],{"className":41,"code":1637,"language":43,"meta":44,"style":44},"3\n3\n3\n",[46,1639,1640,1645,1649],{"__ignoreMap":44},[49,1641,1642],{"class":51,"line":52},[49,1643,1644],{"class":55},"3\n",[49,1646,1647],{"class":51,"line":72},[49,1648,1644],{"class":55},[49,1650,1651],{"class":51,"line":357},[49,1652,1644],{"class":55},[10,1654,1655],{},"Why?",[10,1657,1658,1659,1661,1662,1665],{},"Because ",[46,1660,1391],{}," creates one shared ",[46,1663,1664],{},"i"," for the whole loop. By the time the callbacks run, the loop has already finished.",[10,1667,1470,1668,1670],{},[46,1669,1398],{},", each iteration gets its own variable:",[39,1672,1674],{"className":41,"code":1673,"language":43,"meta":44,"style":44},"for (let i = 0; i \u003C 3; i++) {\n  setTimeout(() => {\n    console.log(i)\n  }, 100)\n}\n",[46,1675,1676,1702,1712,1720,1728],{"__ignoreMap":44},[49,1677,1678,1680,1682,1684,1686,1688,1690,1692,1694,1696,1698,1700],{"class":51,"line":52},[49,1679,1541],{"class":59},[49,1681,1424],{"class":109},[49,1683,1398],{"class":59},[49,1685,1548],{"class":109},[49,1687,312],{"class":59},[49,1689,1553],{"class":55},[49,1691,1556],{"class":109},[49,1693,1559],{"class":59},[49,1695,1562],{"class":55},[49,1697,1565],{"class":109},[49,1699,1568],{"class":59},[49,1701,610],{"class":109},[49,1703,1704,1706,1708,1710],{"class":51,"line":72},[49,1705,1575],{"class":143},[49,1707,1578],{"class":109},[49,1709,1581],{"class":59},[49,1711,1584],{"class":109},[49,1713,1714,1716,1718],{"class":51,"line":357},[49,1715,1589],{"class":109},[49,1717,203],{"class":143},[49,1719,1594],{"class":109},[49,1721,1722,1724,1726],{"class":51,"line":631},[49,1723,1599],{"class":109},[49,1725,1602],{"class":55},[49,1727,215],{"class":109},[49,1729,1730],{"class":51,"line":1190},[49,1731,634],{"class":109},[10,1733,1734],{},"Now the result is:",[39,1736,1737],{"className":41,"code":1614,"language":43,"meta":44,"style":44},[46,1738,1739,1743,1747],{"__ignoreMap":44},[49,1740,1741],{"class":51,"line":52},[49,1742,1621],{"class":55},[49,1744,1745],{"class":51,"line":72},[49,1746,1626],{"class":55},[49,1748,1749],{"class":51,"line":357},[49,1750,1631],{"class":55},[10,1752,1753],{},"This is why my rule is very simple:",[10,1755,637,1756,1758],{},[46,1757,306],{}," by default.",[10,1760,637,1761,1763],{},[46,1762,1398],{}," when you need reassignment.",[10,1765,1766,1767,1769],{},"Do not use ",[46,1768,1391],{}," unless you have a very specific reason.",[10,1771,1772],{},"And most of the time, you do not.",[178,1774],{},[181,1776,1778],{"id":1777},"hoisting-when-code-runs-before-it-looks-like-it-should","Hoisting: When Code Runs Before It Looks Like It Should",[10,1780,1781],{},"JavaScript hoists declarations.",[10,1783,1470,1784,1786],{},[46,1785,1391],{},", this means the variable declaration is moved to the top of the scope, but the value is not.",[39,1788,1790],{"className":41,"code":1789,"language":43,"meta":44,"style":44},"console.log(value)\n// undefined\nvar value = 10\n",[46,1791,1792,1800,1805],{"__ignoreMap":44},[49,1793,1794,1796,1798],{"class":51,"line":52},[49,1795,200],{"class":109},[49,1797,203],{"class":143},[49,1799,1380],{"class":109},[49,1801,1802],{"class":51,"line":72},[49,1803,1804],{"class":75},"// undefined\n",[49,1806,1807,1809,1811,1813],{"class":51,"line":357},[49,1808,1391],{"class":59},[49,1810,453],{"class":109},[49,1812,312],{"class":59},[49,1814,1815],{"class":55}," 10\n",[10,1817,1818],{},"JavaScript treats this roughly like:",[39,1820,1822],{"className":41,"code":1821,"language":43,"meta":44,"style":44},"var value\nconsole.log(value)\n// undefined\nvalue = 10\n",[46,1823,1824,1831,1839,1843],{"__ignoreMap":44},[49,1825,1826,1828],{"class":51,"line":52},[49,1827,1391],{"class":59},[49,1829,1830],{"class":109}," value\n",[49,1832,1833,1835,1837],{"class":51,"line":72},[49,1834,200],{"class":109},[49,1836,203],{"class":143},[49,1838,1380],{"class":109},[49,1840,1841],{"class":51,"line":357},[49,1842,1804],{"class":75},[49,1844,1845,1848,1850],{"class":51,"line":631},[49,1846,1847],{"class":109},"value ",[49,1849,312],{"class":59},[49,1851,1815],{"class":55},[10,1853,1854],{},"That is already confusing.",[10,1856,1857,1858,241,1860,1862],{},"But with ",[46,1859,1398],{},[46,1861,306],{},", the behavior is different:",[39,1864,1866],{"className":41,"code":1865,"language":43,"meta":44,"style":44},"console.log(value)\n// ReferenceError\nlet value = 10\n",[46,1867,1868,1876,1880],{"__ignoreMap":44},[49,1869,1870,1872,1874],{"class":51,"line":52},[49,1871,200],{"class":109},[49,1873,203],{"class":143},[49,1875,1380],{"class":109},[49,1877,1878],{"class":51,"line":72},[49,1879,1520],{"class":75},[49,1881,1882,1884,1886,1888],{"class":51,"line":357},[49,1883,1398],{"class":59},[49,1885,453],{"class":109},[49,1887,312],{"class":59},[49,1889,1815],{"class":55},[10,1891,1892],{},"The variable exists, but it is in the so-called temporal dead zone until the declaration line is reached.",[10,1894,1895],{},"You do not need to build your whole life around this term. Just remember the practical rule:",[10,1897,1898],{},"Declare variables before using them.",[10,1900,1901],{},"It is not a “junior” habit.",[10,1903,1904],{},"It is just clean code.",[178,1906],{},[181,1908,1910,1913],{"id":1909},"this-is-not-where-the-function-lives",[46,1911,1912],{},"this"," Is Not Where the Function Lives",[10,1915,1916,1918],{},[46,1917,1912],{}," in JavaScript is one of those topics that can make even experienced developers tired.",[10,1920,1921],{},"The main idea:",[10,1923,1924,1926],{},[46,1925,1912],{}," depends on how a function is called, not where it is written.",[10,1928,1412],{},[39,1930,1932],{"className":41,"code":1931,"language":43,"meta":44,"style":44},"const user = {\n  name: \"Ravy\",\n  sayHi() {\n    console.log(this.name)\n  }\n}\n\nuser.sayHi()\n// \"Ravy\"\n",[46,1933,1934,1945,1962,1970,1984,1989,1994,1999,2011],{"__ignoreMap":44},[49,1935,1936,1938,1941,1943],{"class":51,"line":52},[49,1937,306],{"class":59},[49,1939,1940],{"class":109}," user ",[49,1942,312],{"class":59},[49,1944,1584],{"class":109},[49,1946,1947,1950,1953,1955,1957,1959],{"class":51,"line":72},[49,1948,1949],{"class":109},"  name",[49,1951,1952],{"class":59},":",[49,1954,1130],{"class":113},[49,1956,1444],{"class":117},[49,1958,114],{"class":113},[49,1960,1961],{"class":109},",\n",[49,1963,1964,1967],{"class":51,"line":357},[49,1965,1966],{"class":143},"  sayHi",[49,1968,1969],{"class":109},"() {\n",[49,1971,1972,1974,1976,1978,1981],{"class":51,"line":631},[49,1973,1589],{"class":109},[49,1975,203],{"class":143},[49,1977,206],{"class":109},[49,1979,1912],{"class":1980},"sqerP",[49,1982,1983],{"class":109},".name)\n",[49,1985,1986],{"class":51,"line":1190},[49,1987,1988],{"class":109},"  }\n",[49,1990,1992],{"class":51,"line":1991},6,[49,1993,634],{"class":109},[49,1995,1997],{"class":51,"line":1996},7,[49,1998,1174],{"emptyLinePlaceholder":1173},[49,2000,2002,2005,2008],{"class":51,"line":2001},8,[49,2003,2004],{"class":109},"user.",[49,2006,2007],{"class":143},"sayHi",[49,2009,2010],{"class":109},"()\n",[49,2012,2014],{"class":51,"line":2013},9,[49,2015,1464],{"class":75},[10,2017,2018],{},"Looks good.",[10,2020,2021],{},"But now:",[39,2023,2025],{"className":41,"code":2024,"language":43,"meta":44,"style":44},"const sayHi = user.sayHi\nsayHi()\n// undefined\n",[46,2026,2027,2039,2045],{"__ignoreMap":44},[49,2028,2029,2031,2034,2036],{"class":51,"line":52},[49,2030,306],{"class":59},[49,2032,2033],{"class":109}," sayHi ",[49,2035,312],{"class":59},[49,2037,2038],{"class":109}," user.sayHi\n",[49,2040,2041,2043],{"class":51,"line":72},[49,2042,2007],{"class":143},[49,2044,2010],{"class":109},[49,2046,2047],{"class":51,"line":357},[49,2048,1804],{"class":75},[10,2050,2051,2052,438],{},"We took the method out of the object. Now it is just a function call, not ",[46,2053,2054],{},"user.sayHi()",[10,2056,561,2057,2059],{},[46,2058,1912],{}," is lost.",[10,2061,2062],{},"This happens a lot when passing methods as callbacks.",[10,2064,2065,2066,1952],{},"You can fix it with ",[46,2067,2068],{},"bind",[39,2070,2072],{"className":41,"code":2071,"language":43,"meta":44,"style":44},"const sayHi = user.sayHi.bind(user)\nsayHi()\n// \"Ravy\"\n",[46,2073,2074,2090,2096],{"__ignoreMap":44},[49,2075,2076,2078,2080,2082,2085,2087],{"class":51,"line":52},[49,2077,306],{"class":59},[49,2079,2033],{"class":109},[49,2081,312],{"class":59},[49,2083,2084],{"class":109}," user.sayHi.",[49,2086,2068],{"class":143},[49,2088,2089],{"class":109},"(user)\n",[49,2091,2092,2094],{"class":51,"line":72},[49,2093,2007],{"class":143},[49,2095,2010],{"class":109},[49,2097,2098],{"class":51,"line":357},[49,2099,1464],{"class":75},[10,2101,2102],{},"Or with a wrapper:",[39,2104,2106],{"className":41,"code":2105,"language":43,"meta":44,"style":44},"const sayHi = () => user.sayHi()\nsayHi()\n// \"Ravy\"\n",[46,2107,2108,2130,2136],{"__ignoreMap":44},[49,2109,2110,2112,2115,2118,2121,2123,2126,2128],{"class":51,"line":52},[49,2111,306],{"class":59},[49,2113,2114],{"class":143}," sayHi",[49,2116,2117],{"class":59}," =",[49,2119,2120],{"class":109}," () ",[49,2122,1581],{"class":59},[49,2124,2125],{"class":109}," user.",[49,2127,2007],{"class":143},[49,2129,2010],{"class":109},[49,2131,2132,2134],{"class":51,"line":72},[49,2133,2007],{"class":143},[49,2135,2010],{"class":109},[49,2137,2138],{"class":51,"line":357},[49,2139,1464],{"class":75},[10,2141,2142],{},"The trap gets even more interesting with arrow functions.",[10,2144,2145,2146,438],{},"Arrow functions do not have their own ",[46,2147,1912],{},[10,2149,2150],{},"So this is usually a bad idea:",[39,2152,2154],{"className":41,"code":2153,"language":43,"meta":44,"style":44},"const user = {\n  name: \"Ravy\",\n  sayHi: () => {\n    console.log(this.name)\n  }\n}\n\nuser.sayHi()\n// undefined\n",[46,2155,2156,2166,2180,2192,2204,2208,2212,2216,2224],{"__ignoreMap":44},[49,2157,2158,2160,2162,2164],{"class":51,"line":52},[49,2159,306],{"class":59},[49,2161,1940],{"class":109},[49,2163,312],{"class":59},[49,2165,1584],{"class":109},[49,2167,2168,2170,2172,2174,2176,2178],{"class":51,"line":72},[49,2169,1949],{"class":109},[49,2171,1952],{"class":59},[49,2173,1130],{"class":113},[49,2175,1444],{"class":117},[49,2177,114],{"class":113},[49,2179,1961],{"class":109},[49,2181,2182,2184,2186,2188,2190],{"class":51,"line":357},[49,2183,1966],{"class":143},[49,2185,1952],{"class":59},[49,2187,2120],{"class":109},[49,2189,1581],{"class":59},[49,2191,1584],{"class":109},[49,2193,2194,2196,2198,2200,2202],{"class":51,"line":631},[49,2195,1589],{"class":109},[49,2197,203],{"class":143},[49,2199,206],{"class":109},[49,2201,1912],{"class":1980},[49,2203,1983],{"class":109},[49,2205,2206],{"class":51,"line":1190},[49,2207,1988],{"class":109},[49,2209,2210],{"class":51,"line":1991},[49,2211,634],{"class":109},[49,2213,2214],{"class":51,"line":1996},[49,2215,1174],{"emptyLinePlaceholder":1173},[49,2217,2218,2220,2222],{"class":51,"line":2001},[49,2219,2004],{"class":109},[49,2221,2007],{"class":143},[49,2223,2010],{"class":109},[49,2225,2226],{"class":51,"line":2013},[49,2227,1804],{"class":75},[10,2229,2230,2231,2233],{},"If you need ",[46,2232,1912],{}," inside an object method, use a regular method:",[39,2235,2237],{"className":41,"code":2236,"language":43,"meta":44,"style":44},"const user = {\n  name: \"Ravy\",\n  sayHi() {\n    console.log(this.name)\n  }\n}\n",[46,2238,2239,2249,2263,2269,2281,2285],{"__ignoreMap":44},[49,2240,2241,2243,2245,2247],{"class":51,"line":52},[49,2242,306],{"class":59},[49,2244,1940],{"class":109},[49,2246,312],{"class":59},[49,2248,1584],{"class":109},[49,2250,2251,2253,2255,2257,2259,2261],{"class":51,"line":72},[49,2252,1949],{"class":109},[49,2254,1952],{"class":59},[49,2256,1130],{"class":113},[49,2258,1444],{"class":117},[49,2260,114],{"class":113},[49,2262,1961],{"class":109},[49,2264,2265,2267],{"class":51,"line":357},[49,2266,1966],{"class":143},[49,2268,1969],{"class":109},[49,2270,2271,2273,2275,2277,2279],{"class":51,"line":631},[49,2272,1589],{"class":109},[49,2274,203],{"class":143},[49,2276,206],{"class":109},[49,2278,1912],{"class":1980},[49,2280,1983],{"class":109},[49,2282,2283],{"class":51,"line":1190},[49,2284,1988],{"class":109},[49,2286,2287],{"class":51,"line":1991},[49,2288,634],{"class":109},[10,2290,2291],{},"Arrow functions are great.",[10,2293,2294],{},"Just not everywhere.",[178,2296],{},[181,2298,2300],{"id":2299},"objects-are-passed-by-reference","Objects Are Passed by Reference",[10,2302,2303],{},"This one creates bugs that look like ghosts.",[39,2305,2307],{"className":41,"code":2306,"language":43,"meta":44,"style":44},"const a = { count: 1 }\nconst b = a\nb.count = 2\nconsole.log(a.count)\n// 2\n",[46,2308,2309,2329,2341,2350,2359],{"__ignoreMap":44},[49,2310,2311,2313,2316,2318,2321,2323,2326],{"class":51,"line":52},[49,2312,306],{"class":59},[49,2314,2315],{"class":109}," a ",[49,2317,312],{"class":59},[49,2319,2320],{"class":109}," { count",[49,2322,1952],{"class":59},[49,2324,2325],{"class":55}," 1",[49,2327,2328],{"class":109}," }\n",[49,2330,2331,2333,2336,2338],{"class":51,"line":72},[49,2332,306],{"class":59},[49,2334,2335],{"class":109}," b ",[49,2337,312],{"class":59},[49,2339,2340],{"class":109}," a\n",[49,2342,2343,2346,2348],{"class":51,"line":357},[49,2344,2345],{"class":109},"b.count ",[49,2347,312],{"class":59},[49,2349,1104],{"class":55},[49,2351,2352,2354,2356],{"class":51,"line":631},[49,2353,200],{"class":109},[49,2355,203],{"class":143},[49,2357,2358],{"class":109},"(a.count)\n",[49,2360,2361],{"class":51,"line":1190},[49,2362,2363],{"class":75},"// 2\n",[10,2365,2366,2367,2370],{},"At first, it feels like ",[46,2368,2369],{},"b"," should be a copy.",[10,2372,2373],{},"But it is not.",[10,2375,2376],{},"Both variables point to the same object.",[10,2378,2379],{},"Same thing with arrays:",[39,2381,2383],{"className":41,"code":2382,"language":43,"meta":44,"style":44},"const first = [1, 2, 3]\nconst second = first\nsecond.push(4)\nconsole.log(first)\n// [1, 2, 3, 4]\n",[46,2384,2385,2412,2424,2439,2448],{"__ignoreMap":44},[49,2386,2387,2389,2392,2394,2397,2399,2401,2404,2406,2409],{"class":51,"line":52},[49,2388,306],{"class":59},[49,2390,2391],{"class":109}," first ",[49,2393,312],{"class":59},[49,2395,2396],{"class":109}," [",[49,2398,1099],{"class":55},[49,2400,123],{"class":109},[49,2402,2403],{"class":55},"2",[49,2405,123],{"class":109},[49,2407,2408],{"class":55},"3",[49,2410,2411],{"class":109},"]\n",[49,2413,2414,2416,2419,2421],{"class":51,"line":72},[49,2415,306],{"class":59},[49,2417,2418],{"class":109}," second ",[49,2420,312],{"class":59},[49,2422,2423],{"class":109}," first\n",[49,2425,2426,2429,2432,2434,2437],{"class":51,"line":357},[49,2427,2428],{"class":109},"second.",[49,2430,2431],{"class":143},"push",[49,2433,206],{"class":109},[49,2435,2436],{"class":55},"4",[49,2438,215],{"class":109},[49,2440,2441,2443,2445],{"class":51,"line":631},[49,2442,200],{"class":109},[49,2444,203],{"class":143},[49,2446,2447],{"class":109},"(first)\n",[49,2449,2450],{"class":51,"line":1190},[49,2451,2452],{"class":75},"// [1, 2, 3, 4]\n",[10,2454,2455],{},"This becomes especially painful in UI development, state management, Redux-like patterns, Vue, React, or anywhere else where you expect data changes to be predictable.",[10,2457,2458],{},"A shallow copy helps:",[39,2460,2462],{"className":41,"code":2461,"language":43,"meta":44,"style":44},"const original = { count: 1 }\nconst copy = { ...original }\ncopy.count = 2\nconsole.log(original.count)\n// 1\n",[46,2463,2464,2481,2499,2508,2517],{"__ignoreMap":44},[49,2465,2466,2468,2471,2473,2475,2477,2479],{"class":51,"line":52},[49,2467,306],{"class":59},[49,2469,2470],{"class":109}," original ",[49,2472,312],{"class":59},[49,2474,2320],{"class":109},[49,2476,1952],{"class":59},[49,2478,2325],{"class":55},[49,2480,2328],{"class":109},[49,2482,2483,2485,2488,2490,2493,2496],{"class":51,"line":72},[49,2484,306],{"class":59},[49,2486,2487],{"class":109}," copy ",[49,2489,312],{"class":59},[49,2491,2492],{"class":109}," { ",[49,2494,2495],{"class":59},"...",[49,2497,2498],{"class":109},"original }\n",[49,2500,2501,2504,2506],{"class":51,"line":357},[49,2502,2503],{"class":109},"copy.count ",[49,2505,312],{"class":59},[49,2507,1104],{"class":55},[49,2509,2510,2512,2514],{"class":51,"line":631},[49,2511,200],{"class":109},[49,2513,203],{"class":143},[49,2515,2516],{"class":109},"(original.count)\n",[49,2518,2519],{"class":51,"line":1190},[49,2520,2521],{"class":75},"// 1\n",[10,2523,2524],{},"For arrays:",[39,2526,2528],{"className":41,"code":2527,"language":43,"meta":44,"style":44},"const original = [1, 2, 3]\nconst copy = [...original]\ncopy.push(4)\nconsole.log(original)\n// [1, 2, 3]\n",[46,2529,2530,2552,2567,2580,2589],{"__ignoreMap":44},[49,2531,2532,2534,2536,2538,2540,2542,2544,2546,2548,2550],{"class":51,"line":52},[49,2533,306],{"class":59},[49,2535,2470],{"class":109},[49,2537,312],{"class":59},[49,2539,2396],{"class":109},[49,2541,1099],{"class":55},[49,2543,123],{"class":109},[49,2545,2403],{"class":55},[49,2547,123],{"class":109},[49,2549,2408],{"class":55},[49,2551,2411],{"class":109},[49,2553,2554,2556,2558,2560,2562,2564],{"class":51,"line":72},[49,2555,306],{"class":59},[49,2557,2487],{"class":109},[49,2559,312],{"class":59},[49,2561,2396],{"class":109},[49,2563,2495],{"class":59},[49,2565,2566],{"class":109},"original]\n",[49,2568,2569,2572,2574,2576,2578],{"class":51,"line":357},[49,2570,2571],{"class":109},"copy.",[49,2573,2431],{"class":143},[49,2575,206],{"class":109},[49,2577,2436],{"class":55},[49,2579,215],{"class":109},[49,2581,2582,2584,2586],{"class":51,"line":631},[49,2583,200],{"class":109},[49,2585,203],{"class":143},[49,2587,2588],{"class":109},"(original)\n",[49,2590,2591],{"class":51,"line":1190},[49,2592,2593],{"class":75},"// [1, 2, 3]\n",[10,2595,2596],{},"But there is another trap.",[10,2598,2599],{},"Shallow copy only copies the first level.",[39,2601,2603],{"className":41,"code":2602,"language":43,"meta":44,"style":44},"const user = {\n  name: \"Ravy\",\n  settings: {\n    theme: \"dark\"\n  }\n}\n\nconst copy = { ...user }\ncopy.settings.theme = \"light\"\nconsole.log(user.settings.theme)\n// \"light\"\n",[46,2604,2605,2615,2629,2638,2652,2656,2660,2664,2679,2693,2703],{"__ignoreMap":44},[49,2606,2607,2609,2611,2613],{"class":51,"line":52},[49,2608,306],{"class":59},[49,2610,1940],{"class":109},[49,2612,312],{"class":59},[49,2614,1584],{"class":109},[49,2616,2617,2619,2621,2623,2625,2627],{"class":51,"line":72},[49,2618,1949],{"class":109},[49,2620,1952],{"class":59},[49,2622,1130],{"class":113},[49,2624,1444],{"class":117},[49,2626,114],{"class":113},[49,2628,1961],{"class":109},[49,2630,2631,2634,2636],{"class":51,"line":357},[49,2632,2633],{"class":109},"  settings",[49,2635,1952],{"class":59},[49,2637,1584],{"class":109},[49,2639,2640,2643,2645,2647,2650],{"class":51,"line":631},[49,2641,2642],{"class":109},"    theme",[49,2644,1952],{"class":59},[49,2646,1130],{"class":113},[49,2648,2649],{"class":117},"dark",[49,2651,1136],{"class":113},[49,2653,2654],{"class":51,"line":1190},[49,2655,1988],{"class":109},[49,2657,2658],{"class":51,"line":1991},[49,2659,634],{"class":109},[49,2661,2662],{"class":51,"line":1996},[49,2663,1174],{"emptyLinePlaceholder":1173},[49,2665,2666,2668,2670,2672,2674,2676],{"class":51,"line":2001},[49,2667,306],{"class":59},[49,2669,2487],{"class":109},[49,2671,312],{"class":59},[49,2673,2492],{"class":109},[49,2675,2495],{"class":59},[49,2677,2678],{"class":109},"user }\n",[49,2680,2681,2684,2686,2688,2691],{"class":51,"line":2013},[49,2682,2683],{"class":109},"copy.settings.theme ",[49,2685,312],{"class":59},[49,2687,1130],{"class":113},[49,2689,2690],{"class":117},"light",[49,2692,1136],{"class":113},[49,2694,2696,2698,2700],{"class":51,"line":2695},10,[49,2697,200],{"class":109},[49,2699,203],{"class":143},[49,2701,2702],{"class":109},"(user.settings.theme)\n",[49,2704,2706],{"class":51,"line":2705},11,[49,2707,2708],{"class":75},"// \"light\"\n",[10,2710,2711],{},"The top-level object was copied.",[10,2713,2714,2715,2718],{},"The nested ",[46,2716,2717],{},"settings"," object was not.",[10,2720,2721,2722,1952],{},"For deep cloning, modern JavaScript has ",[46,2723,2724],{},"structuredClone()",[39,2726,2728],{"className":41,"code":2727,"language":43,"meta":44,"style":44},"const copy = structuredClone(user)\n",[46,2729,2730],{"__ignoreMap":44},[49,2731,2732,2734,2736,2738,2741],{"class":51,"line":52},[49,2733,306],{"class":59},[49,2735,2487],{"class":109},[49,2737,312],{"class":59},[49,2739,2740],{"class":143}," structuredClone",[49,2742,2089],{"class":109},[10,2744,2745],{},"But even here, you need to understand your data. Functions, class instances, special objects — all of this can require special handling.",[10,2747,2748],{},"The real lesson:",[10,2750,2751],{},"When you copy an object, always ask yourself:",[228,2753,2754],{},[10,2755,2756],{},"Did I copy the object, or did I copy a reference?",[10,2758,2759],{},"This question saves a lot of debugging time.",[178,2761],{},[181,2763,2765,2768],{"id":2764},"mapparseint-is-evil-and-beautiful",[46,2766,2767],{},"map(parseInt)"," Is Evil and Beautiful",[10,2770,2771],{},"This is one of my favorite JavaScript traps because it looks so clean.",[39,2773,2775],{"className":41,"code":2774,"language":43,"meta":44,"style":44},"[\"10\", \"10\", \"10\"].map(parseInt)\n",[46,2776,2777],{"__ignoreMap":44},[49,2778,2779,2781,2783,2785,2787,2789,2791,2793,2795,2797,2799,2801,2803,2805,2807],{"class":51,"line":52},[49,2780,110],{"class":109},[49,2782,114],{"class":113},[49,2784,118],{"class":117},[49,2786,114],{"class":113},[49,2788,123],{"class":109},[49,2790,114],{"class":113},[49,2792,118],{"class":117},[49,2794,114],{"class":113},[49,2796,123],{"class":109},[49,2798,114],{"class":113},[49,2800,118],{"class":117},[49,2802,114],{"class":113},[49,2804,140],{"class":109},[49,2806,144],{"class":143},[49,2808,147],{"class":109},[10,2810,1611],{},[39,2812,2814],{"className":41,"code":2813,"language":43,"meta":44,"style":44},"[10, 10, 10]\n",[46,2815,2816],{"__ignoreMap":44},[49,2817,2818,2820,2822,2824,2826,2828,2830],{"class":51,"line":52},[49,2819,110],{"class":109},[49,2821,118],{"class":55},[49,2823,123],{"class":109},[49,2825,118],{"class":55},[49,2827,123],{"class":109},[49,2829,118],{"class":55},[49,2831,2411],{"class":109},[10,2833,2834],{},"But JavaScript gives you:",[39,2836,2838],{"className":41,"code":2837,"language":43,"meta":44,"style":44},"[10, NaN, 2]\n",[46,2839,2840],{"__ignoreMap":44},[49,2841,2842,2844,2846,2848,2850,2852,2854],{"class":51,"line":52},[49,2843,110],{"class":109},[49,2845,118],{"class":55},[49,2847,123],{"class":109},[49,2849,498],{"class":55},[49,2851,123],{"class":109},[49,2853,2403],{"class":55},[49,2855,2411],{"class":109},[10,2857,1655],{},[10,2859,1658,2860,2862],{},[46,2861,144],{}," passes three arguments into the callback:",[39,2864,2866],{"className":41,"code":2865,"language":43,"meta":44,"style":44},"(value, index, array)\n",[46,2867,2868],{"__ignoreMap":44},[49,2869,2870],{"class":51,"line":52},[49,2871,2865],{"class":109},[10,2873,1406,2874,2877],{},[46,2875,2876],{},"parseInt"," accepts two arguments:",[39,2879,2881],{"className":41,"code":2880,"language":43,"meta":44,"style":44},"parseInt(value, radix)\n",[46,2882,2883],{"__ignoreMap":44},[49,2884,2885,2887],{"class":51,"line":52},[49,2886,2876],{"class":143},[49,2888,2889],{"class":109},"(value, radix)\n",[10,2891,1238],{},[39,2893,2894],{"className":41,"code":2774,"language":43,"meta":44,"style":44},[46,2895,2896],{"__ignoreMap":44},[49,2897,2898,2900,2902,2904,2906,2908,2910,2912,2914,2916,2918,2920,2922,2924,2926],{"class":51,"line":52},[49,2899,110],{"class":109},[49,2901,114],{"class":113},[49,2903,118],{"class":117},[49,2905,114],{"class":113},[49,2907,123],{"class":109},[49,2909,114],{"class":113},[49,2911,118],{"class":117},[49,2913,114],{"class":113},[49,2915,123],{"class":109},[49,2917,114],{"class":113},[49,2919,118],{"class":117},[49,2921,114],{"class":113},[49,2923,140],{"class":109},[49,2925,144],{"class":143},[49,2927,147],{"class":109},[10,2929,2930],{},"actually becomes:",[39,2932,2934],{"className":41,"code":2933,"language":43,"meta":44,"style":44},"parseInt(\"10\", 0) // 10\nparseInt(\"10\", 1) // NaN\nparseInt(\"10\", 2) // 2\n",[46,2935,2936,2958,2979],{"__ignoreMap":44},[49,2937,2938,2940,2942,2944,2946,2948,2950,2952,2955],{"class":51,"line":52},[49,2939,2876],{"class":143},[49,2941,206],{"class":109},[49,2943,114],{"class":113},[49,2945,118],{"class":117},[49,2947,114],{"class":113},[49,2949,123],{"class":109},[49,2951,807],{"class":55},[49,2953,2954],{"class":109},") ",[49,2956,2957],{"class":75},"// 10\n",[49,2959,2960,2962,2964,2966,2968,2970,2972,2974,2976],{"class":51,"line":72},[49,2961,2876],{"class":143},[49,2963,206],{"class":109},[49,2965,114],{"class":113},[49,2967,118],{"class":117},[49,2969,114],{"class":113},[49,2971,123],{"class":109},[49,2973,1099],{"class":55},[49,2975,2954],{"class":109},[49,2977,2978],{"class":75},"// NaN\n",[49,2980,2981,2983,2985,2987,2989,2991,2993,2995,2997],{"class":51,"line":357},[49,2982,2876],{"class":143},[49,2984,206],{"class":109},[49,2986,114],{"class":113},[49,2988,118],{"class":117},[49,2990,114],{"class":113},[49,2992,123],{"class":109},[49,2994,2403],{"class":55},[49,2996,2954],{"class":109},[49,2998,2363],{"class":75},[10,3000,3001],{},"It is technically correct.",[10,3003,3004],{},"And completely not what you wanted.",[10,3006,3007],{},"Write this instead:",[39,3009,3011],{"className":41,"code":3010,"language":43,"meta":44,"style":44},"[\"10\", \"10\", \"10\"].map(value => parseInt(value, 10))\n",[46,3012,3013],{"__ignoreMap":44},[49,3014,3015,3017,3019,3021,3023,3025,3027,3029,3031,3033,3035,3037,3039,3041,3043,3045,3049,3052,3055,3058,3060],{"class":51,"line":52},[49,3016,110],{"class":109},[49,3018,114],{"class":113},[49,3020,118],{"class":117},[49,3022,114],{"class":113},[49,3024,123],{"class":109},[49,3026,114],{"class":113},[49,3028,118],{"class":117},[49,3030,114],{"class":113},[49,3032,123],{"class":109},[49,3034,114],{"class":113},[49,3036,118],{"class":117},[49,3038,114],{"class":113},[49,3040,140],{"class":109},[49,3042,144],{"class":143},[49,3044,206],{"class":109},[49,3046,3048],{"class":3047},"sGEwX","value",[49,3050,3051],{"class":59}," =>",[49,3053,3054],{"class":143}," parseInt",[49,3056,3057],{"class":109},"(value, ",[49,3059,118],{"class":55},[49,3061,665],{"class":109},[10,3063,3064],{},"Or:",[39,3066,3068],{"className":41,"code":3067,"language":43,"meta":44,"style":44},"[\"10\", \"10\", \"10\"].map(Number)\n",[46,3069,3070],{"__ignoreMap":44},[49,3071,3072,3074,3076,3078,3080,3082,3084,3086,3088,3090,3092,3094,3096,3098,3100],{"class":51,"line":52},[49,3073,110],{"class":109},[49,3075,114],{"class":113},[49,3077,118],{"class":117},[49,3079,114],{"class":113},[49,3081,123],{"class":109},[49,3083,114],{"class":113},[49,3085,118],{"class":117},[49,3087,114],{"class":113},[49,3089,123],{"class":109},[49,3091,114],{"class":113},[49,3093,118],{"class":117},[49,3095,114],{"class":113},[49,3097,140],{"class":109},[49,3099,144],{"class":143},[49,3101,3102],{"class":109},"(Number)\n",[10,3104,3105],{},"This is a perfect example of a JavaScript problem where every piece works correctly in isolation, but together they create chaos.",[178,3107],{},[181,3109,3111,3114],{"id":3110},"asyncawait-does-not-automatically-make-things-parallel",[46,3112,3113],{},"async/await"," Does Not Automatically Make Things Parallel",[10,3116,3117,3119],{},[46,3118,3113],{}," makes asynchronous code much easier to read.",[10,3121,3122],{},"But it also makes it easy to accidentally write slow code.",[10,3124,1412],{},[39,3126,3128],{"className":41,"code":3127,"language":43,"meta":44,"style":44},"const user = await fetchUser()\nconst posts = await fetchPosts()\nconst comments = await fetchComments()\n",[46,3129,3130,3146,3162],{"__ignoreMap":44},[49,3131,3132,3134,3136,3138,3141,3144],{"class":51,"line":52},[49,3133,306],{"class":59},[49,3135,1940],{"class":109},[49,3137,312],{"class":59},[49,3139,3140],{"class":59}," await",[49,3142,3143],{"class":143}," fetchUser",[49,3145,2010],{"class":109},[49,3147,3148,3150,3153,3155,3157,3160],{"class":51,"line":72},[49,3149,306],{"class":59},[49,3151,3152],{"class":109}," posts ",[49,3154,312],{"class":59},[49,3156,3140],{"class":59},[49,3158,3159],{"class":143}," fetchPosts",[49,3161,2010],{"class":109},[49,3163,3164,3166,3169,3171,3173,3176],{"class":51,"line":357},[49,3165,306],{"class":59},[49,3167,3168],{"class":109}," comments ",[49,3170,312],{"class":59},[49,3172,3140],{"class":59},[49,3174,3175],{"class":143}," fetchComments",[49,3177,2010],{"class":109},[10,3179,3180],{},"This runs sequentially.",[10,3182,3183],{},"First, JavaScript waits for the user.",[10,3185,3186],{},"Then it waits for posts.",[10,3188,3189],{},"Then it waits for comments.",[10,3191,3192],{},"If these requests do not depend on each other, this is wasted time.",[10,3194,323],{},[39,3196,3198],{"className":41,"code":3197,"language":43,"meta":44,"style":44},"const [user, posts, comments] = await Promise.all([\n  fetchUser(),\n  fetchPosts(),\n  fetchComments()\n])\n",[46,3199,3200,3223,3231,3238,3245],{"__ignoreMap":44},[49,3201,3202,3204,3207,3209,3211,3215,3217,3220],{"class":51,"line":52},[49,3203,306],{"class":59},[49,3205,3206],{"class":109}," [user, posts, comments] ",[49,3208,312],{"class":59},[49,3210,3140],{"class":59},[49,3212,3214],{"class":3213},"sCp4m"," Promise",[49,3216,438],{"class":109},[49,3218,3219],{"class":143},"all",[49,3221,3222],{"class":109},"([\n",[49,3224,3225,3228],{"class":51,"line":72},[49,3226,3227],{"class":143},"  fetchUser",[49,3229,3230],{"class":109},"(),\n",[49,3232,3233,3236],{"class":51,"line":357},[49,3234,3235],{"class":143},"  fetchPosts",[49,3237,3230],{"class":109},[49,3239,3240,3243],{"class":51,"line":631},[49,3241,3242],{"class":143},"  fetchComments",[49,3244,2010],{"class":109},[49,3246,3247],{"class":51,"line":1190},[49,3248,3249],{"class":109},"])\n",[10,3251,3252],{},"Now they run in parallel.",[10,3254,3255],{},"But there is another detail.",[10,3257,3258,3261],{},[46,3259,3260],{},"Promise.all()"," fails fast. If one promise rejects, the whole thing rejects.",[10,3263,3264],{},"Sometimes that is what you want.",[10,3266,3267],{},"Sometimes you want to collect all results, even failed ones:",[39,3269,3271],{"className":41,"code":3270,"language":43,"meta":44,"style":44},"const results = await Promise.allSettled([\n  fetchUser(),\n  fetchPosts(),\n  fetchComments()\n])\n",[46,3272,3273,3293,3299,3305,3311],{"__ignoreMap":44},[49,3274,3275,3277,3280,3282,3284,3286,3288,3291],{"class":51,"line":52},[49,3276,306],{"class":59},[49,3278,3279],{"class":109}," results ",[49,3281,312],{"class":59},[49,3283,3140],{"class":59},[49,3285,3214],{"class":3213},[49,3287,438],{"class":109},[49,3289,3290],{"class":143},"allSettled",[49,3292,3222],{"class":109},[49,3294,3295,3297],{"class":51,"line":72},[49,3296,3227],{"class":143},[49,3298,3230],{"class":109},[49,3300,3301,3303],{"class":51,"line":357},[49,3302,3235],{"class":143},[49,3304,3230],{"class":109},[49,3306,3307,3309],{"class":51,"line":631},[49,3308,3242],{"class":143},[49,3310,2010],{"class":109},[49,3312,3313],{"class":51,"line":1190},[49,3314,3249],{"class":109},[10,3316,3317],{},"The trap here is not syntax.",[10,3319,3320],{},"The trap is thinking that pretty asynchronous code is automatically efficient asynchronous code.",[10,3322,3323],{},"It is not.",[10,3325,3326],{},"You still need to think about execution flow.",[178,3328],{},[181,3330,3332,3335],{"id":3331},"trycatch-does-not-catch-promises-unless-you-await-them",[46,3333,3334],{},"try/catch"," Does Not Catch Promises Unless You Await Them",[10,3337,3338],{},"This works:",[39,3340,3342],{"className":41,"code":3341,"language":43,"meta":44,"style":44},"try {\n  await loadData()\n} catch (error) {\n  console.error(error)\n}\n",[46,3343,3344,3351,3361,3372,3382],{"__ignoreMap":44},[49,3345,3346,3349],{"class":51,"line":52},[49,3347,3348],{"class":59},"try",[49,3350,1584],{"class":109},[49,3352,3353,3356,3359],{"class":51,"line":72},[49,3354,3355],{"class":59},"  await",[49,3357,3358],{"class":143}," loadData",[49,3360,2010],{"class":109},[49,3362,3363,3366,3369],{"class":51,"line":357},[49,3364,3365],{"class":109},"} ",[49,3367,3368],{"class":59},"catch",[49,3370,3371],{"class":109}," (error) {\n",[49,3373,3374,3376,3379],{"class":51,"line":631},[49,3375,615],{"class":109},[49,3377,3378],{"class":143},"error",[49,3380,3381],{"class":109},"(error)\n",[49,3383,3384],{"class":51,"line":1190},[49,3385,634],{"class":109},[10,3387,3388],{},"This may not:",[39,3390,3392],{"className":41,"code":3391,"language":43,"meta":44,"style":44},"try {\n  loadData()\n} catch (error) {\n  console.error(error)\n}\n",[46,3393,3394,3400,3407,3415,3423],{"__ignoreMap":44},[49,3395,3396,3398],{"class":51,"line":52},[49,3397,3348],{"class":59},[49,3399,1584],{"class":109},[49,3401,3402,3405],{"class":51,"line":72},[49,3403,3404],{"class":143},"  loadData",[49,3406,2010],{"class":109},[49,3408,3409,3411,3413],{"class":51,"line":357},[49,3410,3365],{"class":109},[49,3412,3368],{"class":59},[49,3414,3371],{"class":109},[49,3416,3417,3419,3421],{"class":51,"line":631},[49,3418,615],{"class":109},[49,3420,3378],{"class":143},[49,3422,3381],{"class":109},[49,3424,3425],{"class":51,"line":1190},[49,3426,634],{"class":109},[10,3428,3429,3430,3433,3434,3437,3438,3440],{},"If ",[46,3431,3432],{},"loadData()"," returns a rejected promise and you do not ",[46,3435,3436],{},"await"," it, your ",[46,3439,3334],{}," will not catch the error.",[10,3442,3443],{},"Because the error happens later, asynchronously.",[10,3445,3446],{},"Correct:",[39,3448,3449],{"className":41,"code":3341,"language":43,"meta":44,"style":44},[46,3450,3451,3457,3465,3473,3481],{"__ignoreMap":44},[49,3452,3453,3455],{"class":51,"line":52},[49,3454,3348],{"class":59},[49,3456,1584],{"class":109},[49,3458,3459,3461,3463],{"class":51,"line":72},[49,3460,3355],{"class":59},[49,3462,3358],{"class":143},[49,3464,2010],{"class":109},[49,3466,3467,3469,3471],{"class":51,"line":357},[49,3468,3365],{"class":109},[49,3470,3368],{"class":59},[49,3472,3371],{"class":109},[49,3474,3475,3477,3479],{"class":51,"line":631},[49,3476,615],{"class":109},[49,3478,3378],{"class":143},[49,3480,3381],{"class":109},[49,3482,3483],{"class":51,"line":1190},[49,3484,634],{"class":109},[10,3486,3064],{},[39,3488,3490],{"className":41,"code":3489,"language":43,"meta":44,"style":44},"loadData().catch(console.error)\n",[46,3491,3492],{"__ignoreMap":44},[49,3493,3494,3497,3500,3502],{"class":51,"line":52},[49,3495,3496],{"class":143},"loadData",[49,3498,3499],{"class":109},"().",[49,3501,3368],{"class":143},[49,3503,3504],{"class":109},"(console.error)\n",[10,3506,3507],{},"This bug is especially annoying because the code visually looks protected.",[10,3509,2373],{},[10,3511,3512],{},"It is like putting an umbrella next to yourself during rain and wondering why you are wet.",[178,3514],{},[181,3516,3518],{"id":3517},"json-is-not-a-universal-clone-tool","JSON Is Not a Universal Clone Tool",[10,3520,3521],{},"A lot of developers have used this trick at some point:",[39,3523,3525],{"className":41,"code":3524,"language":43,"meta":44,"style":44},"const copy = JSON.parse(JSON.stringify(data))\n",[46,3526,3527],{"__ignoreMap":44},[49,3528,3529,3531,3533,3535,3538,3540,3543,3545,3548,3550,3553],{"class":51,"line":52},[49,3530,306],{"class":59},[49,3532,2487],{"class":109},[49,3534,312],{"class":59},[49,3536,3537],{"class":55}," JSON",[49,3539,438],{"class":109},[49,3541,3542],{"class":143},"parse",[49,3544,206],{"class":109},[49,3546,3547],{"class":55},"JSON",[49,3549,438],{"class":109},[49,3551,3552],{"class":143},"stringify",[49,3554,3555],{"class":109},"(data))\n",[10,3557,3558],{},"It looks like a quick deep clone.",[10,3560,3561],{},"And sometimes it works.",[10,3563,3564],{},"Until it does not.",[39,3566,3568],{"className":41,"code":3567,"language":43,"meta":44,"style":44},"const data = {\n  date: new Date(),\n  value: undefined,\n  method: () => {},\n  nan: NaN,\n  infinity: Infinity\n}\n\nconsole.log(JSON.stringify(data))\n",[46,3569,3570,3581,3597,3608,3622,3633,3643,3647,3651],{"__ignoreMap":44},[49,3571,3572,3574,3577,3579],{"class":51,"line":52},[49,3573,306],{"class":59},[49,3575,3576],{"class":109}," data ",[49,3578,312],{"class":59},[49,3580,1584],{"class":109},[49,3582,3583,3586,3588,3592,3595],{"class":51,"line":72},[49,3584,3585],{"class":109},"  date",[49,3587,1952],{"class":59},[49,3589,3591],{"class":3590},"sviCg"," new",[49,3593,3594],{"class":143}," Date",[49,3596,3230],{"class":109},[49,3598,3599,3602,3604,3606],{"class":51,"line":357},[49,3600,3601],{"class":109},"  value",[49,3603,1952],{"class":59},[49,3605,878],{"class":55},[49,3607,1961],{"class":109},[49,3609,3610,3613,3615,3617,3619],{"class":51,"line":631},[49,3611,3612],{"class":143},"  method",[49,3614,1952],{"class":59},[49,3616,2120],{"class":109},[49,3618,1581],{"class":59},[49,3620,3621],{"class":109}," {},\n",[49,3623,3624,3627,3629,3631],{"class":51,"line":1190},[49,3625,3626],{"class":109},"  nan",[49,3628,1952],{"class":59},[49,3630,522],{"class":55},[49,3632,1961],{"class":109},[49,3634,3635,3638,3640],{"class":51,"line":1991},[49,3636,3637],{"class":109},"  infinity",[49,3639,1952],{"class":59},[49,3641,3642],{"class":55}," Infinity\n",[49,3644,3645],{"class":51,"line":1996},[49,3646,634],{"class":109},[49,3648,3649],{"class":51,"line":2001},[49,3650,1174],{"emptyLinePlaceholder":1173},[49,3652,3653,3655,3657,3659,3661,3663,3665],{"class":51,"line":2013},[49,3654,200],{"class":109},[49,3656,203],{"class":143},[49,3658,206],{"class":109},[49,3660,3547],{"class":55},[49,3662,438],{"class":109},[49,3664,3552],{"class":143},[49,3666,3555],{"class":109},[10,3668,1277],{},[39,3670,3674],{"className":3671,"code":3672,"language":3673,"meta":44,"style":44},"language-json shiki shiki-themes dracula","{\n  \"date\": \"2026-05-11T00:00:00.000Z\",\n  \"nan\": null,\n  \"infinity\": null\n}\n","json",[46,3675,3676,3681,3704,3719,3732],{"__ignoreMap":44},[49,3677,3678],{"class":51,"line":52},[49,3679,3680],{"class":109},"{\n",[49,3682,3683,3687,3691,3693,3695,3697,3700,3702],{"class":51,"line":72},[49,3684,3686],{"class":3685},"sY8FZ","  \"",[49,3688,3690],{"class":3689},"sLL85","date",[49,3692,114],{"class":3685},[49,3694,1952],{"class":59},[49,3696,1130],{"class":113},[49,3698,3699],{"class":117},"2026-05-11T00:00:00.000Z",[49,3701,114],{"class":113},[49,3703,1961],{"class":109},[49,3705,3706,3708,3711,3713,3715,3717],{"class":51,"line":357},[49,3707,3686],{"class":3685},[49,3709,3710],{"class":3689},"nan",[49,3712,114],{"class":3685},[49,3714,1952],{"class":59},[49,3716,399],{"class":55},[49,3718,1961],{"class":109},[49,3720,3721,3723,3726,3728,3730],{"class":51,"line":631},[49,3722,3686],{"class":3685},[49,3724,3725],{"class":3689},"infinity",[49,3727,114],{"class":3685},[49,3729,1952],{"class":59},[49,3731,92],{"class":55},[49,3733,3734],{"class":51,"line":1190},[49,3735,634],{"class":109},[10,3737,3738],{},"What happened?",[10,3740,1083,3741,3744],{},[46,3742,3743],{},"Date"," became a string.",[10,3746,3747,3749],{},[46,3748,1023],{}," disappeared.",[10,3751,3752],{},"The function disappeared.",[10,3754,3755,3757,3758,438],{},[46,3756,498],{}," became ",[46,3759,411],{},[10,3761,3762,3757,3765,438],{},[46,3763,3764],{},"Infinity",[46,3766,411],{},[10,3768,3769],{},"JSON is not a clone system.",[10,3771,3772],{},"JSON is a data format.",[10,3774,3775],{},"It is great when your data is actually JSON-compatible. But if your object contains special values, methods, dates, maps, sets, or class instances, JSON will quietly destroy information.",[10,3777,637,3778,3780],{},[46,3779,2724],{}," when it fits:",[39,3782,3784],{"className":41,"code":3783,"language":43,"meta":44,"style":44},"const copy = structuredClone(data)\n",[46,3785,3786],{"__ignoreMap":44},[49,3787,3788,3790,3792,3794,3796],{"class":51,"line":52},[49,3789,306],{"class":59},[49,3791,2487],{"class":109},[49,3793,312],{"class":59},[49,3795,2740],{"class":143},[49,3797,3798],{"class":109},"(data)\n",[10,3800,3801],{},"But again, understand what you are cloning.",[10,3803,3804],{},"Blind cloning is just another way to create bugs with confidence.",[178,3806],{},[181,3808,3810],{"id":3809},"dates-are-a-separate-kind-of-pain","Dates Are a Separate Kind of Pain",[10,3812,3813],{},"JavaScript dates deserve their own article.",[10,3815,3816],{},"But one trap is worth mentioning here.",[39,3818,3820],{"className":41,"code":3819,"language":43,"meta":44,"style":44},"new Date(\"2026-05-11\")\n",[46,3821,3822],{"__ignoreMap":44},[49,3823,3824,3827,3829,3831,3833,3836,3838],{"class":51,"line":52},[49,3825,3826],{"class":3590},"new",[49,3828,3594],{"class":143},[49,3830,206],{"class":109},[49,3832,114],{"class":113},[49,3834,3835],{"class":117},"2026-05-11",[49,3837,114],{"class":113},[49,3839,215],{"class":109},[10,3841,3842],{},"This looks harmless.",[10,3844,3845],{},"But depending on timezone behavior, you can easily end up with a different local date than expected.",[10,3847,3848],{},"Another dangerous format:",[39,3850,3852],{"className":41,"code":3851,"language":43,"meta":44,"style":44},"new Date(\"05/11/2026\")\n",[46,3853,3854],{"__ignoreMap":44},[49,3855,3856,3858,3860,3862,3864,3867,3869],{"class":51,"line":52},[49,3857,3826],{"class":3590},[49,3859,3594],{"class":143},[49,3861,206],{"class":109},[49,3863,114],{"class":113},[49,3865,3866],{"class":117},"05/11/2026",[49,3868,114],{"class":113},[49,3870,215],{"class":109},[10,3872,3873],{},"Is that May 11?",[10,3875,3876],{},"Or November 5?",[10,3878,3879],{},"Depends on expectations, environment, and format.",[10,3881,3882],{},"The safer habit is to use clear ISO strings:",[39,3884,3886],{"className":41,"code":3885,"language":43,"meta":44,"style":44},"new Date(\"2026-05-11T00:00:00Z\")\n",[46,3887,3888],{"__ignoreMap":44},[49,3889,3890,3892,3894,3896,3898,3901,3903],{"class":51,"line":52},[49,3891,3826],{"class":3590},[49,3893,3594],{"class":143},[49,3895,206],{"class":109},[49,3897,114],{"class":113},[49,3899,3900],{"class":117},"2026-05-11T00:00:00Z",[49,3902,114],{"class":113},[49,3904,215],{"class":109},[10,3906,3907],{},"And for serious timezone logic, use proper tools.",[10,3909,3910],{},"Date and time bugs are never “small bugs”.",[10,3912,3913],{},"They become calendar bugs, billing bugs, analytics bugs, reminder bugs, booking bugs — the kind of bugs that make users lose trust.",[178,3915],{},[181,3917,3919],{"id":3918},"optional-chaining-can-hide-real-problems","Optional Chaining Can Hide Real Problems",[10,3921,3922],{},"Optional chaining is one of the best modern JavaScript features.",[39,3924,3926],{"className":41,"code":3925,"language":43,"meta":44,"style":44},"const city = user?.profile?.address?.city\n",[46,3927,3928],{"__ignoreMap":44},[49,3929,3930,3932,3935,3937],{"class":51,"line":52},[49,3931,306],{"class":59},[49,3933,3934],{"class":109}," city ",[49,3936,312],{"class":59},[49,3938,3939],{"class":109}," user?.profile?.address?.city\n",[10,3941,3942],{},"It is clean.",[10,3944,3945],{},"It prevents crashes.",[10,3947,3948],{},"It is useful.",[10,3950,3951],{},"But it can also hide bugs.",[10,3953,1412],{},[39,3955,3957],{"className":41,"code":3956,"language":43,"meta":44,"style":44},"const price = product?.details?.price\n",[46,3958,3959],{"__ignoreMap":44},[49,3960,3961,3963,3965,3967],{"class":51,"line":52},[49,3962,306],{"class":59},[49,3964,309],{"class":109},[49,3966,312],{"class":59},[49,3968,3969],{"class":109}," product?.details?.price\n",[10,3971,3429,3972,3975],{},[46,3973,3974],{},"details"," is genuinely optional, fine.",[10,3977,3978,3979,3981,3982,438],{},"But if ",[46,3980,3974],{}," must always exist, then optional chaining hides a backend problem and quietly gives you ",[46,3983,1023],{},[10,3985,3986],{},"Sometimes you want graceful fallback.",[10,3988,3989],{},"Sometimes you want the app to scream immediately because something is broken.",[10,3991,3992],{},"For required data, I prefer explicit validation:",[39,3994,3996],{"className":41,"code":3995,"language":43,"meta":44,"style":44},"if (!product.details) {\n  throw new Error(\"Product details are missing\")\n}\n",[46,3997,3998,4010,4031],{"__ignoreMap":44},[49,3999,4000,4002,4004,4007],{"class":51,"line":52},[49,4001,600],{"class":59},[49,4003,1424],{"class":109},[49,4005,4006],{"class":59},"!",[49,4008,4009],{"class":109},"product.details) {\n",[49,4011,4012,4015,4017,4020,4022,4024,4027,4029],{"class":51,"line":72},[49,4013,4014],{"class":59},"  throw",[49,4016,3591],{"class":3590},[49,4018,4019],{"class":143}," Error",[49,4021,206],{"class":109},[49,4023,114],{"class":113},[49,4025,4026],{"class":117},"Product details are missing",[49,4028,114],{"class":113},[49,4030,215],{"class":109},[49,4032,4033],{"class":51,"line":357},[49,4034,634],{"class":109},[10,4036,4037],{},"Use optional chaining for optional data.",[10,4039,4040],{},"Not as a blanket carpet to cover broken assumptions.",[178,4042],{},[181,4044,4046,4048],{"id":4045},"const-does-not-mean-immutable",[46,4047,306],{}," Does Not Mean Immutable",[10,4050,4051],{},"This one is simple but important.",[39,4053,4055],{"className":41,"code":4054,"language":43,"meta":44,"style":44},"const user = {\n  name: \"Ravy\"\n}\n\nuser.name = \"Alex\"\nconsole.log(user.name)\n// \"Alex\"\n",[46,4056,4057,4067,4079,4083,4087,4101,4110],{"__ignoreMap":44},[49,4058,4059,4061,4063,4065],{"class":51,"line":52},[49,4060,306],{"class":59},[49,4062,1940],{"class":109},[49,4064,312],{"class":59},[49,4066,1584],{"class":109},[49,4068,4069,4071,4073,4075,4077],{"class":51,"line":72},[49,4070,1949],{"class":109},[49,4072,1952],{"class":59},[49,4074,1130],{"class":113},[49,4076,1444],{"class":117},[49,4078,1136],{"class":113},[49,4080,4081],{"class":51,"line":357},[49,4082,634],{"class":109},[49,4084,4085],{"class":51,"line":631},[49,4086,1174],{"emptyLinePlaceholder":1173},[49,4088,4089,4092,4094,4096,4099],{"class":51,"line":1190},[49,4090,4091],{"class":109},"user.name ",[49,4093,312],{"class":59},[49,4095,1130],{"class":113},[49,4097,4098],{"class":117},"Alex",[49,4100,1136],{"class":113},[49,4102,4103,4105,4107],{"class":51,"line":1991},[49,4104,200],{"class":109},[49,4106,203],{"class":143},[49,4108,4109],{"class":109},"(user.name)\n",[49,4111,4112],{"class":51,"line":1996},[49,4113,4114],{"class":75},"// \"Alex\"\n",[10,4116,4117],{},"This is allowed.",[10,4119,4120,4122],{},[46,4121,306],{}," means you cannot reassign the variable:",[39,4124,4126],{"className":41,"code":4125,"language":43,"meta":44,"style":44},"user = {}\n// TypeError\n",[46,4127,4128,4137],{"__ignoreMap":44},[49,4129,4130,4133,4135],{"class":51,"line":52},[49,4131,4132],{"class":109},"user ",[49,4134,312],{"class":59},[49,4136,1253],{"class":109},[49,4138,4139],{"class":51,"line":72},[49,4140,4141],{"class":75},"// TypeError\n",[10,4143,4144],{},"But the object itself can still be changed.",[10,4146,4147,4148,1952],{},"If you want to prevent changes, there is ",[46,4149,4150],{},"Object.freeze()",[39,4152,4154],{"className":41,"code":4153,"language":43,"meta":44,"style":44},"const user = Object.freeze({\n  name: \"Ravy\"\n})\n\nuser.name = \"Alex\"\nconsole.log(user.name)\n// \"Ravy\"\n",[46,4155,4156,4173,4185,4190,4194,4206,4214],{"__ignoreMap":44},[49,4157,4158,4160,4162,4164,4167,4170],{"class":51,"line":52},[49,4159,306],{"class":59},[49,4161,1940],{"class":109},[49,4163,312],{"class":59},[49,4165,4166],{"class":109}," Object.",[49,4168,4169],{"class":143},"freeze",[49,4171,4172],{"class":109},"({\n",[49,4174,4175,4177,4179,4181,4183],{"class":51,"line":72},[49,4176,1949],{"class":109},[49,4178,1952],{"class":59},[49,4180,1130],{"class":113},[49,4182,1444],{"class":117},[49,4184,1136],{"class":113},[49,4186,4187],{"class":51,"line":357},[49,4188,4189],{"class":109},"})\n",[49,4191,4192],{"class":51,"line":631},[49,4193,1174],{"emptyLinePlaceholder":1173},[49,4195,4196,4198,4200,4202,4204],{"class":51,"line":1190},[49,4197,4091],{"class":109},[49,4199,312],{"class":59},[49,4201,1130],{"class":113},[49,4203,4098],{"class":117},[49,4205,1136],{"class":113},[49,4207,4208,4210,4212],{"class":51,"line":1991},[49,4209,200],{"class":109},[49,4211,203],{"class":143},[49,4213,4109],{"class":109},[49,4215,4216],{"class":51,"line":1996},[49,4217,1464],{"class":75},[10,4219,4220],{},"But even this is shallow.",[10,4222,4223],{},"Nested objects can still be mutable unless you freeze them too.",[10,4225,561,4226,4228],{},[46,4227,306],{}," is not a magic shield.",[10,4230,4231],{},"It protects the binding, not the value inside.",[178,4233],{},[181,4235,4237],{"id":4236},"the-real-lesson","The Real Lesson",[10,4239,4240],{},"It is easy to make fun of JavaScript. And honestly, sometimes JavaScript deserves it. But after writing enough code, I do not think the main problem is that JavaScript is “bad”. The real problem is that JavaScript looks simpler than it is.",[17,4242,4243,4246,4249,4252,4255],{},[20,4244,4245],{},"It lets you start quickly.",[20,4247,4248],{},"It lets you build something fast.",[20,4250,4251],{},"It forgives many things.",[20,4253,4254],{},"It converts types for you.",[20,4256,4257],{},"It hides complexity behind friendly syntax.",[10,4259,4260],{},"And then, when your project grows, all those hidden rules start showing up. This is why I think JavaScript traps are worth learning.",[17,4262,4263,4266],{},[20,4264,4265],{},"Not to feel smarter than other developers.",[20,4267,4268],{},"Not to post weird console screenshots.",[10,4270,4271],{},"But to build a mental map of the language. Because once you understand these traps, JavaScript becomes much more predictable.",[17,4273,4274,4279,4282,4287,4290,4296],{},[20,4275,4276,4277,438],{},"You stop being surprised by ",[46,4278,498],{},[20,4280,4281],{},"You stop trusting implicit coercion.",[20,4283,4284,4285,438],{},"You stop using ",[46,4286,1391],{},[20,4288,4289],{},"You stop cloning everything with JSON.",[20,4291,4292,4293,4295],{},"You stop thinking ",[46,4294,3436],{}," means “parallel”.",[20,4297,4298,4299,4301],{},"You stop assuming ",[46,4300,1912],{}," means what it means in other languages.",[10,4303,4304],{},"And your code becomes calmer. Maybe that is the best compliment code can get.",[17,4306,4307,4310],{},[20,4308,4309],{},"Not clever.",[20,4311,4312],{},"Not magical.",[10,4314,4315],{},"Just calm, predictable, and boring in the right places.",[10,4317,4318],{},"JavaScript is not a cursed language. But it definitely has traps. And it is better to know where they are before stepping into them.",[4320,4321,4322],"style",{},"html pre.shiki code .sIQBb, html code.shiki .sIQBb{--shiki-default:#BD93F9}html pre.shiki code .s0Tla, html code.shiki .s0Tla{--shiki-default:#FF79C6}html pre.shiki code .shSDL, html code.shiki .shSDL{--shiki-default:#6272A4}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 pre.shiki code .sCdxs, html code.shiki .sCdxs{--shiki-default:#F8F8F2}html pre.shiki code .seVfx, html code.shiki .seVfx{--shiki-default:#E9F284}html pre.shiki code .s-mGx, html code.shiki .s-mGx{--shiki-default:#F1FA8C}html pre.shiki code .sAOxA, html code.shiki .sAOxA{--shiki-default:#50FA7B}html pre.shiki code .sqerP, html code.shiki .sqerP{--shiki-default:#BD93F9;--shiki-default-font-style:italic}html pre.shiki code .sGEwX, html code.shiki .sGEwX{--shiki-default:#FFB86C;--shiki-default-font-style:italic}html pre.shiki code .sCp4m, html code.shiki .sCp4m{--shiki-default:#8BE9FD;--shiki-default-font-style:italic}html pre.shiki code .sviCg, html code.shiki .sviCg{--shiki-default:#FF79C6;--shiki-default-font-weight:bold}html pre.shiki code .sY8FZ, html code.shiki .sY8FZ{--shiki-default:#8BE9FE}html pre.shiki code .sLL85, html code.shiki .sLL85{--shiki-default:#8BE9FD}",{"title":44,"searchDepth":72,"depth":72,"links":4324},[4325,4327,4329,4331,4333,4335,4337,4338,4340,4341,4343,4345,4347,4348,4349,4350,4352],{"id":183,"depth":72,"text":4326},"The Famous One: 0.1 + 0.2",{"id":374,"depth":72,"text":4328},"typeof null Is a Historical Scar",{"id":495,"depth":72,"text":4330},"NaN Is Not Equal to Itself",{"id":764,"depth":72,"text":4332},"The Problem With ==",{"id":1075,"depth":72,"text":4334},"Arrays, Objects, and the + Operator",{"id":1388,"depth":72,"text":4336},"var Is Not Your Friend",{"id":1777,"depth":72,"text":1778},{"id":1909,"depth":72,"text":4339},"this Is Not Where the Function Lives",{"id":2299,"depth":72,"text":2300},{"id":2764,"depth":72,"text":4342},"map(parseInt) Is Evil and Beautiful",{"id":3110,"depth":72,"text":4344},"async/await Does Not Automatically Make Things Parallel",{"id":3331,"depth":72,"text":4346},"try/catch Does Not Catch Promises Unless You Await Them",{"id":3517,"depth":72,"text":3518},{"id":3809,"depth":72,"text":3810},{"id":3918,"depth":72,"text":3919},{"id":4045,"depth":72,"text":4351},"const Does Not Mean Immutable",{"id":4236,"depth":72,"text":4237},"2026-05-11T14:16:26.371Z","A field-tested tour of the JavaScript traps that bite real codebases — floating-point math, NaN, ==, hoisting, this, references, async/await, and JSON cloning.","md","/blog-cover/10023.javascript_traps_worth_knowing_before_they_bite_you.webp",{},"/blog-opengraph/10023.javascript-traps-worth-knowing-before-they-bite-you.png","/blogs/javascript-traps-worth-knowing-before-they-bite-you",{"title":5,"description":4354},"blogs/javascript-traps-worth-knowing-before-they-bite-you",[4363],"dev",false,"WIDz-v5szJdZQFjk5d4KvjP2IuMvvyfaEtmKu-oBupk",{"prev":4367,"next":4370},{"path":4368,"title":4369},"/blogs/start-v-it-your-path-to-it","Start v IT: ваш надёжный проводник от новичка до профессионала",null,1778518873249]