[{"data":1,"prerenderedAt":2629},["ShallowReactive",2],{"en-post-\u002Fen\u002Fjavascript-nullish-coalescing-optional-chaining":3},{"id":4,"title":5,"body":6,"description":2617,"extension":2618,"meta":2619,"navigation":72,"path":2624,"seo":2625,"sitemap":2626,"stem":2627,"__hash__":2628},"blogEn\u002Fen\u002Fjavascript-nullish-coalescing-optional-chaining.md","JavaScript ?? vs ||: How to Handle null, undefined, 0, and Empty Strings Correctly",{"type":7,"value":8,"toc":2596},"minimark",[9,14,18,136,139,147,157,221,224,233,259,291,403,406,1378,1399,1401,1408,1411,1442,1458,1486,1498,1560,1613,1635,1637,1650,1653,1718,1792,1805,1807,1813,1827,1924,1927,1988,2000,2037,2101,2103,2107,2119,2135,2195,2210,2214,2302,2310,2316,2379,2398,2407,2453,2456,2458,2462,2571,2592],[10,11,13],"h2",{"id":12},"i-set-the-volume-to-0-why-is-it-50","I set the volume to 0. Why is it 50?",[15,16,17],"p",{},"Here's a common pattern: load the user's settings and fall back to a default when a value is missing.",[19,20,25],"pre",{"className":21,"code":22,"language":23,"meta":24,"style":24},"language-js shiki shiki-themes github-light github-dark","const settings = { volume: 0, nickname: \"\", darkMode: false };\n\nconst volume = settings.volume || 50;\nconst nickname = settings.nickname || \"Anonymous\";\nconst darkMode = settings.darkMode || true;\n","js","",[26,27,28,67,74,96,116],"code",{"__ignoreMap":24},[29,30,33,37,41,44,48,51,54,58,61,64],"span",{"class":31,"line":32},"line",1,[29,34,36],{"class":35},"szBVR","const",[29,38,40],{"class":39},"sj4cs"," settings",[29,42,43],{"class":35}," =",[29,45,47],{"class":46},"sVt8B"," { volume: ",[29,49,50],{"class":39},"0",[29,52,53],{"class":46},", nickname: ",[29,55,57],{"class":56},"sZZnC","\"\"",[29,59,60],{"class":46},", darkMode: ",[29,62,63],{"class":39},"false",[29,65,66],{"class":46}," };\n",[29,68,70],{"class":31,"line":69},2,[29,71,73],{"emptyLinePlaceholder":72},true,"\n",[29,75,77,79,82,84,87,90,93],{"class":31,"line":76},3,[29,78,36],{"class":35},[29,80,81],{"class":39}," volume",[29,83,43],{"class":35},[29,85,86],{"class":46}," settings.volume ",[29,88,89],{"class":35},"||",[29,91,92],{"class":39}," 50",[29,94,95],{"class":46},";\n",[29,97,99,101,104,106,109,111,114],{"class":31,"line":98},4,[29,100,36],{"class":35},[29,102,103],{"class":39}," nickname",[29,105,43],{"class":35},[29,107,108],{"class":46}," settings.nickname ",[29,110,89],{"class":35},[29,112,113],{"class":56}," \"Anonymous\"",[29,115,95],{"class":46},[29,117,119,121,124,126,129,131,134],{"class":31,"line":118},5,[29,120,36],{"class":35},[29,122,123],{"class":39}," darkMode",[29,125,43],{"class":35},[29,127,128],{"class":46}," settings.darkMode ",[29,130,89],{"class":35},[29,132,133],{"class":39}," true",[29,135,95],{"class":46},[15,137,138],{},"The result:",[19,140,145],{"className":141,"code":143,"language":144},[142],"language-text","50           \u002F\u002F the volume the user deliberately set to 0 became 50\n\"Anonymous\"  \u002F\u002F the nickname they left empty became \"Anonymous\"\ntrue         \u002F\u002F dark mode they turned off is now on\n","text",[26,146,143],{"__ignoreMap":24},[15,148,149,150,152,153,156],{},"All three of the user's choices were ignored. The cause is ",[26,151,89],{},", and the fix is ",[26,154,155],{},"??",".",[19,158,160],{"className":21,"code":159,"language":23,"meta":24,"style":24},"const volume = settings.volume ?? 50; \u002F\u002F 0\nconst nickname = settings.nickname ?? \"Anonymous\"; \u002F\u002F \"\"\nconst darkMode = settings.darkMode ?? true; \u002F\u002F false\n",[26,161,162,183,202],{"__ignoreMap":24},[29,163,164,166,168,170,172,174,176,179],{"class":31,"line":32},[29,165,36],{"class":35},[29,167,81],{"class":39},[29,169,43],{"class":35},[29,171,86],{"class":46},[29,173,155],{"class":35},[29,175,92],{"class":39},[29,177,178],{"class":46},"; ",[29,180,182],{"class":181},"sJ8bj","\u002F\u002F 0\n",[29,184,185,187,189,191,193,195,197,199],{"class":31,"line":69},[29,186,36],{"class":35},[29,188,103],{"class":39},[29,190,43],{"class":35},[29,192,108],{"class":46},[29,194,155],{"class":35},[29,196,113],{"class":56},[29,198,178],{"class":46},[29,200,201],{"class":181},"\u002F\u002F \"\"\n",[29,203,204,206,208,210,212,214,216,218],{"class":31,"line":76},[29,205,36],{"class":35},[29,207,123],{"class":39},[29,209,43],{"class":35},[29,211,128],{"class":46},[29,213,155],{"class":35},[29,215,133],{"class":39},[29,217,178],{"class":46},[29,219,220],{"class":181},"\u002F\u002F false\n",[222,223],"hr",{},[10,225,227,228,230,231],{"id":226},"the-difference-between-and","The difference between ",[26,229,89],{}," and ",[26,232,155],{},[234,235,236],"blockquote",{},[15,237,238,240,241,245,246,248,249,156],{},[26,239,89],{}," uses the right side when the left value is ",[242,243,244],"strong",{},"falsy",". ",[26,247,155],{}," (the nullish coalescing operator) uses the right side ",[242,250,251,252,255,256],{},"only when the left value is ",[26,253,254],{},"null"," or ",[26,257,258],{},"undefined",[15,260,261,262,264,265,264,267,269,270,264,273,275,276,245,278,280,281,264,283,275,285,287,288,156],{},"The falsy values in JavaScript are ",[26,263,63],{},", ",[26,266,50],{},[26,268,57],{}," (empty string), ",[26,271,272],{},"NaN",[26,274,254],{},", and ",[26,277,258],{},[26,279,89],{}," treats all six as \"no value.\" But ",[26,282,50],{},[26,284,57],{},[26,286,63],{}," are usually ",[242,289,290],{},"perfectly valid values",[292,293,294,314],"table",{},[295,296,297],"thead",{},[298,299,300,304,309],"tr",{},[301,302,303],"th",{},"Left value",[301,305,306],{},[26,307,308],{},"value || \"default\"",[301,310,311],{},[26,312,313],{},"value ?? \"default\"",[315,316,317,333,347,361,375,389],"tbody",{},[298,318,319,324,329],{},[320,321,322],"td",{},[26,323,50],{},[320,325,326],{},[26,327,328],{},"\"default\"",[320,330,331],{},[26,332,50],{},[298,334,335,339,343],{},[320,336,337],{},[26,338,57],{},[320,340,341],{},[26,342,328],{},[320,344,345],{},[26,346,57],{},[298,348,349,353,357],{},[320,350,351],{},[26,352,63],{},[320,354,355],{},[26,356,328],{},[320,358,359],{},[26,360,63],{},[298,362,363,367,371],{},[320,364,365],{},[26,366,272],{},[320,368,369],{},[26,370,328],{},[320,372,373],{},[26,374,272],{},[298,376,377,381,385],{},[320,378,379],{},[26,380,254],{},[320,382,383],{},[26,384,328],{},[320,386,387],{},[26,388,328],{},[298,390,391,395,399],{},[320,392,393],{},[26,394,258],{},[320,396,397],{},[26,398,328],{},[320,400,401],{},[26,402,328],{},[15,404,405],{},"Click through the values in the preview below to compare them yourself.",[407,408,409,481,786],"code-group",{},[19,410,414],{"className":411,"code":412,"language":413,"meta":24,"style":24},"language-html shiki shiki-themes github-light github-dark","\u003Cdiv class=\"values\">\u003C\u002Fdiv>\n\u003Ctable>\n  \u003Ctbody id=\"rows\">\u003C\u002Ftbody>\n\u003C\u002Ftable>\n","html",[26,415,416,443,451,472],{"__ignoreMap":24},[29,417,418,421,425,429,432,435,438,440],{"class":31,"line":32},[29,419,420],{"class":46},"\u003C",[29,422,424],{"class":423},"s9eBZ","div",[29,426,428],{"class":427},"sScJk"," class",[29,430,431],{"class":46},"=",[29,433,434],{"class":56},"\"values\"",[29,436,437],{"class":46},">\u003C\u002F",[29,439,424],{"class":423},[29,441,442],{"class":46},">\n",[29,444,445,447,449],{"class":31,"line":69},[29,446,420],{"class":46},[29,448,292],{"class":423},[29,450,442],{"class":46},[29,452,453,456,458,461,463,466,468,470],{"class":31,"line":76},[29,454,455],{"class":46},"  \u003C",[29,457,315],{"class":423},[29,459,460],{"class":427}," id",[29,462,431],{"class":46},[29,464,465],{"class":56},"\"rows\"",[29,467,437],{"class":46},[29,469,315],{"class":423},[29,471,442],{"class":46},[29,473,474,477,479],{"class":31,"line":98},[29,475,476],{"class":46},"\u003C\u002F",[29,478,292],{"class":423},[29,480,442],{"class":46},[19,482,486],{"className":483,"code":484,"language":485,"meta":24,"style":24},"language-css shiki shiki-themes github-light github-dark",".values { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }\n.values button { font: 14px ui-monospace, monospace; padding: 6px 10px; border: 1px solid #ccc; border-radius: 8px; background: #fff; cursor: pointer; }\n.values button.active { background: #f59e0b; border-color: #f59e0b; color: #fff; }\ntable { border-collapse: collapse; width: 100%; font: 14px ui-monospace, monospace; }\ntd { padding: 6px 8px; border-bottom: 1px solid #eee; }\ntd:last-child { font-weight: 700; color: #b45309; }\n","css",[26,487,488,543,637,675,720,757],{"__ignoreMap":24},[29,489,490,493,496,499,502,505,507,510,512,515,517,520,522,525,528,530,533,535,538,540],{"class":31,"line":32},[29,491,492],{"class":427},".values",[29,494,495],{"class":46}," { ",[29,497,498],{"class":39},"display",[29,500,501],{"class":46},": ",[29,503,504],{"class":39},"flex",[29,506,178],{"class":46},[29,508,509],{"class":39},"flex-wrap",[29,511,501],{"class":46},[29,513,514],{"class":39},"wrap",[29,516,178],{"class":46},[29,518,519],{"class":39},"gap",[29,521,501],{"class":46},[29,523,524],{"class":39},"6",[29,526,527],{"class":35},"px",[29,529,178],{"class":46},[29,531,532],{"class":39},"margin-bottom",[29,534,501],{"class":46},[29,536,537],{"class":39},"14",[29,539,527],{"class":35},[29,541,542],{"class":46},"; }\n",[29,544,545,547,550,552,555,557,559,561,564,566,569,571,574,576,578,580,583,585,587,590,592,595,597,600,603,605,608,610,613,615,617,620,622,625,627,630,632,635],{"class":31,"line":69},[29,546,492],{"class":427},[29,548,549],{"class":423}," button",[29,551,495],{"class":46},[29,553,554],{"class":39},"font",[29,556,501],{"class":46},[29,558,537],{"class":39},[29,560,527],{"class":35},[29,562,563],{"class":39}," ui-monospace",[29,565,264],{"class":46},[29,567,568],{"class":39},"monospace",[29,570,178],{"class":46},[29,572,573],{"class":39},"padding",[29,575,501],{"class":46},[29,577,524],{"class":39},[29,579,527],{"class":35},[29,581,582],{"class":39}," 10",[29,584,527],{"class":35},[29,586,178],{"class":46},[29,588,589],{"class":39},"border",[29,591,501],{"class":46},[29,593,594],{"class":39},"1",[29,596,527],{"class":35},[29,598,599],{"class":39}," solid",[29,601,602],{"class":39}," #ccc",[29,604,178],{"class":46},[29,606,607],{"class":39},"border-radius",[29,609,501],{"class":46},[29,611,612],{"class":39},"8",[29,614,527],{"class":35},[29,616,178],{"class":46},[29,618,619],{"class":39},"background",[29,621,501],{"class":46},[29,623,624],{"class":39},"#fff",[29,626,178],{"class":46},[29,628,629],{"class":39},"cursor",[29,631,501],{"class":46},[29,633,634],{"class":39},"pointer",[29,636,542],{"class":46},[29,638,639,641,643,646,648,650,652,655,657,660,662,664,666,669,671,673],{"class":31,"line":76},[29,640,492],{"class":427},[29,642,549],{"class":423},[29,644,645],{"class":427},".active",[29,647,495],{"class":46},[29,649,619],{"class":39},[29,651,501],{"class":46},[29,653,654],{"class":39},"#f59e0b",[29,656,178],{"class":46},[29,658,659],{"class":39},"border-color",[29,661,501],{"class":46},[29,663,654],{"class":39},[29,665,178],{"class":46},[29,667,668],{"class":39},"color",[29,670,501],{"class":46},[29,672,624],{"class":39},[29,674,542],{"class":46},[29,676,677,679,681,684,686,689,691,694,696,699,702,704,706,708,710,712,714,716,718],{"class":31,"line":98},[29,678,292],{"class":423},[29,680,495],{"class":46},[29,682,683],{"class":39},"border-collapse",[29,685,501],{"class":46},[29,687,688],{"class":39},"collapse",[29,690,178],{"class":46},[29,692,693],{"class":39},"width",[29,695,501],{"class":46},[29,697,698],{"class":39},"100",[29,700,701],{"class":35},"%",[29,703,178],{"class":46},[29,705,554],{"class":39},[29,707,501],{"class":46},[29,709,537],{"class":39},[29,711,527],{"class":35},[29,713,563],{"class":39},[29,715,264],{"class":46},[29,717,568],{"class":39},[29,719,542],{"class":46},[29,721,722,724,726,728,730,732,734,737,739,741,744,746,748,750,752,755],{"class":31,"line":118},[29,723,320],{"class":423},[29,725,495],{"class":46},[29,727,573],{"class":39},[29,729,501],{"class":46},[29,731,524],{"class":39},[29,733,527],{"class":35},[29,735,736],{"class":39}," 8",[29,738,527],{"class":35},[29,740,178],{"class":46},[29,742,743],{"class":39},"border-bottom",[29,745,501],{"class":46},[29,747,594],{"class":39},[29,749,527],{"class":35},[29,751,599],{"class":39},[29,753,754],{"class":39}," #eee",[29,756,542],{"class":46},[29,758,760,762,765,767,770,772,775,777,779,781,784],{"class":31,"line":759},6,[29,761,320],{"class":423},[29,763,764],{"class":427},":last-child",[29,766,495],{"class":46},[29,768,769],{"class":39},"font-weight",[29,771,501],{"class":46},[29,773,774],{"class":39},"700",[29,776,178],{"class":46},[29,778,668],{"class":39},[29,780,501],{"class":46},[29,782,783],{"class":39},"#b45309",[29,785,542],{"class":46},[19,787,789],{"className":21,"code":788,"language":23,"meta":24,"style":24},"const values = [0, \"\", false, NaN, null, undefined, \"hello\", 42];\nconst show = (v) => (typeof v === \"string\" ? `\"${v}\"` : String(v));\nconst checks = [\n  [\"v || \\\"default\\\"\", (v) => v || \"default\"],\n  [\"v ?? \\\"default\\\"\", (v) => v ?? \"default\"],\n  [\"v?.toString()\", (v) => v?.toString()],\n  [\"v == null\", (v) => v == null],\n  [\"Boolean(v)\", (v) => Boolean(v)],\n];\n\nconst box = document.querySelector(\".values\");\nfunction select(v, btn) {\n  box.querySelectorAll(\"button\").forEach((b) => b.classList.remove(\"active\"));\n  btn.classList.add(\"active\");\n  document.querySelector(\"#rows\").innerHTML = checks\n    .map(([label, fn]) => `\u003Ctr>\u003Ctd>${label}\u003C\u002Ftd>\u003Ctd>${show(fn(v))}\u003C\u002Ftd>\u003C\u002Ftr>`)\n    .join(\"\");\n}\nvalues.forEach((v, i) => {\n  const btn = document.createElement(\"button\");\n  btn.textContent = show(v);\n  btn.addEventListener(\"click\", () => select(v, btn));\n  box.append(btn);\n  if (i === 0) select(v, btn);\n});\n",[26,790,791,838,894,906,944,975,999,1025,1047,1052,1057,1082,1103,1147,1162,1183,1236,1250,1256,1280,1302,1315,1339,1350,1372],{"__ignoreMap":24},[29,792,793,795,798,800,803,805,807,809,811,813,815,817,819,821,823,825,827,830,832,835],{"class":31,"line":32},[29,794,36],{"class":35},[29,796,797],{"class":39}," values",[29,799,43],{"class":35},[29,801,802],{"class":46}," [",[29,804,50],{"class":39},[29,806,264],{"class":46},[29,808,57],{"class":56},[29,810,264],{"class":46},[29,812,63],{"class":39},[29,814,264],{"class":46},[29,816,272],{"class":39},[29,818,264],{"class":46},[29,820,254],{"class":39},[29,822,264],{"class":46},[29,824,258],{"class":39},[29,826,264],{"class":46},[29,828,829],{"class":56},"\"hello\"",[29,831,264],{"class":46},[29,833,834],{"class":39},"42",[29,836,837],{"class":46},"];\n",[29,839,840,842,845,847,850,854,857,860,862,865,868,871,874,877,880,882,885,888,891],{"class":31,"line":69},[29,841,36],{"class":35},[29,843,844],{"class":427}," show",[29,846,43],{"class":35},[29,848,849],{"class":46}," (",[29,851,853],{"class":852},"s4XuR","v",[29,855,856],{"class":46},") ",[29,858,859],{"class":35},"=>",[29,861,849],{"class":46},[29,863,864],{"class":35},"typeof",[29,866,867],{"class":46}," v ",[29,869,870],{"class":35},"===",[29,872,873],{"class":56}," \"string\"",[29,875,876],{"class":35}," ?",[29,878,879],{"class":56}," `\"${",[29,881,853],{"class":46},[29,883,884],{"class":56},"}\"`",[29,886,887],{"class":35}," :",[29,889,890],{"class":427}," String",[29,892,893],{"class":46},"(v));\n",[29,895,896,898,901,903],{"class":31,"line":76},[29,897,36],{"class":35},[29,899,900],{"class":39}," checks",[29,902,43],{"class":35},[29,904,905],{"class":46}," [\n",[29,907,908,911,914,917,920,922,925,928,930,932,934,936,938,941],{"class":31,"line":98},[29,909,910],{"class":46},"  [",[29,912,913],{"class":56},"\"v || ",[29,915,916],{"class":39},"\\\"",[29,918,919],{"class":56},"default",[29,921,916],{"class":39},[29,923,924],{"class":56},"\"",[29,926,927],{"class":46},", (",[29,929,853],{"class":852},[29,931,856],{"class":46},[29,933,859],{"class":35},[29,935,867],{"class":46},[29,937,89],{"class":35},[29,939,940],{"class":56}," \"default\"",[29,942,943],{"class":46},"],\n",[29,945,946,948,951,953,955,957,959,961,963,965,967,969,971,973],{"class":31,"line":118},[29,947,910],{"class":46},[29,949,950],{"class":56},"\"v ?? ",[29,952,916],{"class":39},[29,954,919],{"class":56},[29,956,916],{"class":39},[29,958,924],{"class":56},[29,960,927],{"class":46},[29,962,853],{"class":852},[29,964,856],{"class":46},[29,966,859],{"class":35},[29,968,867],{"class":46},[29,970,155],{"class":35},[29,972,940],{"class":56},[29,974,943],{"class":46},[29,976,977,979,982,984,986,988,990,993,996],{"class":31,"line":759},[29,978,910],{"class":46},[29,980,981],{"class":56},"\"v?.toString()\"",[29,983,927],{"class":46},[29,985,853],{"class":852},[29,987,856],{"class":46},[29,989,859],{"class":35},[29,991,992],{"class":46}," v?.",[29,994,995],{"class":427},"toString",[29,997,998],{"class":46},"()],\n",[29,1000,1002,1004,1007,1009,1011,1013,1015,1017,1020,1023],{"class":31,"line":1001},7,[29,1003,910],{"class":46},[29,1005,1006],{"class":56},"\"v == null\"",[29,1008,927],{"class":46},[29,1010,853],{"class":852},[29,1012,856],{"class":46},[29,1014,859],{"class":35},[29,1016,867],{"class":46},[29,1018,1019],{"class":35},"==",[29,1021,1022],{"class":39}," null",[29,1024,943],{"class":46},[29,1026,1028,1030,1033,1035,1037,1039,1041,1044],{"class":31,"line":1027},8,[29,1029,910],{"class":46},[29,1031,1032],{"class":56},"\"Boolean(v)\"",[29,1034,927],{"class":46},[29,1036,853],{"class":852},[29,1038,856],{"class":46},[29,1040,859],{"class":35},[29,1042,1043],{"class":427}," Boolean",[29,1045,1046],{"class":46},"(v)],\n",[29,1048,1050],{"class":31,"line":1049},9,[29,1051,837],{"class":46},[29,1053,1055],{"class":31,"line":1054},10,[29,1056,73],{"emptyLinePlaceholder":72},[29,1058,1060,1062,1065,1067,1070,1073,1076,1079],{"class":31,"line":1059},11,[29,1061,36],{"class":35},[29,1063,1064],{"class":39}," box",[29,1066,43],{"class":35},[29,1068,1069],{"class":46}," document.",[29,1071,1072],{"class":427},"querySelector",[29,1074,1075],{"class":46},"(",[29,1077,1078],{"class":56},"\".values\"",[29,1080,1081],{"class":46},");\n",[29,1083,1085,1088,1091,1093,1095,1097,1100],{"class":31,"line":1084},12,[29,1086,1087],{"class":35},"function",[29,1089,1090],{"class":427}," select",[29,1092,1075],{"class":46},[29,1094,853],{"class":852},[29,1096,264],{"class":46},[29,1098,1099],{"class":852},"btn",[29,1101,1102],{"class":46},") {\n",[29,1104,1106,1109,1112,1114,1117,1120,1123,1126,1129,1131,1133,1136,1139,1141,1144],{"class":31,"line":1105},13,[29,1107,1108],{"class":46},"  box.",[29,1110,1111],{"class":427},"querySelectorAll",[29,1113,1075],{"class":46},[29,1115,1116],{"class":56},"\"button\"",[29,1118,1119],{"class":46},").",[29,1121,1122],{"class":427},"forEach",[29,1124,1125],{"class":46},"((",[29,1127,1128],{"class":852},"b",[29,1130,856],{"class":46},[29,1132,859],{"class":35},[29,1134,1135],{"class":46}," b.classList.",[29,1137,1138],{"class":427},"remove",[29,1140,1075],{"class":46},[29,1142,1143],{"class":56},"\"active\"",[29,1145,1146],{"class":46},"));\n",[29,1148,1150,1153,1156,1158,1160],{"class":31,"line":1149},14,[29,1151,1152],{"class":46},"  btn.classList.",[29,1154,1155],{"class":427},"add",[29,1157,1075],{"class":46},[29,1159,1143],{"class":56},[29,1161,1081],{"class":46},[29,1163,1165,1168,1170,1172,1175,1178,1180],{"class":31,"line":1164},15,[29,1166,1167],{"class":46},"  document.",[29,1169,1072],{"class":427},[29,1171,1075],{"class":46},[29,1173,1174],{"class":56},"\"#rows\"",[29,1176,1177],{"class":46},").innerHTML ",[29,1179,431],{"class":35},[29,1181,1182],{"class":46}," checks\n",[29,1184,1186,1189,1192,1195,1198,1200,1203,1206,1208,1211,1213,1216,1219,1221,1223,1225,1227,1230,1233],{"class":31,"line":1185},16,[29,1187,1188],{"class":46},"    .",[29,1190,1191],{"class":427},"map",[29,1193,1194],{"class":46},"(([",[29,1196,1197],{"class":852},"label",[29,1199,264],{"class":46},[29,1201,1202],{"class":852},"fn",[29,1204,1205],{"class":46},"]) ",[29,1207,859],{"class":35},[29,1209,1210],{"class":56}," `\u003Ctr>\u003Ctd>${",[29,1212,1197],{"class":46},[29,1214,1215],{"class":56},"}\u003C\u002Ftd>\u003Ctd>${",[29,1217,1218],{"class":427},"show",[29,1220,1075],{"class":56},[29,1222,1202],{"class":427},[29,1224,1075],{"class":56},[29,1226,853],{"class":46},[29,1228,1229],{"class":56},"))",[29,1231,1232],{"class":56},"}\u003C\u002Ftd>\u003C\u002Ftr>`",[29,1234,1235],{"class":46},")\n",[29,1237,1239,1241,1244,1246,1248],{"class":31,"line":1238},17,[29,1240,1188],{"class":46},[29,1242,1243],{"class":427},"join",[29,1245,1075],{"class":46},[29,1247,57],{"class":56},[29,1249,1081],{"class":46},[29,1251,1253],{"class":31,"line":1252},18,[29,1254,1255],{"class":46},"}\n",[29,1257,1259,1262,1264,1266,1268,1270,1273,1275,1277],{"class":31,"line":1258},19,[29,1260,1261],{"class":46},"values.",[29,1263,1122],{"class":427},[29,1265,1125],{"class":46},[29,1267,853],{"class":852},[29,1269,264],{"class":46},[29,1271,1272],{"class":852},"i",[29,1274,856],{"class":46},[29,1276,859],{"class":35},[29,1278,1279],{"class":46}," {\n",[29,1281,1283,1286,1289,1291,1293,1296,1298,1300],{"class":31,"line":1282},20,[29,1284,1285],{"class":35},"  const",[29,1287,1288],{"class":39}," btn",[29,1290,43],{"class":35},[29,1292,1069],{"class":46},[29,1294,1295],{"class":427},"createElement",[29,1297,1075],{"class":46},[29,1299,1116],{"class":56},[29,1301,1081],{"class":46},[29,1303,1305,1308,1310,1312],{"class":31,"line":1304},21,[29,1306,1307],{"class":46},"  btn.textContent ",[29,1309,431],{"class":35},[29,1311,844],{"class":427},[29,1313,1314],{"class":46},"(v);\n",[29,1316,1318,1321,1324,1326,1329,1332,1334,1336],{"class":31,"line":1317},22,[29,1319,1320],{"class":46},"  btn.",[29,1322,1323],{"class":427},"addEventListener",[29,1325,1075],{"class":46},[29,1327,1328],{"class":56},"\"click\"",[29,1330,1331],{"class":46},", () ",[29,1333,859],{"class":35},[29,1335,1090],{"class":427},[29,1337,1338],{"class":46},"(v, btn));\n",[29,1340,1342,1344,1347],{"class":31,"line":1341},23,[29,1343,1108],{"class":46},[29,1345,1346],{"class":427},"append",[29,1348,1349],{"class":46},"(btn);\n",[29,1351,1353,1356,1359,1361,1364,1366,1369],{"class":31,"line":1352},24,[29,1354,1355],{"class":35},"  if",[29,1357,1358],{"class":46}," (i ",[29,1360,870],{"class":35},[29,1362,1363],{"class":39}," 0",[29,1365,856],{"class":46},[29,1367,1368],{"class":427},"select",[29,1370,1371],{"class":46},"(v, btn);\n",[29,1373,1375],{"class":31,"line":1374},25,[29,1376,1377],{"class":46},"});\n",[1379,1380,1381],"tip",{},[234,1382,1383],{},[15,1384,1385,1386,1389,1390,1392,1393,1395,1396,1398],{},"There's one question to ask: ",[242,1387,1388],{},"\"Are 0, an empty string, and false valid values here?\""," If yes, use ",[26,1391,155],{},". If not (you want empty values replaced with the default too), use ",[26,1394,89],{},". For most settings, numbers, and form input, ",[26,1397,155],{}," is the right choice.",[222,1400],{},[10,1402,1404,1407],{"id":1403},"optional-chaining-dont-crash-when-something-in-the-middle-is-missing",[26,1405,1406],{},"?."," optional chaining: don't crash when something in the middle is missing",[15,1409,1410],{},"When you work with objects whose intermediate levels might be empty, like API responses, this is the most common error:",[19,1412,1414],{"className":21,"code":1413,"language":23,"meta":24,"style":24},"const user = { profile: null };\nuser.profile.name;\n\u002F\u002F TypeError: Cannot read properties of null (reading 'name')\n",[26,1415,1416,1432,1437],{"__ignoreMap":24},[29,1417,1418,1420,1423,1425,1428,1430],{"class":31,"line":32},[29,1419,36],{"class":35},[29,1421,1422],{"class":39}," user",[29,1424,43],{"class":35},[29,1426,1427],{"class":46}," { profile: ",[29,1429,254],{"class":39},[29,1431,66],{"class":46},[29,1433,1434],{"class":31,"line":69},[29,1435,1436],{"class":46},"user.profile.name;\n",[29,1438,1439],{"class":31,"line":76},[29,1440,1441],{"class":181},"\u002F\u002F TypeError: Cannot read properties of null (reading 'name')\n",[15,1443,1444,1446,1447,1453,1454,255,1456,156],{},[26,1445,1406],{}," (optional chaining) ",[242,1448,1449,1450,1452],{},"stops and returns ",[26,1451,258],{}," instead of throwing"," when the value before it is ",[26,1455,254],{},[26,1457,258],{},[19,1459,1461],{"className":21,"code":1460,"language":23,"meta":24,"style":24},"user.profile?.name; \u002F\u002F undefined\nuser.profile?.name ?? \"No name\"; \u002F\u002F \"No name\"\n",[26,1462,1463,1471],{"__ignoreMap":24},[29,1464,1465,1468],{"class":31,"line":32},[29,1466,1467],{"class":46},"user.profile?.name; ",[29,1469,1470],{"class":181},"\u002F\u002F undefined\n",[29,1472,1473,1476,1478,1481,1483],{"class":31,"line":69},[29,1474,1475],{"class":46},"user.profile?.name ",[29,1477,155],{"class":35},[29,1479,1480],{"class":56}," \"No name\"",[29,1482,178],{"class":46},[29,1484,1485],{"class":181},"\u002F\u002F \"No name\"\n",[15,1487,1488,230,1490,1492,1493,1495,1496,156],{},[26,1489,1406],{},[26,1491,155],{}," work as a pair: read safely with ",[26,1494,1406],{},", then fill in a default with ",[26,1497,155],{},[292,1499,1500,1513],{},[295,1501,1502],{},[298,1503,1504,1507,1510],{},[301,1505,1506],{},"Where",[301,1508,1509],{},"Syntax",[301,1511,1512],{},"Example",[315,1514,1515,1530,1545],{},[298,1516,1517,1520,1525],{},[320,1518,1519],{},"Property",[320,1521,1522],{},[26,1523,1524],{},"obj?.prop",[320,1526,1527],{},[26,1528,1529],{},"user?.name",[298,1531,1532,1535,1540],{},[320,1533,1534],{},"Bracket access",[320,1536,1537],{},[26,1538,1539],{},"obj?.[key]",[320,1541,1542],{},[26,1543,1544],{},"order.items?.[0]",[298,1546,1547,1550,1555],{},[320,1548,1549],{},"Function call",[320,1551,1552],{},[26,1553,1554],{},"fn?.()",[320,1556,1557],{},[26,1558,1559],{},"options.onSuccess?.()",[19,1561,1563],{"className":21,"code":1562,"language":23,"meta":24,"style":24},"\u002F\u002F Call the callback only if it exists\noptions.onSuccess?.(result);\n\n\u002F\u002F Price of the first item in the cart, or 0\nconst firstPrice = order.items?.[0]?.price ?? 0;\n",[26,1564,1565,1570,1581,1585,1590],{"__ignoreMap":24},[29,1566,1567],{"class":31,"line":32},[29,1568,1569],{"class":181},"\u002F\u002F Call the callback only if it exists\n",[29,1571,1572,1575,1578],{"class":31,"line":69},[29,1573,1574],{"class":46},"options.",[29,1576,1577],{"class":427},"onSuccess",[29,1579,1580],{"class":46},"?.(result);\n",[29,1582,1583],{"class":31,"line":76},[29,1584,73],{"emptyLinePlaceholder":72},[29,1586,1587],{"class":31,"line":98},[29,1588,1589],{"class":181},"\u002F\u002F Price of the first item in the cart, or 0\n",[29,1591,1592,1594,1597,1599,1602,1604,1607,1609,1611],{"class":31,"line":118},[29,1593,36],{"class":35},[29,1595,1596],{"class":39}," firstPrice",[29,1598,43],{"class":35},[29,1600,1601],{"class":46}," order.items?.[",[29,1603,50],{"class":39},[29,1605,1606],{"class":46},"]?.price ",[29,1608,155],{"class":35},[29,1610,1363],{"class":39},[29,1612,95],{"class":46},[1614,1615,1616],"warning",{},[234,1617,1618],{},[15,1619,1620,1621,1623,1624,1627,1628,1631,1632,1634],{},"Don't put ",[26,1622,1406],{}," after every dot out of habit. With ",[26,1625,1626],{},"res?.data?.user?.address?.city",", a value that ",[242,1629,1630],{},"must never be empty"," quietly becomes ",[26,1633,258],{}," when it is, and the bug hides. Use it only on the steps that can genuinely be empty, so a missing required value fails fast with an error.",[222,1636],{},[10,1638,1640,264,1643,264,1646,1649],{"id":1639},"fill-in-only-when-empty",[26,1641,1642],{},"??=",[26,1644,1645],{},"||=",[26,1647,1648],{},"&&=",": fill in only when empty",[15,1651,1652],{},"Logical assignment operators are a short way to write \"assign only if a condition holds.\"",[19,1654,1656],{"className":21,"code":1655,"language":23,"meta":24,"style":24},"const config = { retries: 0, timeout: undefined };\n\nconfig.retries ??= 3; \u002F\u002F 0 stays (it's not null\u002Fundefined)\nconfig.timeout ??= 5000; \u002F\u002F it's undefined, so 5000 goes in\n\u002F\u002F { retries: 0, timeout: 5000 }\n",[26,1657,1658,1679,1683,1698,1713],{"__ignoreMap":24},[29,1659,1660,1662,1665,1667,1670,1672,1675,1677],{"class":31,"line":32},[29,1661,36],{"class":35},[29,1663,1664],{"class":39}," config",[29,1666,43],{"class":35},[29,1668,1669],{"class":46}," { retries: ",[29,1671,50],{"class":39},[29,1673,1674],{"class":46},", timeout: ",[29,1676,258],{"class":39},[29,1678,66],{"class":46},[29,1680,1681],{"class":31,"line":69},[29,1682,73],{"emptyLinePlaceholder":72},[29,1684,1685,1688,1690,1693,1695],{"class":31,"line":76},[29,1686,1687],{"class":46},"config.retries ",[29,1689,1642],{"class":35},[29,1691,1692],{"class":39}," 3",[29,1694,178],{"class":46},[29,1696,1697],{"class":181},"\u002F\u002F 0 stays (it's not null\u002Fundefined)\n",[29,1699,1700,1703,1705,1708,1710],{"class":31,"line":98},[29,1701,1702],{"class":46},"config.timeout ",[29,1704,1642],{"class":35},[29,1706,1707],{"class":39}," 5000",[29,1709,178],{"class":46},[29,1711,1712],{"class":181},"\u002F\u002F it's undefined, so 5000 goes in\n",[29,1714,1715],{"class":31,"line":118},[29,1716,1717],{"class":181},"\u002F\u002F { retries: 0, timeout: 5000 }\n",[292,1719,1720,1733],{},[295,1721,1722],{},[298,1723,1724,1727,1730],{},[301,1725,1726],{},"Operator",[301,1728,1729],{},"Assigns when",[301,1731,1732],{},"Long form",[315,1734,1735,1758,1775],{},[298,1736,1737,1742,1753],{},[320,1738,1739],{},[26,1740,1741],{},"a ??= b",[320,1743,1744,1747,1748,1750,1751],{},[26,1745,1746],{},"a"," is ",[26,1749,254],{},"\u002F",[26,1752,258],{},[320,1754,1755],{},[26,1756,1757],{},"a ?? (a = b)",[298,1759,1760,1765,1770],{},[320,1761,1762],{},[26,1763,1764],{},"a ||= b",[320,1766,1767,1769],{},[26,1768,1746],{}," is falsy",[320,1771,1772],{},[26,1773,1774],{},"a || (a = b)",[298,1776,1777,1782,1787],{},[320,1778,1779],{},[26,1780,1781],{},"a &&= b",[320,1783,1784,1786],{},[26,1785,1746],{}," is truthy",[320,1788,1789],{},[26,1790,1791],{},"a && (a = b)",[15,1793,1794,1795,1798,1799,1801,1802,156],{},"The same trap applies here. Write ",[26,1796,1797],{},"config.retries ||= 3"," and the user's deliberate ",[26,1800,50],{}," (no retries) becomes ",[26,1803,1804],{},"3",[222,1806],{},[10,1808,1810,1811],{"id":1809},"default-parameters-and-destructuring-defaults-apply-only-to-undefined","Default parameters and destructuring defaults apply only to ",[26,1812,258],{},[15,1814,1815,1816,1818,1819,178,1824,1826],{},"Default parameter values cover even less than ",[26,1817,155],{},". They apply ",[242,1820,1821,1822],{},"only to ",[26,1823,258],{},[26,1825,254],{}," passes straight through.",[19,1828,1830],{"className":21,"code":1829,"language":23,"meta":24,"style":24},"function greet(name = \"guest\") {\n  return `Hello, ${name}!`;\n}\n\ngreet(); \u002F\u002F \"Hello, guest!\"\ngreet(undefined); \u002F\u002F \"Hello, guest!\"\ngreet(null); \u002F\u002F \"Hello, null!\"  ← the default doesn't apply\ngreet(\"\"); \u002F\u002F \"Hello, !\"\n",[26,1831,1832,1851,1866,1870,1874,1885,1898,1911],{"__ignoreMap":24},[29,1833,1834,1836,1839,1841,1844,1846,1849],{"class":31,"line":32},[29,1835,1087],{"class":35},[29,1837,1838],{"class":427}," greet",[29,1840,1075],{"class":46},[29,1842,1843],{"class":852},"name",[29,1845,43],{"class":35},[29,1847,1848],{"class":56}," \"guest\"",[29,1850,1102],{"class":46},[29,1852,1853,1856,1859,1861,1864],{"class":31,"line":69},[29,1854,1855],{"class":35},"  return",[29,1857,1858],{"class":56}," `Hello, ${",[29,1860,1843],{"class":46},[29,1862,1863],{"class":56},"}!`",[29,1865,95],{"class":46},[29,1867,1868],{"class":31,"line":76},[29,1869,1255],{"class":46},[29,1871,1872],{"class":31,"line":98},[29,1873,73],{"emptyLinePlaceholder":72},[29,1875,1876,1879,1882],{"class":31,"line":118},[29,1877,1878],{"class":427},"greet",[29,1880,1881],{"class":46},"(); ",[29,1883,1884],{"class":181},"\u002F\u002F \"Hello, guest!\"\n",[29,1886,1887,1889,1891,1893,1896],{"class":31,"line":759},[29,1888,1878],{"class":427},[29,1890,1075],{"class":46},[29,1892,258],{"class":39},[29,1894,1895],{"class":46},"); ",[29,1897,1884],{"class":181},[29,1899,1900,1902,1904,1906,1908],{"class":31,"line":1001},[29,1901,1878],{"class":427},[29,1903,1075],{"class":46},[29,1905,254],{"class":39},[29,1907,1895],{"class":46},[29,1909,1910],{"class":181},"\u002F\u002F \"Hello, null!\"  ← the default doesn't apply\n",[29,1912,1913,1915,1917,1919,1921],{"class":31,"line":1027},[29,1914,1878],{"class":427},[29,1916,1075],{"class":46},[29,1918,57],{"class":56},[29,1920,1895],{"class":46},[29,1922,1923],{"class":181},"\u002F\u002F \"Hello, !\"\n",[15,1925,1926],{},"Destructuring defaults work the same way.",[19,1928,1930],{"className":21,"code":1929,"language":23,"meta":24,"style":24},"const { page = 1, size = 10 } = { page: null, size: undefined };\npage; \u002F\u002F null (no default)\nsize; \u002F\u002F 10\n",[26,1931,1932,1972,1980],{"__ignoreMap":24},[29,1933,1934,1936,1938,1941,1943,1946,1948,1951,1953,1955,1958,1960,1963,1965,1968,1970],{"class":31,"line":32},[29,1935,36],{"class":35},[29,1937,495],{"class":46},[29,1939,1940],{"class":39},"page",[29,1942,43],{"class":35},[29,1944,1945],{"class":39}," 1",[29,1947,264],{"class":46},[29,1949,1950],{"class":39},"size",[29,1952,43],{"class":35},[29,1954,582],{"class":39},[29,1956,1957],{"class":46}," } ",[29,1959,431],{"class":35},[29,1961,1962],{"class":46}," { page: ",[29,1964,254],{"class":39},[29,1966,1967],{"class":46},", size: ",[29,1969,258],{"class":39},[29,1971,66],{"class":46},[29,1973,1974,1977],{"class":31,"line":69},[29,1975,1976],{"class":46},"page; ",[29,1978,1979],{"class":181},"\u002F\u002F null (no default)\n",[29,1981,1982,1985],{"class":31,"line":76},[29,1983,1984],{"class":46},"size; ",[29,1986,1987],{"class":181},"\u002F\u002F 10\n",[15,1989,1990,1991,1993,1994,1996,1997,1999],{},"API responses often contain ",[26,1992,254],{},". If you want ",[26,1995,254],{}," replaced with a default too, use ",[26,1998,155],{}," instead of a default parameter.",[19,2001,2003],{"className":21,"code":2002,"language":23,"meta":24,"style":24},"function greet(name) {\n  return `Hello, ${name ?? \"guest\"}!`;\n}\n",[26,2004,2005,2017,2033],{"__ignoreMap":24},[29,2006,2007,2009,2011,2013,2015],{"class":31,"line":32},[29,2008,1087],{"class":35},[29,2010,1838],{"class":427},[29,2012,1075],{"class":46},[29,2014,1843],{"class":852},[29,2016,1102],{"class":46},[29,2018,2019,2021,2023,2025,2028,2031],{"class":31,"line":69},[29,2020,1855],{"class":35},[29,2022,1858],{"class":56},[29,2024,1843],{"class":46},[29,2026,2027],{"class":35}," ??",[29,2029,2030],{"class":56}," \"guest\"}!`",[29,2032,95],{"class":46},[29,2034,2035],{"class":31,"line":76},[29,2036,1255],{"class":46},[292,2038,2039,2062],{},[295,2040,2041],{},[298,2042,2043,2046,2050,2054],{},[301,2044,2045],{},"Approach",[301,2047,2048],{},[26,2049,258],{},[301,2051,2052],{},[26,2053,254],{},[301,2055,2056,264,2058,264,2060],{},[26,2057,50],{},[26,2059,57],{},[26,2061,63],{},[315,2063,2064,2077,2089],{},[298,2065,2066,2069,2072,2075],{},[320,2067,2068],{},"Default parameter \u002F destructuring default",[320,2070,2071],{},"Default",[320,2073,2074],{},"Kept",[320,2076,2074],{},[298,2078,2079,2083,2085,2087],{},[320,2080,2081],{},[26,2082,155],{},[320,2084,2071],{},[320,2086,2071],{},[320,2088,2074],{},[298,2090,2091,2095,2097,2099],{},[320,2092,2093],{},[26,2094,89],{},[320,2096,2071],{},[320,2098,2071],{},[320,2100,2071],{},[222,2102],{},[10,2104,2106],{"id":2105},"checking-whether-a-value-is-missing-correctly","Checking whether a value is \"missing,\" correctly",[2108,2109,2111,230,2113,2115,2116],"h3",{"id":2110},"null-and-undefined-at-once-null",[26,2112,254],{},[26,2114,258],{}," at once: ",[26,2117,2118],{},"== null",[15,2120,2121,2122,2124,2125,264,2132,2134],{},"Normally you should use ",[26,2123,870],{},", but ",[242,2126,2127,2128,230,2130],{},"when you want to check for both ",[26,2129,254],{},[26,2131,258],{},[26,2133,2118],{}," is short and precise.",[19,2136,2138],{"className":21,"code":2137,"language":23,"meta":24,"style":24},"value == null; \u002F\u002F true only when value is null or undefined\n\n0 == null; \u002F\u002F false\n\"\" == null; \u002F\u002F false\nfalse == null; \u002F\u002F false\n",[26,2139,2140,2154,2158,2171,2183],{"__ignoreMap":24},[29,2141,2142,2145,2147,2149,2151],{"class":31,"line":32},[29,2143,2144],{"class":46},"value ",[29,2146,1019],{"class":35},[29,2148,1022],{"class":39},[29,2150,178],{"class":46},[29,2152,2153],{"class":181},"\u002F\u002F true only when value is null or undefined\n",[29,2155,2156],{"class":31,"line":69},[29,2157,73],{"emptyLinePlaceholder":72},[29,2159,2160,2162,2165,2167,2169],{"class":31,"line":76},[29,2161,50],{"class":39},[29,2163,2164],{"class":35}," ==",[29,2166,1022],{"class":39},[29,2168,178],{"class":46},[29,2170,220],{"class":181},[29,2172,2173,2175,2177,2179,2181],{"class":31,"line":98},[29,2174,57],{"class":56},[29,2176,2164],{"class":35},[29,2178,1022],{"class":39},[29,2180,178],{"class":46},[29,2182,220],{"class":181},[29,2184,2185,2187,2189,2191,2193],{"class":31,"line":118},[29,2186,63],{"class":39},[29,2188,2164],{"class":35},[29,2190,1022],{"class":39},[29,2192,178],{"class":46},[29,2194,220],{"class":181},[15,2196,2197,2200,2201,230,2203,2205,2206,2209],{},[26,2198,2199],{},"if (!value)"," also filters out ",[26,2202,50],{},[26,2204,57],{},", so when you mean \"is this empty?\", ",[26,2207,2208],{},"value == null"," is closer to what you want.",[2108,2211,2213],{"id":2212},"confusing-type-checks","Confusing type checks",[292,2215,2216,2229],{},[295,2217,2218],{},[298,2219,2220,2223,2226],{},[301,2221,2222],{},"What you want",[301,2224,2225],{},"❌ Easy to get wrong",[301,2227,2228],{},"✅ Correct",[315,2230,2231,2246,2271],{},[298,2232,2233,2236,2241],{},[320,2234,2235],{},"Is it an array?",[320,2237,2238],{},[26,2239,2240],{},"typeof arr === \"object\"",[320,2242,2243],{},[26,2244,2245],{},"Array.isArray(arr)",[298,2247,2248,2254,2266],{},[320,2249,2250,2251,2253],{},"Is it ",[26,2252,254],{},"?",[320,2255,2256,849,2259,2261,2262,2265],{},[26,2257,2258],{},"typeof v === \"object\"",[26,2260,254],{}," is also ",[26,2263,2264],{},"\"object\"",")",[320,2267,2268],{},[26,2269,2270],{},"v === null",[298,2272,2273,2277,2297],{},[320,2274,2250,2275,2253],{},[26,2276,272],{},[320,2278,2279,2282,2283,2285,2286,2289,2290,1747,2293,2296],{},[26,2280,2281],{},"v === NaN"," (always ",[26,2284,63],{},"), ",[26,2287,2288],{},"isNaN(v)"," (the string ",[26,2291,2292],{},"\"abc\"",[26,2294,2295],{},"true"," too)",[320,2298,2299],{},[26,2300,2301],{},"Number.isNaN(v)",[2108,2303,2305,2307,2308],{"id":2304},"doesnt-catch-nan",[26,2306,155],{}," doesn't catch ",[26,2309,272],{},[15,2311,2312,2313,2315],{},"A common mistake when combining number conversion with ",[26,2314,155],{},":",[19,2317,2319],{"className":21,"code":2318,"language":23,"meta":24,"style":24},"const qty = Number(\"abc\"); \u002F\u002F NaN\nqty ?? 1; \u002F\u002F NaN  ← NaN isn't null\u002Fundefined, so it stays\nNumber.isNaN(qty) ? 1 : qty; \u002F\u002F 1\n",[26,2320,2321,2342,2356],{"__ignoreMap":24},[29,2322,2323,2325,2328,2330,2333,2335,2337,2339],{"class":31,"line":32},[29,2324,36],{"class":35},[29,2326,2327],{"class":39}," qty",[29,2329,43],{"class":35},[29,2331,2332],{"class":427}," Number",[29,2334,1075],{"class":46},[29,2336,2292],{"class":56},[29,2338,1895],{"class":46},[29,2340,2341],{"class":181},"\u002F\u002F NaN\n",[29,2343,2344,2347,2349,2351,2353],{"class":31,"line":69},[29,2345,2346],{"class":46},"qty ",[29,2348,155],{"class":35},[29,2350,1945],{"class":39},[29,2352,178],{"class":46},[29,2354,2355],{"class":181},"\u002F\u002F NaN  ← NaN isn't null\u002Fundefined, so it stays\n",[29,2357,2358,2361,2364,2367,2369,2371,2373,2376],{"class":31,"line":76},[29,2359,2360],{"class":46},"Number.",[29,2362,2363],{"class":427},"isNaN",[29,2365,2366],{"class":46},"(qty) ",[29,2368,2253],{"class":35},[29,2370,1945],{"class":39},[29,2372,887],{"class":35},[29,2374,2375],{"class":46}," qty; ",[29,2377,2378],{"class":181},"\u002F\u002F 1\n",[15,2380,2381,2382,230,2385,2388,2389,2391,2392,2394,2395,2397],{},"Also remember that ",[26,2383,2384],{},"Number(\"\")",[26,2386,2387],{},"Number(null)"," become ",[26,2390,50],{},", not ",[26,2393,272],{},". That's where the bug of an empty input silently turning into ",[26,2396,50],{}," comes from.",[2108,2399,2401,2402,230,2404,2406],{"id":2400},"you-cant-mix-and-without-parentheses","You can't mix ",[26,2403,155],{},[26,2405,89],{}," without parentheses",[19,2408,2410],{"className":21,"code":2409,"language":23,"meta":24,"style":24},"null || undefined ?? \"x\"; \u002F\u002F SyntaxError\n(null || undefined) ?? \"x\"; \u002F\u002F \"x\"\n",[26,2411,2412,2432],{"__ignoreMap":24},[29,2413,2414,2416,2419,2422,2424,2427,2429],{"class":31,"line":32},[29,2415,254],{"class":39},[29,2417,2418],{"class":35}," ||",[29,2420,2421],{"class":39}," undefined",[29,2423,2027],{"class":35},[29,2425,2426],{"class":56}," \"x\"",[29,2428,178],{"class":46},[29,2430,2431],{"class":181},"\u002F\u002F SyntaxError\n",[29,2433,2434,2436,2438,2440,2442,2444,2446,2448,2450],{"class":31,"line":69},[29,2435,1075],{"class":46},[29,2437,254],{"class":39},[29,2439,2418],{"class":35},[29,2441,2421],{"class":39},[29,2443,856],{"class":46},[29,2445,155],{"class":35},[29,2447,2426],{"class":56},[29,2449,178],{"class":46},[29,2451,2452],{"class":181},"\u002F\u002F \"x\"\n",[15,2454,2455],{},"The language blocks this so there's no confusion about which runs first. If you need both, make the order explicit with parentheses.",[222,2457],{},[10,2459,2461],{"id":2460},"summary-why-this-is-worth-knowing","Summary: why this is worth knowing",[292,2463,2464,2474],{},[295,2465,2466],{},[298,2467,2468,2471],{},[301,2469,2470],{},"Situation",[301,2472,2473],{},"Correct handling",[315,2475,2476,2491,2501,2511,2520,2529,2542,2555],{},[298,2477,2478,2486],{},[320,2479,2480,2481,264,2483,2485],{},"Default value (0, ",[26,2482,57],{},[26,2484,63],{}," are valid)",[320,2487,2488],{},[26,2489,2490],{},"value ?? default",[298,2492,2493,2496],{},[320,2494,2495],{},"Replace every empty value with a default",[320,2497,2498],{},[26,2499,2500],{},"value || default",[298,2502,2503,2506],{},[320,2504,2505],{},"Access an object whose middle may be empty",[320,2507,2508],{},[26,2509,2510],{},"obj?.a?.b",[298,2512,2513,2516],{},[320,2514,2515],{},"Call a callback only if it exists",[320,2517,2518],{},[26,2519,1554],{},[298,2521,2522,2525],{},[320,2523,2524],{},"Fill in only when empty",[320,2526,2527],{},[26,2528,1741],{},[298,2530,2531,2537],{},[320,2532,2533,2534,2536],{},"A parameter that should default on ",[26,2535,254],{}," too",[320,2538,2539,2541],{},[26,2540,155],{}," instead of a default parameter",[298,2543,2544,2551],{},[320,2545,2546,2547,1750,2549],{},"Check for ",[26,2548,254],{},[26,2550,258],{},[320,2552,2553],{},[26,2554,2208],{},[298,2556,2557,2562],{},[320,2558,2559,2560],{},"Check for arrays \u002F ",[26,2561,272],{},[320,2563,2564,2567,2568],{},[26,2565,2566],{},"Array.isArray"," \u002F ",[26,2569,2570],{},"Number.isNaN",[15,2572,2573,2575,2576,2578,2579,2582,2583,2585,2586,2588,2589,2591],{},[26,2574,50],{},", an empty string, and ",[26,2577,63],{}," are often ",[242,2580,2581],{},"values the user chose",", not \"nothing.\" The habit of filling in defaults with ",[26,2584,89],{}," silently erases them, and because nothing throws, these bugs are found late. When you add a default, reach for ",[26,2587,155],{}," first, and use ",[26,2590,89],{}," only when you clearly mean \"replace empty values with the default too.\"",[2593,2594,2595],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}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 .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":24,"searchDepth":69,"depth":69,"links":2597},[2598,2599,2601,2603,2605,2607,2616],{"id":12,"depth":69,"text":13},{"id":226,"depth":69,"text":2600},"The difference between || and ??",{"id":1403,"depth":69,"text":2602},"?. optional chaining: don't crash when something in the middle is missing",{"id":1639,"depth":69,"text":2604},"??=, ||=, &&=: fill in only when empty",{"id":1809,"depth":69,"text":2606},"Default parameters and destructuring defaults apply only to undefined",{"id":2105,"depth":69,"text":2106,"children":2608},[2609,2611,2612,2614],{"id":2110,"depth":76,"text":2610},"null and undefined at once: == null",{"id":2212,"depth":76,"text":2213},{"id":2304,"depth":76,"text":2613},"?? doesn't catch NaN",{"id":2400,"depth":76,"text":2615},"You can't mix ?? and || without parentheses",{"id":2460,"depth":69,"text":2461},"Volume 0 turning into 50 and an empty nickname becoming 'Anonymous' are usually caused by ||. The difference between ?? and ||, optional chaining with ?., ??=, when default parameters actually apply, and the right way to check for null, with an interactive demo.","md",{"date":2620,"field":2621,"tags":2622},"2026.10.08","frontend",[2623],"javascript","\u002Fen\u002Fjavascript-nullish-coalescing-optional-chaining",{"title":5,"description":2617},{"loc":2624},"en\u002Fjavascript-nullish-coalescing-optional-chaining","U6lU8edWf3eUkj88BCqcoIUcYvOFVyNmhrjcaQAgFUw",1791482016618]