[{"data":1,"prerenderedAt":2953},["ShallowReactive",2],{"page-\u002Fjs\u002F09-destructuring-and-spread":3},{"id":4,"title":5,"body":6,"description":30,"extension":2947,"meta":2948,"navigation":121,"path":2949,"seo":2950,"stem":2951,"__hash__":2952},"content\u002Fjs\u002F09-destructuring-and-spread.md","09 — Destructuring & Spread",{"type":7,"value":8,"toc":2924},"minimark",[9,13,186,319,451,650,804,926,1071,1200,1273,1410,1531,1661,1796,1983,2133,2266,2445,2594,2749,2920],[10,11,5],"h1",{"id":12},"_09-destructuring-spread",[14,15,17,22,108,145],"question-wrapper",{"language":16},"javascript",[18,19,21],"h3",{"id":20},"q1-what-does-this-log","Q1. What does this log?",[23,24,25],"code-wrapper",{"language":16},[26,27,31],"pre",{"className":28,"code":29,"language":16,"meta":30,"style":30},"language-javascript shiki shiki-themes github-light github-dark","const arr = [10, 20, 30];\nconst [x, y] = arr;\nconsole.log(x, y);\n","",[32,33,34,71,95],"code",{"__ignoreMap":30},[35,36,39,43,47,50,54,57,60,63,65,68],"span",{"class":37,"line":38},"line",1,[35,40,42],{"class":41},"svdQ7","const",[35,44,46],{"class":45},"snvgF"," arr",[35,48,49],{"class":41}," =",[35,51,53],{"class":52},"ssxIu"," [",[35,55,56],{"class":45},"10",[35,58,59],{"class":52},", ",[35,61,62],{"class":45},"20",[35,64,59],{"class":52},[35,66,67],{"class":45},"30",[35,69,70],{"class":52},"];\n",[35,72,74,76,78,81,83,86,89,92],{"class":37,"line":73},2,[35,75,42],{"class":41},[35,77,53],{"class":52},[35,79,80],{"class":45},"x",[35,82,59],{"class":52},[35,84,85],{"class":45},"y",[35,87,88],{"class":52},"] ",[35,90,91],{"class":41},"=",[35,93,94],{"class":52}," arr;\n",[35,96,98,101,105],{"class":37,"line":97},3,[35,99,100],{"class":52},"console.",[35,102,104],{"class":103},"sIsaT","log",[35,106,107],{"class":52},"(x, y);\n",[109,110,113,124,130,136],"ul",{"className":111},[112],"contains-task-list",[114,115,118,123],"li",{"className":116},[117],"task-list-item",[119,120],"input",{"disabled":121,"type":122},true,"checkbox"," 10 20",[114,125,127,129],{"className":126},[117],[119,128],{"disabled":121,"type":122}," 10 20 30",[114,131,133,135],{"className":132},[117],[119,134],{"disabled":121,"type":122}," undefined undefined",[114,137,139,141,142],{"className":138},[117],[119,140],{"disabled":121,"type":122}," ",[35,143,144],{},"10, 20",[146,147,148,152,160],"details",{},[149,150,151],"summary",{},"Show Answer",[153,154,155,159],"p",{},[156,157,158],"strong",{},"Answer:"," A — 10 20",[153,161,162,165,166,168,169,59,172,168,174,177,178,181,182,185],{},[156,163,164],{},"Explanation:"," Array destructuring binds by position, not by consuming the whole array. ",[32,167,80],{}," takes ",[32,170,171],{},"arr[0]",[32,173,85],{},[32,175,176],{},"arr[1]",", and ",[32,179,180],{},"arr[2]"," is simply left unbound — it still exists in ",[32,183,184],{},"arr",", but no new variable captures it. B is wrong because destructuring only creates as many bindings as the pattern lists. C and D confuse destructuring with cloning or logging the array itself.",[14,187,188,192,256,282],{"language":16},[18,189,191],{"id":190},"q2-what-does-this-log","Q2. What does this log?",[23,193,194],{"language":16},[26,195,197],{"className":28,"code":196,"language":16,"meta":30,"style":30},"const user = { id: 7, name: 'Ada' };\nconst { name, id } = user;\nconsole.log(name, id);\n",[32,198,199,224,247],{"__ignoreMap":30},[35,200,201,203,206,208,211,214,217,221],{"class":37,"line":38},[35,202,42],{"class":41},[35,204,205],{"class":45}," user",[35,207,49],{"class":41},[35,209,210],{"class":52}," { id: ",[35,212,213],{"class":45},"7",[35,215,216],{"class":52},", name: ",[35,218,220],{"class":219},"sJ6F3","'Ada'",[35,222,223],{"class":52}," };\n",[35,225,226,228,231,234,236,239,242,244],{"class":37,"line":73},[35,227,42],{"class":41},[35,229,230],{"class":52}," { ",[35,232,233],{"class":45},"name",[35,235,59],{"class":52},[35,237,238],{"class":45},"id",[35,240,241],{"class":52}," } ",[35,243,91],{"class":41},[35,245,246],{"class":52}," user;\n",[35,248,249,251,253],{"class":37,"line":97},[35,250,100],{"class":52},[35,252,104],{"class":103},[35,254,255],{"class":52},"(name, id);\n",[109,257,259,264,270,276],{"className":258},[112],[114,260,262,135],{"className":261},[117],[119,263],{"disabled":121,"type":122},[114,265,267,269],{"className":266},[117],[119,268],{"disabled":121,"type":122}," 7 Ada",[114,271,273,275],{"className":272},[117],[119,274],{"disabled":121,"type":122}," Ada 7",[114,277,279,281],{"className":278},[117],[119,280],{"disabled":121,"type":122}," TypeError: Cannot destructure",[146,283,284,286,291],{},[149,285,151],{},[153,287,288,290],{},[156,289,158],{}," C — Ada 7",[153,292,293,141,295,298,299,303,304,307,308,311,312,315,316,318],{},[156,294,164],{},[156,296,297],{},"Idiom."," Unlike array destructuring, object destructuring matches by ",[300,301,302],"em",{},"key name",", not position — writing ",[32,305,306],{},"{ name, id }"," instead of ",[32,309,310],{},"{ id, name }"," has zero effect on the result because each identifier looks itself up on ",[32,313,314],{},"user",". B is the tempting wrong answer for anyone assuming destructuring mirrors the object's declared field order. A and D would only apply if the keys didn't exist or ",[32,317,314],{}," were nullish.",[14,320,321,325,381,413],{"language":16},[18,322,324],{"id":323},"q3-what-happens-when-this-runs","Q3. What happens when this runs?",[23,326,327],{"language":16},[26,328,330],{"className":28,"code":329,"language":16,"meta":30,"style":30},"const config = { url: 'https:\u002F\u002Fapi.example.com' };\nconst { url: endpoint } = config;\nconsole.log(url);\n",[32,331,332,349,372],{"__ignoreMap":30},[35,333,334,336,339,341,344,347],{"class":37,"line":38},[35,335,42],{"class":41},[35,337,338],{"class":45}," config",[35,340,49],{"class":41},[35,342,343],{"class":52}," { url: ",[35,345,346],{"class":219},"'https:\u002F\u002Fapi.example.com'",[35,348,223],{"class":52},[35,350,351,353,355,359,362,365,367,369],{"class":37,"line":73},[35,352,42],{"class":41},[35,354,230],{"class":52},[35,356,358],{"class":357},"sCrzJ","url",[35,360,361],{"class":52},": ",[35,363,364],{"class":45},"endpoint",[35,366,241],{"class":52},[35,368,91],{"class":41},[35,370,371],{"class":52}," config;\n",[35,373,374,376,378],{"class":37,"line":97},[35,375,100],{"class":52},[35,377,104],{"class":103},[35,379,380],{"class":52},"(url);\n",[109,382,384,390,401,407],{"className":383},[112],[114,385,387,389],{"className":386},[117],[119,388],{"disabled":121,"type":122}," ReferenceError: url is not defined",[114,391,393,141,395],{"className":392},[117],[119,394],{"disabled":121,"type":122},[396,397,398],"a",{"href":398,"rel":399},"https:\u002F\u002Fapi.example.com",[400],"nofollow",[114,402,404,406],{"className":403},[117],[119,405],{"disabled":121,"type":122}," undefined",[114,408,410,412],{"className":409},[117],[119,411],{"disabled":121,"type":122}," endpoint",[146,414,415,417,422],{},[149,416,151],{},[153,418,419,421],{},[156,420,158],{}," A — ReferenceError: url is not defined",[153,423,424,141,426,429,430,433,434,437,438,441,442,444,445,447,448,450],{},[156,425,164],{},[156,427,428],{},"Debug."," Renaming with ",[32,431,432],{},"{ url: endpoint }"," means the value at ",[32,435,436],{},"config.url"," is bound ",[300,439,440],{},"only"," to the new identifier ",[32,443,364],{}," — the name ",[32,446,358],{}," is never declared as a local binding. Logging ",[32,449,358],{}," therefore hits a plain undeclared-variable error, not a \"no value\" case. B and C wrongly assume the original key name survives as a variable; D confuses the renamed variable's identifier with what was actually requested.",[14,452,453,457,569,596],{"language":16},[18,454,456],{"id":455},"q4-what-does-this-log","Q4. What does this log?",[23,458,459],{"language":16},[26,460,462],{"className":28,"code":461,"language":16,"meta":30,"style":30},"function connect({ port = 8080, host = 'localhost', timeout = 3000 } = {}) {\n  return `${host}:${port} (${timeout}ms)`;\n}\nconsole.log(connect({ port: null, host: undefined }));\n",[32,463,464,510,536,541],{"__ignoreMap":30},[35,465,466,469,472,475,478,480,483,485,488,490,493,495,498,500,503,505,507],{"class":37,"line":38},[35,467,468],{"class":41},"function",[35,470,471],{"class":103}," connect",[35,473,474],{"class":52},"({ ",[35,476,477],{"class":357},"port",[35,479,49],{"class":41},[35,481,482],{"class":45}," 8080",[35,484,59],{"class":52},[35,486,487],{"class":357},"host",[35,489,49],{"class":41},[35,491,492],{"class":219}," 'localhost'",[35,494,59],{"class":52},[35,496,497],{"class":357},"timeout",[35,499,49],{"class":41},[35,501,502],{"class":45}," 3000",[35,504,241],{"class":52},[35,506,91],{"class":41},[35,508,509],{"class":52}," {}) {\n",[35,511,512,515,518,520,523,525,528,530,533],{"class":37,"line":73},[35,513,514],{"class":41},"  return",[35,516,517],{"class":219}," `${",[35,519,487],{"class":52},[35,521,522],{"class":219},"}:${",[35,524,477],{"class":52},[35,526,527],{"class":219},"} (${",[35,529,497],{"class":52},[35,531,532],{"class":219},"}ms)`",[35,534,535],{"class":52},";\n",[35,537,538],{"class":37,"line":97},[35,539,540],{"class":52},"}\n",[35,542,544,546,548,551,554,557,560,563,566],{"class":37,"line":543},4,[35,545,100],{"class":52},[35,547,104],{"class":103},[35,549,550],{"class":52},"(",[35,552,553],{"class":103},"connect",[35,555,556],{"class":52},"({ port: ",[35,558,559],{"class":45},"null",[35,561,562],{"class":52},", host: ",[35,564,565],{"class":45},"undefined",[35,567,568],{"class":52}," }));\n",[109,570,572,578,584,590],{"className":571},[112],[114,573,575,577],{"className":574},[117],[119,576],{"disabled":121,"type":122}," localhost:8080 (3000ms)",[114,579,581,583],{"className":580},[117],[119,582],{"disabled":121,"type":122}," null:8080 (3000ms)",[114,585,587,589],{"className":586},[117],[119,588],{"disabled":121,"type":122}," TypeError: Cannot read properties of null",[114,591,593,595],{"className":592},[117],[119,594],{"disabled":121,"type":122}," localhost:null (3000ms)",[146,597,598,600,605],{},[149,599,151],{},[153,601,602,604],{},[156,603,158],{}," D — localhost:null (3000ms)",[153,606,607,141,609,611,612,614,615,618,619,621,622,614,624,141,627,141,630,632,633,636,637,639,640,642,643,646,647,649],{},[156,608,164],{},[156,610,428],{}," Destructuring defaults trigger for exactly one value: ",[32,613,565],{},". ",[32,616,617],{},"port: null"," is an explicit, real value, so the default is skipped and ",[32,620,477],{}," stays ",[32,623,559],{},[32,625,626],{},"host: undefined",[300,628,629],{},"is",[32,631,565],{},", so its default ",[32,634,635],{},"'localhost'"," kicks in. ",[32,638,497],{}," isn't passed at all, which is also ",[32,641,565],{}," under the hood, so it defaults to ",[32,644,645],{},"3000",". A wrongly assumes ",[32,648,559],{}," behaves like a missing value; B mixes up which field falls back.",[14,651,652,656,744,770],{"language":16},[18,653,655],{"id":654},"q5-what-does-this-log","Q5. What does this log?",[23,657,658],{"language":16},[26,659,661],{"className":28,"code":660,"language":16,"meta":30,"style":30},"const response = {\n  data: [{ id: 1, meta: { active: true } }],\n};\nconst {\n  data: [{ meta: { active } }],\n} = response;\nconsole.log(active);\n",[32,662,663,675,692,697,703,723,734],{"__ignoreMap":30},[35,664,665,667,670,672],{"class":37,"line":38},[35,666,42],{"class":41},[35,668,669],{"class":45}," response",[35,671,49],{"class":41},[35,673,674],{"class":52}," {\n",[35,676,677,680,683,686,689],{"class":37,"line":73},[35,678,679],{"class":52},"  data: [{ id: ",[35,681,682],{"class":45},"1",[35,684,685],{"class":52},", meta: { active: ",[35,687,688],{"class":45},"true",[35,690,691],{"class":52}," } }],\n",[35,693,694],{"class":37,"line":97},[35,695,696],{"class":52},"};\n",[35,698,699,701],{"class":37,"line":543},[35,700,42],{"class":41},[35,702,674],{"class":52},[35,704,706,709,712,715,718,721],{"class":37,"line":705},5,[35,707,708],{"class":357},"  data",[35,710,711],{"class":52},": [{ ",[35,713,714],{"class":357},"meta",[35,716,717],{"class":52},": { ",[35,719,720],{"class":45},"active",[35,722,691],{"class":52},[35,724,726,729,731],{"class":37,"line":725},6,[35,727,728],{"class":52},"} ",[35,730,91],{"class":41},[35,732,733],{"class":52}," response;\n",[35,735,737,739,741],{"class":37,"line":736},7,[35,738,100],{"class":52},[35,740,104],{"class":103},[35,742,743],{"class":52},"(active);\n",[109,745,747,752,758,764],{"className":746},[112],[114,748,750,406],{"className":749},[117],[119,751],{"disabled":121,"type":122},[114,753,755,757],{"className":754},[117],[119,756],{"disabled":121,"type":122}," true",[114,759,761,763],{"className":760},[117],[119,762],{"disabled":121,"type":122}," TypeError: Cannot destructure property 'meta' of undefined",[114,765,767,769],{"className":766},[117],[119,768],{"disabled":121,"type":122}," { active: true }",[146,771,772,774,779],{},[149,773,151],{},[153,775,776,778],{},[156,777,158],{}," B — true",[153,780,781,783,784,787,788,790,791,793,794,797,798,800,801,803],{},[156,782,164],{}," Destructuring patterns can nest arbitrarily deep: ",[32,785,786],{},"data"," is renamed by pattern position into an array pattern, whose single element is object-destructured for ",[32,789,714],{},", which is itself object-destructured for ",[32,792,720],{},". Each layer just walks one level deeper into the structure — since every intermediate value actually exists, no layer fails. C is the trap for anyone who assumes deep nesting is fragile by default; it only throws if an ",[300,795,796],{},"intermediate"," value were ",[32,799,559],{},"\u002F",[32,802,565],{},", which isn't the case here.",[14,805,806,810,869,895],{"language":16},[18,807,809],{"id":808},"q6-what-does-this-log","Q6. What does this log?",[23,811,812],{"language":16},[26,813,815],{"className":28,"code":814,"language":16,"meta":30,"style":30},"const rgb = [255, 165, 0];\nconst [, green] = rgb;\nconsole.log(green);\n",[32,816,817,843,860],{"__ignoreMap":30},[35,818,819,821,824,826,828,831,833,836,838,841],{"class":37,"line":38},[35,820,42],{"class":41},[35,822,823],{"class":45}," rgb",[35,825,49],{"class":41},[35,827,53],{"class":52},[35,829,830],{"class":45},"255",[35,832,59],{"class":52},[35,834,835],{"class":45},"165",[35,837,59],{"class":52},[35,839,840],{"class":45},"0",[35,842,70],{"class":52},[35,844,845,847,850,853,855,857],{"class":37,"line":73},[35,846,42],{"class":41},[35,848,849],{"class":52}," [, ",[35,851,852],{"class":45},"green",[35,854,88],{"class":52},[35,856,91],{"class":41},[35,858,859],{"class":52}," rgb;\n",[35,861,862,864,866],{"class":37,"line":97},[35,863,100],{"class":52},[35,865,104],{"class":103},[35,867,868],{"class":52},"(green);\n",[109,870,872,878,884,890],{"className":871},[112],[114,873,875,877],{"className":874},[117],[119,876],{"disabled":121,"type":122}," 165",[114,879,881,883],{"className":880},[117],[119,882],{"disabled":121,"type":122}," 255",[114,885,887,889],{"className":886},[117],[119,888],{"disabled":121,"type":122}," 0",[114,891,893,406],{"className":892},[117],[119,894],{"disabled":121,"type":122},[146,896,897,899,904],{},[149,898,151],{},[153,900,901,903],{},[156,902,158],{}," A — 165",[153,905,906,141,908,910,911,914,915,917,918,921,922,925],{},[156,907,164],{},[156,909,297],{}," A leading comma with nothing before it is a valid \"elision\" — it holds the position for ",[32,912,913],{},"rgb[0]"," without binding it to any name, so the next identifier, ",[32,916,852],{},", lands on ",[32,919,920],{},"rgb[1]",". This is the standard idiom for skipping array elements you don't need. B would be the answer only if the elision were ignored entirely; D would be the answer if the pattern had too few slots for ",[32,923,924],{},"rgb",".",[14,927,928,932,1015,1042],{"language":16},[18,929,931],{"id":930},"q7-what-does-this-log","Q7. What does this log?",[23,933,934],{"language":16},[26,935,937],{"className":28,"code":936,"language":16,"meta":30,"style":30},"const scores = [95, 88, 72, 60];\nconst [top, ...rest] = scores;\nconsole.log(rest.length, Array.isArray(rest));\n",[32,938,939,970,994],{"__ignoreMap":30},[35,940,941,943,946,948,950,953,955,958,960,963,965,968],{"class":37,"line":38},[35,942,42],{"class":41},[35,944,945],{"class":45}," scores",[35,947,49],{"class":41},[35,949,53],{"class":52},[35,951,952],{"class":45},"95",[35,954,59],{"class":52},[35,956,957],{"class":45},"88",[35,959,59],{"class":52},[35,961,962],{"class":45},"72",[35,964,59],{"class":52},[35,966,967],{"class":45},"60",[35,969,70],{"class":52},[35,971,972,974,976,979,981,984,987,989,991],{"class":37,"line":73},[35,973,42],{"class":41},[35,975,53],{"class":52},[35,977,978],{"class":45},"top",[35,980,59],{"class":52},[35,982,983],{"class":41},"...",[35,985,986],{"class":45},"rest",[35,988,88],{"class":52},[35,990,91],{"class":41},[35,992,993],{"class":52}," scores;\n",[35,995,996,998,1000,1003,1006,1009,1012],{"class":37,"line":97},[35,997,100],{"class":52},[35,999,104],{"class":103},[35,1001,1002],{"class":52},"(rest.",[35,1004,1005],{"class":45},"length",[35,1007,1008],{"class":52},", Array.",[35,1010,1011],{"class":103},"isArray",[35,1013,1014],{"class":52},"(rest));\n",[109,1016,1018,1024,1030,1036],{"className":1017},[112],[114,1019,1021,1023],{"className":1020},[117],[119,1022],{"disabled":121,"type":122}," 4 true",[114,1025,1027,1029],{"className":1026},[117],[119,1028],{"disabled":121,"type":122}," 3 false",[114,1031,1033,1035],{"className":1032},[117],[119,1034],{"disabled":121,"type":122}," 3 true",[114,1037,1039,1041],{"className":1038},[117],[119,1040],{"disabled":121,"type":122}," undefined true",[146,1043,1044,1046,1051],{},[149,1045,151],{},[153,1047,1048,1050],{},[156,1049,158],{}," C — 3 true",[153,1052,1053,141,1055,1057,1058,1061,1062,1065,1066,1068,1069,925],{},[156,1054,164],{},[156,1056,297],{}," The rest pattern ",[32,1059,1060],{},"...rest"," collects every remaining element — here, three of the four — into a genuinely new ",[32,1063,1064],{},"Array"," instance, regardless of how many items it ends up holding (even zero). B is wrong because rest destructuring always produces a real array, never an array-like or plain object. A miscounts by including ",[32,1067,978],{},"'s element in ",[32,1070,986],{},[14,1072,1073,1077,1143,1170],{"language":16},[18,1074,1076],{"id":1075},"q8-what-does-this-log","Q8. What does this log?",[23,1078,1079],{"language":16},[26,1080,1082],{"className":28,"code":1081,"language":16,"meta":30,"style":30},"const user = { id: 1, name: 'Kim', role: 'admin', active: true };\nconst { id, ...meta } = user;\nconsole.log(meta);\n",[32,1083,1084,1114,1134],{"__ignoreMap":30},[35,1085,1086,1088,1090,1092,1094,1096,1098,1101,1104,1107,1110,1112],{"class":37,"line":38},[35,1087,42],{"class":41},[35,1089,205],{"class":45},[35,1091,49],{"class":41},[35,1093,210],{"class":52},[35,1095,682],{"class":45},[35,1097,216],{"class":52},[35,1099,1100],{"class":219},"'Kim'",[35,1102,1103],{"class":52},", role: ",[35,1105,1106],{"class":219},"'admin'",[35,1108,1109],{"class":52},", active: ",[35,1111,688],{"class":45},[35,1113,223],{"class":52},[35,1115,1116,1118,1120,1122,1124,1126,1128,1130,1132],{"class":37,"line":73},[35,1117,42],{"class":41},[35,1119,230],{"class":52},[35,1121,238],{"class":45},[35,1123,59],{"class":52},[35,1125,983],{"class":41},[35,1127,714],{"class":45},[35,1129,241],{"class":52},[35,1131,91],{"class":41},[35,1133,246],{"class":52},[35,1135,1136,1138,1140],{"class":37,"line":97},[35,1137,100],{"class":52},[35,1139,104],{"class":103},[35,1141,1142],{"class":52},"(meta);\n",[109,1144,1146,1152,1158,1164],{"className":1145},[112],[114,1147,1149,1151],{"className":1148},[117],[119,1150],{"disabled":121,"type":122}," { id: 1, name: 'Kim', role: 'admin', active: true }",[114,1153,1155,1157],{"className":1154},[117],[119,1156],{"disabled":121,"type":122}," {}",[114,1159,1161,1163],{"className":1160},[117],[119,1162],{"disabled":121,"type":122}," TypeError: Rest element must be last",[114,1165,1167,1169],{"className":1166},[117],[119,1168],{"disabled":121,"type":122}," { name: 'Kim', role: 'admin', active: true }",[146,1171,1172,1174,1179],{},[149,1173,151],{},[153,1175,1176,1178],{},[156,1177,158],{}," D — { name: 'Kim', role: 'admin', active: true }",[153,1180,1181,141,1183,1185,1186,1189,1190,1192,1193,1195,1196,1199],{},[156,1182,164],{},[156,1184,297],{}," Object rest works like array rest: it gathers every enumerable own property ",[300,1187,1188],{},"not already claimed"," by an earlier name in the pattern into a fresh plain object. ",[32,1191,238],{}," was explicitly pulled out, so it's excluded from ",[32,1194,714],{},". A is the mistake of assuming rest re-includes everything; C confuses the object-rest constraint (rest must be the ",[300,1197,1198],{},"last"," property in the pattern, which it correctly is here) with an actual error.",[14,1201,1202,1217,1244],{},[18,1203,1205,1206,1209,1210,1213,1214,1216],{"id":1204},"q9-in-const-a-b-arr-and-const-c-arr-99-what-role-does-the-play-in-each-statement-respectively","Q9. In ",[32,1207,1208],{},"const [a, ...b] = arr;"," and ",[32,1211,1212],{},"const c = [...arr, 99];",", what role does the ",[32,1215,983],{}," play in each statement, respectively?",[109,1218,1220,1226,1232,1238],{"className":1219},[112],[114,1221,1223,1225],{"className":1222},[117],[119,1224],{"disabled":121,"type":122}," Rest syntax, then spread syntax",[114,1227,1229,1231],{"className":1228},[117],[119,1230],{"disabled":121,"type":122}," Spread syntax, then rest syntax",[114,1233,1235,1237],{"className":1234},[117],[119,1236],{"disabled":121,"type":122}," Rest syntax in both cases",[114,1239,1241,1243],{"className":1240},[117],[119,1242],{"disabled":121,"type":122}," Spread syntax in both cases",[146,1245,1246,1248,1253],{},[149,1247,151],{},[153,1249,1250,1252],{},[156,1251,158],{}," A — Rest syntax, then spread syntax",[153,1254,1255,141,1257,1259,1260,1262,1263,1265,1266,1269,1270,1272],{},[156,1256,164],{},[156,1258,297],{}," The token ",[32,1261,983],{}," is overloaded: on the left side of a destructuring assignment it's the ",[300,1264,986],{}," pattern, collecting leftover elements into a new binding; inside an array or object literal (or a function call) it's ",[300,1267,1268],{},"spread",", expanding an existing iterable's elements into that new context. Same three dots, opposite direction of data flow — memorize it by which side of ",[32,1271,91],{}," (or which kind of expression) you're looking at, not by the symbol itself.",[14,1274,1275,1279,1351,1378],{"language":16},[18,1276,1278],{"id":1277},"q10-what-happens-when-this-code-runs","Q10. What happens when this code runs?",[23,1280,1281],{"language":16},[26,1282,1284],{"className":28,"code":1283,"language":16,"meta":30,"style":30},"const a = { x: 1 };\nconst b = null;\nconst { x, y } = a;\nconst { z } = b;\n",[32,1285,1286,1302,1316,1335],{"__ignoreMap":30},[35,1287,1288,1290,1293,1295,1298,1300],{"class":37,"line":38},[35,1289,42],{"class":41},[35,1291,1292],{"class":45}," a",[35,1294,49],{"class":41},[35,1296,1297],{"class":52}," { x: ",[35,1299,682],{"class":45},[35,1301,223],{"class":52},[35,1303,1304,1306,1309,1311,1314],{"class":37,"line":73},[35,1305,42],{"class":41},[35,1307,1308],{"class":45}," b",[35,1310,49],{"class":41},[35,1312,1313],{"class":45}," null",[35,1315,535],{"class":52},[35,1317,1318,1320,1322,1324,1326,1328,1330,1332],{"class":37,"line":97},[35,1319,42],{"class":41},[35,1321,230],{"class":52},[35,1323,80],{"class":45},[35,1325,59],{"class":52},[35,1327,85],{"class":45},[35,1329,241],{"class":52},[35,1331,91],{"class":41},[35,1333,1334],{"class":52}," a;\n",[35,1336,1337,1339,1341,1344,1346,1348],{"class":37,"line":543},[35,1338,42],{"class":41},[35,1340,230],{"class":52},[35,1342,1343],{"class":45},"z",[35,1345,241],{"class":52},[35,1347,91],{"class":41},[35,1349,1350],{"class":52}," b;\n",[109,1352,1354,1360,1366,1372],{"className":1353},[112],[114,1355,1357,1359],{"className":1356},[117],[119,1358],{"disabled":121,"type":122}," Both lines run fine; y is undefined, z is undefined",[114,1361,1363,1365],{"className":1362},[117],[119,1364],{"disabled":121,"type":122}," Line 3 runs fine (y is undefined); line 4 throws TypeError because null cannot be destructured",[114,1367,1369,1371],{"className":1368},[117],[119,1370],{"disabled":121,"type":122}," Both lines throw TypeError",[114,1373,1375,1377],{"className":1374},[117],[119,1376],{"disabled":121,"type":122}," Line 3 throws ReferenceError; line 4 runs fine",[146,1379,1380,1382,1387],{},[149,1381,151],{},[153,1383,1384,1386],{},[156,1385,158],{}," B — Line 3 runs fine (y is undefined); line 4 throws TypeError because null cannot be destructured",[153,1388,1389,141,1391,1394,1395,1397,1398,1400,1401,1403,1404,1406,1407,1409],{},[156,1390,164],{},[156,1392,1393],{},"Safety."," These two failure modes are easy to conflate but are opposites: destructuring an object for a key it doesn't have simply yields ",[32,1396,565],{}," for that binding (no error — ",[32,1399,396],{}," is a valid object, ",[32,1402,85],{}," just isn't one of its properties). Destructuring ",[32,1405,559],{}," (or ",[32,1408,565],{},") itself is different — the engine must first coerce the right-hand side to an object to read properties off it, and that coercion step throws for nullish values. A wrongly treats both as the harmless \"missing key\" case.",[14,1411,1412,1416,1465,1492],{"language":16},[18,1413,1415],{"id":1414},"q11-what-does-this-log","Q11. What does this log?",[23,1417,1418],{"language":16},[26,1419,1421],{"className":28,"code":1420,"language":16,"meta":30,"style":30},"let a = 1, b = 2;\n[a, b] = [b, a];\nconsole.log(a, b);\n",[32,1422,1423,1446,1456],{"__ignoreMap":30},[35,1424,1425,1428,1431,1433,1436,1439,1441,1444],{"class":37,"line":38},[35,1426,1427],{"class":41},"let",[35,1429,1430],{"class":52}," a ",[35,1432,91],{"class":41},[35,1434,1435],{"class":45}," 1",[35,1437,1438],{"class":52},", b ",[35,1440,91],{"class":41},[35,1442,1443],{"class":45}," 2",[35,1445,535],{"class":52},[35,1447,1448,1451,1453],{"class":37,"line":73},[35,1449,1450],{"class":52},"[a, b] ",[35,1452,91],{"class":41},[35,1454,1455],{"class":52}," [b, a];\n",[35,1457,1458,1460,1462],{"class":37,"line":97},[35,1459,100],{"class":52},[35,1461,104],{"class":103},[35,1463,1464],{"class":52},"(a, b);\n",[109,1466,1468,1474,1480,1486],{"className":1467},[112],[114,1469,1471,1473],{"className":1470},[117],[119,1472],{"disabled":121,"type":122}," 1 2",[114,1475,1477,1479],{"className":1476},[117],[119,1478],{"disabled":121,"type":122}," 1 1",[114,1481,1483,1485],{"className":1482},[117],[119,1484],{"disabled":121,"type":122}," 2 1",[114,1487,1489,1491],{"className":1488},[117],[119,1490],{"disabled":121,"type":122}," ReferenceError: Invalid destructuring assignment target",[146,1493,1494,1496,1501],{},[149,1495,151],{},[153,1497,1498,1500],{},[156,1499,158],{}," C — 2 1",[153,1502,1503,141,1505,1507,1508,1511,1512,1515,1516,1519,1520,1209,1523,1525,1526,1209,1528,1530],{},[156,1504,164],{},[156,1506,297],{}," The right-hand side ",[32,1509,1510],{},"[b, a]"," is fully evaluated first, building a temporary array ",[32,1513,1514],{},"[2, 1]"," from the ",[300,1517,1518],{},"current"," values of ",[32,1521,1522],{},"b",[32,1524,396],{},"; only then does array destructuring assign its elements back into ",[32,1527,396],{},[32,1529,1522],{}," in order. This is the standard no-temp-variable swap idiom — no intermediate variable is needed because the RHS snapshot happens before any reassignment occurs. B is the mistake of assuming the assignments happen sequentially and interfere with each other.",[14,1532,1533,1537,1598,1625],{"language":16},[18,1534,1536],{"id":1535},"q12-what-happens-when-this-runs","Q12. What happens when this runs?",[23,1538,1539],{"language":16},[26,1540,1542],{"className":28,"code":1541,"language":16,"meta":30,"style":30},"function createUser({ id, name }) {\n  return `${id}-${name}`;\n}\nconsole.log(createUser());\n",[32,1543,1544,1562,1580,1584],{"__ignoreMap":30},[35,1545,1546,1548,1551,1553,1555,1557,1559],{"class":37,"line":38},[35,1547,468],{"class":41},[35,1549,1550],{"class":103}," createUser",[35,1552,474],{"class":52},[35,1554,238],{"class":357},[35,1556,59],{"class":52},[35,1558,233],{"class":357},[35,1560,1561],{"class":52}," }) {\n",[35,1563,1564,1566,1568,1570,1573,1575,1578],{"class":37,"line":73},[35,1565,514],{"class":41},[35,1567,517],{"class":219},[35,1569,238],{"class":52},[35,1571,1572],{"class":219},"}-${",[35,1574,233],{"class":52},[35,1576,1577],{"class":219},"}`",[35,1579,535],{"class":52},[35,1581,1582],{"class":37,"line":97},[35,1583,540],{"class":52},[35,1585,1586,1588,1590,1592,1595],{"class":37,"line":543},[35,1587,100],{"class":52},[35,1589,104],{"class":103},[35,1591,550],{"class":52},[35,1593,1594],{"class":103},"createUser",[35,1596,1597],{"class":52},"());\n",[109,1599,1601,1607,1613,1619],{"className":1600},[112],[114,1602,1604,1606],{"className":1603},[117],[119,1605],{"disabled":121,"type":122}," undefined-undefined",[114,1608,1610,1612],{"className":1609},[117],[119,1611],{"disabled":121,"type":122}," TypeError: Cannot destructure property 'id' of 'undefined' as it is undefined",[114,1614,1616,1618],{"className":1615},[117],[119,1617],{"disabled":121,"type":122}," ReferenceError: id is not defined",[114,1620,1622,1624],{"className":1621},[117],[119,1623],{"disabled":121,"type":122}," 0-undefined",[146,1626,1627,1629,1634],{},[149,1628,151],{},[153,1630,1631,1633],{},[156,1632,158],{}," B — TypeError: Cannot destructure property 'id' of 'undefined' as it is undefined",[153,1635,1636,141,1638,1640,1641,1644,1645,1647,1648,1650,1651,1653,1654,1656,1657,1660],{},[156,1637,164],{},[156,1639,1393],{}," Calling ",[32,1642,1643],{},"createUser()"," with no argument means the parameter itself is ",[32,1646,565],{}," — and destructuring ",[32,1649,565],{}," throws for the same reason destructuring ",[32,1652,559],{}," does, before the function body ever runs. A is the tempting guess for anyone assuming missing parameters just cascade into ",[32,1655,565],{}," fields, but that only holds once you're safely destructuring a ",[300,1658,1659],{},"real"," object.",[14,1662,1663,1667,1726,1750],{"language":16},[18,1664,1666],{"id":1665},"q13-what-happens-when-this-runs","Q13. What happens when this runs?",[23,1668,1669],{"language":16},[26,1670,1672],{"className":28,"code":1671,"language":16,"meta":30,"style":30},"function createUser({ id, name } = {}) {\n  return `${id}-${name}`;\n}\nconsole.log(createUser());\n",[32,1673,1674,1694,1710,1714],{"__ignoreMap":30},[35,1675,1676,1678,1680,1682,1684,1686,1688,1690,1692],{"class":37,"line":38},[35,1677,468],{"class":41},[35,1679,1550],{"class":103},[35,1681,474],{"class":52},[35,1683,238],{"class":357},[35,1685,59],{"class":52},[35,1687,233],{"class":357},[35,1689,241],{"class":52},[35,1691,91],{"class":41},[35,1693,509],{"class":52},[35,1695,1696,1698,1700,1702,1704,1706,1708],{"class":37,"line":73},[35,1697,514],{"class":41},[35,1699,517],{"class":219},[35,1701,238],{"class":52},[35,1703,1572],{"class":219},[35,1705,233],{"class":52},[35,1707,1577],{"class":219},[35,1709,535],{"class":52},[35,1711,1712],{"class":37,"line":97},[35,1713,540],{"class":52},[35,1715,1716,1718,1720,1722,1724],{"class":37,"line":543},[35,1717,100],{"class":52},[35,1719,104],{"class":103},[35,1721,550],{"class":52},[35,1723,1594],{"class":103},[35,1725,1597],{"class":52},[109,1727,1729,1734,1739,1745],{"className":1728},[112],[114,1730,1732,1612],{"className":1731},[117],[119,1733],{"disabled":121,"type":122},[114,1735,1737,1157],{"className":1736},[117],[119,1738],{"disabled":121,"type":122},[114,1740,1742,1744],{"className":1741},[117],[119,1743],{"disabled":121,"type":122}," 0-0",[114,1746,1748,1606],{"className":1747},[117],[119,1749],{"disabled":121,"type":122},[146,1751,1752,1754,1759],{},[149,1753,151],{},[153,1755,1756,1758],{},[156,1757,158],{}," D — undefined-undefined",[153,1760,1761,141,1763,1765,1766,1769,1770,1773,1774,1776,1777,1209,1779,1781,1782,1785,1786,1788,1789,1792,1793,1795],{},[156,1762,164],{},[156,1764,1393],{}," Adding ",[32,1767,1768],{},"= {}"," as the ",[300,1771,1772],{},"parameter's own"," default only fires when the argument itself is ",[32,1775,565],{}," — exactly the case of calling with no argument at all. That substitutes an empty object before destructuring runs, so ",[32,1778,238],{},[32,1780,233],{}," are destructured off ",[32,1783,1784],{},"{}"," and each comes out ",[32,1787,565],{}," (not an error) rather than the whole call throwing. This is the standard fix for the crash in the previous question; A describes what happens ",[300,1790,1791],{},"without"," the ",[32,1794,1768],{}," guard.",[14,1797,1798,1802,1907,1945],{"language":16},[18,1799,1801],{"id":1800},"q14-what-does-this-log","Q14. What does this log?",[23,1803,1804],{"language":16},[26,1805,1807],{"className":28,"code":1806,"language":16,"meta":30,"style":30},"function sum(a, b, c) {\n  return a + b + c;\n}\nconst nums = [1, 2, 3];\nconsole.log(sum(...nums), [...nums, 4]);\n",[32,1808,1809,1832,1849,1853,1878],{"__ignoreMap":30},[35,1810,1811,1813,1816,1818,1820,1822,1824,1826,1829],{"class":37,"line":38},[35,1812,468],{"class":41},[35,1814,1815],{"class":103}," sum",[35,1817,550],{"class":52},[35,1819,396],{"class":357},[35,1821,59],{"class":52},[35,1823,1522],{"class":357},[35,1825,59],{"class":52},[35,1827,1828],{"class":357},"c",[35,1830,1831],{"class":52},") {\n",[35,1833,1834,1836,1838,1841,1844,1846],{"class":37,"line":73},[35,1835,514],{"class":41},[35,1837,1430],{"class":52},[35,1839,1840],{"class":41},"+",[35,1842,1843],{"class":52}," b ",[35,1845,1840],{"class":41},[35,1847,1848],{"class":52}," c;\n",[35,1850,1851],{"class":37,"line":97},[35,1852,540],{"class":52},[35,1854,1855,1857,1860,1862,1864,1866,1868,1871,1873,1876],{"class":37,"line":543},[35,1856,42],{"class":41},[35,1858,1859],{"class":45}," nums",[35,1861,49],{"class":41},[35,1863,53],{"class":52},[35,1865,682],{"class":45},[35,1867,59],{"class":52},[35,1869,1870],{"class":45},"2",[35,1872,59],{"class":52},[35,1874,1875],{"class":45},"3",[35,1877,70],{"class":52},[35,1879,1880,1882,1884,1886,1889,1891,1893,1896,1898,1901,1904],{"class":37,"line":705},[35,1881,100],{"class":52},[35,1883,104],{"class":103},[35,1885,550],{"class":52},[35,1887,1888],{"class":103},"sum",[35,1890,550],{"class":52},[35,1892,983],{"class":41},[35,1894,1895],{"class":52},"nums), [",[35,1897,983],{"class":41},[35,1899,1900],{"class":52},"nums, ",[35,1902,1903],{"class":45},"4",[35,1905,1906],{"class":52},"]);\n",[109,1908,1910,1919,1929,1937],{"className":1909},[112],[114,1911,1913,1915,1916],{"className":1912},[117],[119,1914],{"disabled":121,"type":122}," 6 ",[35,1917,1918],{},"1, 2, 3, 4",[114,1920,1922,141,1924,141,1927],{"className":1921},[117],[119,1923],{"disabled":121,"type":122},[35,1925,1926],{},"1, 2, 3",[35,1928,1918],{},[114,1930,1932,1934,1935],{"className":1931},[117],[119,1933],{"disabled":121,"type":122}," NaN ",[35,1936,1918],{},[114,1938,1940,1915,1942],{"className":1939},[117],[119,1941],{"disabled":121,"type":122},[35,1943,1944],{},"4, 1, 2, 3",[146,1946,1947,1949,1956],{},[149,1948,151],{},[153,1950,1951,1953,1954],{},[156,1952,158],{}," A — 6 ",[35,1955,1918],{},[153,1957,1958,141,1960,1962,1963,1966,1967,1970,1971,1974,1975,1978,1979,1982],{},[156,1959,164],{},[156,1961,297],{}," The same ",[32,1964,1965],{},"...nums"," spread means different things purely by context: inside a call's argument list it unpacks the array into three separate positional arguments (",[32,1968,1969],{},"sum(1, 2, 3)"," → ",[32,1972,1973],{},"6","), while inside an array literal it unpacks the array's elements in place, so ",[32,1976,1977],{},"[...nums, 4]"," produces ",[32,1980,1981],{},"[1, 2, 3, 4]"," with the new element appended after. B assumes the call spread packs into a single array argument instead of unpacking it.",[14,1984,1985,1989,2066,2096],{"language":16},[18,1986,1988],{"id":1987},"q15-what-does-this-log","Q15. What does this log?",[23,1990,1991],{"language":16},[26,1992,1994],{"className":28,"code":1993,"language":16,"meta":30,"style":30},"const original = { name: 'A', tags: ['x', 'y'] };\nconst copy = { ...original };\ncopy.tags.push('z');\nconsole.log(original.tags);\n",[32,1995,1996,2025,2041,2057],{"__ignoreMap":30},[35,1997,1998,2000,2003,2005,2008,2011,2014,2017,2019,2022],{"class":37,"line":38},[35,1999,42],{"class":41},[35,2001,2002],{"class":45}," original",[35,2004,49],{"class":41},[35,2006,2007],{"class":52}," { name: ",[35,2009,2010],{"class":219},"'A'",[35,2012,2013],{"class":52},", tags: [",[35,2015,2016],{"class":219},"'x'",[35,2018,59],{"class":52},[35,2020,2021],{"class":219},"'y'",[35,2023,2024],{"class":52},"] };\n",[35,2026,2027,2029,2032,2034,2036,2038],{"class":37,"line":73},[35,2028,42],{"class":41},[35,2030,2031],{"class":45}," copy",[35,2033,49],{"class":41},[35,2035,230],{"class":52},[35,2037,983],{"class":41},[35,2039,2040],{"class":52},"original };\n",[35,2042,2043,2046,2049,2051,2054],{"class":37,"line":97},[35,2044,2045],{"class":52},"copy.tags.",[35,2047,2048],{"class":103},"push",[35,2050,550],{"class":52},[35,2052,2053],{"class":219},"'z'",[35,2055,2056],{"class":52},");\n",[35,2058,2059,2061,2063],{"class":37,"line":543},[35,2060,100],{"class":52},[35,2062,104],{"class":103},[35,2064,2065],{"class":52},"(original.tags);\n",[109,2067,2069,2077,2085,2091],{"className":2068},[112],[114,2070,2072,141,2074],{"className":2071},[117],[119,2073],{"disabled":121,"type":122},[35,2075,2076],{},"'x', 'y'",[114,2078,2080,141,2082],{"className":2079},[117],[119,2081],{"disabled":121,"type":122},[35,2083,2084],{},"'x', 'y', 'z'",[114,2086,2088,2090],{"className":2087},[117],[119,2089],{"disabled":121,"type":122}," TypeError: Cannot push to a spread property",[114,2092,2094,406],{"className":2093},[117],[119,2095],{"disabled":121,"type":122},[146,2097,2098,2100,2107],{},[149,2099,151],{},[153,2101,2102,2104,2105],{},[156,2103,158],{}," B — ",[35,2106,2084],{},[153,2108,2109,141,2111,2113,2114,2117,2118,1209,2121,2124,2125,2128,2129,2132],{},[156,2110,164],{},[156,2112,1393],{}," Object spread is a ",[300,2115,2116],{},"shallow"," copy — it copies each top-level property's value, and for a property whose value is itself an object or array, that \"value\" is a reference. ",[32,2119,2120],{},"copy.tags",[32,2122,2123],{},"original.tags"," point at the exact same array in memory, so mutating one through ",[32,2126,2127],{},".push"," is visible through the other. A is the mistake of assuming spread deep-clones; avoiding this bug requires an explicit deep clone (e.g. ",[32,2130,2131],{},"structuredClone",") or spreading the nested array too.",[14,2134,2135,2139,2183,2210],{"language":16},[18,2136,2138],{"id":2137},"q16-what-does-this-log","Q16. What does this log?",[23,2140,2141],{"language":16},[26,2142,2144],{"className":28,"code":2143,"language":16,"meta":30,"style":30},"const emoji = '👍A';\nconsole.log(emoji.length, [...emoji].length);\n",[32,2145,2146,2160],{"__ignoreMap":30},[35,2147,2148,2150,2153,2155,2158],{"class":37,"line":38},[35,2149,42],{"class":41},[35,2151,2152],{"class":45}," emoji",[35,2154,49],{"class":41},[35,2156,2157],{"class":219}," '👍A'",[35,2159,535],{"class":52},[35,2161,2162,2164,2166,2169,2171,2174,2176,2179,2181],{"class":37,"line":73},[35,2163,100],{"class":52},[35,2165,104],{"class":103},[35,2167,2168],{"class":52},"(emoji.",[35,2170,1005],{"class":45},[35,2172,2173],{"class":52},", [",[35,2175,983],{"class":41},[35,2177,2178],{"class":52},"emoji].",[35,2180,1005],{"class":45},[35,2182,2056],{"class":52},[109,2184,2186,2192,2198,2204],{"className":2185},[112],[114,2187,2189,2191],{"className":2188},[117],[119,2190],{"disabled":121,"type":122}," 2 2",[114,2193,2195,2197],{"className":2194},[117],[119,2196],{"disabled":121,"type":122}," 3 3",[114,2199,2201,2203],{"className":2200},[117],[119,2202],{"disabled":121,"type":122}," 3 2",[114,2205,2207,2209],{"className":2206},[117],[119,2208],{"disabled":121,"type":122}," 2 3",[146,2211,2212,2214,2219],{},[149,2213,151],{},[153,2215,2216,2218],{},[156,2217,158],{}," C — 3 2",[153,2220,2221,141,2223,141,2226,2229,2230,361,2233,2236,2237,2239,2240,2242,2243,2246,2247,2250,2251,2254,2255,2257,2258,2261,2262,2265],{},[156,2222,164],{},[156,2224,2225],{},"Portability.",[32,2227,2228],{},".length"," counts UTF-16 ",[300,2231,2232],{},"code units",[32,2234,2235],{},"👍"," lies outside the Basic Multilingual Plane, so it's stored as a surrogate pair (2 code units), plus ",[32,2238,2010],{}," (1 unit) gives ",[32,2241,1875],{},". Spreading a string, however, iterates by ",[300,2244,2245],{},"Unicode code point"," — the string iterator correctly recognizes the surrogate pair as one character — so ",[32,2248,2249],{},"[...emoji]"," yields ",[32,2252,2253],{},"['👍', 'A']",", length ",[32,2256,1870],{},". This mismatch is why naive indexing (",[32,2259,2260],{},"str[i]",") can slice a surrogate pair in half while spread\u002F",[32,2263,2264],{},"for...of"," never do.",[14,2267,2268,2272,2369,2399],{"language":16},[18,2269,2271],{"id":2270},"q17-what-does-this-log","Q17. What does this log?",[23,2273,2274],{"language":16},[26,2275,2277],{"className":28,"code":2276,"language":16,"meta":30,"style":30},"const map = new Map([['a', 1], ['b', 2]]);\nconst obj = { a: 1, b: 2 };\nconsole.log([...map].length);\nconsole.log([...obj]);\n",[32,2278,2279,2317,2338,2356],{"__ignoreMap":30},[35,2280,2281,2283,2286,2288,2291,2294,2297,2300,2302,2304,2307,2310,2312,2314],{"class":37,"line":38},[35,2282,42],{"class":41},[35,2284,2285],{"class":45}," map",[35,2287,49],{"class":41},[35,2289,2290],{"class":41}," new",[35,2292,2293],{"class":103}," Map",[35,2295,2296],{"class":52},"([[",[35,2298,2299],{"class":219},"'a'",[35,2301,59],{"class":52},[35,2303,682],{"class":45},[35,2305,2306],{"class":52},"], [",[35,2308,2309],{"class":219},"'b'",[35,2311,59],{"class":52},[35,2313,1870],{"class":45},[35,2315,2316],{"class":52},"]]);\n",[35,2318,2319,2321,2324,2326,2329,2331,2334,2336],{"class":37,"line":73},[35,2320,42],{"class":41},[35,2322,2323],{"class":45}," obj",[35,2325,49],{"class":41},[35,2327,2328],{"class":52}," { a: ",[35,2330,682],{"class":45},[35,2332,2333],{"class":52},", b: ",[35,2335,1870],{"class":45},[35,2337,223],{"class":52},[35,2339,2340,2342,2344,2347,2349,2352,2354],{"class":37,"line":97},[35,2341,100],{"class":52},[35,2343,104],{"class":103},[35,2345,2346],{"class":52},"([",[35,2348,983],{"class":41},[35,2350,2351],{"class":52},"map].",[35,2353,1005],{"class":45},[35,2355,2056],{"class":52},[35,2357,2358,2360,2362,2364,2366],{"class":37,"line":543},[35,2359,100],{"class":52},[35,2361,104],{"class":103},[35,2363,2346],{"class":52},[35,2365,983],{"class":41},[35,2367,2368],{"class":52},"obj]);\n",[109,2370,2372,2381,2387,2393],{"className":2371},[112],[114,2373,2375,2377,2378],{"className":2374},[117],[119,2376],{"disabled":121,"type":122}," 2, then ",[35,2379,2380],{},"{ a: 1 }, { b: 2 }",[114,2382,2384,2386],{"className":2383},[117],[119,2385],{"disabled":121,"type":122}," 2, then TypeError: obj is not iterable",[114,2388,2390,2392],{"className":2389},[117],[119,2391],{"disabled":121,"type":122}," 4, then { a: 1, b: 2 }",[114,2394,2396,2398],{"className":2395},[117],[119,2397],{"disabled":121,"type":122}," TypeError on both lines",[146,2400,2401,2403,2408],{},[149,2402,151],{},[153,2404,2405,2407],{},[156,2406,158],{}," B — 2, then TypeError: obj is not iterable",[153,2409,2410,141,2412,141,2414,2417,2418,2421,2422,2424,2425,2428,2429,2432,2433,2436,2437,2440,2441,2444],{},[156,2411,164],{},[156,2413,428],{},[32,2415,2416],{},"Map"," implements the iterable protocol, so spreading it into an array yields its ",[32,2419,2420],{},"[key, value]"," entries — two entries, length ",[32,2423,1870],{},". A plain object does ",[300,2426,2427],{},"not"," implement ",[32,2430,2431],{},"Symbol.iterator"," at all; it only has enumerable own properties, which object spread (",[32,2434,2435],{},"{ ...obj }",") knows how to read but ",[300,2438,2439],{},"array"," spread (",[32,2442,2443],{},"[...obj]",") does not — array spread strictly requires an iterable, so it throws. This is the key distinction: object spread reads enumerable properties, array\u002Fcall spread requires iterability.",[14,2446,2447,2451,2533,2560],{"language":16},[18,2448,2450],{"id":2449},"q18-what-does-this-log","Q18. What does this log?",[23,2452,2453],{"language":16},[26,2454,2456],{"className":28,"code":2455,"language":16,"meta":30,"style":30},"const defaults = { theme: 'light', size: 'md' };\nconst overrides = { size: 'lg' };\nconst final = { ...defaults, size: 'sm', ...overrides };\nconsole.log(final);\n",[32,2457,2458,2481,2498,2524],{"__ignoreMap":30},[35,2459,2460,2462,2465,2467,2470,2473,2476,2479],{"class":37,"line":38},[35,2461,42],{"class":41},[35,2463,2464],{"class":45}," defaults",[35,2466,49],{"class":41},[35,2468,2469],{"class":52}," { theme: ",[35,2471,2472],{"class":219},"'light'",[35,2474,2475],{"class":52},", size: ",[35,2477,2478],{"class":219},"'md'",[35,2480,223],{"class":52},[35,2482,2483,2485,2488,2490,2493,2496],{"class":37,"line":73},[35,2484,42],{"class":41},[35,2486,2487],{"class":45}," overrides",[35,2489,49],{"class":41},[35,2491,2492],{"class":52}," { size: ",[35,2494,2495],{"class":219},"'lg'",[35,2497,223],{"class":52},[35,2499,2500,2502,2505,2507,2509,2511,2514,2517,2519,2521],{"class":37,"line":97},[35,2501,42],{"class":41},[35,2503,2504],{"class":45}," final",[35,2506,49],{"class":41},[35,2508,230],{"class":52},[35,2510,983],{"class":41},[35,2512,2513],{"class":52},"defaults, size: ",[35,2515,2516],{"class":219},"'sm'",[35,2518,59],{"class":52},[35,2520,983],{"class":41},[35,2522,2523],{"class":52},"overrides };\n",[35,2525,2526,2528,2530],{"class":37,"line":543},[35,2527,100],{"class":52},[35,2529,104],{"class":103},[35,2531,2532],{"class":52},"(final);\n",[109,2534,2536,2542,2548,2554],{"className":2535},[112],[114,2537,2539,2541],{"className":2538},[117],[119,2540],{"disabled":121,"type":122}," { theme: 'light', size: 'sm' }",[114,2543,2545,2547],{"className":2544},[117],[119,2546],{"disabled":121,"type":122}," { theme: 'light', size: 'md' }",[114,2549,2551,2553],{"className":2550},[117],[119,2552],{"disabled":121,"type":122}," { theme: 'light', size: 'lg' }",[114,2555,2557,2559],{"className":2556},[117],[119,2558],{"disabled":121,"type":122}," SyntaxError: Duplicate key 'size'",[146,2561,2562,2564,2569],{},[149,2563,151],{},[153,2565,2566,2568],{},[156,2567,158],{}," C — { theme: 'light', size: 'lg' }",[153,2570,2571,141,2573,2575,2576,2579,2580,2583,2584,2586,2587,2590,2591,2593],{},[156,2572,164],{},[156,2574,297],{}," Object literals allow duplicate keys, and later ones simply overwrite earlier ones in strict left-to-right source order — spread just expands into that same sequence of key writes. So ",[32,2577,2578],{},"size"," is written by ",[32,2581,2582],{},"...defaults"," ('md'), then overwritten by the literal ",[32,2585,2516],{},", then overwritten again by ",[32,2588,2589],{},"...overrides"," ('lg'), which appears last and therefore wins. D is wrong because unlike duplicate ",[32,2592,1427],{}," declarations, duplicate object keys are legal JavaScript, not a syntax error.",[14,2595,2596,2600,2667,2702],{"language":16},[18,2597,2599],{"id":2598},"q19-what-does-this-log","Q19. What does this log?",[23,2601,2602],{"language":16},[26,2603,2605],{"className":28,"code":2604,"language":16,"meta":30,"style":30},"const key = 'role';\nconst user = { role: 'admin', id: 42 };\nconst { [key]: value } = user;\nconsole.log(value);\n",[32,2606,2607,2621,2642,2658],{"__ignoreMap":30},[35,2608,2609,2611,2614,2616,2619],{"class":37,"line":38},[35,2610,42],{"class":41},[35,2612,2613],{"class":45}," key",[35,2615,49],{"class":41},[35,2617,2618],{"class":219}," 'role'",[35,2620,535],{"class":52},[35,2622,2623,2625,2627,2629,2632,2634,2637,2640],{"class":37,"line":73},[35,2624,42],{"class":41},[35,2626,205],{"class":45},[35,2628,49],{"class":41},[35,2630,2631],{"class":52}," { role: ",[35,2633,1106],{"class":219},[35,2635,2636],{"class":52},", id: ",[35,2638,2639],{"class":45},"42",[35,2641,223],{"class":52},[35,2643,2644,2646,2649,2652,2654,2656],{"class":37,"line":97},[35,2645,42],{"class":41},[35,2647,2648],{"class":52}," { [key]: ",[35,2650,2651],{"class":45},"value",[35,2653,241],{"class":52},[35,2655,91],{"class":41},[35,2657,246],{"class":52},[35,2659,2660,2662,2664],{"class":37,"line":543},[35,2661,100],{"class":52},[35,2663,104],{"class":103},[35,2665,2666],{"class":52},"(value);\n",[109,2668,2670,2676,2686,2692],{"className":2669},[112],[114,2671,2673,2675],{"className":2672},[117],[119,2674],{"disabled":121,"type":122}," SyntaxError — computed keys cannot appear in a destructuring pattern",[114,2677,2679,2681,2682,2685],{"className":2678},[117],[119,2680],{"disabled":121,"type":122}," undefined, because ",[32,2683,2684],{},"key"," refers to the variable name, not the object's property",[114,2687,2689,2691],{"className":2688},[117],[119,2690],{"disabled":121,"type":122}," 'role' — the destructured value takes the name of the computed key by default",[114,2693,2695,2697,2698,2701],{"className":2694},[117],[119,2696],{"disabled":121,"type":122}," 'admin' — computed property names are valid in destructuring, exactly as in object literals, but they require an explicit ",[32,2699,2700],{},": binding"," (no shorthand form is allowed)",[146,2703,2704,2706,2713],{},[149,2705,151],{},[153,2707,2708,2710,2711,2701],{},[156,2709,158],{}," D — 'admin' — computed property names are valid in destructuring, exactly as in object literals, but they require an explicit ",[32,2712,2700],{},[153,2714,2715,141,2717,2719,2720,2723,2724,2727,2728,2731,2732,2735,2736,2738,2739,2741,2742,2745,2746,2748],{},[156,2716,164],{},[156,2718,428],{}," A common misconception is that computed keys only work in object ",[300,2721,2722],{},"literals",", not on the left side of a destructuring pattern — but ",[32,2725,2726],{},"{ [key]: value } = user"," is valid ES6 syntax: it looks up ",[32,2729,2730],{},"user[key]"," (",[32,2733,2734],{},"user.role",", i.e. ",[32,2737,1106],{},") and binds it to ",[32,2740,2651],{},". The real, genuine limitation is that destructuring has no shorthand form for computed keys — you cannot write ",[32,2743,2744],{},"{ [key] }"," and expect a binding named after the key's runtime value, since JavaScript has no way to turn a dynamic string into an identifier name; the ",[32,2747,2700],{}," is mandatory. A states the actual misconception as fact; C confuses the computed key's name with its resolved value.",[14,2750,2751,2755,2866,2869,2896],{"language":16},[18,2752,2754],{"id":2753},"q20-a-component-factory-function-takes-six-parameters-several-of-which-are-optional-and-are-frequently-skipped-or-passed-out-of-order-by-callers","Q20. A component factory function takes six parameters, several of which are optional and are frequently skipped or passed out of order by callers.",[23,2756,2757],{"language":16},[26,2758,2760],{"className":28,"code":2759,"language":16,"meta":30,"style":30},"function createWidget(id, name, color, size, isVisible, onClick) { \u002F* ... *\u002F }\n\nfunction createWidget({ id, name, color = 'blue', size = 'md', isVisible = true, onClick } = {}) { \u002F* ... *\u002F }\n",[32,2761,2762,2806,2811],{"__ignoreMap":30},[35,2763,2764,2766,2769,2771,2773,2775,2777,2779,2782,2784,2786,2788,2791,2793,2796,2799,2803],{"class":37,"line":38},[35,2765,468],{"class":41},[35,2767,2768],{"class":103}," createWidget",[35,2770,550],{"class":52},[35,2772,238],{"class":357},[35,2774,59],{"class":52},[35,2776,233],{"class":357},[35,2778,59],{"class":52},[35,2780,2781],{"class":357},"color",[35,2783,59],{"class":52},[35,2785,2578],{"class":357},[35,2787,59],{"class":52},[35,2789,2790],{"class":357},"isVisible",[35,2792,59],{"class":52},[35,2794,2795],{"class":357},"onClick",[35,2797,2798],{"class":52},") { ",[35,2800,2802],{"class":2801},"sdCPZ","\u002F* ... *\u002F",[35,2804,2805],{"class":52}," }\n",[35,2807,2808],{"class":37,"line":73},[35,2809,2810],{"emptyLinePlaceholder":121},"\n",[35,2812,2813,2815,2817,2819,2821,2823,2825,2827,2829,2831,2834,2836,2838,2840,2843,2845,2847,2849,2851,2853,2855,2857,2859,2862,2864],{"class":37,"line":97},[35,2814,468],{"class":41},[35,2816,2768],{"class":103},[35,2818,474],{"class":52},[35,2820,238],{"class":357},[35,2822,59],{"class":52},[35,2824,233],{"class":357},[35,2826,59],{"class":52},[35,2828,2781],{"class":357},[35,2830,49],{"class":41},[35,2832,2833],{"class":219}," 'blue'",[35,2835,59],{"class":52},[35,2837,2578],{"class":357},[35,2839,49],{"class":41},[35,2841,2842],{"class":219}," 'md'",[35,2844,59],{"class":52},[35,2846,2790],{"class":357},[35,2848,49],{"class":41},[35,2850,757],{"class":45},[35,2852,59],{"class":52},[35,2854,2795],{"class":357},[35,2856,241],{"class":52},[35,2858,91],{"class":41},[35,2860,2861],{"class":52}," {}) { ",[35,2863,2802],{"class":2801},[35,2865,2805],{"class":52},[153,2867,2868],{},"Which signature is the better design, and why?",[109,2870,2872,2878,2884,2890],{"className":2871},[112],[114,2873,2875,2877],{"className":2874},[117],[119,2876],{"disabled":121,"type":122}," The positional version, because positional parameters are always faster at runtime than destructured ones",[114,2879,2881,2883],{"className":2880},[117],[119,2882],{"disabled":121,"type":122}," The positional version, because JavaScript requires optional parameters to appear positionally after required ones, which destructuring cannot express",[114,2885,2887,2889],{"className":2886},[117],[119,2888],{"disabled":121,"type":122}," Neither — with six parameters you should always use an array and access by index",[114,2891,2893,2895],{"className":2892},[117],[119,2894],{"disabled":121,"type":122}," The destructured version, because it lets callers name only the options they care about, skip optional ones freely, and self-documents each argument at the call site",[146,2897,2898,2900,2905],{},[149,2899,151],{},[153,2901,2902,2904],{},[156,2903,158],{}," D — The destructured version, because it lets callers name only the options they care about, skip optional ones freely, and self-documents each argument at the call site",[153,2906,2907,141,2909,2911,2912,2915,2916,2919],{},[156,2908,164],{},[156,2910,297],{}," Once a function has more than two or three parameters, especially with several optional ones, positional calls become error-prone (",[32,2913,2914],{},"createWidget(undefined, undefined, undefined, 'lg')",") and unreadable at the call site. Destructured parameters with defaults let callers pass an options object naming exactly what they need (",[32,2917,2918],{},"createWidget({ size: 'lg', onClick })",") in any order. A is a myth — the performance difference is negligible and irrelevant to API design; B is factually wrong, since destructuring patterns support per-field defaults regardless of order.",[2921,2922,2923],"style",{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}",{"title":30,"searchDepth":73,"depth":73,"links":2925},[2926,2927,2928,2929,2930,2931,2932,2933,2934,2936,2937,2938,2939,2940,2941,2942,2943,2944,2945,2946],{"id":20,"depth":97,"text":21},{"id":190,"depth":97,"text":191},{"id":323,"depth":97,"text":324},{"id":455,"depth":97,"text":456},{"id":654,"depth":97,"text":655},{"id":808,"depth":97,"text":809},{"id":930,"depth":97,"text":931},{"id":1075,"depth":97,"text":1076},{"id":1204,"depth":97,"text":2935},"Q9. In const [a, ...b] = arr; and const c = [...arr, 99];, what role does the ... play in each statement, respectively?",{"id":1277,"depth":97,"text":1278},{"id":1414,"depth":97,"text":1415},{"id":1535,"depth":97,"text":1536},{"id":1665,"depth":97,"text":1666},{"id":1800,"depth":97,"text":1801},{"id":1987,"depth":97,"text":1988},{"id":2137,"depth":97,"text":2138},{"id":2270,"depth":97,"text":2271},{"id":2449,"depth":97,"text":2450},{"id":2598,"depth":97,"text":2599},{"id":2753,"depth":97,"text":2754},"md",{},"\u002Fjs\u002F09-destructuring-and-spread",{"title":5,"description":30},"js\u002F09-destructuring-and-spread","Fj5PF4LLft8vgxhAC9OGx5Tew253WYpxgNT39cXKEts",1787335397333]