[{"data":1,"prerenderedAt":143746},["ShallowReactive",2],{"all-pages":3},[4,2150,5209,8675,12644,16048,19507,23348,26808,29539,34148,37265,40911,44169,47291,50739,54516,57638,61233,64539,67204,69416,71584,75453,78962,81878,83869,84447,86855,87353,88943,91649,94130,96789,99209,101870,105100,107964,108548,110243,111899,114567,117013,120681,122909,125230,127898,130706,132549,134522,136624,139497,143065],{"id":5,"title":6,"body":7,"description":264,"extension":2144,"meta":2145,"navigation":35,"path":2146,"seo":2147,"stem":2148,"__hash__":2149},"content\u002Fjs\u002F01-introduction-and-setup.md","01 — Introduction & Setup",{"type":8,"value":9,"toc":2110},"minimark",[10,14,112,191,245,367,463,534,594,742,873,942,1054,1192,1314,1457,1530,1671,1749,1894,2042,2106],[11,12,6],"h1",{"id":13},"_01-introduction-setup",[15,16,17,22,65],"question-wrapper",{},[18,19,21],"h3",{"id":20},"q1-what-is-v8-in-the-context-of-javascript","Q1. What is V8, in the context of JavaScript?",[23,24,27,47,53,59],"ul",{"className":25},[26],"contains-task-list",[28,29,32,37,38,42,43,46],"li",{"className":30},[31],"task-list-item",[33,34],"input",{"disabled":35,"type":36},true,"checkbox"," A JavaScript runtime that provides ",[39,40,41],"code",{},"fs",", ",[39,44,45],{},"http",", and other OS-level APIs",[28,48,50,52],{"className":49},[31],[33,51],{"disabled":35,"type":36}," A JavaScript engine that parses and executes JavaScript source code",[28,54,56,58],{"className":55},[31],[33,57],{"disabled":35,"type":36}," A package manager bundled with Node.js",[28,60,62,64],{"className":61},[31],[33,63],{"disabled":35,"type":36}," A transpiler that converts modern JavaScript into ES5",[66,67,68,72,80],"details",{},[69,70,71],"summary",{},"Show Answer",[73,74,75,79],"p",{},[76,77,78],"strong",{},"Answer:"," B — A JavaScript engine that parses and executes JavaScript source code",[73,81,82,85,86,42,89,92,93,96,97,99,100,102,103,107,108,111],{},[76,83,84],{},"Explanation:"," V8 (built by Google) is an engine — it parses, compiles (via JIT), and executes JS code, and implements the ECMAScript spec plus the language's core objects (",[39,87,88],{},"Array",[39,90,91],{},"Promise",", etc.). It does ",[76,94,95],{},"not"," provide ",[39,98,41],{}," or ",[39,101,45],{},"; those come from a ",[104,105,106],"em",{},"runtime"," built around the engine. Option A describes Node.js, which embeds V8 but adds its own APIs. Option C confuses V8 with ",[39,109,110],{},"npm",". Option D describes tools like Babel — V8 runs JS natively, it doesn't transpile.",[15,113,114,118,154],{},[18,115,117],{"id":116},"q2-which-statement-correctly-distinguishes-nodejs-from-v8","Q2. Which statement correctly distinguishes Node.js from V8?",[23,119,121,127,142,148],{"className":120},[26],[28,122,124,126],{"className":123},[31],[33,125],{"disabled":35,"type":36}," They are the same thing — \"Node.js\" is just another name for the V8 engine",[28,128,130,132,133,42,135,137,138,141],{"className":129},[31],[33,131],{"disabled":35,"type":36}," Node.js is a runtime that embeds V8 and adds APIs like ",[39,134,41],{},[39,136,45],{},", and ",[39,139,140],{},"process"," that aren't part of JavaScript itself",[28,143,145,147],{"className":144},[31],[33,146],{"disabled":35,"type":36}," V8 is a superset of Node.js that adds browser-specific APIs",[28,149,151,153],{"className":150},[31],[33,152],{"disabled":35,"type":36}," Node.js replaces V8 with its own custom-built engine",[66,155,156,158,169],{},[69,157,71],{},[73,159,160,162,163,42,165,137,167],{},[76,161,78],{}," B — Node.js is a runtime that embeds V8 and adds APIs like ",[39,164,41],{},[39,166,45],{},[39,168,140],{},[73,170,171,173,174,42,176,179,180,183,184,186,187,190],{},[76,172,84],{}," Node.js embeds the V8 engine and layers on host APIs (filesystem, networking, ",[39,175,140],{},[39,177,178],{},"Buffer",") that are not defined by the ECMAScript spec at all. ",[76,181,182],{},"Portability:"," because ",[39,185,41],{}," and ",[39,188,189],{},"window"," are host APIs, not language features, code using them isn't portable between Node and the browser even though both run \"JavaScript.\" Option A collapses the runtime\u002Fengine distinction. Option C reverses the relationship. Option D is false — Node has always used V8, not a custom engine.",[15,192,193,197,224],{},[18,194,196],{"id":195},"q3-es6-and-es2015-refer-to","Q3. \"ES6\" and \"ES2015\" refer to:",[23,198,200,206,212,218],{"className":199},[26],[28,201,203,205],{"className":202},[31],[33,204],{"disabled":35,"type":36}," Two different, incompatible versions of JavaScript",[28,207,209,211],{"className":208},[31],[33,210],{"disabled":35,"type":36}," The same ECMAScript edition — ES6 is the older name, ES2015 is the year-based name adopted afterward",[28,213,215,217],{"className":214},[31],[33,216],{"disabled":35,"type":36}," ES6 is the browser implementation, ES2015 is the Node.js implementation",[28,219,221,223],{"className":220},[31],[33,222],{"disabled":35,"type":36}," ES2015 is a strict superset of ES6 released a year later",[66,225,226,228,233],{},[69,227,71],{},[73,229,230,232],{},[76,231,78],{}," B — The same edition; ES6 is the older name, ES2015 is the year-based name",[73,234,235,237,238,42,241,244],{},[76,236,84],{}," TC39 switched to annual, year-based release naming starting with the edition that introduced ",[39,239,240],{},"let",[39,242,243],{},"const",", classes, arrow functions, and Promises. That edition is interchangeably called \"ES6\" or \"ES2015\" — they are not different versions. Options A, C, and D all invent a distinction that doesn't exist.",[15,246,248,256,315,342],{"language":247},"javascript",[18,249,251,252,255],{"id":250},"q4-where-must-a-use-strict-directive-appear-to-enable-strict-mode-for-an-entire-script","Q4. Where must a ",[39,253,254],{},"\"use strict\""," directive appear to enable strict mode for an entire script?",[257,258,259],"code-wrapper",{"language":247},[260,261,265],"pre",{"className":262,"code":263,"language":247,"meta":264,"style":264},"language-javascript shiki shiki-themes github-light github-dark","function example() {\n  \"use strict\";\n  x = 10;\n}\n","",[39,266,267,284,294,309],{"__ignoreMap":264},[268,269,272,276,280],"span",{"class":270,"line":271},"line",1,[268,273,275],{"class":274},"svdQ7","function",[268,277,279],{"class":278},"sIsaT"," example",[268,281,283],{"class":282},"ssxIu","() {\n",[268,285,287,291],{"class":270,"line":286},2,[268,288,290],{"class":289},"sJ6F3","  \"use strict\"",[268,292,293],{"class":282},";\n",[268,295,297,300,303,307],{"class":270,"line":296},3,[268,298,299],{"class":282},"  x ",[268,301,302],{"class":274},"=",[268,304,306],{"class":305},"snvgF"," 10",[268,308,293],{"class":282},[268,310,312],{"class":270,"line":311},4,[268,313,314],{"class":282},"}\n",[23,316,318,324,330,336],{"className":317},[26],[28,319,321,323],{"className":320},[31],[33,322],{"disabled":35,"type":36}," Anywhere in the file, even after other executable statements",[28,325,327,329],{"className":326},[31],[33,328],{"disabled":35,"type":36}," As the very first statement in the file (or function body), before any other statements",[28,331,333,335],{"className":332},[31],[33,334],{"disabled":35,"type":36}," Inside a comment at the top of the file",[28,337,339,341],{"className":338},[31],[33,340],{"disabled":35,"type":36}," It must be passed as a CLI flag to Node; it cannot appear in source",[66,343,344,346,351],{},[69,345,71],{},[73,347,348,350],{},[76,349,78],{}," B — As the very first statement in the file (or function body), before any other statements",[73,352,353,355,356,358,359,362,363,366],{},[76,354,84],{}," ",[39,357,254],{}," is a ",[104,360,361],{},"directive prologue"," — the parser only recognizes it as special when it is literally the first statement. ",[76,364,365],{},"Debug:"," if any other statement (even a variable declaration) precedes it, it's silently treated as a harmless, no-op string literal expression instead of enabling strict mode — a common silent-failure trap. Option A is the tempting wrong answer for exactly that reason. It's a plain string literal, not a comment (C), and works in any JS file, not just via a Node flag (D).",[15,368,369,388,418],{},[18,370,372,373,376,377,42,380,383,384,387],{"id":371},"q5-by-default-how-does-a-browser-handle-a-plain-script-srcappjsscript-tag-with-no-async-defer-or-typemodule-attributes","Q5. By default, how does a browser handle a plain ",[39,374,375],{},"\u003Cscript src=\"app.js\">\u003C\u002Fscript>"," tag with no ",[39,378,379],{},"async",[39,381,382],{},"defer",", or ",[39,385,386],{},"type=\"module\""," attributes?",[23,389,391,397,403,409],{"className":390},[26],[28,392,394,396],{"className":393},[31],[33,395],{"disabled":35,"type":36}," It downloads and executes the script without blocking HTML parsing",[28,398,400,402],{"className":399},[31],[33,401],{"disabled":35,"type":36}," It blocks HTML parsing while the script downloads and executes, then resumes parsing",[28,404,406,408],{"className":405},[31],[33,407],{"disabled":35,"type":36}," It waits until the entire document is parsed before downloading the script",[28,410,412,414,415],{"className":411},[31],[33,413],{"disabled":35,"type":36}," It downloads the script in parallel but always executes it after ",[39,416,417],{},"DOMContentLoaded",[66,419,420,422,427],{},[69,421,71],{},[73,423,424,426],{},[76,425,78],{}," B — It blocks HTML parsing while the script downloads and executes, then resumes parsing",[73,428,429,431,432,435,436,439,440,443,444,446,447,449,450,453,454,456,457,459,460,462],{},[76,430,84],{}," A classic synchronous ",[39,433,434],{},"\u003Cscript>"," tag is parser-blocking: the browser must fetch and run it before continuing to parse the rest of the HTML. ",[76,437,438],{},"Performance:"," this is why render-blocking scripts placed in ",[39,441,442],{},"\u003Chead>"," are a common cause of slow page loads, and why ",[39,445,382],{},"\u002F",[39,448,379],{},"\u002Fplacing scripts before ",[39,451,452],{},"\u003C\u002Fbody>"," are recommended. Option A describes ",[39,455,379],{},". Option C is closer to ",[39,458,382],{},"'s execution timing but still wrong about parsing being blocked. Option D is incorrect — plain scripts run as soon as they're evaluated, not after ",[39,461,417],{},".",[15,464,465,473,508],{},[18,466,468,469,472],{"id":467},"q6-a-script-typemodule-tag-behaves-like-which-combination-of-attributes-by-default","Q6. A ",[39,470,471],{},"\u003Cscript type=\"module\">"," tag behaves like which combination of attributes by default?",[23,474,476,482,491,499],{"className":475},[26],[28,477,479,481],{"className":478},[31],[33,480],{"disabled":35,"type":36}," Like a plain script — blocking, synchronous",[28,483,485,487,488,490],{"className":484},[31],[33,486],{"disabled":35,"type":36}," Like ",[39,489,379],{}," — non-blocking, execution order not guaranteed",[28,492,494,487,496,498],{"className":493},[31],[33,495],{"disabled":35,"type":36},[39,497,382],{}," — non-blocking, and execution is deferred until after parsing, in document order",[28,500,502,504,505,507],{"className":501},[31],[33,503],{"disabled":35,"type":36}," Modules cannot be loaded via ",[39,506,434],{}," tags at all; they require a bundler",[66,509,510,512,520],{},[69,511,71],{},[73,513,514,516,517,519],{},[76,515,78],{}," C — Like ",[39,518,382],{}," — non-blocking, deferred, and in document order",[73,521,522,524,525,527,528,530,531,533],{},[76,523,84],{}," ES module scripts are deferred by default: the browser fetches them without blocking parsing, and executes them in document order after parsing completes (unless ",[39,526,379],{}," is also explicitly added, which then allows out-of-order execution). Option A is the common beginner assumption — that \"module\" means \"just a normal script with import support\" — but the loading semantics are different. Option B is wrong unless ",[39,529,379],{}," is explicitly added. Option D is false; native ",[39,532,471],{}," works without any bundler in modern browsers.",[15,535,536,540,567],{},[18,537,539],{"id":538},"q7-what-is-a-defining-characteristic-of-deno-compared-to-nodejs","Q7. What is a defining characteristic of Deno compared to Node.js?",[23,541,543,549,555,561],{"className":542},[26],[28,544,546,548],{"className":545},[31],[33,547],{"disabled":35,"type":36}," Deno cannot execute TypeScript without a separate compile step",[28,550,552,554],{"className":551},[31],[33,553],{"disabled":35,"type":36}," Deno runs scripts with no filesystem, network, or environment access by default, requiring explicit permission flags",[28,556,558,560],{"className":557},[31],[33,559],{"disabled":35,"type":36}," Deno does not support ES modules",[28,562,564,566],{"className":563},[31],[33,565],{"disabled":35,"type":36}," Deno uses the SpiderMonkey engine instead of V8",[66,568,569,571,576],{},[69,570,71],{},[73,572,573,575],{},[76,574,78],{}," B — Deno runs scripts with no filesystem, network, or environment access by default, requiring explicit permission flags",[73,577,578,355,580,583,584,42,587,42,590,593],{},[76,579,84],{},[76,581,582],{},"Safety:"," Deno is secure-by-default — a script needs ",[39,585,586],{},"--allow-read",[39,588,589],{},"--allow-net",[39,591,592],{},"--allow-env",", etc. explicitly granted, unlike Node where any script has full system access the moment it runs. Deno actually supports TypeScript natively without a separate build step (making A false), supports ES modules as its primary module system (making C false), and uses V8 just like Node (making D false).",[15,595,596,600,644,688],{"language":247},[18,597,599],{"id":598},"q8-what-is-the-key-syntacticbehavioral-difference-between-commonjs-and-es-modules-in-nodejs","Q8. What is the key syntactic\u002Fbehavioral difference between CommonJS and ES modules in Node.js?",[257,601,602],{"language":247},[260,603,605],{"className":262,"code":604,"language":247,"meta":264,"style":264},"const fs = require('fs');\nmodule.exports = { readConfig };\n",[39,606,607,629],{"__ignoreMap":264},[268,608,609,611,614,617,620,623,626],{"class":270,"line":271},[268,610,243],{"class":274},[268,612,613],{"class":305}," fs",[268,615,616],{"class":274}," =",[268,618,619],{"class":278}," require",[268,621,622],{"class":282},"(",[268,624,625],{"class":289},"'fs'",[268,627,628],{"class":282},");\n",[268,630,631,634,636,639,641],{"class":270,"line":286},[268,632,633],{"class":305},"module",[268,635,462],{"class":282},[268,637,638],{"class":305},"exports",[268,640,616],{"class":274},[268,642,643],{"class":282}," { readConfig };\n",[23,645,647,667,673,682],{"className":646},[26],[28,648,650,652,653,446,656,659,660,446,663,666],{"className":649},[31],[33,651],{"disabled":35,"type":36}," CommonJS uses ",[39,654,655],{},"require",[39,657,658],{},"module.exports"," and loads synchronously; ESM uses ",[39,661,662],{},"import",[39,664,665],{},"export"," and is loaded asynchronously with static analysis",[28,668,670,672],{"className":669},[31],[33,671],{"disabled":35,"type":36}," There is no real difference — Node treats both identically at runtime",[28,674,676,678,679,681],{"className":675},[31],[33,677],{"disabled":35,"type":36}," CommonJS supports ",[39,680,662],{}," statements but ESM does not",[28,683,685,687],{"className":684},[31],[33,686],{"disabled":35,"type":36}," ESM is only available in the browser, never in Node.js",[66,689,690,692,707],{},[69,691,71],{},[73,693,694,696,697,446,699,701,702,446,704,706],{},[76,695,78],{}," A — CommonJS uses ",[39,698,655],{},[39,700,658],{}," synchronously; ESM uses ",[39,703,662],{},[39,705,665],{},", resolved asynchronously and statically analyzable",[73,708,709,711,712,715,716,446,718,720,721,723,724,446,727,730,731,734,735,738,739,741],{},[76,710,84],{}," CommonJS ",[39,713,714],{},"require()"," calls are synchronous function calls that can happen conditionally anywhere in code. ESM ",[39,717,662],{},[39,719,665],{}," bindings are statically analyzed at parse time (enabling tree-shaking) and top-level ",[39,722,662],{}," cannot be conditional. Node determines which system to use per-file based on ",[39,725,726],{},".mjs",[39,728,729],{},".cjs"," extensions or the ",[39,732,733],{},"\"type\""," field in ",[39,736,737],{},"package.json",". Option B ignores real interop pitfalls (e.g., CJS's ",[39,740,655],{}," is unavailable by default in ESM files). Option C is backwards. Option D is false — Node has supported ESM natively since Node 12+.",[15,743,744,748,795,845],{"language":247},[18,745,747],{"id":746},"q9-what-happens-when-you-assign-to-an-undeclared-variable-inside-strict-mode-code","Q9. What happens when you assign to an undeclared variable inside strict-mode code?",[257,749,750],{"language":247},[260,751,753],{"className":262,"code":752,"language":247,"meta":264,"style":264},"\"use strict\";\nfunction setTotal() {\n  total = 42;\n}\nsetTotal();\n",[39,754,755,761,770,782,786],{"__ignoreMap":264},[268,756,757,759],{"class":270,"line":271},[268,758,254],{"class":289},[268,760,293],{"class":282},[268,762,763,765,768],{"class":270,"line":286},[268,764,275],{"class":274},[268,766,767],{"class":278}," setTotal",[268,769,283],{"class":282},[268,771,772,775,777,780],{"class":270,"line":296},[268,773,774],{"class":282},"  total ",[268,776,302],{"class":274},[268,778,779],{"class":305}," 42",[268,781,293],{"class":282},[268,783,784],{"class":270,"line":311},[268,785,314],{"class":282},[268,787,789,792],{"class":270,"line":788},5,[268,790,791],{"class":278},"setTotal",[268,793,794],{"class":282},"();\n",[23,796,798,807,820,834],{"className":797},[26],[28,799,801,355,803,806],{"className":800},[31],[33,802],{"disabled":35,"type":36},[39,804,805],{},"total"," is silently created as a global variable, same as in non-strict mode",[28,808,810,812,813,816,817,819],{"className":809},[31],[33,811],{"disabled":35,"type":36}," A ",[39,814,815],{},"ReferenceError"," is thrown because ",[39,818,805],{}," was never declared",[28,821,823,812,825,816,828,830,831],{"className":822},[31],[33,824],{"disabled":35,"type":36},[39,826,827],{},"TypeError",[39,829,805],{}," is ",[39,832,833],{},"undefined",[28,835,837,839,840,842,843],{"className":836},[31],[33,838],{"disabled":35,"type":36}," It works fine, but ",[39,841,805],{}," is scoped only to ",[39,844,791],{},[66,846,847,849,858],{},[69,848,71],{},[73,850,851,853,854,816,856,819],{},[76,852,78],{}," B — A ",[39,855,815],{},[39,857,805],{},[73,859,860,862,863,865,866,868,869,872],{},[76,861,84],{}," In non-strict mode, assigning to an undeclared identifier silently creates a global variable — a notorious source of bugs. Strict mode closes this hole: it throws a ",[39,864,815],{}," instead. ",[76,867,582],{}," the correct fix is to declare the variable explicitly (",[39,870,871],{},"let total = 42;",") rather than rely on implicit globals. Option A describes the (bug-prone) non-strict behavior. Option C names the wrong error type. Option D is wrong because the assignment never succeeds at all.",[15,874,875,887,914],{},[18,876,878,879,99,881,883,884,886],{"id":877},"q10-do-es-modules-script-typemodule-or-mjs-files-require-an-explicit-use-strict-directive-to-run-in-strict-mode","Q10. Do ES modules (",[39,880,471],{},[39,882,726],{}," files) require an explicit ",[39,885,254],{}," directive to run in strict mode?",[23,888,890,896,902,908],{"className":889},[26],[28,891,893,895],{"className":892},[31],[33,894],{"disabled":35,"type":36}," Yes — without it, modules run in sloppy (non-strict) mode",[28,897,899,901],{"className":898},[31],[33,900],{"disabled":35,"type":36}," No — ES modules are automatically strict mode, with no directive needed",[28,903,905,907],{"className":904},[31],[33,906],{"disabled":35,"type":36}," Only if the module also uses classes",[28,909,911,913],{"className":910},[31],[33,912],{"disabled":35,"type":36}," Only in Node.js, not in browsers",[66,915,916,918,923],{},[69,917,71],{},[73,919,920,922],{},[76,921,78],{}," B — No, ES modules are automatically strict mode",[73,924,925,927,928,931,932,934,935,937,938,941],{},[76,926,84],{}," The ECMAScript spec mandates that all module code is implicitly strict — there's no opt-out and no need for the directive. ",[76,929,930],{},"Idiom:"," adding ",[39,933,254],{}," at the top of a ",[39,936,726],{}," file is harmless but redundant. Option A is the common false assumption carried over from script-tag habits. Option C invents a class-specific rule (classes are ",[104,939,940],{},"always"," strict-mode bodies regardless of module status, but that's a separate rule). Option D is false — this is a language-level guarantee, not runtime-specific.",[15,943,944,952,996],{},[18,945,947,948,951],{"id":946},"q11-what-does-top-level-this-refer-to-in-each-of-a-classic-non-module-browser-script-an-es-module-and-a-nodejs-commonjs-file","Q11. What does top-level ",[39,949,950],{},"this"," refer to in each of: a classic (non-module) browser script, an ES module, and a Node.js CommonJS file?",[23,953,955,967,975,987],{"className":954},[26],[28,956,958,355,960,42,962,137,964,966],{"className":957},[31],[33,959],{"disabled":35,"type":36},[39,961,189],{},[39,963,189],{},[39,965,658],{}," respectively",[28,968,970,355,972,974],{"className":969},[31],[33,971],{"disabled":35,"type":36},[39,973,833],{}," in all three",[28,976,978,355,980,982,983,137,985,966],{"className":977},[31],[33,979],{"disabled":35,"type":36},[39,981,189],{}," (global object), ",[39,984,833],{},[39,986,658],{},[28,988,990,355,992,995],{"className":989},[31],[33,991],{"disabled":35,"type":36},[39,993,994],{},"globalThis"," in all three, since ES2020 unified them",[66,997,998,1000,1011],{},[69,999,71],{},[73,1001,1002,1004,1005,42,1007,137,1009,966],{},[76,1003,78],{}," C — ",[39,1006,189],{},[39,1008,833],{},[39,1010,658],{},[73,1012,1013,1015,1016,1018,1019,1021,1022,830,1024,1026,1027,1029,1030,1032,1033,1035,1036,1038,1039,1041,1042,1044,1045,358,1047,1050,1051,1053],{},[76,1014,84],{}," In a classic script, top-level ",[39,1017,950],{}," is the global object (",[39,1020,189],{}," in browsers). In an ES module, top-level ",[39,1023,950],{},[39,1025,833],{}," by spec — modules don't have an implicit global receiver. In a Node CommonJS file, top-level ",[39,1028,950],{}," refers to ",[39,1031,658],{}," because the file is wrapped in a function by Node's module loader. ",[76,1034,365],{}," relying on top-level ",[39,1037,950],{}," for global access is fragile precisely because it varies by context — use ",[39,1040,994],{}," instead when you genuinely need the global object. Option D wrongly claims ",[39,1043,994],{}," replaced these semantics; ",[39,1046,994],{},[104,1048,1049],{},"new, separate"," way to reliably reach the global object, it didn't change what ",[39,1052,950],{}," means.",[15,1055,1057,1064,1121,1155],{"language":1056},"html",[18,1058,1060,1061,1063],{"id":1059},"q12-given-two-scripts-loaded-with-async-in-what-order-do-they-execute-relative-to-each-other","Q12. Given two scripts loaded with ",[39,1062,379],{},", in what order do they execute relative to each other?",[257,1065,1066],{"language":1056},[260,1067,1070],{"className":1068,"code":1069,"language":1056,"meta":264,"style":264},"language-html shiki shiki-themes github-light github-dark","\u003Cscript src=\"a.js\" async>\u003C\u002Fscript>\n\u003Cscript src=\"b.js\" async>\u003C\u002Fscript>\n",[39,1071,1072,1100],{"__ignoreMap":264},[268,1073,1074,1077,1081,1084,1086,1089,1092,1095,1097],{"class":270,"line":271},[268,1075,1076],{"class":282},"\u003C",[268,1078,1080],{"class":1079},"sk71V","script",[268,1082,1083],{"class":278}," src",[268,1085,302],{"class":282},[268,1087,1088],{"class":289},"\"a.js\"",[268,1090,1091],{"class":278}," async",[268,1093,1094],{"class":282},">\u003C\u002F",[268,1096,1080],{"class":1079},[268,1098,1099],{"class":282},">\n",[268,1101,1102,1104,1106,1108,1110,1113,1115,1117,1119],{"class":270,"line":286},[268,1103,1076],{"class":282},[268,1105,1080],{"class":1079},[268,1107,1083],{"class":278},[268,1109,302],{"class":282},[268,1111,1112],{"class":289},"\"b.js\"",[268,1114,1091],{"class":278},[268,1116,1094],{"class":282},[268,1118,1080],{"class":1079},[268,1120,1099],{"class":282},[23,1122,1124,1137,1143,1149],{"className":1123},[26],[28,1125,1127,1129,1130,1133,1134],{"className":1126},[31],[33,1128],{"disabled":35,"type":36}," Always in document order: ",[39,1131,1132],{},"a.js"," then ",[39,1135,1136],{},"b.js",[28,1138,1140,1142],{"className":1139},[31],[33,1141],{"disabled":35,"type":36}," In whichever order each script finishes downloading first — order is not guaranteed",[28,1144,1146,1148],{"className":1145},[31],[33,1147],{"disabled":35,"type":36}," Always in reverse document order",[28,1150,1152,1154],{"className":1151},[31],[33,1153],{"disabled":35,"type":36}," Simultaneously, on separate threads",[66,1156,1157,1159,1164],{},[69,1158,71],{},[73,1160,1161,1163],{},[76,1162,78],{}," B — In whichever order each script finishes downloading first; order is not guaranteed",[73,1165,1166,355,1168,1170,1171,1173,1174,1176,1177,1179,1180,1182,1183,1185,1186,1188,1189,1191],{},[76,1167,84],{},[39,1169,379],{}," scripts download in parallel and each executes immediately as soon as it finishes downloading, independent of the other or of document order. ",[76,1172,182],{}," this means a smaller\u002Ffaster-to-fetch ",[39,1175,1136],{}," can easily execute before ",[39,1178,1132],{},", so ",[39,1181,379],{}," is unsafe for scripts with ordering dependencies (use ",[39,1184,382],{}," for that instead). Option A describes ",[39,1187,382],{},"'s guarantee, not ",[39,1190,379],{},"'s. Option C and D describe behaviors JavaScript's single-threaded execution model doesn't produce — script execution itself is never literally parallel\u002Fsimultaneous even though downloads are.",[15,1193,1194,1198,1254,1292],{"language":247},[18,1195,1197],{"id":1196},"q13-what-happens-when-a-strict-mode-function-is-declared-with-duplicate-parameter-names","Q13. What happens when a strict-mode function is declared with duplicate parameter names?",[257,1199,1200],{"language":247},[260,1201,1203],{"className":262,"code":1202,"language":247,"meta":264,"style":264},"\"use strict\";\nfunction add(a, a, b) {\n  return a + b;\n}\n",[39,1204,1205,1211,1236,1250],{"__ignoreMap":264},[268,1206,1207,1209],{"class":270,"line":271},[268,1208,254],{"class":289},[268,1210,293],{"class":282},[268,1212,1213,1215,1218,1220,1224,1226,1228,1230,1233],{"class":270,"line":286},[268,1214,275],{"class":274},[268,1216,1217],{"class":278}," add",[268,1219,622],{"class":282},[268,1221,1223],{"class":1222},"sCrzJ","a",[268,1225,42],{"class":282},[268,1227,1223],{"class":1222},[268,1229,42],{"class":282},[268,1231,1232],{"class":1222},"b",[268,1234,1235],{"class":282},") {\n",[268,1237,1238,1241,1244,1247],{"class":270,"line":296},[268,1239,1240],{"class":274},"  return",[268,1242,1243],{"class":282}," a ",[268,1245,1246],{"class":274},"+",[268,1248,1249],{"class":282}," b;\n",[268,1251,1252],{"class":270,"line":311},[268,1253,314],{"class":282},[23,1255,1257,1266,1276,1284],{"className":1256},[26],[28,1258,1260,1262,1263,1265],{"className":1259},[31],[33,1261],{"disabled":35,"type":36}," It runs fine; the last ",[39,1264,1223],{}," argument silently shadows the first",[28,1267,1269,1271,1272,1275],{"className":1268},[31],[33,1270],{"disabled":35,"type":36}," It throws a ",[39,1273,1274],{},"SyntaxError"," at parse time",[28,1277,1279,1271,1281,1283],{"className":1278},[31],[33,1280],{"disabled":35,"type":36},[39,1282,827],{}," only when the function is called",[28,1285,1287,1289,1290],{"className":1286},[31],[33,1288],{"disabled":35,"type":36}," It works the same as in non-strict mode, using the first ",[39,1291,1223],{},[66,1293,1294,1296,1303],{},[69,1295,71],{},[73,1297,1298,1300,1301,1275],{},[76,1299,78],{}," B — It throws a ",[39,1302,1274],{},[73,1304,1305,1307,1308,1310,1311,1313],{},[76,1306,84],{}," Non-strict mode silently allows duplicate parameter names (later ones shadow earlier ones) — a foot-gun strict mode explicitly forbids by making it a parse-time ",[39,1309,1274],{},", so the code never even runs. ",[76,1312,582],{}," the fix is simply to rename parameters uniquely. Option A and D describe the permissive non-strict behavior. Option C is wrong about timing — this is caught before execution, not at call time.",[15,1315,1316,1324,1365,1417],{"language":247},[18,1317,1319,1320,1323],{"id":1318},"q14-how-does-eval-behave-differently-in-strict-mode-versus-non-strict-mode-regarding-variable-declarations","Q14. How does ",[39,1321,1322],{},"eval()"," behave differently in strict mode versus non-strict mode regarding variable declarations?",[257,1325,1326],{"language":247},[260,1327,1329],{"className":262,"code":1328,"language":247,"meta":264,"style":264},"\"use strict\";\neval(\"var leaked = 1;\");\nconsole.log(typeof leaked);\n",[39,1330,1331,1337,1349],{"__ignoreMap":264},[268,1332,1333,1335],{"class":270,"line":271},[268,1334,254],{"class":289},[268,1336,293],{"class":282},[268,1338,1339,1342,1344,1347],{"class":270,"line":286},[268,1340,1341],{"class":278},"eval",[268,1343,622],{"class":282},[268,1345,1346],{"class":289},"\"var leaked = 1;\"",[268,1348,628],{"class":282},[268,1350,1351,1354,1357,1359,1362],{"class":270,"line":296},[268,1352,1353],{"class":282},"console.",[268,1355,1356],{"class":278},"log",[268,1358,622],{"class":282},[268,1360,1361],{"class":274},"typeof",[268,1363,1364],{"class":282}," leaked);\n",[23,1366,1368,1384,1398,1408],{"className":1367},[26],[28,1369,1371,1373,1374,1376,1377,1380,1381],{"className":1370},[31],[33,1372],{"disabled":35,"type":36}," In strict mode, ",[39,1375,1341],{}," still leaks ",[39,1378,1379],{},"leaked"," into the surrounding scope, logging ",[39,1382,1383],{},"\"number\"",[28,1385,1387,1373,1389,1391,1392,1394,1395],{"className":1386},[31],[33,1388],{"disabled":35,"type":36},[39,1390,1341],{}," gets its own variable scope, so ",[39,1393,1379],{}," never escapes; this logs ",[39,1396,1397],{},"\"undefined\"",[28,1399,1401,355,1403,1405,1406],{"className":1400},[31],[33,1402],{"disabled":35,"type":36},[39,1404,1341],{}," is entirely disabled in strict mode and throws a ",[39,1407,1274],{},[28,1409,1411,1413,1414,1416],{"className":1410},[31],[33,1412],{"disabled":35,"type":36}," Both strict and non-strict ",[39,1415,1341],{}," behave identically — there's no scoping difference",[66,1418,1419,1421,1433],{},[69,1420,71],{},[73,1422,1423,1425,1426,1428,1429,1394,1431],{},[76,1424,78],{}," B — In strict mode, ",[39,1427,1341],{}," gets its own scope, so ",[39,1430,1379],{},[39,1432,1397],{},[73,1434,1435,1437,1438,1441,1442,1444,1445,1447,1448,1450,1451,1453,1454,1456],{},[76,1436,84],{}," In non-strict mode, ",[39,1439,1440],{},"var"," declarations inside ",[39,1443,1322],{}," leak into the calling scope — a well-known danger of ",[39,1446,1341],{},". Strict mode contains this: code run via ",[39,1449,1341],{}," gets its own variable environment, so declarations inside it stay local. ",[76,1452,582],{}," this is one of several reasons strict mode is recommended even when not using classes\u002Fmodules. Option A describes the leaky non-strict behavior. Option C overstates it — ",[39,1455,1341],{}," still works in strict mode, it's just scoped. Option D ignores this real, spec-mandated difference.",[15,1458,1459,1470,1503],{},[18,1460,1462,1463,1465,1466,1469],{"id":1461},"q15-is-it-necessary-to-add-use-strict-at-the-top-of-a-file-that-only-contains-es-class-declarations-and-no-other-top-level-code","Q15. Is it necessary to add ",[39,1464,254],{}," at the top of a file that only contains ES ",[39,1467,1468],{},"class"," declarations and no other top-level code?",[23,1471,1473,1479,1485,1494],{"className":1472},[26],[28,1474,1476,1478],{"className":1475},[31],[33,1477],{"disabled":35,"type":36}," Yes, classes are not strict by default and need the directive",[28,1480,1482,1484],{"className":1481},[31],[33,1483],{"disabled":35,"type":36}," No — class bodies are always executed in strict mode regardless of any directive, though it's still good practice to add it for non-class code in the same file",[28,1486,1488,1490,1491,1493],{"className":1487},[31],[33,1489],{"disabled":35,"type":36}," No, and adding it would cause a ",[39,1492,1274],{}," inside a class",[28,1495,1497,1499,1500],{"className":1496},[31],[33,1498],{"disabled":35,"type":36}," It depends on whether the class uses ",[39,1501,1502],{},"extends",[66,1504,1505,1507,1512],{},[69,1506,71],{},[73,1508,1509,1511],{},[76,1510,78],{}," B — No, class bodies are always strict regardless of a directive; still good practice for non-class code in the same file",[73,1513,1514,1516,1517,1519,1520,1522,1523,1525,1526,1529],{},[76,1515,84],{}," The ECMAScript spec mandates that the body of every ",[39,1518,1468],{}," (constructor and methods) runs in strict mode automatically, independent of directives or module status. ",[76,1521,930],{}," if a file mixes classes with regular top-level function code, you may still want an explicit ",[39,1524,254],{}," (or use a module) so that ",[104,1527,1528],{},"non-class"," code in the same file also gets strict-mode protections. Option A misunderstands the spec rule. Option C is false — the directive is legal syntax anywhere a directive prologue is allowed. Option D invents an irrelevant condition.",[15,1531,1532,1543,1599,1639],{"language":1056},[18,1533,1535,1536,1538,1539,1542],{"id":1534},"q16-what-is-the-idiomatic-reason-modern-projects-prefer-script-typemodule-over-the-older-script-nomodule-fallback-pattern","Q16. What is the idiomatic reason modern projects prefer ",[39,1537,471],{}," over the older ",[39,1540,1541],{},"\u003Cscript nomodule>"," fallback pattern?",[257,1544,1545],{"language":1056},[260,1546,1548],{"className":1068,"code":1547,"language":1056,"meta":264,"style":264},"\u003Cscript type=\"module\" src=\"modern.js\">\u003C\u002Fscript>\n\u003Cscript nomodule src=\"legacy.js\">\u003C\u002Fscript>\n",[39,1549,1550,1577],{"__ignoreMap":264},[268,1551,1552,1554,1556,1559,1561,1564,1566,1568,1571,1573,1575],{"class":270,"line":271},[268,1553,1076],{"class":282},[268,1555,1080],{"class":1079},[268,1557,1558],{"class":278}," type",[268,1560,302],{"class":282},[268,1562,1563],{"class":289},"\"module\"",[268,1565,1083],{"class":278},[268,1567,302],{"class":282},[268,1569,1570],{"class":289},"\"modern.js\"",[268,1572,1094],{"class":282},[268,1574,1080],{"class":1079},[268,1576,1099],{"class":282},[268,1578,1579,1581,1583,1586,1588,1590,1593,1595,1597],{"class":270,"line":286},[268,1580,1076],{"class":282},[268,1582,1080],{"class":1079},[268,1584,1585],{"class":278}," nomodule",[268,1587,1083],{"class":278},[268,1589,302],{"class":282},[268,1591,1592],{"class":289},"\"legacy.js\"",[268,1594,1094],{"class":282},[268,1596,1080],{"class":1079},[268,1598,1099],{"class":282},[23,1600,1602,1611,1620,1631],{"className":1601},[26],[28,1603,1605,355,1607,1610],{"className":1604},[31],[33,1606],{"disabled":35,"type":36},[39,1608,1609],{},"nomodule"," scripts always execute first regardless of load order",[28,1612,1614,1616,1617,1619],{"className":1613},[31],[33,1615],{"disabled":35,"type":36}," The fallback pattern exists to serve modern ESM bundles to browsers that support modules and a transpiled\u002Fbundled fallback to those that don't; with legacy browser support largely dropped, many modern projects skip the fallback and ship ",[39,1618,386],{}," only",[28,1621,1623,355,1625,1627,1628,1630],{"className":1622},[31],[33,1624],{"disabled":35,"type":36},[39,1626,386],{}," scripts cannot import other modules, so ",[39,1629,1609],{}," is required as a workaround",[28,1632,1634,355,1636,1638],{"className":1633},[31],[33,1635],{"disabled":35,"type":36},[39,1637,1609],{}," is deprecated syntax that throws an error in all current browsers",[66,1640,1641,1643,1648],{},[69,1642,71],{},[73,1644,1645,1647],{},[76,1646,78],{}," B — The pattern serves modern ESM to capable browsers and a fallback bundle to legacy ones; many projects now skip the fallback entirely",[73,1649,1650,1652,1653,1655,1656,1658,1659,1661,1662,1664,1665,1667,1668,1670],{},[76,1651,84],{}," The dual-script pattern exploited the fact that browsers old enough to not understand ",[39,1654,386],{}," also don't recognize ",[39,1657,1609],{}," as special and thus ignore it as an unknown attribute (loading the legacy bundle), while modern browsers understand ",[39,1660,1609],{}," and skip that script. ",[76,1663,930],{}," since evergreen browsers dominate today, many teams now ship ESM-only bundles and drop the legacy fallback and its build complexity entirely. Option A misdescribes the loading logic. Option C is false — modules import other modules constantly via ",[39,1666,662],{},". Option D is false; ",[39,1669,1609],{}," isn't deprecated, it's just often unnecessary now.",[15,1672,1673,1686,1719],{},[18,1674,1676,1677,1679,1680,1682,1683,1685],{"id":1675},"q17-why-is-defer-generally-preferred-over-placing-multiple-plain-script-tags-right-before-body","Q17. Why is ",[39,1678,382],{}," generally preferred over placing multiple plain ",[39,1681,434],{}," tags right before ",[39,1684,452],{},"?",[23,1687,1689,1697,1705,1711],{"className":1688},[26],[28,1690,1692,355,1694,1696],{"className":1691},[31],[33,1693],{"disabled":35,"type":36},[39,1695,382],{}," scripts execute before the DOM is parsed, which is faster",[28,1698,1700,355,1702,1704],{"className":1699},[31],[33,1701],{"disabled":35,"type":36},[39,1703,382],{}," lets the browser download scripts in parallel with HTML parsing (non-blocking) while still guaranteeing document order execution after parsing — plain end-of-body scripts still block parsing when the parser reaches them",[28,1706,1708,1710],{"className":1707},[31],[33,1709],{"disabled":35,"type":36}," There is no real difference; both approaches are functionally identical",[28,1712,1714,355,1716,1718],{"className":1713},[31],[33,1715],{"disabled":35,"type":36},[39,1717,382],{}," scripts run once per animation frame instead of once on load",[66,1720,1721,1723,1731],{},[69,1722,71],{},[73,1724,1725,1727,1728,1730],{},[76,1726,78],{}," B — ",[39,1729,382],{}," downloads in parallel with parsing, non-blocking, and still preserves document order after parsing completes",[73,1732,1733,355,1735,1737,1738,1741,1742,1744,1745,1748],{},[76,1734,84],{},[76,1736,438],{}," even scripts placed at the bottom of ",[39,1739,1740],{},"\u003Cbody>"," still block parsing for the moment the parser reaches them (they just do so after most content is already visible); ",[39,1743,382],{}," avoids blocking entirely by downloading concurrently with parsing and only executing once parsing is fully done, in document order. Option A gets the timing backwards — deferred scripts run ",[104,1746,1747],{},"after"," parsing, not before. Option C ignores the real performance and blocking difference. Option D describes something scripts don't do at all.",[15,1750,1752,1763,1804,1851],{"language":1751},"json",[18,1753,1755,1756,1759,1760,1762],{"id":1754},"q18-setting-type-module-in-a-nodejs-packagejson-changes-what","Q18. Setting ",[39,1757,1758],{},"\"type\": \"module\""," in a Node.js ",[39,1761,737],{}," changes what?",[257,1764,1765],{"language":1751},[260,1766,1769],{"className":1767,"code":1768,"language":1751,"meta":264,"style":264},"language-json shiki shiki-themes github-light github-dark","{\n  \"name\": \"app\",\n  \"type\": \"module\"\n}\n",[39,1770,1771,1776,1790,1800],{"__ignoreMap":264},[268,1772,1773],{"class":270,"line":271},[268,1774,1775],{"class":282},"{\n",[268,1777,1778,1781,1784,1787],{"class":270,"line":286},[268,1779,1780],{"class":305},"  \"name\"",[268,1782,1783],{"class":282},": ",[268,1785,1786],{"class":289},"\"app\"",[268,1788,1789],{"class":282},",\n",[268,1791,1792,1795,1797],{"class":270,"line":296},[268,1793,1794],{"class":305},"  \"type\"",[268,1796,1783],{"class":282},[268,1798,1799],{"class":289},"\"module\"\n",[268,1801,1802],{"class":270,"line":311},[268,1803,314],{"class":282},[23,1805,1807,1817,1834,1845],{"className":1806},[26],[28,1808,1810,1812,1813,1816],{"className":1809},[31],[33,1811],{"disabled":35,"type":36}," It only affects TypeScript files, not ",[39,1814,1815],{},".js"," files",[28,1818,1820,1822,1823,1825,1826,446,1828,1830,1831,1833],{"className":1819},[31],[33,1821],{"disabled":35,"type":36}," It makes Node interpret ",[39,1824,1815],{}," files in that package as ES modules (",[39,1827,662],{},[39,1829,665],{},") instead of the CommonJS default, while ",[39,1832,729],{}," files remain CommonJS regardless",[28,1835,1837,1839,1840,1842,1843,1816],{"className":1836},[31],[33,1838],{"disabled":35,"type":36}," It disables ",[39,1841,714],{}," globally, even in ",[39,1844,729],{},[28,1846,1848,1850],{"className":1847},[31],[33,1849],{"disabled":35,"type":36}," It has no effect unless a bundler like webpack is also configured",[66,1852,1853,1855,1866],{},[69,1854,71],{},[73,1856,1857,1859,1860,1862,1863,1865],{},[76,1858,78],{}," B — It makes ",[39,1861,1815],{}," files in that package parse as ES modules; ",[39,1864,729],{}," files stay CommonJS regardless",[73,1867,1868,1870,1871,42,1873,1875,1876,1878,1879,1881,1882,1884,1885,1887,1888,1890,1891,1893],{},[76,1869,84],{}," Node picks a module system per file: without ",[39,1872,1758],{},[39,1874,1815],{}," defaults to CommonJS; with it set, ",[39,1877,1815],{}," defaults to ESM. The explicit extensions ",[39,1880,726],{}," (always ESM) and ",[39,1883,729],{}," (always CommonJS) override the ",[39,1886,737],{}," setting entirely — this is the escape hatch for mixed codebases. Option A is wrong; this setting is about ",[39,1889,1815],{}," resolution, unrelated to TypeScript compilation. Option C is too broad — ",[39,1892,729],{}," files are unaffected. Option D is false; this is native Node behavior with zero bundler involvement.",[15,1895,1896,1905,1954,1992],{"language":1751},[18,1897,1899,1900,734,1903,1685],{"id":1898},"q19-what-is-the-purpose-of-the-engines-field-in-packagejson","Q19. What is the purpose of the ",[39,1901,1902],{},"\"engines\"",[39,1904,737],{},[257,1906,1907],{"language":1751},[260,1908,1910],{"className":1767,"code":1909,"language":1751,"meta":264,"style":264},"{\n  \"name\": \"app\",\n  \"engines\": {\n    \"node\": \">=18.0.0\"\n  }\n}\n",[39,1911,1912,1916,1926,1934,1944,1949],{"__ignoreMap":264},[268,1913,1914],{"class":270,"line":271},[268,1915,1775],{"class":282},[268,1917,1918,1920,1922,1924],{"class":270,"line":286},[268,1919,1780],{"class":305},[268,1921,1783],{"class":282},[268,1923,1786],{"class":289},[268,1925,1789],{"class":282},[268,1927,1928,1931],{"class":270,"line":296},[268,1929,1930],{"class":305},"  \"engines\"",[268,1932,1933],{"class":282},": {\n",[268,1935,1936,1939,1941],{"class":270,"line":311},[268,1937,1938],{"class":305},"    \"node\"",[268,1940,1783],{"class":282},[268,1942,1943],{"class":289},"\">=18.0.0\"\n",[268,1945,1946],{"class":270,"line":788},[268,1947,1948],{"class":282},"  }\n",[268,1950,1952],{"class":270,"line":1951},6,[268,1953,314],{"class":282},[23,1955,1957,1967,1980,1986],{"className":1956},[26],[28,1958,1960,1962,1963,1966],{"className":1959},[31],[33,1961],{"disabled":35,"type":36}," It automatically installs the specified Node.js version when ",[39,1964,1965],{},"npm install"," runs",[28,1968,1970,1972,1973,1975,1976,1979],{"className":1969},[31],[33,1971],{"disabled":35,"type":36}," It declares the Node.js (and optionally npm) version range the package expects; by default ",[39,1974,1965],{}," only warns (doesn't block) if the current version doesn't match, unless ",[39,1977,1978],{},"engine-strict"," is enabled",[28,1981,1983,1985],{"className":1982},[31],[33,1984],{"disabled":35,"type":36}," It sets the JavaScript engine (V8, SpiderMonkey, etc.) the app requires",[28,1987,1989,1991],{"className":1988},[31],[33,1990],{"disabled":35,"type":36}," It is required for ES modules to work",[66,1993,1994,1996,2004],{},[69,1995,71],{},[73,1997,1998,2000,2001,2003],{},[76,1999,78],{}," B — It declares the expected Node\u002Fnpm version range; npm warns by default rather than blocking, unless ",[39,2002,1978],{}," is set",[73,2005,2006,355,2008,2010,2011,2014,2015,2018,2019,2022,2023,446,2026,2029,2030,2033,2034,2036,2037,2039,2040,462],{},[76,2007,84],{},[76,2009,930],{}," teams add ",[39,2012,2013],{},"engines"," to document compatibility and catch version mismatches early, but by default npm treats a mismatch as a warning, not a hard failure — many developers are surprised the install still succeeds. Setting ",[39,2016,2017],{},"engine-strict=true"," in ",[39,2020,2021],{},".npmrc"," (or using tools like ",[39,2024,2025],{},"volta",[39,2027,2028],{},"nvm"," with ",[39,2031,2032],{},".nvmrc",") is needed to actually enforce it. Option A confuses it with a version manager's job — npm doesn't install Node versions. Option C confuses \"engine\" as used in ",[39,2035,737],{}," (meaning runtime version) with a JS engine like V8. Option D is unrelated; ESM support depends on the ",[39,2038,733],{}," field and Node version, not ",[39,2041,2013],{},[15,2043,2044,2048,2083],{},[18,2045,2047],{"id":2046},"q20-what-is-the-recommended-way-to-check-whether-a-javascript-runtime-supports-a-given-feature-eg-optional-chaining-before-using-it-in-production-code","Q20. What is the recommended way to check whether a JavaScript runtime supports a given feature (e.g., optional chaining) before using it in production code?",[23,2049,2051,2061,2067,2073],{"className":2050},[26],[28,2052,2054,2056,2057,2060],{"className":2053},[31],[33,2055],{"disabled":35,"type":36}," Parse the ",[39,2058,2059],{},"navigator.userAgent"," string and branch based on browser name\u002Fversion",[28,2062,2064,2066],{"className":2063},[31],[33,2065],{"disabled":35,"type":36}," Use feature detection — check for the existence of the API\u002Fbehavior directly (or rely on a transpiler\u002Fpolyfill pipeline), rather than inferring support from the browser or engine identity",[28,2068,2070,2072],{"className":2069},[31],[33,2071],{"disabled":35,"type":36}," Assume all evergreen browsers support all features equally, so no check is needed",[28,2074,2076,2078,2079,2082],{"className":2075},[31],[33,2077],{"disabled":35,"type":36}," Wrap all code in ",[39,2080,2081],{},"try\u002Fcatch"," and silently ignore failures",[66,2084,2085,2087,2092],{},[69,2086,71],{},[73,2088,2089,2091],{},[76,2090,78],{}," B — Use feature detection rather than inferring support from browser\u002Fengine identity",[73,2093,2094,355,2096,2098,2099,42,2102,2105],{},[76,2095,84],{},[76,2097,930],{}," UA sniffing (option A) is notoriously unreliable — user agents can be spoofed, forks and embedded webviews report misleading strings, and new browser versions ship features unpredictably. Feature detection (checking ",[39,2100,2101],{},"typeof obj?.prop !== 'undefined'",[39,2103,2104],{},"'querySelector' in document",", etc.) or using build tooling (Babel\u002FTypeScript targets, Browserslist-driven polyfills) checks reality directly. Option C is risky since even \"evergreen\" runtimes lag on brand-new proposals. Option D silently swallowing errors trades a clear compatibility failure for a much harder-to-debug silent one, which is the opposite of good practice.",[2107,2108,2109],"style",{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sk71V, html code.shiki .sk71V{--shiki-default:#22863A;--shiki-github-dark:#85E89D}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}",{"title":264,"searchDepth":286,"depth":286,"links":2111},[2112,2113,2114,2115,2117,2119,2121,2122,2123,2124,2126,2128,2130,2131,2133,2135,2137,2139,2141,2143],{"id":20,"depth":296,"text":21},{"id":116,"depth":296,"text":117},{"id":195,"depth":296,"text":196},{"id":250,"depth":296,"text":2116},"Q4. Where must a \"use strict\" directive appear to enable strict mode for an entire script?",{"id":371,"depth":296,"text":2118},"Q5. By default, how does a browser handle a plain \u003Cscript src=\"app.js\">\u003C\u002Fscript> tag with no async, defer, or type=\"module\" attributes?",{"id":467,"depth":296,"text":2120},"Q6. A \u003Cscript type=\"module\"> tag behaves like which combination of attributes by default?",{"id":538,"depth":296,"text":539},{"id":598,"depth":296,"text":599},{"id":746,"depth":296,"text":747},{"id":877,"depth":296,"text":2125},"Q10. Do ES modules (\u003Cscript type=\"module\"> or .mjs files) require an explicit \"use strict\" directive to run in strict mode?",{"id":946,"depth":296,"text":2127},"Q11. What does top-level this refer to in each of: a classic (non-module) browser script, an ES module, and a Node.js CommonJS file?",{"id":1059,"depth":296,"text":2129},"Q12. Given two scripts loaded with async, in what order do they execute relative to each other?",{"id":1196,"depth":296,"text":1197},{"id":1318,"depth":296,"text":2132},"Q14. How does eval() behave differently in strict mode versus non-strict mode regarding variable declarations?",{"id":1461,"depth":296,"text":2134},"Q15. Is it necessary to add \"use strict\" at the top of a file that only contains ES class declarations and no other top-level code?",{"id":1534,"depth":296,"text":2136},"Q16. What is the idiomatic reason modern projects prefer \u003Cscript type=\"module\"> over the older \u003Cscript nomodule> fallback pattern?",{"id":1675,"depth":296,"text":2138},"Q17. Why is defer generally preferred over placing multiple plain \u003Cscript> tags right before \u003C\u002Fbody>?",{"id":1754,"depth":296,"text":2140},"Q18. Setting \"type\": \"module\" in a Node.js package.json changes what?",{"id":1898,"depth":296,"text":2142},"Q19. What is the purpose of the \"engines\" field in package.json?",{"id":2046,"depth":296,"text":2047},"md",{},"\u002Fjs\u002F01-introduction-and-setup",{"title":6,"description":264},"js\u002F01-introduction-and-setup","057e7M3dBnyPZbrNFkox6JTX-lHc414h7f3Yg0IbFMU",{"id":2151,"title":2152,"body":2153,"description":264,"extension":2144,"meta":5204,"navigation":35,"path":5205,"seo":5206,"stem":5207,"__hash__":5208},"content\u002Fjs\u002F02-variables-and-data-types.md","02 — Variables & Data Types",{"type":8,"value":2154,"toc":5168},[2155,2158,2352,2481,2610,2762,2911,2995,3139,3323,3525,3657,3805,3942,4049,4193,4289,4466,4610,4756,5000,5165],[11,2156,2152],{"id":2157},"_02-variables-data-types",[15,2159,2160,2168,2239,2300],{"language":247},[18,2161,2163,2164,186,2166,1685],{"id":2162},"q1-what-is-the-key-scoping-difference-between-var-and-let","Q1. What is the key scoping difference between ",[39,2165,1440],{},[39,2167,240],{},[257,2169,2170],{"language":247},[260,2171,2173],{"className":262,"code":2172,"language":247,"meta":264,"style":264},"if (true) {\n  var a = 1;\n  let b = 2;\n}\nconsole.log(a);\nconsole.log(b);\n",[39,2174,2175,2188,2202,2217,2221,2230],{"__ignoreMap":264},[268,2176,2177,2180,2183,2186],{"class":270,"line":271},[268,2178,2179],{"class":274},"if",[268,2181,2182],{"class":282}," (",[268,2184,2185],{"class":305},"true",[268,2187,1235],{"class":282},[268,2189,2190,2193,2195,2197,2200],{"class":270,"line":286},[268,2191,2192],{"class":274},"  var",[268,2194,1243],{"class":282},[268,2196,302],{"class":274},[268,2198,2199],{"class":305}," 1",[268,2201,293],{"class":282},[268,2203,2204,2207,2210,2212,2215],{"class":270,"line":296},[268,2205,2206],{"class":274},"  let",[268,2208,2209],{"class":282}," b ",[268,2211,302],{"class":274},[268,2213,2214],{"class":305}," 2",[268,2216,293],{"class":282},[268,2218,2219],{"class":270,"line":311},[268,2220,314],{"class":282},[268,2222,2223,2225,2227],{"class":270,"line":788},[268,2224,1353],{"class":282},[268,2226,1356],{"class":278},[268,2228,2229],{"class":282},"(a);\n",[268,2231,2232,2234,2236],{"class":270,"line":1951},[268,2233,1353],{"class":282},[268,2235,1356],{"class":278},[268,2237,2238],{"class":282},"(b);\n",[23,2240,2242,2259,2281,2289],{"className":2241},[26],[28,2243,2245,2247,2248,186,2250,2252,2253,1133,2256],{"className":2244},[31],[33,2246],{"disabled":35,"type":36}," Both ",[39,2249,1223],{},[39,2251,1232],{}," are accessible outside the block; the code logs ",[39,2254,2255],{},"1",[39,2257,2258],{},"2",[28,2260,2262,355,2264,2266,2267,2269,2270,2272,2273,2275,2276,2278,2279],{"className":2261},[31],[33,2263],{"disabled":35,"type":36},[39,2265,1440],{}," is function\u002Fglobal-scoped so ",[39,2268,1223],{}," logs ",[39,2271,2255],{},"; ",[39,2274,240],{}," is block-scoped so accessing ",[39,2277,1232],{}," throws a ",[39,2280,815],{},[28,2282,2284,2286,2287],{"className":2283},[31],[33,2285],{"disabled":35,"type":36}," Neither is accessible outside the block; both throw ",[39,2288,815],{},[28,2290,2292,355,2294,2296,2297,2299],{"className":2291},[31],[33,2293],{"disabled":35,"type":36},[39,2295,240],{}," is function-scoped and ",[39,2298,1440],{}," is block-scoped, the reverse of the truth",[66,2301,2302,2304,2319],{},[69,2303,71],{},[73,2305,2306,1727,2308,2266,2310,2269,2312,2272,2314,2275,2316,2318],{},[76,2307,78],{},[39,2309,1440],{},[39,2311,1223],{},[39,2313,2255],{},[39,2315,240],{},[39,2317,1232],{}," throws",[73,2320,2321,355,2323,2325,2326,2329,2330,2332,2333,2335,2336,2338,2339,2341,2342,2344,2345,2347,2348,2351],{},[76,2322,84],{},[39,2324,1440],{}," ignores block boundaries (",[39,2327,2328],{},"{}",") and attaches to the nearest function or global scope, so ",[39,2331,1223],{}," leaks out of the ",[39,2334,2179],{}," block. ",[39,2337,240],{}," (and ",[39,2340,243],{},") are genuinely block-scoped, so ",[39,2343,1232],{}," does not exist outside the ",[39,2346,2179],{}," block, and referencing it throws ",[39,2349,2350],{},"ReferenceError: b is not defined",". Option A wrongly assumes both leak. Option D swaps the actual rule.",[15,2353,2354,2360,2390,2442],{"language":247},[18,2355,2357,2358,1685],{"id":2356},"q2-what-is-variable-hoisting-as-it-applies-to-var","Q2. What is variable hoisting, as it applies to ",[39,2359,1440],{},[257,2361,2362],{"language":247},[260,2363,2365],{"className":262,"code":2364,"language":247,"meta":264,"style":264},"console.log(x);\nvar x = 5;\n",[39,2366,2367,2376],{"__ignoreMap":264},[268,2368,2369,2371,2373],{"class":270,"line":271},[268,2370,1353],{"class":282},[268,2372,1356],{"class":278},[268,2374,2375],{"class":282},"(x);\n",[268,2377,2378,2380,2383,2385,2388],{"class":270,"line":286},[268,2379,1440],{"class":274},[268,2381,2382],{"class":282}," x ",[268,2384,302],{"class":274},[268,2386,2387],{"class":305}," 5",[268,2389,293],{"class":282},[23,2391,2393,2405,2422,2431],{"className":2392},[26],[28,2394,2396,2398,2399,183,2401,2404],{"className":2395},[31],[33,2397],{"disabled":35,"type":36}," This throws a ",[39,2400,815],{},[39,2402,2403],{},"x"," is used before declaration",[28,2406,2408,2410,2411,2413,2414,2417,2418,2421],{"className":2407},[31],[33,2409],{"disabled":35,"type":36}," This logs ",[39,2412,833],{},", because the declaration ",[39,2415,2416],{},"var x"," is hoisted to the top of scope but the assignment ",[39,2419,2420],{},"= 5"," is not",[28,2423,2425,2410,2427,2430],{"className":2424},[31],[33,2426],{"disabled":35,"type":36},[39,2428,2429],{},"5",", because JavaScript hoists both the declaration and the assignment",[28,2432,2434,2436,2437,183,2439,2441],{"className":2433},[31],[33,2435],{"disabled":35,"type":36}," This is a ",[39,2438,1274],{},[39,2440,1440],{}," cannot be declared after use",[66,2443,2444,2446,2454],{},[69,2445,71],{},[73,2447,2448,2450,2451,2453],{},[76,2449,78],{}," B — Logs ",[39,2452,833],{},"; the declaration is hoisted but the assignment stays in place",[73,2455,2456,2458,2459,2461,2462,2464,2465,2468,2469,2472,2473,2475,2476,446,2478,2480],{},[76,2457,84],{}," During compilation, ",[39,2460,2416],{}," is conceptually moved to the top of its enclosing scope and initialized to ",[39,2463,833],{},"; the ",[39,2466,2467],{},"x = 5"," assignment still executes at its original position. So by the time ",[39,2470,2471],{},"console.log(x)"," runs, ",[39,2474,2403],{}," exists but hasn't been assigned yet. Option A confuses this with ",[39,2477,240],{},[39,2479,243],{},"'s TDZ behavior. Option C is the common misconception that hoisting moves the whole statement, initializer included — it only moves the declaration.",[15,2482,2483,2487,2516,2559],{"language":247},[18,2484,2486],{"id":2485},"q3-what-is-the-temporal-dead-zone-tdz","Q3. What is the Temporal Dead Zone (TDZ)?",[257,2488,2489],{"language":247},[260,2490,2492],{"className":262,"code":2491,"language":247,"meta":264,"style":264},"console.log(y);\nlet y = 10;\n",[39,2493,2494,2503],{"__ignoreMap":264},[268,2495,2496,2498,2500],{"class":270,"line":271},[268,2497,1353],{"class":282},[268,2499,1356],{"class":278},[268,2501,2502],{"class":282},"(y);\n",[268,2504,2505,2507,2510,2512,2514],{"class":270,"line":286},[268,2506,240],{"class":274},[268,2508,2509],{"class":282}," y ",[268,2511,302],{"class":274},[268,2513,306],{"class":305},[268,2515,293],{"class":282},[23,2517,2519,2531,2547,2553],{"className":2518},[26],[28,2520,2522,2524,2525,2527,2528,2530],{"className":2521},[31],[33,2523],{"disabled":35,"type":36}," The period during which a ",[39,2526,1440],{}," variable holds ",[39,2529,833],{}," before assignment",[28,2532,2534,2536,2537,446,2539,2541,2542,2544,2545],{"className":2533},[31],[33,2535],{"disabled":35,"type":36}," The span between entering a scope and a ",[39,2538,240],{},[39,2540,243],{}," variable's declaration line, during which accessing the variable throws a ",[39,2543,815],{}," instead of returning ",[39,2546,833],{},[28,2548,2550,2552],{"className":2549},[31],[33,2551],{"disabled":35,"type":36}," A deprecated ES5 feature no longer relevant in modern JS",[28,2554,2556,2558],{"className":2555},[31],[33,2557],{"disabled":35,"type":36}," The time it takes the garbage collector to free an unused variable",[66,2560,2561,2563,2575],{},[69,2562,71],{},[73,2564,2565,2567,2568,446,2570,2572,2573],{},[76,2566,78],{}," B — The span before a ",[39,2569,240],{},[39,2571,243],{}," declaration executes, where accessing it throws instead of returning ",[39,2574,833],{},[73,2576,2577,355,2579,186,2581,2583,2584,2586,2587,2589,2590,2592,2593,2596,2597,2600,2601,2603,2604,2606,2607,2609],{},[76,2578,84],{},[39,2580,240],{},[39,2582,243],{}," are hoisted too, but unlike ",[39,2585,1440],{}," they are not initialized to ",[39,2588,833],{}," — they remain in an uninitialized \"temporal dead zone\" from the top of the block until their declaration executes. ",[76,2591,365],{}," this is why ",[39,2594,2595],{},"console.log(y)"," here throws ",[39,2598,2599],{},"ReferenceError: Cannot access 'y' before initialization"," rather than silently logging ",[39,2602,833],{}," like the ",[39,2605,1440],{}," case would. Option A describes ",[39,2608,1440],{},"'s actual (different) behavior. Option C and D are fabricated.",[15,2611,2612,2616,2691],{},[18,2613,2615],{"id":2614},"q4-which-of-the-following-are-javascript-primitive-types-select-the-option-that-lists-only-primitives","Q4. Which of the following are JavaScript primitive types? (Select the option that lists ONLY primitives)",[23,2617,2619,2635,2657,2673],{"className":2618},[26],[28,2620,2622,355,2624,42,2627,42,2630,42,2632],{"className":2621},[31],[33,2623],{"disabled":35,"type":36},[39,2625,2626],{},"string",[39,2628,2629],{},"number",[39,2631,88],{},[39,2633,2634],{},"boolean",[28,2636,2638,355,2640,42,2642,42,2644,42,2646,42,2648,42,2651,42,2654],{"className":2637},[31],[33,2639],{"disabled":35,"type":36},[39,2641,2626],{},[39,2643,2629],{},[39,2645,2634],{},[39,2647,833],{},[39,2649,2650],{},"null",[39,2652,2653],{},"symbol",[39,2655,2656],{},"bigint",[28,2658,2660,355,2662,42,2665,42,2667,42,2670],{"className":2659},[31],[33,2661],{"disabled":35,"type":36},[39,2663,2664],{},"object",[39,2666,275],{},[39,2668,2669],{},"Date",[39,2671,2672],{},"Map",[28,2674,2676,355,2678,42,2680,42,2683,2686,2687,2690],{"className":2675},[31],[33,2677],{"disabled":35,"type":36},[39,2679,2626],{},[39,2681,2682],{},"Number",[39,2684,2685],{},"Boolean"," (the wrapper objects created via ",[39,2688,2689],{},"new",")",[66,2692,2693,2695,2713],{},[69,2694,71],{},[73,2696,2697,1727,2699,42,2701,42,2703,42,2705,42,2707,42,2709,42,2711],{},[76,2698,78],{},[39,2700,2626],{},[39,2702,2629],{},[39,2704,2634],{},[39,2706,833],{},[39,2708,2650],{},[39,2710,2653],{},[39,2712,2656],{},[73,2714,2715,2717,2718,42,2720,42,2722,42,2724,42,2726,42,2728,2730,2731,2733,2734,42,2736,2738,2739,2741,2742,2744,2745,2748,2749,2751,2752,830,2755,2758,2759,462],{},[76,2716,84],{}," JavaScript has exactly seven primitive types: ",[39,2719,2626],{},[39,2721,2629],{},[39,2723,2634],{},[39,2725,833],{},[39,2727,2650],{},[39,2729,2653],{}," (ES2015), and ",[39,2732,2656],{}," (ES2020). Everything else — arrays, plain objects, functions, ",[39,2735,2669],{},[39,2737,2672],{}," — is a reference type (",[39,2740,2664],{}," under the hood). Option A wrongly includes ",[39,2743,88],{},", which is a reference type. Option D is a trap: ",[39,2746,2747],{},"new String(\"x\")"," creates a boxed ",[104,2750,2664],{},", not a primitive string — ",[39,2753,2754],{},"typeof new String(\"x\")",[39,2756,2757],{},"\"object\"",", not ",[39,2760,2761],{},"\"string\"",[15,2763,2764,2768,2823,2878],{"language":247},[18,2765,2767],{"id":2766},"q5-how-are-primitives-and-reference-types-objectsarrays-different-when-assigned-to-a-new-variable","Q5. How are primitives and reference types (objects\u002Farrays) different when assigned to a new variable?",[257,2769,2770],{"language":247},[260,2771,2773],{"className":262,"code":2772,"language":247,"meta":264,"style":264},"let a = { count: 1 };\nlet b = a;\nb.count = 99;\nconsole.log(a.count);\n",[39,2774,2775,2791,2802,2814],{"__ignoreMap":264},[268,2776,2777,2779,2781,2783,2786,2788],{"class":270,"line":271},[268,2778,240],{"class":274},[268,2780,1243],{"class":282},[268,2782,302],{"class":274},[268,2784,2785],{"class":282}," { count: ",[268,2787,2255],{"class":305},[268,2789,2790],{"class":282}," };\n",[268,2792,2793,2795,2797,2799],{"class":270,"line":286},[268,2794,240],{"class":274},[268,2796,2209],{"class":282},[268,2798,302],{"class":274},[268,2800,2801],{"class":282}," a;\n",[268,2803,2804,2807,2809,2812],{"class":270,"line":296},[268,2805,2806],{"class":282},"b.count ",[268,2808,302],{"class":274},[268,2810,2811],{"class":305}," 99",[268,2813,293],{"class":282},[268,2815,2816,2818,2820],{"class":270,"line":311},[268,2817,1353],{"class":282},[268,2819,1356],{"class":278},[268,2821,2822],{"class":282},"(a.count);\n",[23,2824,2826,2839,2856,2870],{"className":2825},[26],[28,2827,2829,355,2831,2833,2834,2836,2837],{"className":2828},[31],[33,2830],{"disabled":35,"type":36},[39,2832,2255],{},", because ",[39,2835,1232],{}," is a fully independent copy of ",[39,2838,1223],{},[28,2840,2842,355,2844,2833,2847,2850,2851,186,2853,2855],{"className":2841},[31],[33,2843],{"disabled":35,"type":36},[39,2845,2846],{},"99",[39,2848,2849],{},"b = a"," copies the reference, so ",[39,2852,1223],{},[39,2854,1232],{}," point to the same object in memory",[28,2857,2859,355,2861,2863,2864,2867,2868],{"className":2858},[31],[33,2860],{"disabled":35,"type":36},[39,2862,833],{},", because reassigning ",[39,2865,2866],{},"b.count"," breaks the link to ",[39,2869,1223],{},[28,2871,2873,2398,2875,2877],{"className":2872},[31],[33,2874],{"disabled":35,"type":36},[39,2876,827],{}," because objects are immutable by default",[66,2879,2880,2882,2889],{},[69,2881,71],{},[73,2883,2884,1727,2886,2888],{},[76,2885,78],{},[39,2887,2846],{},", because objects are assigned\u002Fcopied by reference",[73,2890,2891,2893,2894,2897,2898,186,2900,2902,2903,2906,2907,2910],{},[76,2892,84],{}," Reference types are stored as a pointer to a location in memory; ",[39,2895,2896],{},"let b = a"," copies that pointer, not the object's contents, so ",[39,2899,1223],{},[39,2901,1232],{}," alias the same object — mutating via one is visible through the other. This is different from primitives, where ",[39,2904,2905],{},"let x = 1; let y = x;"," gives ",[39,2908,2909],{},"y"," a fully independent copy of the value. Option A describes primitive copy semantics, mistakenly applied to an object. Option C and D are fabricated — nothing here breaks a link or throws.",[15,2912,2913,2921,2954],{},[18,2914,2916,2917,2920],{"id":2915},"q6-what-does-typeof-null-evaluate-to","Q6. What does ",[39,2918,2919],{},"typeof null"," evaluate to?",[23,2922,2924,2932,2939,2946],{"className":2923},[26],[28,2925,2927,355,2929],{"className":2926},[31],[33,2928],{"disabled":35,"type":36},[39,2930,2931],{},"\"null\"",[28,2933,2935,355,2937],{"className":2934},[31],[33,2936],{"disabled":35,"type":36},[39,2938,1397],{},[28,2940,2942,355,2944],{"className":2941},[31],[33,2943],{"disabled":35,"type":36},[39,2945,2757],{},[28,2947,2949,355,2951],{"className":2948},[31],[33,2950],{"disabled":35,"type":36},[39,2952,2953],{},"\"boolean\"",[66,2955,2956,2958,2964],{},[69,2957,71],{},[73,2959,2960,1004,2962],{},[76,2961,78],{},[39,2963,2757],{},[73,2965,2966,355,2968,2970,2971,2974,2975,2977,2978,2980,2981,830,2984,137,2987,2989,2990,2029,2992,2994],{},[76,2967,84],{},[76,2969,365],{}," this is one of JavaScript's most famous quirks — ",[39,2972,2973],{},"typeof null === \"object\""," is a bug baked into the language since its first implementation (null was represented internally with the same tag as objects) and has been kept for backward compatibility ever since; it will never be fixed. It does ",[104,2976,95],{}," mean ",[39,2979,2650],{}," is actually an object — ",[39,2982,2983],{},"null === undefined",[39,2985,2986],{},"false",[39,2988,2650],{}," has no properties\u002Fmethods. Option A is the intuitive-but-wrong guess. Option B confuses ",[39,2991,2650],{},[39,2993,833],{},", a related but distinct \"empty\" value.",[15,2996,2997,3008,3048,3088],{"language":247},[18,2998,3000,3001,3004,3005,2920],{"id":2999},"q7-what-does-typeof-nan-evaluate-to-and-what-does-nan-nan-evaluate-to","Q7. What does ",[39,3002,3003],{},"typeof NaN"," evaluate to, and what does ",[39,3006,3007],{},"NaN === NaN",[257,3009,3010],{"language":247},[260,3011,3013],{"className":262,"code":3012,"language":247,"meta":264,"style":264},"console.log(typeof NaN);\nconsole.log(NaN === NaN);\n",[39,3014,3015,3030],{"__ignoreMap":264},[268,3016,3017,3019,3021,3023,3025,3028],{"class":270,"line":271},[268,3018,1353],{"class":282},[268,3020,1356],{"class":278},[268,3022,622],{"class":282},[268,3024,1361],{"class":274},[268,3026,3027],{"class":305}," NaN",[268,3029,628],{"class":282},[268,3031,3032,3034,3036,3038,3041,3044,3046],{"class":270,"line":286},[268,3033,1353],{"class":282},[268,3035,1356],{"class":278},[268,3037,622],{"class":282},[268,3039,3040],{"class":305},"NaN",[268,3042,3043],{"class":274}," ===",[268,3045,3027],{"class":305},[268,3047,628],{"class":282},[23,3049,3051,3061,3070,3079],{"className":3050},[26],[28,3052,3054,355,3056,186,3059],{"className":3053},[31],[33,3055],{"disabled":35,"type":36},[39,3057,3058],{},"\"NaN\"",[39,3060,2185],{},[28,3062,3064,355,3066,186,3068],{"className":3063},[31],[33,3065],{"disabled":35,"type":36},[39,3067,1383],{},[39,3069,2986],{},[28,3071,3073,355,3075,186,3077],{"className":3072},[31],[33,3074],{"disabled":35,"type":36},[39,3076,1397],{},[39,3078,2986],{},[28,3080,3082,355,3084,186,3086],{"className":3081},[31],[33,3083],{"disabled":35,"type":36},[39,3085,1383],{},[39,3087,2185],{},[66,3089,3090,3092,3100],{},[69,3091,71],{},[73,3093,3094,1727,3096,186,3098],{},[76,3095,78],{},[39,3097,1383],{},[39,3099,2986],{},[73,3101,3102,355,3104,3106,3107,3109,3110,355,3112,3114,3115,3118,3119,830,3121,3123,3124,3126,3127,3130,3131,3134,3135,3138],{},[76,3103,84],{},[39,3105,3040],{}," (\"Not a Number\") is, paradoxically, of type ",[39,3108,1383],{}," — it represents an invalid numeric result but is still part of the number type. ",[76,3111,365],{},[39,3113,3040],{}," is the ",[104,3116,3117],{},"only"," value in JavaScript that is not equal to itself, by IEEE-754 floating-point spec design, so ",[39,3120,3007],{},[39,3122,2986],{},". To actually test for ",[39,3125,3040],{},", use ",[39,3128,3129],{},"Number.isNaN(x)"," (not the legacy, coercing global ",[39,3132,3133],{},"isNaN(x)",") or ",[39,3136,3137],{},"Object.is(x, NaN)",". Options A, C, and D all misstate one or both facts.",[15,3140,3141,3145,3203,3250],{"language":247},[18,3142,3144],{"id":3143},"q8-which-of-these-correctly-demonstrates-implicit-type-coercion-in-a-comparison","Q8. Which of these correctly demonstrates implicit type coercion in a comparison?",[257,3146,3147],{"language":247},[260,3148,3150],{"className":262,"code":3149,"language":247,"meta":264,"style":264},"console.log(\"5\" == 5);\nconsole.log(\"5\" === 5);\nconsole.log([] == false);\n",[39,3151,3152,3170,3186],{"__ignoreMap":264},[268,3153,3154,3156,3158,3160,3163,3166,3168],{"class":270,"line":271},[268,3155,1353],{"class":282},[268,3157,1356],{"class":278},[268,3159,622],{"class":282},[268,3161,3162],{"class":289},"\"5\"",[268,3164,3165],{"class":274}," ==",[268,3167,2387],{"class":305},[268,3169,628],{"class":282},[268,3171,3172,3174,3176,3178,3180,3182,3184],{"class":270,"line":286},[268,3173,1353],{"class":282},[268,3175,1356],{"class":278},[268,3177,622],{"class":282},[268,3179,3162],{"class":289},[268,3181,3043],{"class":274},[268,3183,2387],{"class":305},[268,3185,628],{"class":282},[268,3187,3188,3190,3192,3195,3198,3201],{"class":270,"line":296},[268,3189,1353],{"class":282},[268,3191,1356],{"class":278},[268,3193,3194],{"class":282},"([] ",[268,3196,3197],{"class":274},"==",[268,3199,3200],{"class":305}," false",[268,3202,628],{"class":282},[23,3204,3206,3217,3228,3239],{"className":3205},[26],[28,3207,3209,355,3211,42,3213,42,3215],{"className":3208},[31],[33,3210],{"disabled":35,"type":36},[39,3212,2986],{},[39,3214,2986],{},[39,3216,2986],{},[28,3218,3220,355,3222,42,3224,42,3226],{"className":3219},[31],[33,3221],{"disabled":35,"type":36},[39,3223,2185],{},[39,3225,2185],{},[39,3227,2185],{},[28,3229,3231,355,3233,42,3235,42,3237],{"className":3230},[31],[33,3232],{"disabled":35,"type":36},[39,3234,2185],{},[39,3236,2986],{},[39,3238,2185],{},[28,3240,3242,355,3244,42,3246,42,3248],{"className":3241},[31],[33,3243],{"disabled":35,"type":36},[39,3245,2185],{},[39,3247,2986],{},[39,3249,2986],{},[66,3251,3252,3254,3264],{},[69,3253,71],{},[73,3255,3256,1004,3258,42,3260,42,3262],{},[76,3257,78],{},[39,3259,2185],{},[39,3261,2986],{},[39,3263,2185],{},[73,3265,3266,355,3268,3270,3271,3274,3275,3277,3278,3281,3282,3277,3284,3287,3288,3291,3292,3295,3296,3299,3300,186,3302,3304,3305,186,3308,3310,3311,3313,3314,3316,3317,3319,3320,3322],{},[76,3267,84],{},[39,3269,3197],{}," performs type coercion before comparing: ",[39,3272,3273],{},"\"5\" == 5"," coerces the string to a number, giving ",[39,3276,2185],{},". ",[39,3279,3280],{},"==="," performs no coercion, so comparing a string to a number is always ",[39,3283,2986],{},[39,3285,3286],{},"[] == false"," is a classic gotcha: ",[39,3289,3290],{},"[]"," is coerced to ",[39,3293,3294],{},"\"\""," (via ",[39,3297,3298],{},"ToPrimitive","), then ",[39,3301,3294],{},[39,3303,2986],{}," are both coerced to numbers (",[39,3306,3307],{},"0",[39,3309,3307],{},"), so it's ",[39,3312,2185],{}," — despite an array and a boolean seeming completely unrelated. ",[76,3315,930],{}," this exact unpredictability is why ",[39,3318,3280],{}," is recommended over ",[39,3321,3197],{}," in production code.",[15,3324,3325,3331,3399,3451],{"language":247},[18,3326,3328,3329,1685],{"id":3327},"q9-what-is-the-result-of-adding-a-number-and-a-string-with","Q9. What is the result of adding a number and a string with ",[39,3330,1246],{},[257,3332,3333],{"language":247},[260,3334,3336],{"className":262,"code":3335,"language":247,"meta":264,"style":264},"console.log(1 + \"2\");\nconsole.log(1 + 2 + \"3\");\nconsole.log(\"1\" + 2 + 3);\n",[39,3337,3338,3356,3377],{"__ignoreMap":264},[268,3339,3340,3342,3344,3346,3348,3351,3354],{"class":270,"line":271},[268,3341,1353],{"class":282},[268,3343,1356],{"class":278},[268,3345,622],{"class":282},[268,3347,2255],{"class":305},[268,3349,3350],{"class":274}," +",[268,3352,3353],{"class":289}," \"2\"",[268,3355,628],{"class":282},[268,3357,3358,3360,3362,3364,3366,3368,3370,3372,3375],{"class":270,"line":286},[268,3359,1353],{"class":282},[268,3361,1356],{"class":278},[268,3363,622],{"class":282},[268,3365,2255],{"class":305},[268,3367,3350],{"class":274},[268,3369,2214],{"class":305},[268,3371,3350],{"class":274},[268,3373,3374],{"class":289}," \"3\"",[268,3376,628],{"class":282},[268,3378,3379,3381,3383,3385,3388,3390,3392,3394,3397],{"class":270,"line":296},[268,3380,1353],{"class":282},[268,3382,1356],{"class":278},[268,3384,622],{"class":282},[268,3386,3387],{"class":289},"\"1\"",[268,3389,3350],{"class":274},[268,3391,2214],{"class":305},[268,3393,3350],{"class":274},[268,3395,3396],{"class":305}," 3",[268,3398,628],{"class":282},[23,3400,3402,3416,3429,3440],{"className":3401},[26],[28,3403,3405,355,3407,42,3410,42,3413],{"className":3404},[31],[33,3406],{"disabled":35,"type":36},[39,3408,3409],{},"\"12\"",[39,3411,3412],{},"\"33\"",[39,3414,3415],{},"\"123\"",[28,3417,3419,355,3421,42,3424,42,3426],{"className":3418},[31],[33,3420],{"disabled":35,"type":36},[39,3422,3423],{},"3",[39,3425,3412],{},[39,3427,3428],{},"\"15\"",[28,3430,3432,355,3434,42,3436,42,3438],{"className":3431},[31],[33,3433],{"disabled":35,"type":36},[39,3435,3409],{},[39,3437,3412],{},[39,3439,3412],{},[28,3441,3443,355,3445,42,3447,42,3449],{"className":3442},[31],[33,3444],{"disabled":35,"type":36},[39,3446,3040],{},[39,3448,3040],{},[39,3450,3415],{},[66,3452,3453,3455,3466],{},[69,3454,71],{},[73,3456,3457,3459,3460,42,3462,42,3464],{},[76,3458,78],{}," A — ",[39,3461,3409],{},[39,3463,3412],{},[39,3465,3415],{},[73,3467,3468,355,3470,3472,3473,3476,3477,3291,3479,3481,3482,3277,3484,1783,3487,3490,3491,3493,3494,3497,3498,3277,3500,1783,3503,3497,3506,3508,3509,3497,3512,3514,3515,3517,3518,3521,3522,3524],{},[76,3469,84],{},[39,3471,1246],{}," evaluates left-to-right. ",[39,3474,3475],{},"1 + \"2\"",": number meets string, so ",[39,3478,2255],{},[39,3480,3387],{}," and they concatenate to ",[39,3483,3409],{},[39,3485,3486],{},"1 + 2 + \"3\"",[39,3488,3489],{},"1 + 2"," happens first (both numbers) giving ",[39,3492,3423],{},", then ",[39,3495,3496],{},"3 + \"3\""," concatenates to ",[39,3499,3412],{},[39,3501,3502],{},"\"1\" + 2 + 3",[39,3504,3505],{},"\"1\" + 2",[39,3507,3409],{}," first (left-to-right), then ",[39,3510,3511],{},"\"12\" + 3",[39,3513,3415],{}," — note it does ",[76,3516,95],{}," add ",[39,3519,3520],{},"2 + 3"," first, because ",[39,3523,1246],{}," has no special \"do the numbers first\" rule; it strictly evaluates left to right. This ordering trap is a frequent source of bugs when mixing types.",[15,3526,3527,3534,3570,3613],{"language":247},[18,3528,3530,3531,3533],{"id":3529},"q10-what-happens-when-you-access-a-property-on-undefined-versus-declaring-a-variable-with-no-initializer","Q10. What happens when you access a property on ",[39,3532,833],{},", versus declaring a variable with no initializer?",[257,3535,3536],{"language":247},[260,3537,3539],{"className":262,"code":3538,"language":247,"meta":264,"style":264},"let x;\nconsole.log(x);\nconsole.log(x.length);\n",[39,3540,3541,3548,3556],{"__ignoreMap":264},[268,3542,3543,3545],{"class":270,"line":271},[268,3544,240],{"class":274},[268,3546,3547],{"class":282}," x;\n",[268,3549,3550,3552,3554],{"class":270,"line":286},[268,3551,1353],{"class":282},[268,3553,1356],{"class":278},[268,3555,2375],{"class":282},[268,3557,3558,3560,3562,3565,3568],{"class":270,"line":296},[268,3559,1353],{"class":282},[268,3561,1356],{"class":278},[268,3563,3564],{"class":282},"(x.",[268,3566,3567],{"class":305},"length",[268,3569,628],{"class":282},[23,3571,3573,3584,3595,3604],{"className":3572},[26],[28,3574,3576,3578,3579,3581,3582],{"className":3575},[31],[33,3577],{"disabled":35,"type":36}," Logs ",[39,3580,833],{},", then logs ",[39,3583,3307],{},[28,3585,3587,3578,3589,3591,3592],{"className":3586},[31],[33,3588],{"disabled":35,"type":36},[39,3590,833],{},", then throws ",[39,3593,3594],{},"TypeError: Cannot read properties of undefined (reading 'length')",[28,3596,3598,3578,3600,3591,3602],{"className":3597},[31],[33,3599],{"disabled":35,"type":36},[39,3601,2650],{},[39,3603,815],{},[28,3605,3607,3609,3610,3612],{"className":3606},[31],[33,3608],{"disabled":35,"type":36}," Both lines throw, because ",[39,3611,2403],{}," is never assigned",[66,3614,3615,3617,3626],{},[69,3616,71],{},[73,3618,3619,2450,3621,3623,3624],{},[76,3620,78],{},[39,3622,833],{},", then throws a ",[39,3625,827],{},[73,3627,3628,812,3630,446,3632,3634,3635,3637,3638,3640,3641,3644,3645,3277,3647,3649,3650,3653,3654,3656],{},[76,3629,84],{},[39,3631,240],{},[39,3633,1440],{}," declared without an initializer is automatically set to ",[39,3636,833],{}," (not an error to read it, unlike TDZ). But ",[39,3639,833],{}," is a primitive with no properties, so attempting to read ",[39,3642,3643],{},".length"," off it throws ",[39,3646,827],{},[76,3648,365],{}," this exact error is one of the most common in production JS, typically from an object that was expected to exist (e.g., an API response field) but didn't. The fix is optional chaining (",[39,3651,3652],{},"x?.length",") or an existence check before access. Option A wrongly assumes property access on ",[39,3655,833],{}," is safe.",[15,3658,3659,3666,3713,3753],{"language":247},[18,3660,3662,3663,3665],{"id":3661},"q11-what-is-the-result-of-typeof-applied-to-a-function","Q11. What is the result of ",[39,3664,1361],{}," applied to a function?",[257,3667,3668],{"language":247},[260,3669,3671],{"className":262,"code":3670,"language":247,"meta":264,"style":264},"function greet() {}\nconsole.log(typeof greet);\nconsole.log(greet instanceof Object);\n",[39,3672,3673,3683,3696],{"__ignoreMap":264},[268,3674,3675,3677,3680],{"class":270,"line":271},[268,3676,275],{"class":274},[268,3678,3679],{"class":278}," greet",[268,3681,3682],{"class":282},"() {}\n",[268,3684,3685,3687,3689,3691,3693],{"class":270,"line":286},[268,3686,1353],{"class":282},[268,3688,1356],{"class":278},[268,3690,622],{"class":282},[268,3692,1361],{"class":274},[268,3694,3695],{"class":282}," greet);\n",[268,3697,3698,3700,3702,3705,3708,3711],{"class":270,"line":296},[268,3699,1353],{"class":282},[268,3701,1356],{"class":278},[268,3703,3704],{"class":282},"(greet ",[268,3706,3707],{"class":274},"instanceof",[268,3709,3710],{"class":278}," Object",[268,3712,628],{"class":282},[23,3714,3716,3725,3735,3744],{"className":3715},[26],[28,3717,3719,355,3721,186,3723],{"className":3718},[31],[33,3720],{"disabled":35,"type":36},[39,3722,2757],{},[39,3724,2185],{},[28,3726,3728,355,3730,186,3733],{"className":3727},[31],[33,3729],{"disabled":35,"type":36},[39,3731,3732],{},"\"function\"",[39,3734,2185],{},[28,3736,3738,355,3740,186,3742],{"className":3737},[31],[33,3739],{"disabled":35,"type":36},[39,3741,3732],{},[39,3743,2986],{},[28,3745,3747,355,3749,186,3751],{"className":3746},[31],[33,3748],{"disabled":35,"type":36},[39,3750,2757],{},[39,3752,2986],{},[66,3754,3755,3757,3765],{},[69,3756,71],{},[73,3758,3759,1727,3761,186,3763],{},[76,3760,78],{},[39,3762,3732],{},[39,3764,2185],{},[73,3766,3767,3769,3770,3772,3773,3775,3776,3778,3779,3782,3783,3785,3786,3788,3789,3791,3792,3794,3795,3797,3798,3801,3802,462],{},[76,3768,84],{}," JavaScript special-cases ",[39,3771,1361],{}," for callable objects, returning ",[39,3774,3732],{}," even though functions are technically a subtype of ",[39,3777,2664],{}," under the hood — which is why ",[39,3780,3781],{},"greet instanceof Object"," is also ",[39,3784,2185],{},". This dual nature surprises people who expect ",[39,3787,1361],{}," categories and the prototype chain to be mutually exclusive. Option A misses that ",[39,3790,1361],{}," has a dedicated ",[39,3793,3732],{}," result. Options C and D get the ",[39,3796,3707],{}," half wrong — functions genuinely do inherit from ",[39,3799,3800],{},"Object.prototype"," via ",[39,3803,3804],{},"Function.prototype",[15,3806,3807,3815,3861,3905],{"language":247},[18,3808,3810,3811,3814],{"id":3809},"q12-what-does-01-02-03-evaluate-to-and-why","Q12. What does ",[39,3812,3813],{},"0.1 + 0.2 === 0.3"," evaluate to, and why?",[257,3816,3817],{"language":247},[260,3818,3820],{"className":262,"code":3819,"language":247,"meta":264,"style":264},"console.log(0.1 + 0.2 === 0.3);\nconsole.log(0.1 + 0.2);\n",[39,3821,3822,3845],{"__ignoreMap":264},[268,3823,3824,3826,3828,3830,3833,3835,3838,3840,3843],{"class":270,"line":271},[268,3825,1353],{"class":282},[268,3827,1356],{"class":278},[268,3829,622],{"class":282},[268,3831,3832],{"class":305},"0.1",[268,3834,3350],{"class":274},[268,3836,3837],{"class":305}," 0.2",[268,3839,3043],{"class":274},[268,3841,3842],{"class":305}," 0.3",[268,3844,628],{"class":282},[268,3846,3847,3849,3851,3853,3855,3857,3859],{"class":270,"line":286},[268,3848,1353],{"class":282},[268,3850,1356],{"class":278},[268,3852,622],{"class":282},[268,3854,3832],{"class":305},[268,3856,3350],{"class":274},[268,3858,3837],{"class":305},[268,3860,628],{"class":282},[23,3862,3864,3872,3887,3895],{"className":3863},[26],[28,3865,3867,355,3869,3871],{"className":3866},[31],[33,3868],{"disabled":35,"type":36},[39,3870,2185],{},"; JavaScript numbers are always exact",[28,3873,3875,355,3877,2272,3879,3882,3883,3886],{"className":3874},[31],[33,3876],{"disabled":35,"type":36},[39,3878,2986],{},[39,3880,3881],{},"0.1 + 0.2"," actually equals ",[39,3884,3885],{},"0.30000000000000004"," due to IEEE-754 double-precision floating-point representation, which cannot represent most decimal fractions exactly",[28,3888,3890,355,3892,3894],{"className":3889},[31],[33,3891],{"disabled":35,"type":36},[39,3893,2986],{},"; this is a bug specific to V8 that other engines don't have",[28,3896,3898,355,3900,3902,3903],{"className":3897},[31],[33,3899],{"disabled":35,"type":36},[39,3901,2185],{},"; JavaScript rounds floating point arithmetic automatically for ",[39,3904,3280],{},[66,3906,3907,3909,3919],{},[69,3908,71],{},[73,3910,3911,1727,3913,3915,3916,3918],{},[76,3912,78],{},[39,3914,2986],{},"; the sum is ",[39,3917,3885],{}," due to IEEE-754 binary floating-point representation",[73,3920,3921,355,3923,3925,3926,3928,3929,186,3931,3934,3935,3938,3939,3941],{},[76,3922,84],{},[76,3924,182],{}," JavaScript's ",[39,3927,2629],{}," type uses IEEE-754 double-precision floats (as do essentially all mainstream languages using this format — Python, Java, C, etc. exhibit the identical rounding, so this is not V8-specific). Fractions like ",[39,3930,3832],{},[39,3932,3933],{},"0.2"," cannot be represented exactly in binary floating point, so tiny representation errors accumulate. The correct way to compare is checking the difference is within an epsilon (e.g., ",[39,3936,3937],{},"Math.abs(a - b) \u003C Number.EPSILON","), not ",[39,3940,3280],{},". Option A and D are false — there is no automatic rounding. Option C is a plausible-sounding but wrong claim of engine-specific behavior.",[15,3943,3944,3951,3967,4013],{"language":247},[18,3945,3947,3948,3950],{"id":3946},"q13-what-is-the-type-and-value-of-an-empty-const-declaration-attempt","Q13. What is the type and value of an empty ",[39,3949,243],{}," declaration attempt?",[257,3952,3953],{"language":247},[260,3954,3956],{"className":262,"code":3955,"language":247,"meta":264,"style":264},"const PI;\n",[39,3957,3958],{"__ignoreMap":264},[268,3959,3960,3962,3965],{"class":270,"line":271},[268,3961,243],{"class":274},[268,3963,3964],{"class":305}," PI",[268,3966,293],{"class":282},[23,3968,3970,3982,3994,4004],{"className":3969},[26],[28,3971,3973,3975,3976,830,3979,3981],{"className":3972},[31],[33,3974],{"disabled":35,"type":36}," Valid; ",[39,3977,3978],{},"PI",[39,3980,833],{}," until assigned later",[28,3983,3985,355,3987,3990,3991,3993],{"className":3984},[31],[33,3986],{"disabled":35,"type":36},[39,3988,3989],{},"SyntaxError: Missing initializer in const declaration"," — ",[39,3992,243],{}," requires an initializer at declaration time",[28,3995,3997,3975,3999,4001,4002],{"className":3996},[31],[33,3998],{"disabled":35,"type":36},[39,4000,3978],{}," defaults to ",[39,4003,3307],{},[28,4005,4007,4009,4010,4012],{"className":4006},[31],[33,4008],{"disabled":35,"type":36}," Valid, but ",[39,4011,3978],{}," enters a permanent TDZ",[66,4014,4015,4017,4026],{},[69,4016,71],{},[73,4018,4019,1727,4021,2272,4023,4025],{},[76,4020,78],{},[39,4022,1274],{},[39,4024,243],{}," requires an initializer",[73,4027,4028,4030,4031,186,4033,42,4035,4037,4038,4040,4041,4043,4044,2029,4046,4048],{},[76,4029,84],{}," Unlike ",[39,4032,240],{},[39,4034,1440],{},[39,4036,243],{}," bindings must be initialized in the same statement they're declared — there is no such thing as \"declare now, assign later\" for ",[39,4039,243],{},", because a ",[39,4042,243],{}," binding can never be reassigned at all. Option A confuses ",[39,4045,243],{},[39,4047,240],{},"'s allowed no-initializer form. Options C and D invent behavior that doesn't exist — this is a parse-time error, so the code never runs.",[15,4050,4051,4058,4108,4157],{"language":247},[18,4052,4054,4055,4057],{"id":4053},"q14-does-const-make-an-objects-contents-immutable","Q14. Does ",[39,4056,243],{}," make an object's contents immutable?",[257,4059,4060],{"language":247},[260,4061,4063],{"className":262,"code":4062,"language":247,"meta":264,"style":264},"const user = { name: \"Ana\" };\nuser.name = \"Beto\";\nuser = { name: \"Carla\" };\n",[39,4064,4065,4082,4094],{"__ignoreMap":264},[268,4066,4067,4069,4072,4074,4077,4080],{"class":270,"line":271},[268,4068,243],{"class":274},[268,4070,4071],{"class":305}," user",[268,4073,616],{"class":274},[268,4075,4076],{"class":282}," { name: ",[268,4078,4079],{"class":289},"\"Ana\"",[268,4081,2790],{"class":282},[268,4083,4084,4087,4089,4092],{"class":270,"line":286},[268,4085,4086],{"class":282},"user.name ",[268,4088,302],{"class":274},[268,4090,4091],{"class":289}," \"Beto\"",[268,4093,293],{"class":282},[268,4095,4096,4099,4101,4103,4106],{"class":270,"line":296},[268,4097,4098],{"class":282},"user ",[268,4100,302],{"class":274},[268,4102,4076],{"class":282},[268,4104,4105],{"class":289},"\"Carla\"",[268,4107,2790],{"class":282},[23,4109,4111,4120,4137,4145],{"className":4110},[26],[28,4112,4114,4116,4117,4119],{"className":4113},[31],[33,4115],{"disabled":35,"type":36}," Both lines work fine — ",[39,4118,243],{}," prevents any mutation",[28,4121,4123,355,4125,4128,4129,4132,4133,4136],{"className":4122},[31],[33,4124],{"disabled":35,"type":36},[39,4126,4127],{},"user.name = \"Beto\""," works (mutating properties is allowed); ",[39,4130,4131],{},"user = {...}"," throws ",[39,4134,4135],{},"TypeError: Assignment to constant variable"," (reassigning the binding is not allowed)",[28,4138,4140,4142,4143],{"className":4139},[31],[33,4141],{"disabled":35,"type":36}," Both lines throw ",[39,4144,827],{},[28,4146,4148,355,4150,4152,4153,4156],{"className":4147},[31],[33,4149],{"disabled":35,"type":36},[39,4151,4127],{}," throws, but reassigning ",[39,4154,4155],{},"user"," works",[66,4158,4159,4161,4166],{},[69,4160,71],{},[73,4162,4163,4165],{},[76,4164,78],{}," B — Mutating a property works; reassigning the binding throws",[73,4167,4168,355,4170,4172,4173,4176,4177,4179,4180,4182,4183,4186,4187,4189,4190,4192],{},[76,4169,84],{},[39,4171,243],{}," only freezes the ",[104,4174,4175],{},"binding"," (the variable name cannot be pointed at a new value) — it says nothing about the mutability of the value itself. Since ",[39,4178,4155],{}," still refers to the same object, mutating its properties is completely legal. ",[76,4181,930],{}," to actually prevent mutation of the object's own properties, use ",[39,4184,4185],{},"Object.freeze(user)"," (shallow) in addition to ",[39,4188,243],{},". Option A is the classic misconception that ",[39,4191,243],{}," means \"constant\u002Fimmutable data.\" Option D reverses the true behavior.",[15,4194,4195,4199,4246],{},[18,4196,4198],{"id":4197},"q15-which-is-the-idiomatic-default-choice-for-variable-declarations-in-modern-javascript-and-why","Q15. Which is the idiomatic default choice for variable declarations in modern JavaScript, and why?",[23,4200,4202,4211,4229,4240],{"className":4201},[26],[28,4203,4205,4207,4208,4210],{"className":4204},[31],[33,4206],{"disabled":35,"type":36}," Always use ",[39,4209,1440],{},", since it has the widest historical browser support",[28,4212,4214,4216,4217,4219,4220,4222,4223,4225,4226,4228],{"className":4213},[31],[33,4215],{"disabled":35,"type":36}," Default to ",[39,4218,243],{}," for bindings that are never reassigned, use ",[39,4221,240],{}," only when reassignment is genuinely needed, and avoid ",[39,4224,1440],{}," — this communicates intent and avoids ",[39,4227,1440],{},"'s function-scoping\u002Fhoisting pitfalls",[28,4230,4232,4207,4234,4236,4237,4239],{"className":4231},[31],[33,4233],{"disabled":35,"type":36},[39,4235,240],{}," everywhere for consistency, and reserve ",[39,4238,243],{}," only for primitive values",[28,4241,4243,4245],{"className":4242},[31],[33,4244],{"disabled":35,"type":36}," It doesn't matter; all three are functionally interchangeable in modern engines",[66,4247,4248,4250,4262],{},[69,4249,71],{},[73,4251,4252,4254,4255,3126,4257,4259,4260],{},[76,4253,78],{}," B — Default to ",[39,4256,243],{},[39,4258,240],{}," only when reassignment is needed, avoid ",[39,4261,1440],{},[73,4263,4264,355,4266,4268,4269,4271,4272,4274,4275,4277,4278,4280,4281,446,4283,4285,4286,4288],{},[76,4265,84],{},[76,4267,930],{}," preferring ",[39,4270,243],{}," signals to readers (and tooling\u002Flinters) that a binding won't be reassigned, catching accidental reassignment bugs at parse\u002Flint time; ",[39,4273,240],{},"'s block scoping avoids the classic ",[39,4276,1440],{}," closure-in-loop bug (see Control Flow topic); ",[39,4279,1440],{},"'s hoisting and function-scoping are considered legacy footguns in modern style guides (Airbnb, StandardJS, etc.) with no upside over ",[39,4282,240],{},[39,4284,243],{},". Option A is outdated advice from an era before ES2015 adoption. Option C undersells ",[39,4287,243],{},"'s usefulness for objects\u002Farrays too (the binding, not contents, is what's fixed). Option D ignores real, observable scoping differences.",[15,4290,4291,4297,4335,4401],{"language":247},[18,4292,4294,4295,1685],{"id":4293},"q16-what-is-the-best-practice-way-to-check-if-a-value-is-nan","Q16. What is the best-practice way to check if a value is ",[39,4296,3040],{},[257,4298,4299],{"language":247},[260,4300,4302],{"className":262,"code":4301,"language":247,"meta":264,"style":264},"function isInvalidNumber(val) {\n  return val !== val;\n}\n",[39,4303,4304,4318,4331],{"__ignoreMap":264},[268,4305,4306,4308,4311,4313,4316],{"class":270,"line":271},[268,4307,275],{"class":274},[268,4309,4310],{"class":278}," isInvalidNumber",[268,4312,622],{"class":282},[268,4314,4315],{"class":1222},"val",[268,4317,1235],{"class":282},[268,4319,4320,4322,4325,4328],{"class":270,"line":286},[268,4321,1240],{"class":274},[268,4323,4324],{"class":282}," val ",[268,4326,4327],{"class":274},"!==",[268,4329,4330],{"class":282}," val;\n",[268,4332,4333],{"class":270,"line":296},[268,4334,314],{"class":282},[23,4336,4338,4348,4379,4391],{"className":4337},[26],[28,4339,4341,4343,4344,4347],{"className":4340},[31],[33,4342],{"disabled":35,"type":36}," Use the global ",[39,4345,4346],{},"isNaN(val)"," function, since it's the shortest and most common option",[28,4349,4351,4353,4354,4357,4358,4361,4362,4365,4366,4368,4369,4372,4373,4375,4376,4378],{"className":4350},[31],[33,4352],{"disabled":35,"type":36}," Use ",[39,4355,4356],{},"Number.isNaN(val)",", because the global ",[39,4359,4360],{},"isNaN()"," first coerces its argument, causing false positives like ",[39,4363,4364],{},"isNaN(\"hello\")"," being ",[39,4367,2185],{}," when the value isn't even numeric; ",[39,4370,4371],{},"Number.isNaN"," only returns ",[39,4374,2185],{}," for the actual ",[39,4377,3040],{}," value with no coercion",[28,4380,4382,4353,4384,4387,4388,4390],{"className":4381},[31],[33,4383],{"disabled":35,"type":36},[39,4385,4386],{},"val === NaN",", since ",[39,4389,3040],{}," is a well-defined constant",[28,4392,4394,4396,4397,4400],{"className":4393},[31],[33,4395],{"disabled":35,"type":36}," The ",[39,4398,4399],{},"val !== val"," trick shown above is the only reliable method; all built-ins are broken",[66,4402,4403,4405,4413],{},[69,4404,71],{},[73,4406,4407,4409,4410,4412],{},[76,4408,78],{}," B — Use ",[39,4411,4356],{}," to avoid the global function's coercion-related false positives",[73,4414,4415,355,4417,4419,4420,4422,4423,830,4425,4427,4428,830,4431,4433,4434,4437,4438,4441,4442,4444,4445,355,4448,4450,4451,4453,4454,4456,4457,4459,4460,4462,4463,4465],{},[76,4416,84],{},[76,4418,930],{}," the legacy global ",[39,4421,4360],{}," coerces its argument to a number first, so ",[39,4424,4364],{},[39,4426,2185],{}," (because ",[39,4429,4430],{},"Number(\"hello\")",[39,4432,3040],{},") even though ",[39,4435,4436],{},"\"hello\""," was never intended as a numeric check target — a classic false positive. ",[39,4439,4440],{},"Number.isNaN()"," (ES2015+) does no coercion, returning ",[39,4443,2185],{}," only if the value literally ",[104,4446,4447],{},"is",[39,4449,3040],{},". Option C is invalid — as established, ",[39,4452,3007],{}," is always ",[39,4455,2986],{},", so this check can never succeed. Option D is an overstatement — the ",[39,4458,4399],{}," trick does work (it exploits the same self-inequality), but ",[39,4461,4371],{}," is the clearer, idiomatic choice; it's not the ",[104,4464,3117],{}," reliable method.",[15,4467,4468,4475,4515,4563],{"language":247},[18,4469,4471,4472,1685],{"id":4470},"q17-what-is-the-idiomatic-way-to-handle-very-large-integers-that-exceed-numbermax_safe_integer","Q17. What is the idiomatic way to handle very large integers that exceed ",[39,4473,4474],{},"Number.MAX_SAFE_INTEGER",[257,4476,4477],{"language":247},[260,4478,4480],{"className":262,"code":4479,"language":247,"meta":264,"style":264},"console.log(Number.MAX_SAFE_INTEGER);\nconsole.log(Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2);\n",[39,4481,4482,4491],{"__ignoreMap":264},[268,4483,4484,4486,4488],{"class":270,"line":271},[268,4485,1353],{"class":282},[268,4487,1356],{"class":278},[268,4489,4490],{"class":282},"(Number.MAX_SAFE_INTEGER);\n",[268,4492,4493,4495,4497,4500,4502,4504,4506,4509,4511,4513],{"class":270,"line":286},[268,4494,1353],{"class":282},[268,4496,1356],{"class":278},[268,4498,4499],{"class":282},"(Number.MAX_SAFE_INTEGER ",[268,4501,1246],{"class":274},[268,4503,2199],{"class":305},[268,4505,3043],{"class":274},[268,4507,4508],{"class":282}," Number.MAX_SAFE_INTEGER ",[268,4510,1246],{"class":274},[268,4512,2214],{"class":305},[268,4514,628],{"class":282},[23,4516,4518,4524,4543,4553],{"className":4517},[26],[28,4519,4521,4523],{"className":4520},[31],[33,4522],{"disabled":35,"type":36}," Continue using regular numbers; JavaScript numbers have unlimited precision",[28,4525,4527,4529,4530,4532,4533,4536,4537,4539,4540],{"className":4526},[31],[33,4528],{"disabled":35,"type":36}," Use the ",[39,4531,2656],{}," primitive type (e.g., ",[39,4534,4535],{},"9007199254740993n","), which represents arbitrary-precision integers exactly, instead of the ",[39,4538,2629],{}," type, which silently loses precision beyond ",[39,4541,4542],{},"2^53 - 1",[28,4544,4546,4548,4549,4552],{"className":4545},[31],[33,4547],{"disabled":35,"type":36}," Round the result using ",[39,4550,4551],{},"Math.round()"," to fix precision loss",[28,4554,4556,4558,4559,4562],{"className":4555},[31],[33,4557],{"disabled":35,"type":36}," Store the number as a string and use ",[39,4560,4561],{},"parseInt()"," whenever arithmetic is needed",[66,4564,4565,4567,4576],{},[69,4566,71],{},[73,4568,4569,4409,4571,4573,4574],{},[76,4570,78],{},[39,4572,2656],{}," for exact arbitrary-precision integers beyond ",[39,4575,4474],{},[73,4577,4578,355,4580,4582,4583,4585,4586,2182,4588,4590,4591,4593,4594,4596,4597,4600,4601,4603,4604,4132,4607,4609],{},[76,4579,84],{},[76,4581,582],{}," regular ",[39,4584,2629],{}," values are IEEE-754 doubles that can only represent integers exactly up to ",[39,4587,4542],{},[39,4589,4474],{},"); beyond that, distinct integers can silently collapse to the same floating-point value (as the ",[39,4592,2185],{}," result of the comparison above demonstrates) — a silent correctness bug, not an error you'd notice. ",[39,4595,2656],{}," (suffix ",[39,4598,4599],{},"n",", ES2020) stores arbitrary-precision integers with no such ceiling, at the cost of not being directly mixable with ",[39,4602,2629],{}," in arithmetic (",[39,4605,4606],{},"1n + 1",[39,4608,827],{},"). Option A is false — this is precisely the bug being demonstrated. Option C doesn't address the root precision-loss cause. Option D works but is a clunky workaround compared to a proper primitive type.",[15,4611,4612,4619,4667,4702],{"language":247},[18,4613,4615,4616,1685],{"id":4614},"q18-which-best-describes-idiomatic-use-of-symbol","Q18. Which best describes idiomatic use of ",[39,4617,4618],{},"Symbol",[257,4620,4621],{"language":247},[260,4622,4624],{"className":262,"code":4623,"language":247,"meta":264,"style":264},"const id = Symbol(\"userId\");\nconst obj = { [id]: 42, name: \"Ana\" };\n",[39,4625,4626,4645],{"__ignoreMap":264},[268,4627,4628,4630,4633,4635,4638,4640,4643],{"class":270,"line":271},[268,4629,243],{"class":274},[268,4631,4632],{"class":305}," id",[268,4634,616],{"class":274},[268,4636,4637],{"class":278}," Symbol",[268,4639,622],{"class":282},[268,4641,4642],{"class":289},"\"userId\"",[268,4644,628],{"class":282},[268,4646,4647,4649,4652,4654,4657,4660,4663,4665],{"class":270,"line":286},[268,4648,243],{"class":274},[268,4650,4651],{"class":305}," obj",[268,4653,616],{"class":274},[268,4655,4656],{"class":282}," { [id]: ",[268,4658,4659],{"class":305},"42",[268,4661,4662],{"class":282},", name: ",[268,4664,4079],{"class":289},[268,4666,2790],{"class":282},[23,4668,4670,4676,4682,4693],{"className":4669},[26],[28,4671,4673,4675],{"className":4672},[31],[33,4674],{"disabled":35,"type":36}," Symbols are mainly used to create guaranteed-unique property keys (e.g., to avoid accidental collisions with string keys or to define \"hidden,\" non-enumerable-by-default-iteration metadata), not as a general-purpose string replacement",[28,4677,4679,4681],{"className":4678},[31],[33,4680],{"disabled":35,"type":36}," Symbols are just a stylistic alternative to strings for any object key, interchangeable with strings in all cases",[28,4683,4685,355,4687,830,4690,4692],{"className":4684},[31],[33,4686],{"disabled":35,"type":36},[39,4688,4689],{},"Symbol(\"userId\") === Symbol(\"userId\")",[39,4691,2185],{},", so symbols are good for deduplication",[28,4694,4696,4698,4699,4701],{"className":4695},[31],[33,4697],{"disabled":35,"type":36}," Symbols can be implicitly converted to strings via ",[39,4700,1246],{},", making them convenient for string concatenation",[66,4703,4704,4706,4711],{},[69,4705,71],{},[73,4707,4708,4710],{},[76,4709,78],{}," A — Symbols create guaranteed-unique keys, not a general string replacement",[73,4712,4713,4715,4716,4719,4720,4722,4723,4725,4726,42,4729,383,4732,4735,4736,4738,4739,4741,4742,186,4745,4748,4749,99,4752,4755],{},[76,4714,84],{}," Every ",[39,4717,4718],{},"Symbol()"," call produces a value unique from every other symbol, even with the same description string — so ",[39,4721,4689],{}," is actually ",[39,4724,2986],{}," (making option C the tempting-but-wrong trap). Symbol-keyed properties don't show up in ",[39,4727,4728],{},"for...in",[39,4730,4731],{},"Object.keys()",[39,4733,4734],{},"JSON.stringify()"," by default, making them useful for \"semi-private\" metadata that won't collide with user-defined string keys. Option B ignores this uniqueness\u002Finterop purpose. Option D is false — ",[39,4737,4618],{}," values throw ",[39,4740,827],{}," when used with implicit string coercion (e.g., ",[39,4743,4744],{},"`${sym}`",[39,4746,4747],{},"sym + \"\""," both throw); you must call ",[39,4750,4751],{},".toString()",[39,4753,4754],{},".description"," explicitly.",[15,4757,4758,4762,4851,4918],{"language":247},[18,4759,4761],{"id":4760},"q19-why-does-this-equality-check-behave-unexpectedly-and-whats-the-idiomatic-fix","Q19. Why does this equality check behave unexpectedly, and what's the idiomatic fix?",[257,4763,4764],{"language":247},[260,4765,4767],{"className":262,"code":4766,"language":247,"meta":264,"style":264},"function isEmpty(value) {\n  return value == null;\n}\nconsole.log(isEmpty(undefined));\nconsole.log(isEmpty(null));\nconsole.log(isEmpty(0));\n",[39,4768,4769,4783,4797,4801,4819,4835],{"__ignoreMap":264},[268,4770,4771,4773,4776,4778,4781],{"class":270,"line":271},[268,4772,275],{"class":274},[268,4774,4775],{"class":278}," isEmpty",[268,4777,622],{"class":282},[268,4779,4780],{"class":1222},"value",[268,4782,1235],{"class":282},[268,4784,4785,4787,4790,4792,4795],{"class":270,"line":286},[268,4786,1240],{"class":274},[268,4788,4789],{"class":282}," value ",[268,4791,3197],{"class":274},[268,4793,4794],{"class":305}," null",[268,4796,293],{"class":282},[268,4798,4799],{"class":270,"line":296},[268,4800,314],{"class":282},[268,4802,4803,4805,4807,4809,4812,4814,4816],{"class":270,"line":311},[268,4804,1353],{"class":282},[268,4806,1356],{"class":278},[268,4808,622],{"class":282},[268,4810,4811],{"class":278},"isEmpty",[268,4813,622],{"class":282},[268,4815,833],{"class":305},[268,4817,4818],{"class":282},"));\n",[268,4820,4821,4823,4825,4827,4829,4831,4833],{"class":270,"line":788},[268,4822,1353],{"class":282},[268,4824,1356],{"class":278},[268,4826,622],{"class":282},[268,4828,4811],{"class":278},[268,4830,622],{"class":282},[268,4832,2650],{"class":305},[268,4834,4818],{"class":282},[268,4836,4837,4839,4841,4843,4845,4847,4849],{"class":270,"line":1951},[268,4838,1353],{"class":282},[268,4840,1356],{"class":278},[268,4842,622],{"class":282},[268,4844,4811],{"class":278},[268,4846,622],{"class":282},[268,4848,3307],{"class":305},[268,4850,4818],{"class":282},[23,4852,4854,4867,4892,4904],{"className":4853},[26],[28,4855,4857,355,4859,4862,4863,4866],{"className":4856},[31],[33,4858],{"disabled":35,"type":36},[39,4860,4861],{},"value == null"," is a bug; it should always be written as ",[39,4864,4865],{},"value === null"," for safety",[28,4868,4870,355,4872,4875,4876,830,4879,4881,4882,4884,4885,186,4887,4889,4890],{"className":4869},[31],[33,4871],{"disabled":35,"type":36},[39,4873,4874],{},"== null"," is actually an idiomatic, intentional pattern: due to type coercion rules, ",[39,4877,4878],{},"null == undefined",[39,4880,2185],{}," (and only to each other), so ",[39,4883,4861],{}," cleanly catches both ",[39,4886,2650],{},[39,4888,833],{}," in one check without matching falsy-but-defined values like ",[39,4891,3307],{},[28,4893,4895,2398,4897,183,4899,4901,4902],{"className":4894},[31],[33,4896],{"disabled":35,"type":36},[39,4898,827],{},[39,4900,2650],{}," cannot be compared with ",[39,4903,3197],{},[28,4905,4907,355,4909,4912,4913,183,4915,4917],{"className":4906},[31],[33,4908],{"disabled":35,"type":36},[39,4910,4911],{},"isEmpty(0)"," returns ",[39,4914,2185],{},[39,4916,3307],{}," is falsy",[66,4919,4920,4922,4934],{},[69,4921,71],{},[73,4923,4924,1727,4926,4928,4929,186,4931,4933],{},[76,4925,78],{},[39,4927,4874],{}," intentionally catches both ",[39,4930,2650],{},[39,4932,833],{}," via a special-cased coercion rule, without matching other falsy values",[73,4935,4936,355,4938,4940,4941,4943,4944,830,4946,4948,4949,186,4951,4953,4954,4956,4957,2758,4959,2758,4961,4963,4964,4966,4967,446,4970,4973,4974,4977,4978,42,4980,4977,4983,42,4985,4977,4987,4989,4990,4992,4993,4995,4996,4999],{},[76,4937,84],{},[76,4939,930],{}," per the spec, ",[39,4942,3197],{}," has a special rule that ",[39,4945,4878],{},[39,4947,2185],{},", but ",[39,4950,2650],{},[39,4952,833],{}," are ",[39,4955,3197],{}," to nothing else (not ",[39,4958,3307],{},[39,4960,3294],{},[39,4962,2986],{},"). This makes ",[39,4965,4861],{}," a widely-used, deliberate idiom to check for \"nullish\" in one line, predating ",[39,4968,4969],{},"??",[39,4971,4972],{},"?.",". So ",[39,4975,4976],{},"isEmpty(undefined)"," → ",[39,4979,2185],{},[39,4981,4982],{},"isEmpty(null)",[39,4984,2185],{},[39,4986,4911],{},[39,4988,2986],{}," (0 is not loosely equal to null). Option A is overly cautious — this is one of the few places ",[39,4991,3197],{}," is considered acceptable\u002Fidiomatic rather than a footgun. Option D wrongly assumes truthiness is involved; this comparison uses the ",[39,4994,3197],{}," coercion table, not ",[39,4997,4998],{},"Boolean()"," coercion.",[15,5001,5002,5009,5060,5112],{"language":247},[18,5003,5005,5006,5008],{"id":5004},"q20-what-is-the-best-practice-explanation-for-why-typeof-is-safe-to-use-on-a-variable-that-might-not-be-declared-at-all-but-not-on-one-known-to-be-in-the-tdz","Q20. What is the best-practice explanation for why ",[39,5007,1361],{}," is safe to use on a variable that might not be declared at all, but not on one known to be in the TDZ?",[257,5010,5011],{"language":247},[260,5012,5014],{"className":262,"code":5013,"language":247,"meta":264,"style":264},"console.log(typeof undeclaredVar);\n\nconsole.log(typeof laterVar);\nlet laterVar = 5;\n",[39,5015,5016,5029,5034,5047],{"__ignoreMap":264},[268,5017,5018,5020,5022,5024,5026],{"class":270,"line":271},[268,5019,1353],{"class":282},[268,5021,1356],{"class":278},[268,5023,622],{"class":282},[268,5025,1361],{"class":274},[268,5027,5028],{"class":282}," undeclaredVar);\n",[268,5030,5031],{"class":270,"line":286},[268,5032,5033],{"emptyLinePlaceholder":35},"\n",[268,5035,5036,5038,5040,5042,5044],{"class":270,"line":296},[268,5037,1353],{"class":282},[268,5039,1356],{"class":278},[268,5041,622],{"class":282},[268,5043,1361],{"class":274},[268,5045,5046],{"class":282}," laterVar);\n",[268,5048,5049,5051,5054,5056,5058],{"class":270,"line":311},[268,5050,240],{"class":274},[268,5052,5053],{"class":282}," laterVar ",[268,5055,302],{"class":274},[268,5057,2387],{"class":305},[268,5059,293],{"class":282},[23,5061,5063,5072,5097,5104],{"className":5062},[26],[28,5064,5066,5068,5069,5071],{"className":5065},[31],[33,5067],{"disabled":35,"type":36}," Both lines behave identically, logging ",[39,5070,1397],{}," in both cases",[28,5073,5075,355,5077,5080,5081,5083,5084,4132,5087,183,5089,830,5092,5094,5095],{"className":5074},[31],[33,5076],{"disabled":35,"type":36},[39,5078,5079],{},"typeof undeclaredVar"," safely returns ",[39,5082,1397],{}," for a name that was never declared anywhere (a historic idiom for feature-detection); but ",[39,5085,5086],{},"typeof laterVar",[39,5088,815],{},[39,5090,5091],{},"laterVar",[39,5093,240],{},"-declared later in scope, so referencing it here falls inside its Temporal Dead Zone even under ",[39,5096,1361],{},[28,5098,5100,4142,5102],{"className":5099},[31],[33,5101],{"disabled":35,"type":36},[39,5103,815],{},[28,5105,5107,355,5109,5111],{"className":5106},[31],[33,5108],{"disabled":35,"type":36},[39,5110,1361],{}," never throws under any circumstances, by design, for any identifier",[66,5113,5114,5116,5131],{},[69,5115,71],{},[73,5117,5118,1727,5120,5122,5123,5125,5126,446,5128,5130],{},[76,5119,78],{},[39,5121,1361],{}," on a truly undeclared name is safe; but ",[39,5124,1361],{}," on a ",[39,5127,240],{},[39,5129,243],{}," name still in its TDZ throws",[73,5132,5133,355,5135,355,5137,5140,5141,5144,5145,5147,5148,5150,5151,5153,5154,446,5156,5158,5159,5161,5162,5164],{},[76,5134,84],{},[76,5136,930],{},[39,5138,5139],{},"typeof someGlobalThatMightNotExist"," is a long-standing, safe idiom (e.g., ",[39,5142,5143],{},"typeof window !== \"undefined\""," to detect a browser environment) specifically because ",[39,5146,1361],{}," was designed not to throw for names that were never declared. However, this safety does ",[104,5149,95],{}," extend to TDZ: if the identifier ",[104,5152,4447],{}," declared later in the same scope via ",[39,5155,240],{},[39,5157,243],{},", the engine already knows about it and considers it \"temporally dead\" until its declaration line, so even the normally-safe ",[39,5160,1361],{}," throws. Option D is the common but incorrect belief that ",[39,5163,1361],{}," is unconditionally throw-proof.",[2107,5166,5167],{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html 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}",{"title":264,"searchDepth":286,"depth":286,"links":5169},[5170,5172,5174,5175,5176,5177,5179,5181,5182,5184,5186,5188,5190,5192,5194,5195,5197,5199,5201,5202],{"id":2162,"depth":296,"text":5171},"Q1. What is the key scoping difference between var and let?",{"id":2356,"depth":296,"text":5173},"Q2. What is variable hoisting, as it applies to var?",{"id":2485,"depth":296,"text":2486},{"id":2614,"depth":296,"text":2615},{"id":2766,"depth":296,"text":2767},{"id":2915,"depth":296,"text":5178},"Q6. What does typeof null evaluate to?",{"id":2999,"depth":296,"text":5180},"Q7. What does typeof NaN evaluate to, and what does NaN === NaN evaluate to?",{"id":3143,"depth":296,"text":3144},{"id":3327,"depth":296,"text":5183},"Q9. What is the result of adding a number and a string with +?",{"id":3529,"depth":296,"text":5185},"Q10. What happens when you access a property on undefined, versus declaring a variable with no initializer?",{"id":3661,"depth":296,"text":5187},"Q11. What is the result of typeof applied to a function?",{"id":3809,"depth":296,"text":5189},"Q12. What does 0.1 + 0.2 === 0.3 evaluate to, and why?",{"id":3946,"depth":296,"text":5191},"Q13. What is the type and value of an empty const declaration attempt?",{"id":4053,"depth":296,"text":5193},"Q14. Does const make an object's contents immutable?",{"id":4197,"depth":296,"text":4198},{"id":4293,"depth":296,"text":5196},"Q16. What is the best-practice way to check if a value is NaN?",{"id":4470,"depth":296,"text":5198},"Q17. What is the idiomatic way to handle very large integers that exceed Number.MAX_SAFE_INTEGER?",{"id":4614,"depth":296,"text":5200},"Q18. Which best describes idiomatic use of Symbol?",{"id":4760,"depth":296,"text":4761},{"id":5004,"depth":296,"text":5203},"Q20. What is the best-practice explanation for why typeof is safe to use on a variable that might not be declared at all, but not on one known to be in the TDZ?",{},"\u002Fjs\u002F02-variables-and-data-types",{"title":2152,"description":264},"js\u002F02-variables-and-data-types","RAjeyieLgHQ_ybiHXsVWq8DzfxZTNeAvqZtMepcHzlg",{"id":5210,"title":5211,"body":5212,"description":264,"extension":2144,"meta":8670,"navigation":35,"path":8671,"seo":8672,"stem":8673,"__hash__":8674},"content\u002Fjs\u002F03-operators-and-expressions.md","03 — Operators & Expressions",{"type":8,"value":5213,"toc":8634},[5214,5217,5356,5519,5699,5910,6079,6233,6425,6600,6796,6932,7180,7319,7511,7718,7860,8005,8132,8294,8470,8631],[11,5215,5211],{"id":5216},"_03-operators-expressions",[15,5218,5219,5227,5267,5314],{"language":247},[18,5220,5222,5223,186,5225,1685],{"id":5221},"q1-what-is-the-fundamental-difference-between-and","Q1. What is the fundamental difference between ",[39,5224,3197],{},[39,5226,3280],{},[257,5228,5229],{"language":247},[260,5230,5232],{"className":262,"code":5231,"language":247,"meta":264,"style":264},"console.log(1 == \"1\");\nconsole.log(1 === \"1\");\n",[39,5233,5234,5251],{"__ignoreMap":264},[268,5235,5236,5238,5240,5242,5244,5246,5249],{"class":270,"line":271},[268,5237,1353],{"class":282},[268,5239,1356],{"class":278},[268,5241,622],{"class":282},[268,5243,2255],{"class":305},[268,5245,3165],{"class":274},[268,5247,5248],{"class":289}," \"1\"",[268,5250,628],{"class":282},[268,5252,5253,5255,5257,5259,5261,5263,5265],{"class":270,"line":286},[268,5254,1353],{"class":282},[268,5256,1356],{"class":278},[268,5258,622],{"class":282},[268,5260,2255],{"class":305},[268,5262,3043],{"class":274},[268,5264,5248],{"class":289},[268,5266,628],{"class":282},[23,5268,5270,5281,5292,5303],{"className":5269},[26],[28,5271,5273,5275,5276,5278,5279],{"className":5272},[31],[33,5274],{"disabled":35,"type":36}," They are functionally identical; ",[39,5277,3280],{}," is just a stylistic alias for ",[39,5280,3197],{},[28,5282,5284,355,5286,5288,5289,5291],{"className":5283},[31],[33,5285],{"disabled":35,"type":36},[39,5287,3197],{}," (loose equality) performs type coercion before comparing; ",[39,5290,3280],{}," (strict equality) compares both value and type with no coercion",[28,5293,5295,355,5297,5299,5300,5302],{"className":5294},[31],[33,5296],{"disabled":35,"type":36},[39,5298,3280],{}," performs coercion, ",[39,5301,3197],{}," does not",[28,5304,5306,355,5308,5310,5311,5313],{"className":5305},[31],[33,5307],{"disabled":35,"type":36},[39,5309,3197],{}," compares references for objects, ",[39,5312,3280],{}," compares values",[66,5315,5316,5318,5328],{},[69,5317,71],{},[73,5319,5320,1727,5322,5324,5325,5327],{},[76,5321,78],{},[39,5323,3197],{}," coerces types before comparing; ",[39,5326,3280],{}," requires matching type and value with no coercion",[73,5329,5330,355,5332,5335,5336,5338,5339,5341,5342,3277,5344,5347,5348,5350,5351,186,5353,5355],{},[76,5331,84],{},[39,5333,5334],{},"1 == \"1\""," coerces the string ",[39,5337,3387],{}," to the number ",[39,5340,2255],{}," before comparing, yielding ",[39,5343,2185],{},[39,5345,5346],{},"1 === \"1\""," compares type first — number vs. string — and since the types differ it immediately returns ",[39,5349,2986],{}," without any coercion. Option C reverses the actual rule. Option D is unrelated to how these operators work with objects (both ",[39,5352,3197],{},[39,5354,3280],{}," compare object references identically; neither does a deep comparison).",[15,5357,5358,5365,5388,5460],{"language":247},[18,5359,5361,5362,2920],{"id":5360},"q2-what-does-evaluate-to","Q2. What does ",[39,5363,5364],{},"[] == ![]",[257,5366,5367],{"language":247},[260,5368,5370],{"className":262,"code":5369,"language":247,"meta":264,"style":264},"console.log([] == ![]);\n",[39,5371,5372],{"__ignoreMap":264},[268,5373,5374,5376,5378,5380,5382,5385],{"class":270,"line":271},[268,5375,1353],{"class":282},[268,5377,1356],{"class":278},[268,5379,3194],{"class":282},[268,5381,3197],{"class":274},[268,5383,5384],{"class":274}," !",[268,5386,5387],{"class":282},"[]);\n",[23,5389,5391,5399,5442,5450],{"className":5390},[26],[28,5392,5394,355,5396,5398],{"className":5393},[31],[33,5395],{"disabled":35,"type":36},[39,5397,2986],{},", because an array is never equal to a boolean",[28,5400,5402,355,5404,3990,5406,5409,5410,5412,5413,5415,5416,5419,5420,5422,5423,5425,5426,186,5428,5425,5430,137,5432,5434,5435,1179,5437,830,5440],{"className":5401},[31],[33,5403],{"disabled":35,"type":36},[39,5405,2185],{},[39,5407,5408],{},"![]"," evaluates to ",[39,5411,2986],{}," first (since ",[39,5414,3290],{}," is truthy, ",[39,5417,5418],{},"!"," negates it), then ",[39,5421,3286],{}," coerces ",[39,5424,3290],{}," to ",[39,5427,3294],{},[39,5429,2986],{},[39,5431,3307],{},[39,5433,3294],{}," coerces to ",[39,5436,3307],{},[39,5438,5439],{},"0 == 0",[39,5441,2185],{},[28,5443,5445,355,5447,5449],{"className":5444},[31],[33,5446],{"disabled":35,"type":36},[39,5448,3040],{},", because arrays can't be converted to numbers",[28,5451,5453,355,5455,4387,5457,5459],{"className":5452},[31],[33,5454],{"disabled":35,"type":36},[39,5456,1274],{},[39,5458,5418],{}," cannot be applied to an array literal",[66,5461,5462,5464,5471],{},[69,5463,71],{},[73,5465,5466,1727,5468,5470],{},[76,5467,78],{},[39,5469,2185],{},", through a chain of coercions",[73,5472,5473,355,5475,5477,5478,5480,5481,830,5483,5485,5486,5488,5489,5491,5492,4977,5494,5496,5497,5499,5500,4977,5502,5504,5505,4977,5507,5509,5510,5512,5513,5515,5516,5518],{},[76,5474,84],{},[76,5476,365],{}," this is a famous JavaScript \"wat\" moment. Step by step: ",[39,5479,3290],{}," is a truthy object, so ",[39,5482,5408],{},[39,5484,2986],{},". Now the comparison is ",[39,5487,3286],{},". Per the ",[39,5490,3197],{}," algorithm, when one side is boolean, it's converted to a number first: ",[39,5493,2986],{},[39,5495,3307],{},". The other side ",[39,5498,3290],{}," is an object compared against a number, so it's converted via ",[39,5501,3298],{},[39,5503,3294],{}," (empty string), then ",[39,5506,3294],{},[39,5508,3307],{}," (number coercion of an empty string). Now it's ",[39,5511,5439],{},", which is ",[39,5514,2185],{},". Every step is individually \"correct\" per spec, which is exactly what makes the combined result so counterintuitive. This is a textbook argument for avoiding ",[39,5517,3197],{}," (option A is the intuitive-but-wrong guess).",[15,5520,5521,5532,5599,5656],{"language":247},[18,5522,5524,5525,446,5528,5531],{"id":5523},"q3-what-is-the-difference-between-short-circuiting-and-how-does-it-affect-side-effects","Q3. What is the difference between ",[39,5526,5527],{},"&&",[39,5529,5530],{},"||"," short-circuiting and how does it affect side effects?",[257,5533,5534],{"language":247},[260,5535,5537],{"className":262,"code":5536,"language":247,"meta":264,"style":264},"function logAndReturn(val) {\n  console.log(\"called with\", val);\n  return val;\n}\nconst result = false && logAndReturn(1);\n",[39,5538,5539,5552,5567,5573,5577],{"__ignoreMap":264},[268,5540,5541,5543,5546,5548,5550],{"class":270,"line":271},[268,5542,275],{"class":274},[268,5544,5545],{"class":278}," logAndReturn",[268,5547,622],{"class":282},[268,5549,4315],{"class":1222},[268,5551,1235],{"class":282},[268,5553,5554,5557,5559,5561,5564],{"class":270,"line":286},[268,5555,5556],{"class":282},"  console.",[268,5558,1356],{"class":278},[268,5560,622],{"class":282},[268,5562,5563],{"class":289},"\"called with\"",[268,5565,5566],{"class":282},", val);\n",[268,5568,5569,5571],{"class":270,"line":296},[268,5570,1240],{"class":274},[268,5572,4330],{"class":282},[268,5574,5575],{"class":270,"line":311},[268,5576,314],{"class":282},[268,5578,5579,5581,5584,5586,5588,5591,5593,5595,5597],{"class":270,"line":788},[268,5580,243],{"class":274},[268,5582,5583],{"class":305}," result",[268,5585,616],{"class":274},[268,5587,3200],{"class":305},[268,5589,5590],{"class":274}," &&",[268,5592,5545],{"class":278},[268,5594,622],{"class":282},[268,5596,2255],{"class":305},[268,5598,628],{"class":282},[23,5600,5602,5611,5634,5644],{"className":5601},[26],[28,5603,5605,355,5607,5610],{"className":5604},[31],[33,5606],{"disabled":35,"type":36},[39,5608,5609],{},"logAndReturn(1)"," is always called regardless of the left operand",[28,5612,5614,355,5616,5618,5619,5621,5622,5624,5625,5628,5629,830,5632],{"className":5613},[31],[33,5615],{"disabled":35,"type":36},[39,5617,5527],{}," only evaluates the right operand if the left is truthy; since ",[39,5620,2986],{}," is falsy, ",[39,5623,5609],{}," is never called, and ",[39,5626,5627],{},"console.log"," never runs — ",[39,5630,5631],{},"result",[39,5633,2986],{},[28,5635,5637,2398,5639,183,5641,5643],{"className":5636},[31],[33,5638],{"disabled":35,"type":36},[39,5640,827],{},[39,5642,5527],{}," requires both operands to be booleans",[28,5645,5647,355,5649,830,5651,2833,5653,5655],{"className":5646},[31],[33,5648],{"disabled":35,"type":36},[39,5650,5631],{},[39,5652,2255],{},[39,5654,5527],{}," always evaluates to the last operand",[66,5657,5658,5660,5667],{},[69,5659,71],{},[73,5661,5662,1727,5664,5666],{},[76,5663,78],{},[39,5665,5527],{}," short-circuits on a falsy left operand, so the right side is never evaluated",[73,5668,5669,355,5671,5673,5674,5676,5677,5621,5679,5681,5682,830,5684,5686,5687,5689,5690,5693,5694,446,5696,5698],{},[76,5670,84],{},[39,5672,5527],{}," only evaluates its right-hand operand if the left is truthy (it \"short-circuits\" otherwise); ",[39,5675,5530],{}," is the mirror — it skips the right side once the left is truthy. Since ",[39,5678,2986],{},[39,5680,5609],{}," is never invoked at all — no log line prints, and ",[39,5683,5631],{},[39,5685,2986],{}," (the value of the left operand, not a boolean cast of it). ",[76,5688,365],{}," relying on short-circuiting for side effects (e.g., ",[39,5691,5692],{},"isLoggedIn && trackEvent()",") is idiomatic but can silently skip important calls if the guard condition is wrong — worth being deliberate about. Option D is a common misconception; ",[39,5695,5527],{},[39,5697,5530],{}," return one of the actual operand values, not necessarily a boolean.",[15,5700,5701,5710,5760,5841],{"language":247},[18,5702,5704,5705,5707,5708,1685],{"id":5703},"q4-what-does-the-nullish-coalescing-operator-do-differently-from","Q4. What does the nullish coalescing operator ",[39,5706,4969],{}," do differently from ",[39,5709,5530],{},[257,5711,5712],{"language":247},[260,5713,5715],{"className":262,"code":5714,"language":247,"meta":264,"style":264},"const count = 0;\nconsole.log(count || 10);\nconsole.log(count ?? 10);\n",[39,5716,5717,5731,5746],{"__ignoreMap":264},[268,5718,5719,5721,5724,5726,5729],{"class":270,"line":271},[268,5720,243],{"class":274},[268,5722,5723],{"class":305}," count",[268,5725,616],{"class":274},[268,5727,5728],{"class":305}," 0",[268,5730,293],{"class":282},[268,5732,5733,5735,5737,5740,5742,5744],{"class":270,"line":286},[268,5734,1353],{"class":282},[268,5736,1356],{"class":278},[268,5738,5739],{"class":282},"(count ",[268,5741,5530],{"class":274},[268,5743,306],{"class":305},[268,5745,628],{"class":282},[268,5747,5748,5750,5752,5754,5756,5758],{"class":270,"line":296},[268,5749,1353],{"class":282},[268,5751,1356],{"class":278},[268,5753,5739],{"class":282},[268,5755,4969],{"class":274},[268,5757,306],{"class":305},[268,5759,628],{"class":282},[23,5761,5763,5769,5809,5826],{"className":5762},[26],[28,5764,5766,5768],{"className":5765},[31],[33,5767],{"disabled":35,"type":36}," They behave identically in all cases",[28,5770,5772,355,5774,5776,5777,42,5779,42,5781,42,5783,42,5785,42,5787,5789,5790,5792,5793,99,5795,5797,5798,5801,5802,5804,5805,5808],{"className":5771},[31],[33,5773],{"disabled":35,"type":36},[39,5775,5530],{}," returns the right operand if the left is any falsy value (",[39,5778,3307],{},[39,5780,3294],{},[39,5782,3040],{},[39,5784,2986],{},[39,5786,2650],{},[39,5788,833],{},"); ",[39,5791,4969],{}," only returns the right operand if the left is specifically ",[39,5794,2650],{},[39,5796,833],{}," — so ",[39,5799,5800],{},"count || 10"," wrongly overrides a legitimate ",[39,5803,3307],{},", while ",[39,5806,5807],{},"count ?? 10"," correctly preserves it",[28,5810,5812,355,5814,5816,5817,5819,5820,5822,5823],{"className":5811},[31],[33,5813],{"disabled":35,"type":36},[39,5815,4969],{}," treats ",[39,5818,3307],{}," the same as ",[39,5821,2650],{},", so both log ",[39,5824,5825],{},"10",[28,5827,5829,355,5831,5833,5834,446,5836,137,5838,5840],{"className":5828},[31],[33,5830],{"disabled":35,"type":36},[39,5832,5530],{}," only checks for ",[39,5835,2650],{},[39,5837,833],{},[39,5839,4969],{}," checks all falsy values — the reverse of the truth",[66,5842,5843,5845,5859],{},[69,5844,71],{},[73,5846,5847,1727,5849,5851,5852,5854,5855,446,5857],{},[76,5848,78],{},[39,5850,5530],{}," falls back on any falsy value; ",[39,5853,4969],{}," only falls back on ",[39,5856,2650],{},[39,5858,833],{},[73,5860,5861,355,5863,5865,5866,5868,5869,5872,5873,5875,5876,2833,5878,5880,5881,5884,5885,5887,5888,5890,5891,5893,5894,5896,5897,2269,5899,5901,5902,5904,5905,2269,5907,5909],{},[76,5862,84],{},[76,5864,365],{}," this is one of the most common real-world bugs ",[39,5867,4969],{}," (ES2020) was introduced to fix: ",[39,5870,5871],{},"someConfig.retries || 5"," silently replaces a deliberately-set ",[39,5874,3307],{}," retries value with the default ",[39,5877,2429],{},[39,5879,3307],{}," is falsy. ",[39,5882,5883],{},"someConfig.retries ?? 5"," correctly keeps ",[39,5886,3307],{}," since ",[39,5889,3307],{}," is neither ",[39,5892,2650],{}," nor ",[39,5895,833],{},". So here, ",[39,5898,5800],{},[39,5900,5825],{}," (wrong, loses the real ",[39,5903,3307],{},"), while ",[39,5906,5807],{},[39,5908,3307],{}," (correct). Option C and D invert or misstate the actual distinction.",[15,5911,5912,5923,5963,6020],{"language":247},[18,5913,5915,5916,5918,5919,99,5921,1685],{"id":5914},"q5-what-does-optional-chaining-do-when-the-left-hand-side-is-null-or-undefined","Q5. What does optional chaining ",[39,5917,4972],{}," do when the left-hand side is ",[39,5920,2650],{},[39,5922,833],{},[257,5924,5925],{"language":247},[260,5926,5928],{"className":262,"code":5927,"language":247,"meta":264,"style":264},"const user = { profile: null };\nconsole.log(user.profile?.bio);\nconsole.log(user.profile.bio);\n",[39,5929,5930,5945,5954],{"__ignoreMap":264},[268,5931,5932,5934,5936,5938,5941,5943],{"class":270,"line":271},[268,5933,243],{"class":274},[268,5935,4071],{"class":305},[268,5937,616],{"class":274},[268,5939,5940],{"class":282}," { profile: ",[268,5942,2650],{"class":305},[268,5944,2790],{"class":282},[268,5946,5947,5949,5951],{"class":270,"line":286},[268,5948,1353],{"class":282},[268,5950,1356],{"class":278},[268,5952,5953],{"class":282},"(user.profile?.bio);\n",[268,5955,5956,5958,5960],{"class":270,"line":296},[268,5957,1353],{"class":282},[268,5959,1356],{"class":278},[268,5961,5962],{"class":282},"(user.profile.bio);\n",[23,5964,5966,5972,5999,6011],{"className":5965},[26],[28,5967,5969,5971],{"className":5968},[31],[33,5970],{"disabled":35,"type":36}," Both lines throw the same error",[28,5973,5975,355,5977,5980,5981,5983,5984,830,5987,2272,5989,5992,5993,5995,5996],{"className":5974},[31],[33,5976],{"disabled":35,"type":36},[39,5978,5979],{},"user.profile?.bio"," short-circuits and returns ",[39,5982,833],{}," without throwing, since ",[39,5985,5986],{},"user.profile",[39,5988,2650],{},[39,5990,5991],{},"user.profile.bio"," (no ",[39,5994,4972],{},") throws ",[39,5997,5998],{},"TypeError: Cannot read properties of null (reading 'bio')",[28,6000,6002,355,6004,6006,6007,4912,6009],{"className":6001},[31],[33,6003],{"disabled":35,"type":36},[39,6005,5979],{}," throws, but ",[39,6008,5991],{},[39,6010,833],{},[28,6012,6014,6016,6017,6019],{"className":6013},[31],[33,6015],{"disabled":35,"type":36}," Both lines return ",[39,6018,833],{}," safely, since JavaScript never throws on property access",[66,6021,6022,6024,6039],{},[69,6023,71],{},[73,6025,6026,1727,6028,6030,6031,6033,6034,446,6036,6038],{},[76,6027,78],{},[39,6029,4972],{}," short-circuits to ",[39,6032,833],{}," on ",[39,6035,2650],{},[39,6037,833],{},"; plain access throws",[73,6040,6041,6043,6044,99,6046,6048,6049,6051,6052,6054,6055,6033,6058,2278,6060,4387,6062,6064,6065,6067,6068,6070,6071,6074,6075,186,6077,462],{},[76,6042,84],{}," Optional chaining checks the left side before attempting property access — if it's ",[39,6045,2650],{},[39,6047,833],{},", the entire chain short-circuits and evaluates to ",[39,6050,833],{}," immediately, skipping the rest of the expression. Without ",[39,6053,4972],{},", accessing ",[39,6056,6057],{},".bio",[39,6059,2650],{},[39,6061,827],{},[39,6063,2650],{}," has no properties. ",[76,6066,582],{}," the fix for the second line's error is exactly to add ",[39,6069,4972],{},", or to explicitly check ",[39,6072,6073],{},"user.profile !== null"," first. Option D falsely claims JS never throws on property access — it does, for both ",[39,6076,2650],{},[39,6078,833],{},[15,6080,6081,6085,6139,6180],{"language":247},[18,6082,6084],{"id":6083},"q6-what-is-the-correct-operator-precedence-outcome-here","Q6. What is the correct operator precedence outcome here?",[257,6086,6087],{"language":247},[260,6088,6090],{"className":262,"code":6089,"language":247,"meta":264,"style":264},"console.log(2 + 3 * 4);\nconsole.log((2 + 3) * 4);\n",[39,6091,6092,6114],{"__ignoreMap":264},[268,6093,6094,6096,6098,6100,6102,6104,6106,6109,6112],{"class":270,"line":271},[268,6095,1353],{"class":282},[268,6097,1356],{"class":278},[268,6099,622],{"class":282},[268,6101,2258],{"class":305},[268,6103,3350],{"class":274},[268,6105,3396],{"class":305},[268,6107,6108],{"class":274}," *",[268,6110,6111],{"class":305}," 4",[268,6113,628],{"class":282},[268,6115,6116,6118,6120,6123,6125,6127,6129,6132,6135,6137],{"class":270,"line":286},[268,6117,1353],{"class":282},[268,6119,1356],{"class":278},[268,6121,6122],{"class":282},"((",[268,6124,2258],{"class":305},[268,6126,3350],{"class":274},[268,6128,3396],{"class":305},[268,6130,6131],{"class":282},") ",[268,6133,6134],{"class":274},"*",[268,6136,6111],{"class":305},[268,6138,628],{"class":282},[23,6140,6142,6152,6162,6171],{"className":6141},[26],[28,6143,6145,355,6147,186,6150],{"className":6144},[31],[33,6146],{"disabled":35,"type":36},[39,6148,6149],{},"20",[39,6151,6149],{},[28,6153,6155,355,6157,186,6160],{"className":6154},[31],[33,6156],{"disabled":35,"type":36},[39,6158,6159],{},"14",[39,6161,6149],{},[28,6163,6165,355,6167,186,6169],{"className":6164},[31],[33,6166],{"disabled":35,"type":36},[39,6168,6149],{},[39,6170,6159],{},[28,6172,6174,355,6176,186,6178],{"className":6173},[31],[33,6175],{"disabled":35,"type":36},[39,6177,6159],{},[39,6179,6159],{},[66,6181,6182,6184,6192],{},[69,6183,71],{},[73,6185,6186,1727,6188,186,6190],{},[76,6187,78],{},[39,6189,6159],{},[39,6191,6149],{},[73,6193,6194,355,6196,6198,6199,1179,6201,6204,6205,6208,6209,6212,6213,6216,6217,6220,6221,6223,6224,383,6226,6228,6229,6232],{},[76,6195,84],{},[39,6197,6134],{}," has higher precedence than ",[39,6200,1246],{},[39,6202,6203],{},"2 + 3 * 4"," computes ",[39,6206,6207],{},"3 * 4 = 12"," first, then ",[39,6210,6211],{},"2 + 12 = 14",". Parentheses override natural precedence, so ",[39,6214,6215],{},"(2 + 3) * 4"," forces ",[39,6218,6219],{},"5 * 4 = 20",". This is standard math-like precedence, but it's worth internalizing because JavaScript has many more operators with less intuitive precedence than arithmetic (e.g., where does ",[39,6222,4969],{}," sit relative to ",[39,6225,5530],{},[39,6227,1361],{}," relative to ",[39,6230,6231],{},"**",").",[15,6234,6235,6246,6295,6361],{"language":247},[18,6236,6238,6239,6241,6242,6245],{"id":6237},"q7-what-does-associativity-determine-and-how-does-exponentiation-differ-from-subtraction-in-this-regard","Q7. What does associativity determine, and how does ",[39,6240,6231],{}," (exponentiation) differ from ",[39,6243,6244],{},"-"," (subtraction) in this regard?",[257,6247,6248],{"language":247},[260,6249,6251],{"className":262,"code":6250,"language":247,"meta":264,"style":264},"console.log(2 ** 3 ** 2);\nconsole.log(10 - 3 - 2);\n",[39,6252,6253,6274],{"__ignoreMap":264},[268,6254,6255,6257,6259,6261,6263,6266,6268,6270,6272],{"class":270,"line":271},[268,6256,1353],{"class":282},[268,6258,1356],{"class":278},[268,6260,622],{"class":282},[268,6262,2258],{"class":305},[268,6264,6265],{"class":274}," **",[268,6267,3396],{"class":305},[268,6269,6265],{"class":274},[268,6271,2214],{"class":305},[268,6273,628],{"class":282},[268,6275,6276,6278,6280,6282,6284,6287,6289,6291,6293],{"class":270,"line":286},[268,6277,1353],{"class":282},[268,6279,1356],{"class":278},[268,6281,622],{"class":282},[268,6283,5825],{"class":305},[268,6285,6286],{"class":274}," -",[268,6288,3396],{"class":305},[268,6290,6286],{"class":274},[268,6292,2214],{"class":305},[268,6294,628],{"class":282},[23,6296,6298,6309,6335,6350],{"className":6297},[26],[28,6299,6301,6303,6304,186,6307],{"className":6300},[31],[33,6302],{"disabled":35,"type":36}," Both evaluate left-to-right: ",[39,6305,6306],{},"64",[39,6308,2429],{},[28,6310,6312,355,6314,6316,6317,6320,6321,6320,6324,5789,6327,6329,6330,6320,6333,2690],{"className":6311},[31],[33,6313],{"disabled":35,"type":36},[39,6315,6231],{}," is right-associative (",[39,6318,6319],{},"2 ** (3 ** 2)"," = ",[39,6322,6323],{},"2 ** 9",[39,6325,6326],{},"512",[39,6328,6244],{}," is left-associative (",[39,6331,6332],{},"(10 - 3) - 2",[39,6334,2429],{},[28,6336,6338,355,6340,6342,6343,6345,6346,186,6348],{"className":6337},[31],[33,6339],{"disabled":35,"type":36},[39,6341,6231],{}," is left-associative like ",[39,6344,6244],{},", giving ",[39,6347,6306],{},[39,6349,2429],{},[28,6351,6353,6355,6356,186,6358],{"className":6352},[31],[33,6354],{"disabled":35,"type":36}," Both are right-associative, giving ",[39,6357,6326],{},[39,6359,6360],{},"9",[66,6362,6363,6365,6377],{},[69,6364,71],{},[73,6366,6367,1727,6369,6316,6371,5789,6373,6329,6375,2690],{},[76,6368,78],{},[39,6370,6231],{},[39,6372,6326],{},[39,6374,6244],{},[39,6376,2429],{},[73,6378,6379,6381,6382,42,6384,42,6386,42,6388,6390,6391,6394,6395,6398,6399,6401,6402,6405,6406,2758,6409,3277,6412,6414,6415,6394,6418,2758,6421,6424],{},[76,6380,84],{}," Associativity determines grouping order when the same-precedence operator repeats. Most operators (",[39,6383,6244],{},[39,6385,1246],{},[39,6387,6134],{},[39,6389,446],{},") are left-associative, evaluating left to right: ",[39,6392,6393],{},"10 - 3 - 2"," groups as ",[39,6396,6397],{},"(10 - 3) - 2 = 5",". Exponentiation ",[39,6400,6231],{}," is a deliberate exception — it's right-associative, matching mathematical convention where ",[39,6403,6404],{},"2^3^2"," means ",[39,6407,6408],{},"2^(3^2)",[39,6410,6411],{},"(2^3)^2",[76,6413,365],{}," so ",[39,6416,6417],{},"2 ** 3 ** 2",[39,6419,6420],{},"2 ** (3 ** 2) = 2 ** 9 = 512",[39,6422,6423],{},"(2 ** 3) ** 2 = 64"," — a frequent trip-up for people assuming all arithmetic operators associate the same way.",[15,6426,6427,6437,6496,6540],{"language":247},[18,6428,6430,6431,446,6433,6436],{"id":6429},"q8-what-happens-when-you-compare-with-across-mixed-types-eg-strings-and-numbers","Q8. What happens when you compare with ",[39,6432,1076],{},[39,6434,6435],{},">"," across mixed types, e.g., strings and numbers?",[257,6438,6439],{"language":247},[260,6440,6442],{"className":262,"code":6441,"language":247,"meta":264,"style":264},"console.log(\"10\" \u003C \"9\");\nconsole.log(10 \u003C 9);\nconsole.log(\"10\" \u003C 9);\n",[39,6443,6444,6463,6480],{"__ignoreMap":264},[268,6445,6446,6448,6450,6452,6455,6458,6461],{"class":270,"line":271},[268,6447,1353],{"class":282},[268,6449,1356],{"class":278},[268,6451,622],{"class":282},[268,6453,6454],{"class":289},"\"10\"",[268,6456,6457],{"class":274}," \u003C",[268,6459,6460],{"class":289}," \"9\"",[268,6462,628],{"class":282},[268,6464,6465,6467,6469,6471,6473,6475,6478],{"class":270,"line":286},[268,6466,1353],{"class":282},[268,6468,1356],{"class":278},[268,6470,622],{"class":282},[268,6472,5825],{"class":305},[268,6474,6457],{"class":274},[268,6476,6477],{"class":305}," 9",[268,6479,628],{"class":282},[268,6481,6482,6484,6486,6488,6490,6492,6494],{"class":270,"line":296},[268,6483,1353],{"class":282},[268,6485,1356],{"class":278},[268,6487,622],{"class":282},[268,6489,6454],{"class":289},[268,6491,6457],{"class":274},[268,6493,6477],{"class":305},[268,6495,628],{"class":282},[23,6497,6499,6510,6522,6530],{"className":6498},[26],[28,6500,6502,355,6504,42,6506,42,6508],{"className":6501},[31],[33,6503],{"disabled":35,"type":36},[39,6505,2986],{},[39,6507,2986],{},[39,6509,2986],{},[28,6511,6513,355,6515,42,6517,42,6519,6521],{"className":6512},[31],[33,6514],{"disabled":35,"type":36},[39,6516,2185],{},[39,6518,2986],{},[39,6520,2986],{}," — the first compares two strings lexicographically (\"1\" \u003C \"9\" character-wise), the second and third involve numeric comparison after coercion",[28,6523,6525,6527,6528],{"className":6524},[31],[33,6526],{"disabled":35,"type":36}," All three are ",[39,6529,2185],{},[28,6531,6533,355,6535,6537,6538],{"className":6532},[31],[33,6534],{"disabled":35,"type":36},[39,6536,1274],{},", since strings cannot be compared with ",[39,6539,1076],{},[66,6541,6542,6544,6554],{},[69,6543,71],{},[73,6545,6546,1727,6548,42,6550,42,6552],{},[76,6547,78],{},[39,6549,2185],{},[39,6551,2986],{},[39,6553,2986],{},[73,6555,6556,355,6558,6561,6562,6565,6566,6568,6569,6572,6573,6575,6576,6579,6580,3277,6582,6585,6586,6588,6589,4977,6591,3277,6593,6595,6596,6599],{},[76,6557,84],{},[39,6559,6560],{},"\"10\" \u003C \"9\""," compares two strings ",[104,6563,6564],{},"lexicographically"," (character by character, like dictionary order), not numerically: the first character ",[39,6567,3387],{}," has a lower char code than ",[39,6570,6571],{},"\"9\"",", so it's ",[39,6574,2185],{}," — this is the trap, since numerically 10 is greater than 9. ",[39,6577,6578],{},"10 \u003C 9"," is a normal numeric comparison: ",[39,6581,2986],{},[39,6583,6584],{},"\"10\" \u003C 9"," mixes a string and a number, so the relational operator coerces the string to a number (",[39,6587,5825],{},"), giving ",[39,6590,6578],{},[39,6592,2986],{},[76,6594,365],{}," relational operators only compare lexicographically when ",[104,6597,6598],{},"both"," sides are strings; introduce any non-string operand and numeric coercion kicks in instead — an inconsistency that trips up sorting and comparison logic on stringified data (e.g., data from form inputs or JSON).",[15,6601,6602,6609,6682,6742],{"language":247},[18,6603,6605,6606,6608],{"id":6604},"q9-what-is-the-result-of-comparing-with-nan-using-relational-operators","Q9. What is the result of comparing with ",[39,6607,3040],{}," using relational operators?",[257,6610,6611],{"language":247},[260,6612,6614],{"className":262,"code":6613,"language":247,"meta":264,"style":264},"console.log(NaN \u003C 1);\nconsole.log(NaN > 1);\nconsole.log(NaN \u003C= NaN);\nconsole.log(NaN == NaN);\n",[39,6615,6616,6632,6649,6666],{"__ignoreMap":264},[268,6617,6618,6620,6622,6624,6626,6628,6630],{"class":270,"line":271},[268,6619,1353],{"class":282},[268,6621,1356],{"class":278},[268,6623,622],{"class":282},[268,6625,3040],{"class":305},[268,6627,6457],{"class":274},[268,6629,2199],{"class":305},[268,6631,628],{"class":282},[268,6633,6634,6636,6638,6640,6642,6645,6647],{"class":270,"line":286},[268,6635,1353],{"class":282},[268,6637,1356],{"class":278},[268,6639,622],{"class":282},[268,6641,3040],{"class":305},[268,6643,6644],{"class":274}," >",[268,6646,2199],{"class":305},[268,6648,628],{"class":282},[268,6650,6651,6653,6655,6657,6659,6662,6664],{"class":270,"line":296},[268,6652,1353],{"class":282},[268,6654,1356],{"class":278},[268,6656,622],{"class":282},[268,6658,3040],{"class":305},[268,6660,6661],{"class":274}," \u003C=",[268,6663,3027],{"class":305},[268,6665,628],{"class":282},[268,6667,6668,6670,6672,6674,6676,6678,6680],{"class":270,"line":311},[268,6669,1353],{"class":282},[268,6671,1356],{"class":278},[268,6673,622],{"class":282},[268,6675,3040],{"class":305},[268,6677,3165],{"class":274},[268,6679,3027],{"class":305},[268,6681,628],{"class":282},[23,6683,6685,6698,6720,6733],{"className":6684},[26],[28,6686,6688,355,6690,42,6692,42,6694,42,6696],{"className":6687},[31],[33,6689],{"disabled":35,"type":36},[39,6691,2185],{},[39,6693,2986],{},[39,6695,2185],{},[39,6697,2986],{},[28,6699,6701,355,6703,42,6705,42,6707,42,6709,6711,6712,6714,6715,6717,6718],{"className":6700},[31],[33,6702],{"disabled":35,"type":36},[39,6704,2986],{},[39,6706,2986],{},[39,6708,2986],{},[39,6710,2986],{}," — every comparison involving ",[39,6713,3040],{}," (including ",[39,6716,3040],{}," against itself) is ",[39,6719,2986],{},[28,6721,6723,355,6725,42,6727,42,6729,42,6731],{"className":6722},[31],[33,6724],{"disabled":35,"type":36},[39,6726,2986],{},[39,6728,2986],{},[39,6730,2185],{},[39,6732,2185],{},[28,6734,6736,6738,6739,6741],{"className":6735},[31],[33,6737],{"disabled":35,"type":36}," Throws ",[39,6740,827],{}," on every line",[66,6743,6744,6746,6758],{},[69,6745,71],{},[73,6747,6748,1727,6750,42,6752,42,6754,42,6756],{},[76,6749,78],{},[39,6751,2986],{},[39,6753,2986],{},[39,6755,2986],{},[39,6757,2986],{},[73,6759,6760,355,6762,355,6764,6766,6767,6769,6770,42,6772,42,6774,42,6777,42,6780,42,6782,6784,6785,6787,6788,6790,6791,6793,6794,462],{},[76,6761,84],{},[76,6763,365],{},[39,6765,3040],{}," compares as ",[39,6768,2986],{}," against literally everything, including itself, for every relational and equality operator (",[39,6771,1076],{},[39,6773,6435],{},[39,6775,6776],{},"\u003C=",[39,6778,6779],{},">=",[39,6781,3197],{},[39,6783,3280],{},"). This is by IEEE-754 design — ",[39,6786,3040],{}," is defined as \"unordered\" relative to all values. It never throws (option D is wrong); it just always evaluates to ",[39,6789,2986],{},". This is exactly why ",[39,6792,4440],{}," (not a comparison operator) is the only reliable way to detect ",[39,6795,3040],{},[15,6797,6798,6802,6853,6893],{"language":247},[18,6799,6801],{"id":6800},"q10-what-is-the-value-of-an-empty-expression-involving-the-comma-operator","Q10. What is the value of an empty expression involving the comma operator?",[257,6803,6804],{"language":247},[260,6805,6807],{"className":262,"code":6806,"language":247,"meta":264,"style":264},"const result = (1 + 2, 3 + 4, 5 + 6);\nconsole.log(result);\n",[39,6808,6809,6844],{"__ignoreMap":264},[268,6810,6811,6813,6815,6817,6819,6821,6823,6825,6827,6829,6831,6833,6835,6837,6839,6842],{"class":270,"line":271},[268,6812,243],{"class":274},[268,6814,5583],{"class":305},[268,6816,616],{"class":274},[268,6818,2182],{"class":282},[268,6820,2255],{"class":305},[268,6822,3350],{"class":274},[268,6824,2214],{"class":305},[268,6826,42],{"class":282},[268,6828,3423],{"class":305},[268,6830,3350],{"class":274},[268,6832,6111],{"class":305},[268,6834,42],{"class":282},[268,6836,2429],{"class":305},[268,6838,3350],{"class":274},[268,6840,6841],{"class":305}," 6",[268,6843,628],{"class":282},[268,6845,6846,6848,6850],{"class":270,"line":286},[268,6847,1353],{"class":282},[268,6849,1356],{"class":278},[268,6851,6852],{"class":282},"(result);\n",[23,6854,6856,6864,6872,6881],{"className":6855},[26],[28,6857,6859,355,6861,6863],{"className":6858},[31],[33,6860],{"disabled":35,"type":36},[39,6862,1274],{}," — commas are not valid inside parentheses like this",[28,6865,6867,355,6869,6871],{"className":6866},[31],[33,6868],{"disabled":35,"type":36},[39,6870,3423],{},", the result of the first expression",[28,6873,6875,355,6877,6880],{"className":6874},[31],[33,6876],{"disabled":35,"type":36},[39,6878,6879],{},"11",", the result of the second expression",[28,6882,6884,355,6886,6888,6889,6892],{"className":6883},[31],[33,6885],{"disabled":35,"type":36},[39,6887,6879],{},", since the comma operator evaluates each operand left to right and yields the value of the ",[104,6890,6891],{},"last"," one",[66,6894,6895,6897,6905],{},[69,6896,71],{},[73,6898,6899,6901,6902,6904],{},[76,6900,78],{}," D — ",[39,6903,6879],{},", the value of the last comma-separated expression",[73,6906,6907,6909,6910,6912,6913,6916,6917,6920,6921,6923,6924,6927,6928,6931],{},[76,6908,84],{}," The comma operator evaluates each expression in sequence (for their side effects) and yields only the final one's value. Here ",[39,6911,3489],{}," (=3) and ",[39,6914,6915],{},"3 + 4"," (=7) are computed and discarded, and ",[39,6918,6919],{},"5 + 6"," (=11) becomes the expression's value, assigned to ",[39,6922,5631],{},". This operator is rarely used explicitly outside of terse ",[39,6925,6926],{},"for"," loop headers (",[39,6929,6930],{},"for (let i = 0, j = 10; i \u003C j; i++, j--)",") — using it for arbitrary sequencing like this example is unusual and hurts readability, but is valid, well-defined syntax, not an error (ruling out option A).",[15,6933,6934,6941,7035,7116],{"language":247},[18,6935,6937,6938,6940],{"id":6936},"q11-what-does-the-unary-operator-do-to-a-string-operand","Q11. What does the unary ",[39,6939,1246],{}," operator do to a string operand?",[257,6942,6943],{"language":247},[260,6944,6946],{"className":262,"code":6945,"language":247,"meta":264,"style":264},"console.log(+\"42\");\nconsole.log(+\"\");\nconsole.log(+\"  \");\nconsole.log(+\"abc\");\nconsole.log(+null);\nconsole.log(+undefined);\n",[39,6947,6948,6963,6977,6992,7007,7021],{"__ignoreMap":264},[268,6949,6950,6952,6954,6956,6958,6961],{"class":270,"line":271},[268,6951,1353],{"class":282},[268,6953,1356],{"class":278},[268,6955,622],{"class":282},[268,6957,1246],{"class":274},[268,6959,6960],{"class":289},"\"42\"",[268,6962,628],{"class":282},[268,6964,6965,6967,6969,6971,6973,6975],{"class":270,"line":286},[268,6966,1353],{"class":282},[268,6968,1356],{"class":278},[268,6970,622],{"class":282},[268,6972,1246],{"class":274},[268,6974,3294],{"class":289},[268,6976,628],{"class":282},[268,6978,6979,6981,6983,6985,6987,6990],{"class":270,"line":296},[268,6980,1353],{"class":282},[268,6982,1356],{"class":278},[268,6984,622],{"class":282},[268,6986,1246],{"class":274},[268,6988,6989],{"class":289},"\"  \"",[268,6991,628],{"class":282},[268,6993,6994,6996,6998,7000,7002,7005],{"class":270,"line":311},[268,6995,1353],{"class":282},[268,6997,1356],{"class":278},[268,6999,622],{"class":282},[268,7001,1246],{"class":274},[268,7003,7004],{"class":289},"\"abc\"",[268,7006,628],{"class":282},[268,7008,7009,7011,7013,7015,7017,7019],{"class":270,"line":788},[268,7010,1353],{"class":282},[268,7012,1356],{"class":278},[268,7014,622],{"class":282},[268,7016,1246],{"class":274},[268,7018,2650],{"class":305},[268,7020,628],{"class":282},[268,7022,7023,7025,7027,7029,7031,7033],{"class":270,"line":1951},[268,7024,1353],{"class":282},[268,7026,1356],{"class":278},[268,7028,622],{"class":282},[268,7030,1246],{"class":274},[268,7032,833],{"class":305},[268,7034,628],{"class":282},[23,7036,7038,7055,7090,7108],{"className":7037},[26],[28,7039,7041,355,7043,42,7045,42,7047,42,7049,42,7051,42,7053],{"className":7040},[31],[33,7042],{"disabled":35,"type":36},[39,7044,4659],{},[39,7046,3040],{},[39,7048,3040],{},[39,7050,3040],{},[39,7052,3307],{},[39,7054,3040],{},[28,7056,7058,355,7060,42,7062,42,7064,42,7066,42,7068,42,7070,7072,7073,7075,7076,7078,7079,42,7081,7083,7084,137,7086,7083,7088],{"className":7057},[31],[33,7059],{"disabled":35,"type":36},[39,7061,4659],{},[39,7063,3307],{},[39,7065,3307],{},[39,7067,3040],{},[39,7069,3307],{},[39,7071,3040],{}," — unary ",[39,7074,1246],{}," coerces to a number; an empty or whitespace-only string becomes ",[39,7077,3307],{},", a non-numeric string becomes ",[39,7080,3040],{},[39,7082,2650],{}," becomes ",[39,7085,3307],{},[39,7087,833],{},[39,7089,3040],{},[28,7091,7093,355,7095,42,7097,42,7099,42,7101,42,7103,42,7105,7107],{"className":7092},[31],[33,7094],{"disabled":35,"type":36},[39,7096,6960],{},[39,7098,3294],{},[39,7100,3294],{},[39,7102,7004],{},[39,7104,2650],{},[39,7106,833],{}," (no coercion happens)",[28,7109,7111,7113,7114],{"className":7110},[31],[33,7112],{"disabled":35,"type":36}," All six results are ",[39,7115,3040],{},[66,7117,7118,7120,7136],{},[69,7119,71],{},[73,7121,7122,1727,7124,42,7126,42,7128,42,7130,42,7132,42,7134],{},[76,7123,78],{},[39,7125,4659],{},[39,7127,3307],{},[39,7129,3307],{},[39,7131,3040],{},[39,7133,3307],{},[39,7135,3040],{},[73,7137,7138,7140,7141,7143,7144,7147,7148,2758,7150,7152,7153,7156,7157,7159,7160,7162,7163,830,7166,7168,7169,830,7172,3277,7174,7176,7177,7179],{},[76,7139,84],{}," Unary ",[39,7142,1246],{}," is a common idiom for explicit numeric coercion. Strings are converted via ",[39,7145,7146],{},"Number()"," rules: numeric-looking strings parse normally, and — the gotcha — an empty string or a string of only whitespace converts to ",[39,7149,3307],{},[39,7151,3040],{}," (since ",[39,7154,7155],{},"Number(\"\")"," trims to nothing and treats that as zero). A truly non-numeric string like ",[39,7158,7004],{}," produces ",[39,7161,3040],{},". Separately, ",[39,7164,7165],{},"Number(null)",[39,7167,3307],{}," (a well-known inconsistency), while ",[39,7170,7171],{},"Number(undefined)",[39,7173,3040],{},[76,7175,365],{}," the empty-string-becomes-zero behavior is a frequent source of validation bugs when checking \"is this field a number\" using truthiness or unary ",[39,7178,1246],{}," alone.",[15,7181,7182,7190,7228,7279],{"language":247},[18,7183,7185,7186,7189],{"id":7184},"q12-in-a-b-c-what-happens","Q12. In ",[39,7187,7188],{},"a ?? b || c",", what happens?",[257,7191,7192],{"language":247},[260,7193,7195],{"className":262,"code":7194,"language":247,"meta":264,"style":264},"const a = null;\nconsole.log(a ?? b || c);\n",[39,7196,7197,7210],{"__ignoreMap":264},[268,7198,7199,7201,7204,7206,7208],{"class":270,"line":271},[268,7200,243],{"class":274},[268,7202,7203],{"class":305}," a",[268,7205,616],{"class":274},[268,7207,4794],{"class":305},[268,7209,293],{"class":282},[268,7211,7212,7214,7216,7219,7221,7223,7225],{"class":270,"line":286},[268,7213,1353],{"class":282},[268,7215,1356],{"class":278},[268,7217,7218],{"class":282},"(a ",[268,7220,4969],{"class":274},[268,7222,2209],{"class":282},[268,7224,5530],{"class":274},[268,7226,7227],{"class":282}," c);\n",[23,7229,7231,7242,7259,7269],{"className":7230},[26],[28,7232,7234,7236,7237,186,7239,7241],{"className":7233},[31],[33,7235],{"disabled":35,"type":36}," It evaluates fine, left to right, treating ",[39,7238,4969],{},[39,7240,5530],{}," as equal precedence",[28,7243,7245,1271,7247,7249,7250,7252,7253,7255,7256,7258],{"className":7244},[31],[33,7246],{"disabled":35,"type":36},[39,7248,1274],{}," — mixing ",[39,7251,4969],{}," directly with ",[39,7254,5530],{}," (or ",[39,7257,5527],{},") without explicit parentheses is a syntax error, precisely because their relative precedence\u002Fassociativity is ambiguous and disallowed by the spec",[28,7260,7262,355,7264,7266,7267],{"className":7261},[31],[33,7263],{"disabled":35,"type":36},[39,7265,4969],{}," always takes precedence and short-circuits, ignoring ",[39,7268,5530],{},[28,7270,7272,355,7274,7276,7277],{"className":7271},[31],[33,7273],{"disabled":35,"type":36},[39,7275,5530],{}," always takes precedence over ",[39,7278,4969],{},[66,7280,7281,7283,7297],{},[69,7282,71],{},[73,7284,7285,7287,7288,2029,7290,446,7292,7294,7295],{},[76,7286,78],{}," B — Mixing ",[39,7289,4969],{},[39,7291,5530],{},[39,7293,5527],{}," without parentheses is a ",[39,7296,1274],{},[73,7298,7299,355,7301,7303,7304,7306,7307,99,7309,7311,7312,99,7315,7318],{},[76,7300,84],{},[76,7302,582],{}," unlike most operators, which have a well-defined relative precedence, the spec explicitly forbids writing ",[39,7305,4969],{}," directly adjacent to ",[39,7308,5530],{},[39,7310,5527],{}," without parentheses (",[39,7313,7314],{},"(a ?? b) || c",[39,7316,7317],{},"a ?? (b || c)","), because their intended grouping is genuinely ambiguous and error-prone to guess. This is a deliberate design choice to force developers to be explicit rather than rely on a precedence table few people would remember correctly. Options C and D each assume an implicit ordering that the language intentionally refuses to define without parentheses.",[15,7320,7321,7325,7382,7449],{"language":247},[18,7322,7324],{"id":7323},"q13-what-is-the-output-of-this-logical-assignment-operator-usage","Q13. What is the output of this logical assignment operator usage?",[257,7326,7327],{"language":247},[260,7328,7330],{"className":262,"code":7329,"language":247,"meta":264,"style":264},"let config = { timeout: 0 };\nconfig.timeout ??= 3000;\nconfig.retries ||= 5;\nconsole.log(config);\n",[39,7331,7332,7348,7361,7373],{"__ignoreMap":264},[268,7333,7334,7336,7339,7341,7344,7346],{"class":270,"line":271},[268,7335,240],{"class":274},[268,7337,7338],{"class":282}," config ",[268,7340,302],{"class":274},[268,7342,7343],{"class":282}," { timeout: ",[268,7345,3307],{"class":305},[268,7347,2790],{"class":282},[268,7349,7350,7353,7356,7359],{"class":270,"line":286},[268,7351,7352],{"class":282},"config.timeout ",[268,7354,7355],{"class":274},"??=",[268,7357,7358],{"class":305}," 3000",[268,7360,293],{"class":282},[268,7362,7363,7366,7369,7371],{"class":270,"line":296},[268,7364,7365],{"class":282},"config.retries ",[268,7367,7368],{"class":274},"||=",[268,7370,2387],{"class":305},[268,7372,293],{"class":282},[268,7374,7375,7377,7379],{"class":270,"line":311},[268,7376,1353],{"class":282},[268,7378,1356],{"class":278},[268,7380,7381],{"class":282},"(config);\n",[23,7383,7385,7396,7430,7441],{"className":7384},[26],[28,7386,7388,355,7390,7393,7394,4917],{"className":7387},[31],[33,7389],{"disabled":35,"type":36},[39,7391,7392],{},"{ timeout: 3000, retries: 5 }"," — both operators overwrite because ",[39,7395,3307],{},[28,7397,7399,355,7401,3990,7404,7406,7407,446,7409,7411,7412,7415,7416,5789,7418,7420,7421,7424,7425,7427,7428,2690],{"className":7398},[31],[33,7400],{"disabled":35,"type":36},[39,7402,7403],{},"{ timeout: 0, retries: 5 }",[39,7405,7355],{}," only assigns if the left is ",[39,7408,2650],{},[39,7410,833],{}," (so ",[39,7413,7414],{},"timeout"," stays ",[39,7417,3307],{},[39,7419,7368],{}," assigns if the left is falsy or missing (so ",[39,7422,7423],{},"retries",", being ",[39,7426,833],{},", becomes ",[39,7429,2429],{},[28,7431,7433,355,7435,3990,7438,7440],{"className":7432},[31],[33,7434],{"disabled":35,"type":36},[39,7436,7437],{},"{ timeout: 0 }",[39,7439,7423],{}," is left untouched since it was never declared",[28,7442,7444,355,7446,7448],{"className":7443},[31],[33,7445],{"disabled":35,"type":36},[39,7447,827],{},", since you can't use logical assignment on object properties",[66,7450,7451,7453,7459],{},[69,7452,71],{},[73,7454,7455,1727,7457],{},[76,7456,78],{},[39,7458,7403],{},[73,7460,7461,355,7463,7465,7466,7469,7470,446,7472,7474,7475,830,7477,7479,7480,7482,7483,7485,7486,7488,7489,7491,7492,3277,7494,355,7496,7498,7499,7501,7502,7504,7505,7507,7508,7510],{},[76,7462,84],{},[39,7464,7355],{}," (ES2021) is shorthand for ",[39,7467,7468],{},"x ?? (x = y)"," — it only assigns when the current value is ",[39,7471,2650],{},[39,7473,833],{},". Since ",[39,7476,7414],{},[39,7478,3307],{}," (not nullish), ",[39,7481,7355],{}," leaves it untouched. ",[39,7484,7423],{}," doesn't exist yet, so accessing it is ",[39,7487,833],{},", which is both nullish and falsy — ",[39,7490,7368],{}," assigns ",[39,7493,2429],{},[76,7495,930],{},[39,7497,7355],{}," is the safer choice specifically for numeric defaults like ",[39,7500,7414],{}," where ",[39,7503,3307],{}," is a meaningful, valid value that shouldn't be clobbered — mirroring the ",[39,7506,4969],{}," vs ",[39,7509,5530],{}," distinction from Q4.",[15,7512,7513,7520,7585,7651],{"language":247},[18,7514,7516,7517,7519],{"id":7515},"q14-what-does-typeof-return-for-these-edge-case-expressions","Q14. What does ",[39,7518,1361],{}," return for these edge-case expressions?",[257,7521,7522],{"language":247},[260,7523,7525],{"className":262,"code":7524,"language":247,"meta":264,"style":264},"console.log(typeof (1 \u003C 2));\nconsole.log(typeof typeof 1);\nconsole.log(typeof (1, \"a\"));\n",[39,7526,7527,7547,7564],{"__ignoreMap":264},[268,7528,7529,7531,7533,7535,7537,7539,7541,7543,7545],{"class":270,"line":271},[268,7530,1353],{"class":282},[268,7532,1356],{"class":278},[268,7534,622],{"class":282},[268,7536,1361],{"class":274},[268,7538,2182],{"class":282},[268,7540,2255],{"class":305},[268,7542,6457],{"class":274},[268,7544,2214],{"class":305},[268,7546,4818],{"class":282},[268,7548,7549,7551,7553,7555,7557,7560,7562],{"class":270,"line":286},[268,7550,1353],{"class":282},[268,7552,1356],{"class":278},[268,7554,622],{"class":282},[268,7556,1361],{"class":274},[268,7558,7559],{"class":274}," typeof",[268,7561,2199],{"class":305},[268,7563,628],{"class":282},[268,7565,7566,7568,7570,7572,7574,7576,7578,7580,7583],{"class":270,"line":296},[268,7567,1353],{"class":282},[268,7569,1356],{"class":278},[268,7571,622],{"class":282},[268,7573,1361],{"class":274},[268,7575,2182],{"class":282},[268,7577,2255],{"class":305},[268,7579,42],{"class":282},[268,7581,7582],{"class":289},"\"a\"",[268,7584,4818],{"class":282},[23,7586,7588,7599,7629,7640],{"className":7587},[26],[28,7589,7591,355,7593,42,7595,42,7597],{"className":7590},[31],[33,7592],{"disabled":35,"type":36},[39,7594,2953],{},[39,7596,1383],{},[39,7598,2761],{},[28,7600,7602,355,7604,42,7606,42,7608,3990,7610,7612,7613,2272,7615,4453,7618,183,7620,7622,7623,7625,7626,7628],{"className":7601},[31],[33,7603],{"disabled":35,"type":36},[39,7605,2953],{},[39,7607,2761],{},[39,7609,2761],{},[39,7611,1361],{}," on a comparison gives ",[39,7614,2953],{},[39,7616,7617],{},"typeof typeof x",[39,7619,2761],{},[39,7621,1361],{}," itself always returns a string, and the comma operator yields its last operand (",[39,7624,7582],{},") before ",[39,7627,1361],{}," runs on it",[28,7630,7632,355,7634,42,7636,42,7638],{"className":7631},[31],[33,7633],{"disabled":35,"type":36},[39,7635,2953],{},[39,7637,1383],{},[39,7639,1383],{},[28,7641,7643,355,7645,7647,7648,7650],{"className":7642},[31],[33,7644],{"disabled":35,"type":36},[39,7646,1274],{}," on the last line, since ",[39,7649,1361],{}," cannot be applied to a comma expression",[66,7652,7653,7655,7665],{},[69,7654,71],{},[73,7656,7657,1727,7659,42,7661,42,7663],{},[76,7658,78],{},[39,7660,2953],{},[39,7662,2761],{},[39,7664,2761],{},[73,7666,7667,355,7669,7672,7673,1179,7675,2906,7677,3277,7679,7682,7683,7685,7686,5425,7688,7691,7692,7694,7695,7697,7698,7700,7701,5409,7704,7706,7707,830,7710,7712,7713,7715,7716,462],{},[76,7668,84],{},[39,7670,7671],{},"1 \u003C 2"," evaluates to the boolean ",[39,7674,2185],{},[39,7676,1361],{},[39,7678,2953],{},[39,7680,7681],{},"typeof 1"," evaluates to the string ",[39,7684,1383],{},"; applying ",[39,7687,1361],{},[104,7689,7690],{},"that"," result (a string) gives ",[39,7693,2761],{}," — a fun consequence of ",[39,7696,1361],{}," always producing a string value, so nesting it twice always ends in ",[39,7699,2761],{}," regardless of the original operand. The comma expression ",[39,7702,7703],{},"(1, \"a\")",[39,7705,7582],{}," (per Q10's rule), and ",[39,7708,7709],{},"typeof \"a\"",[39,7711,2761],{},". Option D wrongly assumes ",[39,7714,1361],{}," can't handle a parenthesized comma expression — it's just a normal expression to ",[39,7717,1361],{},[15,7719,7720,7735,7774,7825],{"language":247},[18,7721,7723,7724,446,7726,7728,7729,446,7731,7734],{"id":7722},"q15-what-is-the-idiomatic-reason-to-prefer-over-in-production-code","Q15. What is the idiomatic reason to prefer ",[39,7725,3280],{},[39,7727,4327],{}," over ",[39,7730,3197],{},[39,7732,7733],{},"!="," in production code?",[257,7736,7737],{"language":247},[260,7738,7740],{"className":262,"code":7739,"language":247,"meta":264,"style":264},"function isAdmin(role) {\n  return role == \"admin\";\n}\n",[39,7741,7742,7756,7770],{"__ignoreMap":264},[268,7743,7744,7746,7749,7751,7754],{"class":270,"line":271},[268,7745,275],{"class":274},[268,7747,7748],{"class":278}," isAdmin",[268,7750,622],{"class":282},[268,7752,7753],{"class":1222},"role",[268,7755,1235],{"class":282},[268,7757,7758,7760,7763,7765,7768],{"class":270,"line":286},[268,7759,1240],{"class":274},[268,7761,7762],{"class":282}," role ",[268,7764,3197],{"class":274},[268,7766,7767],{"class":289}," \"admin\"",[268,7769,293],{"class":282},[268,7771,7772],{"class":270,"line":296},[268,7773,314],{"class":282},[23,7775,7777,7785,7805,7819],{"className":7776},[26],[28,7778,7780,355,7782,7784],{"className":7779},[31],[33,7781],{"disabled":35,"type":36},[39,7783,3197],{}," is deprecated and will be removed from future ECMAScript versions",[28,7786,7788,355,7790,7792,7793,7795,7796,7798,7799,7801,7802],{"className":7787},[31],[33,7789],{"disabled":35,"type":36},[39,7791,3280],{}," avoids the unpredictable, hard-to-audit coercion rules of ",[39,7794,3197],{}," (as seen with ",[39,7797,3286],{}," and similar cases), making comparisons behave exactly as written; ",[39,7800,3197],{}," should be reserved for the few well-understood idioms like ",[39,7803,7804],{},"x == null",[28,7806,7808,355,7810,7812,7813,7815,7816,7818],{"className":7807},[31],[33,7809],{"disabled":35,"type":36},[39,7811,3197],{}," is slower at runtime than ",[39,7814,3280],{}," in all engines, so ",[39,7817,3280],{}," is purely a performance optimization",[28,7820,7822,7824],{"className":7821},[31],[33,7823],{"disabled":35,"type":36}," There's no real-world difference; the choice is purely stylistic with zero behavioral impact",[66,7826,7827,7829,7844],{},[69,7828,71],{},[73,7830,7831,1727,7833,7835,7836,7838,7839,7841,7842],{},[76,7832,78],{},[39,7834,3280],{}," avoids ",[39,7837,3197],{},"'s unpredictable coercion; ",[39,7840,3197],{}," is reserved for well-understood idioms like ",[39,7843,7804],{},[73,7845,7846,355,7848,7850,7851,7853,7854,7856,7857,7859],{},[76,7847,84],{},[76,7849,930],{}," the core argument for ",[39,7852,3280],{}," is correctness and reviewability, not performance — coercion rules like the array\u002Fboolean example from Q2 are genuinely hard to reason about at a glance, and bugs from accidental type mismatches (e.g., comparing a form input string against a numeric constant) are common. Style guides carve out ",[39,7855,4874],{}," as an accepted exception (per Q19 of the previous file) precisely because that one coercion behavior is well-known and intentional. Option A is false — ",[39,7858,3197],{}," is not deprecated or going anywhere. Option C overstates and mischaracterizes the actual (in practice negligible) performance difference as the primary motivation.",[15,7861,7862,7873,7914,7962],{"language":247},[18,7863,7865,7866,42,7868,383,7870,7872],{"id":7864},"q16-what-is-the-best-practice-way-to-write-a-conditional-default-value-assignment-when-0-or-false-might-be-legitimate-values","Q16. What is the best-practice way to write a conditional default value assignment when ",[39,7867,3307],{},[39,7869,3294],{},[39,7871,2986],{}," might be legitimate values?",[257,7874,7875],{"language":247},[260,7876,7878],{"className":262,"code":7877,"language":247,"meta":264,"style":264},"function createUser({ retries = 3, isActive = true } = {}) {}\n",[39,7879,7880],{"__ignoreMap":264},[268,7881,7882,7884,7887,7890,7892,7894,7896,7898,7901,7903,7906,7909,7911],{"class":270,"line":271},[268,7883,275],{"class":274},[268,7885,7886],{"class":278}," createUser",[268,7888,7889],{"class":282},"({ ",[268,7891,7423],{"class":1222},[268,7893,616],{"class":274},[268,7895,3396],{"class":305},[268,7897,42],{"class":282},[268,7899,7900],{"class":1222},"isActive",[268,7902,616],{"class":274},[268,7904,7905],{"class":305}," true",[268,7907,7908],{"class":282}," } ",[268,7910,302],{"class":274},[268,7912,7913],{"class":282}," {}) {}\n",[23,7915,7917,7928,7946,7956],{"className":7916},[26],[28,7918,7920,4207,7922,7924,7925],{"className":7919},[31],[33,7921],{"disabled":35,"type":36},[39,7923,5530],{}," for defaults: ",[39,7926,7927],{},"const r = retries || 3;",[28,7929,7931,7933,7934,7728,7936,7938,7939,7941,7942,99,7944],{"className":7930},[31],[33,7932],{"disabled":35,"type":36}," Prefer default parameters (as shown) or ",[39,7935,4969],{},[39,7937,5530],{}," for fallback values, since both correctly distinguish \"not provided\" (",[39,7940,833],{},") from an intentionally falsy value like ",[39,7943,3307],{},[39,7945,2986],{},[28,7947,7949,7951,7952,7955],{"className":7948},[31],[33,7950],{"disabled":35,"type":36}," Use a ternary checking ",[39,7953,7954],{},"typeof x === \"boolean\""," for every possible falsy type individually",[28,7957,7959,7961],{"className":7958},[31],[33,7960],{"disabled":35,"type":36}," It never matters which operator is used, since defaults are rarely falsy in practice",[66,7963,7964,7966,7974],{},[69,7965,71],{},[73,7967,7968,7970,7971,7973],{},[76,7969,78],{}," B — Prefer default parameters or ",[39,7972,4969],{}," since they correctly distinguish \"not provided\" from a legitimate falsy value",[73,7975,7976,355,7978,7980,7981,7984,7985,7987,7988,7991,7992,7994,7995,7997,7998,42,8000,383,8002,8004],{},[76,7977,84],{},[76,7979,930],{}," default parameters (as in the ",[39,7982,7983],{},"createUser"," signature) only kick in when an argument is literally ",[39,7986,833],{}," — passing ",[39,7989,7990],{},"retries: 0"," explicitly is respected, not overridden — which mirrors ",[39,7993,4969],{},"'s \"nullish, not falsy\" semantics discussed in Q4. Using ",[39,7996,5530],{}," for defaults, by contrast, is a common but subtly wrong pattern that silently discards deliberate falsy inputs like ",[39,7999,3307],{},[39,8001,3294],{},[39,8003,2986],{},". Option C is technically workable but needlessly verbose compared to the built-in mechanisms designed for exactly this. Option D is wrong in practice — falsy-but-valid defaults (counts, flags, empty strings) are extremely common in real APIs.",[15,8006,8007,8016,8037,8086],{"language":247},[18,8008,8010,8011,446,8013,8015],{"id":8009},"q17-which-is-the-idiomatic-pattern-for-guarding-against-nullundefined-when-calling-a-method-that-might-not-exist","Q17. Which is the idiomatic pattern for guarding against ",[39,8012,2650],{},[39,8014,833],{}," when calling a method that might not exist?",[257,8017,8018],{"language":247},[260,8019,8021],{"className":262,"code":8020,"language":247,"meta":264,"style":264},"const config = getConfig();\n",[39,8022,8023],{"__ignoreMap":264},[268,8024,8025,8027,8030,8032,8035],{"class":270,"line":271},[268,8026,243],{"class":274},[268,8028,8029],{"class":305}," config",[268,8031,616],{"class":274},[268,8033,8034],{"class":278}," getConfig",[268,8036,794],{"class":282},[23,8038,8040,8048,8068,8077],{"className":8039},[26],[28,8041,8043,355,8045],{"className":8042},[31],[33,8044],{"disabled":35,"type":36},[39,8046,8047],{},"config && config.onReady && config.onReady()",[28,8049,8051,355,8053,8056,8057,8059,8060,446,8062,8064,8065,8067],{"className":8050},[31],[33,8052],{"disabled":35,"type":36},[39,8054,8055],{},"config?.onReady?.()"," — optional chaining combined with the optional call syntax, which short-circuits to ",[39,8058,833],{}," at the first ",[39,8061,2650],{},[39,8063,833],{}," link without throwing, and is more concise\u002Fless error-prone than manual ",[39,8066,5527],{}," chains",[28,8069,8071,355,8073,8076],{"className":8070},[31],[33,8072],{"disabled":35,"type":36},[39,8074,8075],{},"if (config.onReady !== undefined) config.onReady();"," (no chaining needed)",[28,8078,8080,355,8082,8085],{"className":8079},[31],[33,8081],{"disabled":35,"type":36},[39,8083,8084],{},"try { config.onReady(); } catch (e) {}"," — swallow any resulting error",[66,8087,8088,8090,8097],{},[69,8089,71],{},[73,8091,8092,1727,8094,8096],{},[76,8093,78],{},[39,8095,8055],{}," using optional chaining plus optional call syntax",[73,8098,8099,355,8101,355,8103,8106,8107,99,8110,8113,8114,8116,8117,8119,8120,446,8122,6054,8124,8127,8128,8131],{},[76,8100,84],{},[76,8102,930],{},[39,8104,8105],{},"?.()"," (optional call, part of the same ES2020 optional chaining feature) skips the call entirely if ",[39,8108,8109],{},"config",[39,8111,8112],{},"config.onReady"," is nullish, matching the intent of the older ",[39,8115,5527],{},"-chain pattern (option A) but far more concisely and without repeating each property name. Option C is unsafe — if ",[39,8118,8109],{}," itself is ",[39,8121,2650],{},[39,8123,833],{},[39,8125,8126],{},".onReady"," on it throws before the check even runs. Option D is a code smell: swallowing all errors silently (including genuine bugs inside ",[39,8129,8130],{},"onReady",") makes debugging much harder — the correct approach is to only guard against the specific \"doesn't exist\" case, not blanket-catch everything.",[15,8133,8134,8138,8188,8244],{"language":247},[18,8135,8137],{"id":8136},"q18-why-can-chained-optional-chaining-still-throw-in-some-cases-and-how-should-that-be-handled","Q18. Why can chained optional chaining still throw in some cases, and how should that be handled?",[257,8139,8140],{"language":247},[260,8141,8143],{"className":262,"code":8142,"language":247,"meta":264,"style":264},"const user = { getProfile: null };\nconsole.log(user.getProfile());\nconsole.log(user.getProfile?.());\n",[39,8144,8145,8160,8175],{"__ignoreMap":264},[268,8146,8147,8149,8151,8153,8156,8158],{"class":270,"line":271},[268,8148,243],{"class":274},[268,8150,4071],{"class":305},[268,8152,616],{"class":274},[268,8154,8155],{"class":282}," { getProfile: ",[268,8157,2650],{"class":305},[268,8159,2790],{"class":282},[268,8161,8162,8164,8166,8169,8172],{"class":270,"line":286},[268,8163,1353],{"class":282},[268,8165,1356],{"class":278},[268,8167,8168],{"class":282},"(user.",[268,8170,8171],{"class":278},"getProfile",[268,8173,8174],{"class":282},"());\n",[268,8176,8177,8179,8181,8183,8185],{"class":270,"line":296},[268,8178,1353],{"class":282},[268,8180,1356],{"class":278},[268,8182,8168],{"class":282},[268,8184,8171],{"class":278},[268,8186,8187],{"class":282},"?.());\n",[23,8189,8191,8200,8224,8235],{"className":8190},[26],[28,8192,8194,8196,8197,8199],{"className":8193},[31],[33,8195],{"disabled":35,"type":36}," Both lines behave identically since ",[39,8198,8171],{}," is falsy either way",[28,8201,8203,355,8205,4132,8208,2833,8211,8213,8214,8217,8218,8220,8221,8223],{"className":8202},[31],[33,8204],{"disabled":35,"type":36},[39,8206,8207],{},"user.getProfile()",[39,8209,8210],{},"TypeError: user.getProfile is not a function",[39,8212,2650],{}," is not callable, and plain (non-optional) call syntax always attempts the call; ",[39,8215,8216],{},"user.getProfile?.()"," correctly short-circuits to ",[39,8219,833],{}," instead, since ",[39,8222,8105],{}," checks for nullish before attempting to invoke",[28,8225,8227,355,8229,8231,8232,8234],{"className":8226},[31],[33,8228],{"disabled":35,"type":36},[39,8230,8216],{}," also throws, because ",[39,8233,4972],{}," doesn't work on function calls, only property access",[28,8236,8238,8240,8241,8243],{"className":8237},[31],[33,8239],{"disabled":35,"type":36}," Neither line throws, since JS treats calling ",[39,8242,2650],{}," as a no-op",[66,8245,8246,8248,8260],{},[69,8247,71],{},[73,8249,8250,8252,8253,4132,8255,2272,8257,8259],{},[76,8251,78],{}," B — Plain calling ",[39,8254,2650],{},[39,8256,827],{},[39,8258,8105],{}," correctly short-circuits instead",[73,8261,8262,355,8264,355,8266,8268,8269,8271,8272,8275,8276,5887,8278,8280,8281,8283,8284,8286,8287,8290,8291,8293],{},[76,8263,84],{},[76,8265,582],{},[39,8267,8171],{}," here is ",[39,8270,2650],{},", not a function — calling it directly attempts ",[39,8273,8274],{},"null()",", which is a ",[39,8277,827],{},[39,8279,2650],{}," isn't callable. ",[39,8282,8105],{}," is specifically designed to guard exactly this: if the reference just before it is nullish, the call is skipped and the whole expression evaluates to ",[39,8285,833],{},". The idiomatic fix for code that might call a possibly-missing\u002Fpossibly-null method is exactly this optional call syntax rather than a manual ",[39,8288,8289],{},"typeof x === \"function\""," check everywhere. Option C is wrong — ",[39,8292,8105],{}," is valid, dedicated syntax for guarding function calls, not just property reads.",[15,8295,8296,8300,8352,8416],{"language":247},[18,8297,8299],{"id":8298},"q19-in-a-chain-of-mixed-logicalcomparison-operators-used-for-validation-whats-the-risk-of-relying-on-operator-precedence-instead-of-explicit-parentheses","Q19. In a chain of mixed logical\u002Fcomparison operators used for validation, what's the risk of relying on operator precedence instead of explicit parentheses?",[257,8301,8302],{"language":247},[260,8303,8305],{"className":262,"code":8304,"language":247,"meta":264,"style":264},"function canCheckout(cart, user) {\n  return cart.length > 0 && user.verified || user.isAdmin;\n}\n",[39,8306,8307,8325,8348],{"__ignoreMap":264},[268,8308,8309,8311,8314,8316,8319,8321,8323],{"class":270,"line":271},[268,8310,275],{"class":274},[268,8312,8313],{"class":278}," canCheckout",[268,8315,622],{"class":282},[268,8317,8318],{"class":1222},"cart",[268,8320,42],{"class":282},[268,8322,4155],{"class":1222},[268,8324,1235],{"class":282},[268,8326,8327,8329,8332,8334,8336,8338,8340,8343,8345],{"class":270,"line":286},[268,8328,1240],{"class":274},[268,8330,8331],{"class":282}," cart.",[268,8333,3567],{"class":305},[268,8335,6644],{"class":274},[268,8337,5728],{"class":305},[268,8339,5590],{"class":274},[268,8341,8342],{"class":282}," user.verified ",[268,8344,5530],{"class":274},[268,8346,8347],{"class":282}," user.isAdmin;\n",[268,8349,8350],{"class":270,"line":296},[268,8351,314],{"class":282},[23,8353,8355,8366,8387,8400],{"className":8354},[26],[28,8356,8358,8360,8361,186,8363,8365],{"className":8357},[31],[33,8359],{"disabled":35,"type":36}," There's no risk; ",[39,8362,5527],{},[39,8364,5530],{}," always evaluate strictly left to right regardless of precedence",[28,8367,8369,355,8371,8373,8374,8376,8377,8380,8381,8383,8384,8386],{"className":8368},[31],[33,8370],{"disabled":35,"type":36},[39,8372,5527],{}," binds tighter than ",[39,8375,5530],{},", so this actually means ",[39,8378,8379],{},"(cart.length > 0 && user.verified) || user.isAdmin"," — which may be the intended logic, but relying on readers to recall that ",[39,8382,5527],{}," outranks ",[39,8385,5530],{}," (rather than writing the parens explicitly) risks misreadings and subtle bugs when the expression grows more complex",[28,8388,8390,355,8392,8373,8394,8396,8397],{"className":8389},[31],[33,8391],{"disabled":35,"type":36},[39,8393,5530],{},[39,8395,5527],{},", so this means ",[39,8398,8399],{},"cart.length > 0 && (user.verified || user.isAdmin)",[28,8401,8403,2436,8405,183,8407,186,8409,8411,8412,446,8414,2690],{"className":8402},[31],[33,8404],{"disabled":35,"type":36},[39,8406,1274],{},[39,8408,5527],{},[39,8410,5530],{}," cannot be mixed without parentheses (like ",[39,8413,4969],{},[39,8415,5530],{},[66,8417,8418,8420,8431],{},[69,8419,71],{},[73,8421,8422,1727,8424,8426,8427,8430],{},[76,8423,78],{},[39,8425,5527],{}," binds tighter, meaning ",[39,8428,8429],{},"(... && ...) || ...","; explicit parens are still best practice to avoid misreadings",[73,8432,8433,355,8435,355,8437,8439,8440,8442,8443,446,8445,8447,8448,186,8450,8452,8453,446,8455,446,8457,8459,8460,446,8462,8464,8465,446,8467,8469],{},[76,8434,84],{},[76,8436,930],{},[39,8438,5527],{}," does have higher precedence than ",[39,8441,5530],{}," (unlike the ",[39,8444,4969],{},[39,8446,5530],{}," combination, which the spec explicitly disallows without parens — see Q12 — ",[39,8449,5527],{},[39,8451,5530],{}," together are legal and well-defined). Here that means admins bypass the cart check entirely, which may or may not be the intended business logic. Because getting this precedence order wrong is an easy, silent mistake (and because ",[39,8454,5527],{},[39,8456,5530],{},[39,8458,4969],{}," chains multiply in complexity fast), production code should make grouping explicit with parentheses even when not strictly required — self-documenting code beats a mentally-recalled precedence table. Option D wrongly extends the ",[39,8461,4969],{},[39,8463,5530],{}," restriction to ",[39,8466,5527],{},[39,8468,5530],{},", which don't share that restriction.",[15,8471,8472,8476,8540,8578],{"language":247},[18,8473,8475],{"id":8474},"q20-what-is-the-best-practice-way-to-compare-two-numbers-for-close-enough-equality-given-floating-point-imprecision","Q20. What is the best-practice way to compare two numbers for \"close enough\" equality given floating-point imprecision?",[257,8477,8478],{"language":247},[260,8479,8481],{"className":262,"code":8480,"language":247,"meta":264,"style":264},"function isCloseEnough(a, b) {\n  return a === b;\n}\nconsole.log(isCloseEnough(0.1 + 0.2, 0.3));\n",[39,8482,8483,8500,8510,8514],{"__ignoreMap":264},[268,8484,8485,8487,8490,8492,8494,8496,8498],{"class":270,"line":271},[268,8486,275],{"class":274},[268,8488,8489],{"class":278}," isCloseEnough",[268,8491,622],{"class":282},[268,8493,1223],{"class":1222},[268,8495,42],{"class":282},[268,8497,1232],{"class":1222},[268,8499,1235],{"class":282},[268,8501,8502,8504,8506,8508],{"class":270,"line":286},[268,8503,1240],{"class":274},[268,8505,1243],{"class":282},[268,8507,3280],{"class":274},[268,8509,1249],{"class":282},[268,8511,8512],{"class":270,"line":296},[268,8513,314],{"class":282},[268,8515,8516,8518,8520,8522,8525,8527,8529,8531,8533,8535,8538],{"class":270,"line":311},[268,8517,1353],{"class":282},[268,8519,1356],{"class":278},[268,8521,622],{"class":282},[268,8523,8524],{"class":278},"isCloseEnough",[268,8526,622],{"class":282},[268,8528,3832],{"class":305},[268,8530,3350],{"class":274},[268,8532,3837],{"class":305},[268,8534,42],{"class":282},[268,8536,8537],{"class":305},"0.3",[268,8539,4818],{"class":282},[23,8541,8543,8552,8561,8567],{"className":8542},[26],[28,8544,8546,8548,8549,8551],{"className":8545},[31],[33,8547],{"disabled":35,"type":36}," Keep using ",[39,8550,3280],{},"; floating-point issues are rare enough to ignore in production",[28,8553,8555,8557,8558,8560],{"className":8554},[31],[33,8556],{"disabled":35,"type":36}," Compare the absolute difference against a small epsilon: ",[39,8559,3937],{}," (or a domain-appropriate tolerance), rather than exact equality, since binary floating-point arithmetic accumulates tiny representation errors",[28,8562,8564,8566],{"className":8563},[31],[33,8565],{"disabled":35,"type":36}," Convert both numbers to strings and compare those instead",[28,8568,8570,4353,8572,8574,8575,8577],{"className":8569},[31],[33,8571],{"disabled":35,"type":36},[39,8573,3197],{}," instead of ",[39,8576,3280],{}," to allow \"reasonably close\" values to match",[66,8579,8580,8582,8587],{},[69,8581,71],{},[73,8583,8584,8586],{},[76,8585,78],{}," B — Compare via an epsilon-tolerant difference check instead of exact equality",[73,8588,8589,355,8591,8593,8594,8597,8598,8600,8601,8603,8604,8606,8607,8610,8611,7507,8614,8617,8618,8620,8621,8624,8625,8628,8629,462],{},[76,8590,84],{},[76,8592,930],{}," as established in the Variables topic, ",[39,8595,8596],{},"0.1 + 0.2 !== 0.3"," due to IEEE-754 rounding, so ",[39,8599,8524],{}," above returns ",[39,8602,2986],{}," for what a user would consider \"the same\" value. The standard fix is tolerance-based comparison — ",[39,8605,3937],{}," for values near the precision limit, or a larger domain-specific epsilon (e.g., ",[39,8608,8609],{},"0.0001",") for currency\u002Fmeasurement contexts. Option A dismisses a genuinely common bug source (any repeated decimal arithmetic — totals, percentages). Option C is a fragile workaround that breaks on formatting differences (",[39,8612,8613],{},"\"0.30000000000000004\"",[39,8615,8616],{},"\"0.3\"","). Option D is wrong — ",[39,8619,3197],{}," performs ",[104,8622,8623],{},"type"," coercion, not numeric fuzzy-matching; ",[39,8626,8627],{},"0.1 + 0.2 == 0.3"," is still ",[39,8630,2986],{},[2107,8632,8633],{},"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 pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}",{"title":264,"searchDepth":286,"depth":286,"links":8635},[8636,8638,8640,8642,8644,8646,8647,8649,8651,8653,8654,8656,8658,8659,8661,8663,8665,8667,8668,8669],{"id":5221,"depth":296,"text":8637},"Q1. What is the fundamental difference between == and ===?",{"id":5360,"depth":296,"text":8639},"Q2. What does [] == ![] evaluate to?",{"id":5523,"depth":296,"text":8641},"Q3. What is the difference between &&\u002F|| short-circuiting and how does it affect side effects?",{"id":5703,"depth":296,"text":8643},"Q4. What does the nullish coalescing operator ?? do differently from ||?",{"id":5914,"depth":296,"text":8645},"Q5. What does optional chaining ?. do when the left-hand side is null or undefined?",{"id":6083,"depth":296,"text":6084},{"id":6237,"depth":296,"text":8648},"Q7. What does associativity determine, and how does ** (exponentiation) differ from - (subtraction) in this regard?",{"id":6429,"depth":296,"text":8650},"Q8. What happens when you compare with \u003C\u002F> across mixed types, e.g., strings and numbers?",{"id":6604,"depth":296,"text":8652},"Q9. What is the result of comparing with NaN using relational operators?",{"id":6800,"depth":296,"text":6801},{"id":6936,"depth":296,"text":8655},"Q11. What does the unary + operator do to a string operand?",{"id":7184,"depth":296,"text":8657},"Q12. In a ?? b || c, what happens?",{"id":7323,"depth":296,"text":7324},{"id":7515,"depth":296,"text":8660},"Q14. What does typeof return for these edge-case expressions?",{"id":7722,"depth":296,"text":8662},"Q15. What is the idiomatic reason to prefer ===\u002F!== over ==\u002F!= in production code?",{"id":7864,"depth":296,"text":8664},"Q16. What is the best-practice way to write a conditional default value assignment when 0, \"\", or false might be legitimate values?",{"id":8009,"depth":296,"text":8666},"Q17. Which is the idiomatic pattern for guarding against null\u002Fundefined when calling a method that might not exist?",{"id":8136,"depth":296,"text":8137},{"id":8298,"depth":296,"text":8299},{"id":8474,"depth":296,"text":8475},{},"\u002Fjs\u002F03-operators-and-expressions",{"title":5211,"description":264},"js\u002F03-operators-and-expressions","sm70BNaZ5Y7lXZL5iyvU8IQN3nDjJp-Ctyinwd3-_uU",{"id":8676,"title":8677,"body":8678,"description":264,"extension":2144,"meta":12639,"navigation":35,"path":12640,"seo":12641,"stem":12642,"__hash__":12643},"content\u002Fjs\u002F04-control-flow.md","04 — Control Flow",{"type":8,"value":8679,"toc":12598},[8680,8683,8872,9153,9355,9607,9829,10069,10244,10404,10628,10826,11031,11178,11343,11506,11700,11895,12046,12230,12407,12595],[11,8681,8677],{"id":8682},"_04-control-flow",[15,8684,8685,8692,8738,8804],{"language":247},[18,8686,8688,8689,8691],{"id":8687},"q1-which-of-these-values-is-falsy-in-a-boolean-context-eg-inside-an-if","Q1. Which of these values is falsy in a boolean context (e.g., inside an ",[39,8690,2179],{},")?",[257,8693,8694],{"language":247},[260,8695,8697],{"className":262,"code":8696,"language":247,"meta":264,"style":264},"const values = [\"\", 0, \"0\", [], {}, null, undefined, NaN];\n",[39,8698,8699],{"__ignoreMap":264},[268,8700,8701,8703,8706,8708,8711,8713,8715,8717,8719,8722,8725,8727,8729,8731,8733,8735],{"class":270,"line":271},[268,8702,243],{"class":274},[268,8704,8705],{"class":305}," values",[268,8707,616],{"class":274},[268,8709,8710],{"class":282}," [",[268,8712,3294],{"class":289},[268,8714,42],{"class":282},[268,8716,3307],{"class":305},[268,8718,42],{"class":282},[268,8720,8721],{"class":289},"\"0\"",[268,8723,8724],{"class":282},", [], {}, ",[268,8726,2650],{"class":305},[268,8728,42],{"class":282},[268,8730,833],{"class":305},[268,8732,42],{"class":282},[268,8734,3040],{"class":305},[268,8736,8737],{"class":282},"];\n",[23,8739,8741,8759,8778,8798],{"className":8740},[26],[28,8742,8744,355,8746,42,8748,42,8750,42,8752,42,8754,42,8756,8758],{"className":8743},[31],[33,8745],{"disabled":35,"type":36},[39,8747,3294],{},[39,8749,3307],{},[39,8751,8721],{},[39,8753,2650],{},[39,8755,833],{},[39,8757,3040],{}," — six of the eight",[28,8760,8762,355,8764,42,8766,42,8768,42,8770,42,8772,8774,8775,8777],{"className":8761},[31],[33,8763],{"disabled":35,"type":36},[39,8765,3294],{},[39,8767,3307],{},[39,8769,2650],{},[39,8771,833],{},[39,8773,3040],{}," — five values (",[39,8776,8721],{}," is truthy since it's a non-empty string)",[28,8779,8781,355,8783,42,8785,42,8787,42,8789,42,8791,42,8793,42,8795,8797],{"className":8780},[31],[33,8782],{"disabled":35,"type":36},[39,8784,3294],{},[39,8786,3307],{},[39,8788,3290],{},[39,8790,2328],{},[39,8792,2650],{},[39,8794,833],{},[39,8796,3040],{}," — seven values",[28,8799,8801,8803],{"className":8800},[31],[33,8802],{"disabled":35,"type":36}," All eight values are falsy",[66,8805,8806,8808,8833],{},[69,8807,71],{},[73,8809,8810,1727,8812,42,8814,42,8816,42,8818,42,8820,8822,8823,186,8825,8828,8829,8832],{},[76,8811,78],{},[39,8813,3294],{},[39,8815,3307],{},[39,8817,2650],{},[39,8819,833],{},[39,8821,3040],{}," (plus ",[39,8824,2986],{},[39,8826,8827],{},"0n"," \u002F ",[39,8830,8831],{},"-0",", not listed here) are the only falsy values",[73,8834,8835,8837,8838,42,8840,42,8842,42,8844,42,8846,42,8848,42,8850,137,8852,8854,8855,8857,8858,8866,8867,446,8869,8871],{},[76,8836,84],{}," JavaScript has a fixed, short list of falsy values: ",[39,8839,2986],{},[39,8841,3307],{},[39,8843,8831],{},[39,8845,8827],{},[39,8847,3294],{},[39,8849,2650],{},[39,8851,833],{},[39,8853,3040],{},". Everything else is truthy — including ",[39,8856,8721],{}," (a non-empty string is always truthy regardless of its content) and, critically, ",[76,8859,8860,8861,8863,8864],{},"both empty arrays ",[39,8862,3290],{}," and empty objects ",[39,8865,2328],{},", since any object reference is truthy no matter how \"empty\" it looks. Option C is the classic trap of assuming ",[39,8868,3290],{},[39,8870,2328],{}," are falsy because they \"feel empty\" — they are not.",[15,8873,8874,8885,9019,9081],{"language":247},[18,8875,8877,8878,8881,8882,1685],{"id":8876},"q2-what-happens-without-break-statements-in-a-switch","Q2. What happens without ",[39,8879,8880],{},"break"," statements in a ",[39,8883,8884],{},"switch",[257,8886,8887],{"language":247},[260,8888,8890],{"className":262,"code":8889,"language":247,"meta":264,"style":264},"function getDiscount(tier) {\n  let discount;\n  switch (tier) {\n    case \"gold\":\n      discount = 20;\n    case \"silver\":\n      discount = 10;\n    default:\n      discount = 0;\n  }\n  return discount;\n}\nconsole.log(getDiscount(\"gold\"));\n",[39,8891,8892,8906,8913,8921,8932,8944,8953,8964,8972,8983,8988,8995,9000],{"__ignoreMap":264},[268,8893,8894,8896,8899,8901,8904],{"class":270,"line":271},[268,8895,275],{"class":274},[268,8897,8898],{"class":278}," getDiscount",[268,8900,622],{"class":282},[268,8902,8903],{"class":1222},"tier",[268,8905,1235],{"class":282},[268,8907,8908,8910],{"class":270,"line":286},[268,8909,2206],{"class":274},[268,8911,8912],{"class":282}," discount;\n",[268,8914,8915,8918],{"class":270,"line":296},[268,8916,8917],{"class":274},"  switch",[268,8919,8920],{"class":282}," (tier) {\n",[268,8922,8923,8926,8929],{"class":270,"line":311},[268,8924,8925],{"class":274},"    case",[268,8927,8928],{"class":289}," \"gold\"",[268,8930,8931],{"class":282},":\n",[268,8933,8934,8937,8939,8942],{"class":270,"line":788},[268,8935,8936],{"class":282},"      discount ",[268,8938,302],{"class":274},[268,8940,8941],{"class":305}," 20",[268,8943,293],{"class":282},[268,8945,8946,8948,8951],{"class":270,"line":1951},[268,8947,8925],{"class":274},[268,8949,8950],{"class":289}," \"silver\"",[268,8952,8931],{"class":282},[268,8954,8956,8958,8960,8962],{"class":270,"line":8955},7,[268,8957,8936],{"class":282},[268,8959,302],{"class":274},[268,8961,306],{"class":305},[268,8963,293],{"class":282},[268,8965,8967,8970],{"class":270,"line":8966},8,[268,8968,8969],{"class":274},"    default",[268,8971,8931],{"class":282},[268,8973,8975,8977,8979,8981],{"class":270,"line":8974},9,[268,8976,8936],{"class":282},[268,8978,302],{"class":274},[268,8980,5728],{"class":305},[268,8982,293],{"class":282},[268,8984,8986],{"class":270,"line":8985},10,[268,8987,1948],{"class":282},[268,8989,8991,8993],{"class":270,"line":8990},11,[268,8992,1240],{"class":274},[268,8994,8912],{"class":282},[268,8996,8998],{"class":270,"line":8997},12,[268,8999,314],{"class":282},[268,9001,9003,9005,9007,9009,9012,9014,9017],{"class":270,"line":9002},13,[268,9004,1353],{"class":282},[268,9006,1356],{"class":278},[268,9008,622],{"class":282},[268,9010,9011],{"class":278},"getDiscount",[268,9013,622],{"class":282},[268,9015,9016],{"class":289},"\"gold\"",[268,9018,4818],{"class":282},[23,9020,9022,9033,9060,9068],{"className":9021},[26],[28,9023,9025,355,9027,2833,9029,9032],{"className":9024},[31],[33,9026],{"disabled":35,"type":36},[39,9028,6149],{},[39,9030,9031],{},"case \"gold\""," matches and returns immediately",[28,9034,9036,355,9038,9040,9041,9043,9044,9047,9048,9050,9051,9054,9055,9057,9058],{"className":9035},[31],[33,9037],{"disabled":35,"type":36},[39,9039,3307],{},", because without ",[39,9042,8880],{},", execution \"falls through\" every subsequent case (including ",[39,9045,9046],{},"default",") until a ",[39,9049,8880],{}," or the end of the block, so ",[39,9052,9053],{},"discount"," gets overwritten by each case in sequence, ending on ",[39,9056,9046],{},"'s ",[39,9059,3307],{},[28,9061,9063,355,9065,9067],{"className":9062},[31],[33,9064],{"disabled":35,"type":36},[39,9066,5825],{},", because it falls through only one level before stopping",[28,9069,9071,355,9073,2833,9075,9077,9078,9080],{"className":9070},[31],[33,9072],{"disabled":35,"type":36},[39,9074,1274],{},[39,9076,8884],{}," cases require ",[39,9079,8880],{}," statements",[66,9082,9083,9085,9095],{},[69,9084,71],{},[73,9086,9087,1727,9089,9091,9092,9094],{},[76,9088,78],{},[39,9090,3307],{},", due to fallthrough overwriting ",[39,9093,9053],{}," in every subsequent case",[73,9096,9097,355,9099,9101,9102,42,9104,9106,9107,9110,9111,9113,9114,9116,9117,9119,9120,9122,9123,9126,9127,9057,9130,9126,9133,9057,9135,9138,9139,9141,9142,9144,9145,9148,9149,9152],{},[76,9098,84],{},[76,9100,365],{}," without an explicit ",[39,9103,8880],{},[39,9105,8884],{}," doesn't stop at the matched case — it keeps executing every statement below it, including other ",[39,9108,9109],{},"case"," bodies and ",[39,9112,9046],{},", until it hits a ",[39,9115,8880],{}," or the end of the ",[39,9118,8884],{}," block. Here, matching ",[39,9121,9016],{}," sets ",[39,9124,9125],{},"discount = 20",", then falls through to ",[39,9128,9129],{},"\"silver\"",[39,9131,9132],{},"discount = 10",[39,9134,9046],{},[39,9136,9137],{},"discount = 0",", leaving ",[39,9140,3307],{}," as the final value returned. This is one of the most common ",[39,9143,8884],{}," bugs — the fix is adding ",[39,9146,9147],{},"break;"," after each case (or ",[39,9150,9151],{},"return"," directly, if inside a function).",[15,9154,9155,9164,9236,9308],{"language":247},[18,9156,9158,9159,186,9161,1685],{"id":9157},"q3-whats-the-key-difference-between-forin-and-forof","Q3. What's the key difference between ",[39,9160,4728],{},[39,9162,9163],{},"for...of",[257,9165,9166],{"language":247},[260,9167,9169],{"className":262,"code":9168,"language":247,"meta":264,"style":264},"const arr = [\"a\", \"b\", \"c\"];\nfor (const x in arr) console.log(x);\nfor (const x of arr) console.log(x);\n",[39,9170,9171,9196,9217],{"__ignoreMap":264},[268,9172,9173,9175,9178,9180,9182,9184,9186,9189,9191,9194],{"class":270,"line":271},[268,9174,243],{"class":274},[268,9176,9177],{"class":305}," arr",[268,9179,616],{"class":274},[268,9181,8710],{"class":282},[268,9183,7582],{"class":289},[268,9185,42],{"class":282},[268,9187,9188],{"class":289},"\"b\"",[268,9190,42],{"class":282},[268,9192,9193],{"class":289},"\"c\"",[268,9195,8737],{"class":282},[268,9197,9198,9200,9202,9204,9207,9210,9213,9215],{"class":270,"line":286},[268,9199,6926],{"class":274},[268,9201,2182],{"class":282},[268,9203,243],{"class":274},[268,9205,9206],{"class":305}," x",[268,9208,9209],{"class":274}," in",[268,9211,9212],{"class":282}," arr) console.",[268,9214,1356],{"class":278},[268,9216,2375],{"class":282},[268,9218,9219,9221,9223,9225,9227,9230,9232,9234],{"class":270,"line":296},[268,9220,6926],{"class":274},[268,9222,2182],{"class":282},[268,9224,243],{"class":274},[268,9226,9206],{"class":305},[268,9228,9229],{"class":274}," of",[268,9231,9212],{"class":282},[268,9233,1356],{"class":278},[268,9235,2375],{"class":282},[23,9237,9239,9251,9283,9294],{"className":9238},[26],[28,9240,9242,9244,9245,42,9247,42,9249],{"className":9241},[31],[33,9243],{"disabled":35,"type":36}," They are interchangeable for arrays; both log ",[39,9246,7582],{},[39,9248,9188],{},[39,9250,9193],{},[28,9252,9254,355,9256,9258,9259,9262,9263,42,9265,42,9267,5789,9270,9272,9273,9276,9277,42,9279,42,9281,2690],{"className":9253},[31],[33,9255],{"disabled":35,"type":36},[39,9257,4728],{}," iterates over enumerable property ",[104,9260,9261],{},"keys"," (here, the string indices ",[39,9264,8721],{},[39,9266,3387],{},[39,9268,9269],{},"\"2\"",[39,9271,9163],{}," iterates over the ",[104,9274,9275],{},"values"," of an iterable (here, ",[39,9278,7582],{},[39,9280,9188],{},[39,9282,9193],{},[28,9284,9286,355,9288,9290,9291,9293],{"className":9285},[31],[33,9287],{"disabled":35,"type":36},[39,9289,4728],{}," iterates values, ",[39,9292,9163],{}," iterates keys — the reverse of the truth",[28,9295,9297,355,9299,9301,9302,446,9304,9307],{"className":9296},[31],[33,9298],{"disabled":35,"type":36},[39,9300,9163],{}," only works on ",[39,9303,2672],{},[39,9305,9306],{},"Set",", never on plain arrays",[66,9309,9310,9312,9322],{},[69,9311,71],{},[73,9313,9314,1727,9316,9318,9319,9321],{},[76,9315,78],{},[39,9317,4728],{}," yields keys (indices as strings for arrays); ",[39,9320,9163],{}," yields values",[73,9323,9324,355,9326,9328,9329,9331,9332,42,9334,42,9336,9338,9339,9341,9342,42,9344,9346,9347,355,9349,9351,9352,9354],{},[76,9325,84],{},[39,9327,4728],{}," enumerates property ",[104,9330,9261],{}," of any object, including inherited enumerable ones — for an array, that means it logs the string indices ",[39,9333,8721],{},[39,9335,3387],{},[39,9337,9269],{}," (not the values, and not necessarily in guaranteed numeric order for non-index keys). ",[39,9340,9163],{}," (ES2015) works on anything implementing the iterable protocol (arrays, strings, ",[39,9343,2672],{},[39,9345,9306],{},", etc.) and yields the actual values in order. ",[76,9348,930],{},[39,9350,4728],{}," is generally discouraged for arrays specifically because of this keys-not-values behavior plus the risk of picking up inherited\u002Fnon-index enumerable properties; ",[39,9353,9163],{}," (or array methods) is preferred.",[15,9356,9357,9367,9483,9543],{"language":247},[18,9358,9360,9361,9363,9364,9366],{"id":9359},"q4-what-is-the-classic-closure-in-loop-bug-with-var-and-how-does-let-fix-it","Q4. What is the classic closure-in-loop bug with ",[39,9362,1440],{},", and how does ",[39,9365,240],{}," fix it?",[257,9368,9369],{"language":247},[260,9370,9372],{"className":262,"code":9371,"language":247,"meta":264,"style":264},"for (var i = 0; i \u003C 3; i++) {\n  setTimeout(() => console.log(i), 0);\n}\nfor (let j = 0; j \u003C 3; j++) {\n  setTimeout(() => console.log(j), 0);\n}\n",[39,9373,9374,9404,9427,9431,9460,9479],{"__ignoreMap":264},[268,9375,9376,9378,9380,9382,9385,9387,9389,9392,9394,9396,9399,9402],{"class":270,"line":271},[268,9377,6926],{"class":274},[268,9379,2182],{"class":282},[268,9381,1440],{"class":274},[268,9383,9384],{"class":282}," i ",[268,9386,302],{"class":274},[268,9388,5728],{"class":305},[268,9390,9391],{"class":282},"; i ",[268,9393,1076],{"class":274},[268,9395,3396],{"class":305},[268,9397,9398],{"class":282},"; i",[268,9400,9401],{"class":274},"++",[268,9403,1235],{"class":282},[268,9405,9406,9409,9412,9415,9418,9420,9423,9425],{"class":270,"line":286},[268,9407,9408],{"class":278},"  setTimeout",[268,9410,9411],{"class":282},"(() ",[268,9413,9414],{"class":274},"=>",[268,9416,9417],{"class":282}," console.",[268,9419,1356],{"class":278},[268,9421,9422],{"class":282},"(i), ",[268,9424,3307],{"class":305},[268,9426,628],{"class":282},[268,9428,9429],{"class":270,"line":296},[268,9430,314],{"class":282},[268,9432,9433,9435,9437,9439,9442,9444,9446,9449,9451,9453,9456,9458],{"class":270,"line":311},[268,9434,6926],{"class":274},[268,9436,2182],{"class":282},[268,9438,240],{"class":274},[268,9440,9441],{"class":282}," j ",[268,9443,302],{"class":274},[268,9445,5728],{"class":305},[268,9447,9448],{"class":282},"; j ",[268,9450,1076],{"class":274},[268,9452,3396],{"class":305},[268,9454,9455],{"class":282},"; j",[268,9457,9401],{"class":274},[268,9459,1235],{"class":282},[268,9461,9462,9464,9466,9468,9470,9472,9475,9477],{"class":270,"line":788},[268,9463,9408],{"class":278},[268,9465,9411],{"class":282},[268,9467,9414],{"class":274},[268,9469,9417],{"class":282},[268,9471,1356],{"class":278},[268,9473,9474],{"class":282},"(j), ",[268,9476,3307],{"class":305},[268,9478,628],{"class":282},[268,9480,9481],{"class":270,"line":1951},[268,9482,314],{"class":282},[23,9484,9486,9495,9521,9536],{"className":9485},[26],[28,9487,9489,9491,9492],{"className":9488},[31],[33,9490],{"disabled":35,"type":36}," Both loops log ",[39,9493,9494],{},"0, 1, 2",[28,9496,9498,4396,9500,9502,9503,9506,9507,5512,9510,9512,9513,9502,9515,9517,9518,2690],{"className":9497},[31],[33,9499],{"disabled":35,"type":36},[39,9501,1440],{}," loop logs ",[39,9504,9505],{},"3, 3, 3"," (all closures share the single function-scoped ",[39,9508,9509],{},"i",[39,9511,3423],{}," by the time the callbacks run); the ",[39,9514,240],{},[39,9516,9494],{}," (each iteration gets its own freshly bound ",[39,9519,9520],{},"j",[28,9522,9524,4396,9526,9502,9528,9530,9531,9502,9533,9535],{"className":9523},[31],[33,9525],{"disabled":35,"type":36},[39,9527,1440],{},[39,9529,9494],{}," and the ",[39,9532,240],{},[39,9534,9505],{}," — the reverse",[28,9537,9539,9491,9541],{"className":9538},[31],[33,9540],{"disabled":35,"type":36},[39,9542,9505],{},[66,9544,9545,9547,9559],{},[69,9546,71],{},[73,9548,9549,1727,9551,9502,9553,2272,9555,9502,9557],{},[76,9550,78],{},[39,9552,1440],{},[39,9554,9505],{},[39,9556,240],{},[39,9558,9494],{},[73,9560,9561,355,9563,9565,9566,9569,9570,355,9573,9575,9576,9579,9580,9582,9583,3277,9585,9587,9588,1243,9591,9597,9598,9600,9601,9603,9604,9606],{},[76,9562,84],{},[76,9564,365],{}," this is one of the most famous JavaScript interview gotchas. ",[39,9567,9568],{},"var i"," is function\u002Fglobal-scoped, so there is only ever ",[104,9571,9572],{},"one",[39,9574,9509],{}," variable shared across all loop iterations and all the closures created inside it; by the time the ",[39,9577,9578],{},"setTimeout"," callbacks actually run (after the loop has fully finished), ",[39,9581,9509],{}," has already reached ",[39,9584,3423],{},[39,9586,240],{}," fixes this because the spec gives ",[39,9589,9590],{},"for (let j ...)",[76,9592,9593,9594,9596],{},"fresh binding of ",[39,9595,9520],{}," for each iteration"," — each closure captures its own distinct ",[39,9599,9520],{},", preserving the value at the time that iteration ran. This is a core reason ",[39,9602,240],{}," is preferred over ",[39,9605,1440],{}," in loops with async callbacks.",[15,9608,9609,9617,9721,9768],{"language":247},[18,9610,9612,9613,9616],{"id":9611},"q5-what-does-a-labeled-continue-statement-do-inside-nested-loops","Q5. What does a labeled ",[39,9614,9615],{},"continue"," statement do inside nested loops?",[257,9618,9619],{"language":247},[260,9620,9622],{"className":262,"code":9621,"language":247,"meta":264,"style":264},"outer: for (let i = 0; i \u003C 3; i++) {\n  for (let j = 0; j \u003C 3; j++) {\n    if (j === 1) continue outer;\n    console.log(i, j);\n  }\n}\n",[39,9623,9624,9655,9682,9703,9713,9717],{"__ignoreMap":264},[268,9625,9626,9629,9631,9633,9635,9637,9639,9641,9643,9645,9647,9649,9651,9653],{"class":270,"line":271},[268,9627,9628],{"class":278},"outer",[268,9630,1783],{"class":282},[268,9632,6926],{"class":274},[268,9634,2182],{"class":282},[268,9636,240],{"class":274},[268,9638,9384],{"class":282},[268,9640,302],{"class":274},[268,9642,5728],{"class":305},[268,9644,9391],{"class":282},[268,9646,1076],{"class":274},[268,9648,3396],{"class":305},[268,9650,9398],{"class":282},[268,9652,9401],{"class":274},[268,9654,1235],{"class":282},[268,9656,9657,9660,9662,9664,9666,9668,9670,9672,9674,9676,9678,9680],{"class":270,"line":286},[268,9658,9659],{"class":274},"  for",[268,9661,2182],{"class":282},[268,9663,240],{"class":274},[268,9665,9441],{"class":282},[268,9667,302],{"class":274},[268,9669,5728],{"class":305},[268,9671,9448],{"class":282},[268,9673,1076],{"class":274},[268,9675,3396],{"class":305},[268,9677,9455],{"class":282},[268,9679,9401],{"class":274},[268,9681,1235],{"class":282},[268,9683,9684,9687,9690,9692,9694,9696,9698,9701],{"class":270,"line":296},[268,9685,9686],{"class":274},"    if",[268,9688,9689],{"class":282}," (j ",[268,9691,3280],{"class":274},[268,9693,2199],{"class":305},[268,9695,6131],{"class":282},[268,9697,9615],{"class":274},[268,9699,9700],{"class":278}," outer",[268,9702,293],{"class":282},[268,9704,9705,9708,9710],{"class":270,"line":311},[268,9706,9707],{"class":282},"    console.",[268,9709,1356],{"class":278},[268,9711,9712],{"class":282},"(i, j);\n",[268,9714,9715],{"class":270,"line":788},[268,9716,1948],{"class":282},[268,9718,9719],{"class":270,"line":1951},[268,9720,314],{"class":282},[23,9722,9724,9733,9748,9756],{"className":9723},[26],[28,9725,9727,9729,9730,9732],{"className":9726},[31],[33,9728],{"disabled":35,"type":36}," It behaves like a normal ",[39,9731,9615],{},", only skipping the rest of the inner loop's current iteration",[28,9734,9736,9738,9739,42,9742,42,9745],{"className":9735},[31],[33,9737],{"disabled":35,"type":36}," It skips the rest of the inner loop entirely and jumps straight to the next iteration of the labeled outer loop, effectively logging only ",[39,9740,9741],{},"(0,0)",[39,9743,9744],{},"(1,0)",[39,9746,9747],{},"(2,0)",[28,9749,9751,9753,9754],{"className":9750},[31],[33,9752],{"disabled":35,"type":36}," It exits both loops entirely, like a labeled ",[39,9755,8880],{},[28,9757,9759,355,9761,9763,9764,2758,9766],{"className":9758},[31],[33,9760],{"disabled":35,"type":36},[39,9762,1274],{}," — labels can only be used with ",[39,9765,8880],{},[39,9767,9615],{},[66,9769,9770,9772,9783],{},[69,9771,71],{},[73,9773,9774,9776,9777,42,9779,42,9781],{},[76,9775,78],{}," B — Jumps to the next iteration of the labeled outer loop, logging only ",[39,9778,9741],{},[39,9780,9744],{},[39,9782,9747],{},[73,9784,9785,9787,9788,9790,9791,42,9794,9797,9798,9800,9801,9803,9804,9806,9807,99,9809,9811,9812,9814,9815,9817,9818,9820,9821,9823,9824,186,9826,9828],{},[76,9786,84],{}," A labeled ",[39,9789,9615],{}," targets a specific enclosing loop by name, skipping straight to that loop's next iteration rather than just the innermost one. Here, once ",[39,9792,9793],{},"j === 1",[39,9795,9796],{},"continue outer"," abandons the rest of the inner loop for that ",[39,9799,9509],{}," and advances ",[39,9802,9509],{}," instead — so ",[39,9805,9520],{}," never reaches ",[39,9808,2255],{},[39,9810,2258],{}," in the output. Option A describes plain unlabeled ",[39,9813,9615],{},". Option C describes labeled ",[39,9816,8880],{},", a related but distinct construct (",[39,9819,8880],{}," exits the loop entirely; ",[39,9822,9615],{}," advances it). Labels work with both ",[39,9825,8880],{},[39,9827,9615],{}," (ruling out D), though labels are rare in idiomatic code outside deeply nested loop scenarios like this.",[15,9830,9831,9839,9949,9997],{"language":247},[18,9832,9834,9835,9838],{"id":9833},"q6-what-is-the-output-of-this-ifelse-ifelse-chain-given-javascripts-truthyfalsy-coercion","Q6. What is the output of this ",[39,9836,9837],{},"if\u002Felse if\u002Felse"," chain, given JavaScript's truthy\u002Ffalsy coercion?",[257,9840,9841],{"language":247},[260,9842,9844],{"className":262,"code":9843,"language":247,"meta":264,"style":264},"function describe(val) {\n  if (val) {\n    return \"truthy\";\n  } else if (val === 0) {\n    return \"zero\";\n  } else {\n    return \"other falsy\";\n  }\n}\nconsole.log(describe(0));\n",[39,9845,9846,9859,9867,9877,9897,9906,9915,9924,9928,9932],{"__ignoreMap":264},[268,9847,9848,9850,9853,9855,9857],{"class":270,"line":271},[268,9849,275],{"class":274},[268,9851,9852],{"class":278}," describe",[268,9854,622],{"class":282},[268,9856,4315],{"class":1222},[268,9858,1235],{"class":282},[268,9860,9861,9864],{"class":270,"line":286},[268,9862,9863],{"class":274},"  if",[268,9865,9866],{"class":282}," (val) {\n",[268,9868,9869,9872,9875],{"class":270,"line":296},[268,9870,9871],{"class":274},"    return",[268,9873,9874],{"class":289}," \"truthy\"",[268,9876,293],{"class":282},[268,9878,9879,9882,9885,9888,9891,9893,9895],{"class":270,"line":311},[268,9880,9881],{"class":282},"  } ",[268,9883,9884],{"class":274},"else",[268,9886,9887],{"class":274}," if",[268,9889,9890],{"class":282}," (val ",[268,9892,3280],{"class":274},[268,9894,5728],{"class":305},[268,9896,1235],{"class":282},[268,9898,9899,9901,9904],{"class":270,"line":788},[268,9900,9871],{"class":274},[268,9902,9903],{"class":289}," \"zero\"",[268,9905,293],{"class":282},[268,9907,9908,9910,9912],{"class":270,"line":1951},[268,9909,9881],{"class":282},[268,9911,9884],{"class":274},[268,9913,9914],{"class":282}," {\n",[268,9916,9917,9919,9922],{"class":270,"line":8955},[268,9918,9871],{"class":274},[268,9920,9921],{"class":289}," \"other falsy\"",[268,9923,293],{"class":282},[268,9925,9926],{"class":270,"line":8966},[268,9927,1948],{"class":282},[268,9929,9930],{"class":270,"line":8974},[268,9931,314],{"class":282},[268,9933,9934,9936,9938,9940,9943,9945,9947],{"class":270,"line":8985},[268,9935,1353],{"class":282},[268,9937,1356],{"class":278},[268,9939,622],{"class":282},[268,9941,9942],{"class":278},"describe",[268,9944,622],{"class":282},[268,9946,3307],{"class":305},[268,9948,4818],{"class":282},[23,9950,9952,9963,9974,9990],{"className":9951},[26],[28,9953,9955,355,9957,4387,9960,9962],{"className":9954},[31],[33,9956],{"disabled":35,"type":36},[39,9958,9959],{},"\"truthy\"",[39,9961,3307],{}," matches the first branch",[28,9964,9966,355,9968,9971,9972],{"className":9965},[31],[33,9967],{"disabled":35,"type":36},[39,9969,9970],{},"\"other falsy\"",", since it skips straight to the ",[39,9973,9884],{},[28,9975,9977,355,9979,9982,9983,9985,9986,9989],{"className":9976},[31],[33,9978],{"disabled":35,"type":36},[39,9980,9981],{},"\"zero\""," never runs, because ",[39,9984,3307],{}," is falsy and the ",[39,9987,9988],{},"if (val)"," branch has already consumed it — this is actually unreachable dead code",[28,9991,9993,355,9995],{"className":9992},[31],[33,9994],{"disabled":35,"type":36},[39,9996,827],{},[66,9998,9999,10001,10010],{},[69,10000,71],{},[73,10002,10003,1004,10005,10007,10008],{},[76,10004,78],{},[39,10006,9981],{}," is dead code; the function actually returns ",[39,10009,9970],{},[73,10011,10012,355,10014,10016,10017,10019,10020,10023,10024,10026,10027,830,10029,2272,10031,10034,10035,830,10038,10040,10041,10044,10045,10047,10048,10050,10051,10054,10055,10058,10059,10061,10062,10065,10066,10068],{},[76,10013,84],{},[39,10015,9988],{}," checks truthiness first, and ",[39,10018,3307],{}," is falsy, so the first branch is skipped — flow moves to ",[39,10021,10022],{},"else if (val === 0)",", which correctly matches, returning ",[39,10025,9981],{},". Wait — trace it carefully: ",[39,10028,4315],{},[39,10030,3307],{},[39,10032,10033],{},"if (0)"," is falsy, skip; ",[39,10036,10037],{},"else if (0 === 0)",[39,10039,2185],{},", so it ",[104,10042,10043],{},"does"," return ",[39,10046,9981],{},". Correcting the above: the actual output is ",[39,10049,9981],{},", not dead code — the ",[39,10052,10053],{},"else if"," condition is reachable precisely ",[104,10056,10057],{},"because"," the first branch failed. The important lesson is that a truthiness check (",[39,10060,9988],{},") and a strict equality check (",[39,10063,10064],{},"val === 0",") test different things, and ordering matters: had the branches been swapped, results would differ. Option A wrongly assumes truthy already caught ",[39,10067,3307],{},". Option D invents an error that doesn't occur.",[15,10070,10071,10078,10158,10208],{"language":247},[18,10072,10074,10075,10077],{"id":10073},"q7-what-does-a-for-loop-do-when-the-condition-is-omitted-entirely","Q7. What does a ",[39,10076,6926],{}," loop do when the condition is omitted entirely?",[257,10079,10080],{"language":247},[260,10081,10083],{"className":262,"code":10082,"language":247,"meta":264,"style":264},"let count = 0;\nfor (let i = 0; ; i++) {\n  count++;\n  if (count === 3) break;\n}\nconsole.log(count);\n",[39,10084,10085,10098,10119,10128,10145,10149],{"__ignoreMap":264},[268,10086,10087,10089,10092,10094,10096],{"class":270,"line":271},[268,10088,240],{"class":274},[268,10090,10091],{"class":282}," count ",[268,10093,302],{"class":274},[268,10095,5728],{"class":305},[268,10097,293],{"class":282},[268,10099,10100,10102,10104,10106,10108,10110,10112,10115,10117],{"class":270,"line":286},[268,10101,6926],{"class":274},[268,10103,2182],{"class":282},[268,10105,240],{"class":274},[268,10107,9384],{"class":282},[268,10109,302],{"class":274},[268,10111,5728],{"class":305},[268,10113,10114],{"class":282},"; ; i",[268,10116,9401],{"class":274},[268,10118,1235],{"class":282},[268,10120,10121,10124,10126],{"class":270,"line":296},[268,10122,10123],{"class":282},"  count",[268,10125,9401],{"class":274},[268,10127,293],{"class":282},[268,10129,10130,10132,10135,10137,10139,10141,10143],{"class":270,"line":311},[268,10131,9863],{"class":274},[268,10133,10134],{"class":282}," (count ",[268,10136,3280],{"class":274},[268,10138,3396],{"class":305},[268,10140,6131],{"class":282},[268,10142,8880],{"class":274},[268,10144,293],{"class":282},[268,10146,10147],{"class":270,"line":788},[268,10148,314],{"class":282},[268,10150,10151,10153,10155],{"class":270,"line":1951},[268,10152,1353],{"class":282},[268,10154,1356],{"class":278},[268,10156,10157],{"class":282},"(count);\n",[23,10159,10161,10172,10180,10198],{"className":10160},[26],[28,10162,10164,355,10166,10168,10169,10171],{"className":10163},[31],[33,10165],{"disabled":35,"type":36},[39,10167,1274],{},", because the middle clause of a ",[39,10170,6926],{}," loop is mandatory",[28,10173,10175,10177,10178],{"className":10174},[31],[33,10176],{"disabled":35,"type":36}," The loop runs zero times, since an omitted condition defaults to ",[39,10179,2986],{},[28,10181,10183,10185,10186,10188,10189,10192,10193,10195,10196],{"className":10182},[31],[33,10184],{"disabled":35,"type":36}," The loop runs forever, since an omitted condition defaults to always-truthy — but here ",[39,10187,8880],{}," stops it manually once ",[39,10190,10191],{},"count"," reaches ",[39,10194,3423],{},", so it logs ",[39,10197,3423],{},[28,10199,10201,355,10203,4387,10205,10207],{"className":10200},[31],[33,10202],{"disabled":35,"type":36},[39,10204,833],{},[39,10206,10191],{}," is never properly initialized",[66,10209,10210,10212,10220],{},[69,10211,71],{},[73,10213,10214,10216,10217,10219],{},[76,10215,78],{}," C — Omitted condition defaults to always-true (infinite loop) unless stopped manually; logs ",[39,10218,3423],{}," here",[73,10221,10222,10224,10225,10228,10229,10232,10233,10235,10236,10192,10238,10240,10241,10243],{},[76,10223,84],{}," All three clauses of a classic ",[39,10226,10227],{},"for (init; condition; update)"," loop are optional. An omitted condition is treated as always truthy, making ",[39,10230,10231],{},"for (let i = 0; ; i++)"," loop forever by default — this is a legitimate, if unusual, idiom for an intentionally infinite loop that relies entirely on an internal ",[39,10234,8880],{}," to terminate (as shown here, breaking once ",[39,10237,10191],{},[39,10239,3423],{},"). Option A is wrong; omitting any\u002Fall of the three ",[39,10242,6926],{}," clauses is valid syntax. Option B inverts the actual default.",[15,10245,10246,10257,10305,10350],{"language":247},[18,10247,10249,10250,10252,10253,383,10255,8691],{"id":10248},"q8-what-happens-when-a-forof-loop-is-used-on-a-plain-object-not-an-array-map-or-set","Q8. What happens when a ",[39,10251,9163],{}," loop is used on a plain object (not an array, ",[39,10254,2672],{},[39,10256,9306],{},[257,10258,10259],{"language":247},[260,10260,10262],{"className":262,"code":10261,"language":247,"meta":264,"style":264},"const obj = { a: 1, b: 2 };\nfor (const val of obj) console.log(val);\n",[39,10263,10264,10284],{"__ignoreMap":264},[268,10265,10266,10268,10270,10272,10275,10277,10280,10282],{"class":270,"line":271},[268,10267,243],{"class":274},[268,10269,4651],{"class":305},[268,10271,616],{"class":274},[268,10273,10274],{"class":282}," { a: ",[268,10276,2255],{"class":305},[268,10278,10279],{"class":282},", b: ",[268,10281,2258],{"class":305},[268,10283,2790],{"class":282},[268,10285,10286,10288,10290,10292,10295,10297,10300,10302],{"class":270,"line":286},[268,10287,6926],{"class":274},[268,10289,2182],{"class":282},[268,10291,243],{"class":274},[268,10293,10294],{"class":305}," val",[268,10296,9229],{"class":274},[268,10298,10299],{"class":282}," obj) console.",[268,10301,1356],{"class":278},[268,10303,10304],{"class":282},"(val);\n",[23,10306,10308,10318,10328,10341],{"className":10307},[26],[28,10309,10311,3578,10313,1133,10315,10317],{"className":10310},[31],[33,10312],{"disabled":35,"type":36},[39,10314,2255],{},[39,10316,2258],{},", the object's values",[28,10319,10321,3578,10323,1133,10325,10327],{"className":10320},[31],[33,10322],{"disabled":35,"type":36},[39,10324,7582],{},[39,10326,9188],{},", the object's keys",[28,10329,10331,6738,10333,10336,10337,10340],{"className":10330},[31],[33,10332],{"disabled":35,"type":36},[39,10334,10335],{},"TypeError: obj is not iterable",", because plain objects don't implement the iterable protocol (",[39,10338,10339],{},"Symbol.iterator",") by default",[28,10342,10344,10346,10347,10349],{"className":10343},[31],[33,10345],{"disabled":35,"type":36}," Logs nothing, silently, since the object has no ",[39,10348,3567],{}," property",[66,10351,10352,10354,10361],{},[69,10353,71],{},[73,10355,10356,10358,10359],{},[76,10357,78],{}," C — Throws ",[39,10360,10335],{},[73,10362,10363,355,10365,355,10367,10369,10370,10373,10374,42,10376,10378,10379,10381,10382,10384,10385,446,10388,446,10391,10394,10395,10397,10398,10400,10401,10403],{},[76,10364,84],{},[76,10366,365],{},[39,10368,9163],{}," requires its target to implement the iterable protocol (i.e., have a ",[39,10371,10372],{},"[Symbol.iterator]"," method) — arrays, strings, ",[39,10375,2672],{},[39,10377,9306],{},", and generators do; plain objects (",[39,10380,2328],{},") do not, by design, since object key order\u002Fstructure isn't inherently sequential the way a list is. The correct way to iterate a plain object's entries is ",[39,10383,4728],{}," (keys only), or ",[39,10386,10387],{},"Object.entries(obj)",[39,10389,10390],{},"Object.keys(obj)",[39,10392,10393],{},"Object.values(obj)"," combined with ",[39,10396,9163],{}," on the resulting array. This is a common runtime error when developers assume ",[39,10399,9163],{}," works universally like ",[39,10402,4728],{}," does.",[15,10405,10406,10413,10514,10573],{"language":247},[18,10407,10409,10410,10412],{"id":10408},"q9-what-is-the-output-when-a-switch-uses-strict-comparison-against-mixed-types","Q9. What is the output when a ",[39,10411,8884],{}," uses strict comparison against mixed types?",[257,10414,10415],{"language":247},[260,10416,10418],{"className":262,"code":10417,"language":247,"meta":264,"style":264},"function check(val) {\n  switch (val) {\n    case \"1\":\n      return \"string one\";\n    case 1:\n      return \"number one\";\n    default:\n      return \"no match\";\n  }\n}\nconsole.log(check(1));\n",[39,10419,10420,10433,10439,10447,10457,10465,10474,10480,10489,10493,10497],{"__ignoreMap":264},[268,10421,10422,10424,10427,10429,10431],{"class":270,"line":271},[268,10423,275],{"class":274},[268,10425,10426],{"class":278}," check",[268,10428,622],{"class":282},[268,10430,4315],{"class":1222},[268,10432,1235],{"class":282},[268,10434,10435,10437],{"class":270,"line":286},[268,10436,8917],{"class":274},[268,10438,9866],{"class":282},[268,10440,10441,10443,10445],{"class":270,"line":296},[268,10442,8925],{"class":274},[268,10444,5248],{"class":289},[268,10446,8931],{"class":282},[268,10448,10449,10452,10455],{"class":270,"line":311},[268,10450,10451],{"class":274},"      return",[268,10453,10454],{"class":289}," \"string one\"",[268,10456,293],{"class":282},[268,10458,10459,10461,10463],{"class":270,"line":788},[268,10460,8925],{"class":274},[268,10462,2199],{"class":305},[268,10464,8931],{"class":282},[268,10466,10467,10469,10472],{"class":270,"line":1951},[268,10468,10451],{"class":274},[268,10470,10471],{"class":289}," \"number one\"",[268,10473,293],{"class":282},[268,10475,10476,10478],{"class":270,"line":8955},[268,10477,8969],{"class":274},[268,10479,8931],{"class":282},[268,10481,10482,10484,10487],{"class":270,"line":8966},[268,10483,10451],{"class":274},[268,10485,10486],{"class":289}," \"no match\"",[268,10488,293],{"class":282},[268,10490,10491],{"class":270,"line":8974},[268,10492,1948],{"class":282},[268,10494,10495],{"class":270,"line":8985},[268,10496,314],{"class":282},[268,10498,10499,10501,10503,10505,10508,10510,10512],{"class":270,"line":8990},[268,10500,1353],{"class":282},[268,10502,1356],{"class":278},[268,10504,622],{"class":282},[268,10506,10507],{"class":278},"check",[268,10509,622],{"class":282},[268,10511,2255],{"class":305},[268,10513,4818],{"class":282},[23,10515,10517,10535,10558,10567],{"className":10516},[26],[28,10518,10520,355,10522,2833,10525,10527,10528,10530,10531,5425,10533],{"className":10519},[31],[33,10521],{"disabled":35,"type":36},[39,10523,10524],{},"\"string one\"",[39,10526,8884],{}," uses ",[39,10529,3197],{}," and coerces ",[39,10532,2255],{},[39,10534,3387],{},[28,10536,10538,355,10540,2833,10543,10545,10546,10548,10549,10551,10552,2758,10555],{"className":10537},[31],[33,10539],{"disabled":35,"type":36},[39,10541,10542],{},"\"number one\"",[39,10544,8884],{}," compares using strict equality (",[39,10547,3280],{},"), so ",[39,10550,2255],{}," (a number) only matches ",[39,10553,10554],{},"case 1",[39,10556,10557],{},"case \"1\"",[28,10559,10561,355,10563,10566],{"className":10560},[31],[33,10562],{"disabled":35,"type":36},[39,10564,10565],{},"\"no match\"",", because neither case matches",[28,10568,10570,10572],{"className":10569},[31],[33,10571],{"disabled":35,"type":36}," Both cases match simultaneously and it returns the first one syntactically, regardless of type",[66,10574,10575,10577,10586],{},[69,10576,71],{},[73,10578,10579,1727,10581,4387,10583,10585],{},[76,10580,78],{},[39,10582,10542],{},[39,10584,8884],{}," compares with strict equality",[73,10587,10588,355,10590,10592,10593,10595,10596,10598,10599,10602,10603,10605,10606,10608,10609,10611,10612,10614,10615,10617,10618,10620,10621,10624,10625,10627],{},[76,10589,84],{},[76,10591,365],{}," a common misconception is that ",[39,10594,8884],{}," behaves like loose ",[39,10597,3197],{}," comparison (similar to ",[39,10600,10601],{},"if (val == \"1\")","); it actually uses strict ",[39,10604,3280],{}," comparison internally, so type mismatches between the switched value and a ",[39,10607,9109],{}," label never match, even if they'd be loosely equal. Since ",[39,10610,4315],{}," is the number ",[39,10613,2255],{},", it only matches ",[39,10616,10554],{},", skipping ",[39,10619,10557],{}," entirely. This matters in real code when switching on values that might arrive as strings (e.g., from ",[39,10622,10623],{},"URLSearchParams"," or form inputs) — an easy silent-fallthrough-to-",[39,10626,9046],{}," bug if the type isn't what's expected.",[15,10629,10630,10637,10745,10790],{"language":247},[18,10631,10633,10634,10636],{"id":10632},"q10-what-does-an-empty-for-loop-body-with-a-semicolon-do","Q10. What does an empty ",[39,10635,6926],{}," loop body with a semicolon do?",[257,10638,10639],{"language":247},[260,10640,10642],{"className":262,"code":10641,"language":247,"meta":264,"style":264},"const arr = [5, 3, 8, 1];\nlet max = arr[0];\nfor (let i = 1; i \u003C arr.length; max = arr[i] > max ? arr[i] : max, i++);\nconsole.log(max);\n",[39,10643,10644,10671,10687,10736],{"__ignoreMap":264},[268,10645,10646,10648,10650,10652,10654,10656,10658,10660,10662,10665,10667,10669],{"class":270,"line":271},[268,10647,243],{"class":274},[268,10649,9177],{"class":305},[268,10651,616],{"class":274},[268,10653,8710],{"class":282},[268,10655,2429],{"class":305},[268,10657,42],{"class":282},[268,10659,3423],{"class":305},[268,10661,42],{"class":282},[268,10663,10664],{"class":305},"8",[268,10666,42],{"class":282},[268,10668,2255],{"class":305},[268,10670,8737],{"class":282},[268,10672,10673,10675,10678,10680,10683,10685],{"class":270,"line":286},[268,10674,240],{"class":274},[268,10676,10677],{"class":282}," max ",[268,10679,302],{"class":274},[268,10681,10682],{"class":282}," arr[",[268,10684,3307],{"class":305},[268,10686,8737],{"class":282},[268,10688,10689,10691,10693,10695,10697,10699,10701,10703,10705,10708,10710,10713,10715,10718,10720,10722,10724,10726,10729,10732,10734],{"class":270,"line":296},[268,10690,6926],{"class":274},[268,10692,2182],{"class":282},[268,10694,240],{"class":274},[268,10696,9384],{"class":282},[268,10698,302],{"class":274},[268,10700,2199],{"class":305},[268,10702,9391],{"class":282},[268,10704,1076],{"class":274},[268,10706,10707],{"class":282}," arr.",[268,10709,3567],{"class":305},[268,10711,10712],{"class":282},"; max ",[268,10714,302],{"class":274},[268,10716,10717],{"class":282}," arr[i] ",[268,10719,6435],{"class":274},[268,10721,10677],{"class":282},[268,10723,1685],{"class":274},[268,10725,10717],{"class":282},[268,10727,10728],{"class":274},":",[268,10730,10731],{"class":282}," max, i",[268,10733,9401],{"class":274},[268,10735,628],{"class":282},[268,10737,10738,10740,10742],{"class":270,"line":311},[268,10739,1353],{"class":282},[268,10741,1356],{"class":278},[268,10743,10744],{"class":282},"(max);\n",[23,10746,10748,10759,10771,10779],{"className":10747},[26],[28,10749,10751,355,10753,10755,10756,10758],{"className":10750},[31],[33,10752],{"disabled":35,"type":36},[39,10754,1274],{},", since a ",[39,10757,6926],{}," loop body cannot be empty",[28,10760,10762,355,10764,10766,10767,10770],{"className":10761},[31],[33,10763],{"disabled":35,"type":36},[39,10765,10664],{}," — the loop still runs correctly; all the work happens in the update clause via the comma operator, and the trailing ",[39,10768,10769],{},";"," is simply an empty statement acting as the loop body",[28,10772,10774,355,10776,10778],{"className":10773},[31],[33,10775],{"disabled":35,"type":36},[39,10777,2255],{},", because the loop never actually executes the comparison",[28,10780,10782,355,10784,4387,10786,10789],{"className":10781},[31],[33,10783],{"disabled":35,"type":36},[39,10785,833],{},[39,10787,10788],{},"max"," is never reassigned",[66,10791,10792,10794,10801],{},[69,10793,71],{},[73,10795,10796,1727,10798,10800],{},[76,10797,78],{},[39,10799,10664],{},"; the loop is legal, doing all its work in the update clause via the comma operator",[73,10802,10803,10805,10806,10808,10809,10812,10813,10816,10817,10819,10820,10822,10823,10825],{},[76,10804,84],{}," A lone ",[39,10807,10769],{}," immediately after a ",[39,10810,10811],{},"for(...)"," header is a valid (if unusual and generally discouraged) ",[104,10814,10815],{},"empty statement",", serving as the loop's entire body. This example is legal but poor style: it stuffs both the max-tracking logic and the increment into the update clause using the comma operator (see Operators topic Q10) so no loop body is needed at all. It does correctly compute the max (",[39,10818,10664],{},"). ",[76,10821,930],{}," despite being valid, this kind of \"do everything in the ",[39,10824,10811],{}," header\" pattern is considered bad practice — real code should put logic in the loop body for readability, reserving the empty-body pattern for rare, deliberate cases.",[15,10827,10828,10838,10932,10980],{"language":247},[18,10829,10831,10832,10834,10835,10837],{"id":10830},"q11-what-is-the-scoping-behavior-of-a-variable-declared-with-let-inside-a-switch-block-with-no-per-case-braces","Q11. What is the scoping behavior of a variable declared with ",[39,10833,240],{}," inside a ",[39,10836,8884],{}," block with no per-case braces?",[257,10839,10840],{"language":247},[260,10841,10843],{"className":262,"code":10842,"language":247,"meta":264,"style":264},"function process(type) {\n  switch (type) {\n    case \"a\":\n      let result = \"A result\";\n      return result;\n    case \"b\":\n      let result = \"B result\";\n      return result;\n  }\n}\n",[39,10844,10845,10858,10865,10874,10889,10896,10905,10918,10924,10928],{"__ignoreMap":264},[268,10846,10847,10849,10852,10854,10856],{"class":270,"line":271},[268,10848,275],{"class":274},[268,10850,10851],{"class":278}," process",[268,10853,622],{"class":282},[268,10855,8623],{"class":1222},[268,10857,1235],{"class":282},[268,10859,10860,10862],{"class":270,"line":286},[268,10861,8917],{"class":274},[268,10863,10864],{"class":282}," (type) {\n",[268,10866,10867,10869,10872],{"class":270,"line":296},[268,10868,8925],{"class":274},[268,10870,10871],{"class":289}," \"a\"",[268,10873,8931],{"class":282},[268,10875,10876,10879,10882,10884,10887],{"class":270,"line":311},[268,10877,10878],{"class":274},"      let",[268,10880,10881],{"class":282}," result ",[268,10883,302],{"class":274},[268,10885,10886],{"class":289}," \"A result\"",[268,10888,293],{"class":282},[268,10890,10891,10893],{"class":270,"line":788},[268,10892,10451],{"class":274},[268,10894,10895],{"class":282}," result;\n",[268,10897,10898,10900,10903],{"class":270,"line":1951},[268,10899,8925],{"class":274},[268,10901,10902],{"class":289}," \"b\"",[268,10904,8931],{"class":282},[268,10906,10907,10909,10911,10913,10916],{"class":270,"line":8955},[268,10908,10878],{"class":274},[268,10910,10881],{"class":282},[268,10912,302],{"class":274},[268,10914,10915],{"class":289}," \"B result\"",[268,10917,293],{"class":282},[268,10919,10920,10922],{"class":270,"line":8966},[268,10921,10451],{"class":274},[268,10923,10895],{"class":282},[268,10925,10926],{"class":270,"line":8974},[268,10927,1948],{"class":282},[268,10929,10930],{"class":270,"line":8985},[268,10931,314],{"class":282},[23,10933,10935,10946,10965,10971],{"className":10934},[26],[28,10936,10938,10940,10941,10943,10944],{"className":10937},[31],[33,10939],{"disabled":35,"type":36}," This runs fine; each ",[39,10942,9109],{}," gets its own scope for ",[39,10945,240],{},[28,10947,10949,355,10951,10954,10955,10957,10958,10960,10961,10964],{"className":10948},[31],[33,10950],{"disabled":35,"type":36},[39,10952,10953],{},"SyntaxError: Identifier 'result' has already been declared"," — a ",[39,10956,8884],{}," block (without per-case ",[39,10959,2328],{},") is a single shared block scope, so both ",[39,10962,10963],{},"let result"," declarations collide",[28,10966,10968,10970],{"className":10967},[31],[33,10969],{"disabled":35,"type":36}," Only a runtime error occurs when both cases are reached, not a parse-time error",[28,10972,10974,10976,10977,10979],{"className":10973},[31],[33,10975],{"disabled":35,"type":36}," This is valid; the second ",[39,10978,10963],{}," simply shadows the first",[66,10981,10982,10984,10994],{},[69,10983,71],{},[73,10985,10986,1727,10988,10990,10991,10993],{},[76,10987,78],{},[39,10989,1274],{},", since the whole ",[39,10992,8884],{}," body is one shared block scope",[73,10995,10996,355,10998,11000,11001,11004,11005,11007,11008,11011,11012,11014,11015,11017,11018,11020,11021,11024,11025,11027,11028,11030],{},[76,10997,84],{},[76,10999,365],{}," an entire ",[39,11002,11003],{},"switch (...) { ... }"," statement is just a single block for scoping purposes, unless individual ",[39,11006,9109],{},"s add their own ",[39,11009,11010],{},"{ }"," braces. Both ",[39,11013,10963],{}," declarations exist in that same shared scope, so this is a duplicate-declaration ",[39,11016,1274],{}," caught at parse time — before the function even runs, regardless of which ",[39,11019,9109],{}," would actually execute. The fix is wrapping each case body in its own block: ",[39,11022,11023],{},"case \"a\": { let result = ...; return result; }",". This is a common surprise for developers assuming each ",[39,11026,9109],{}," is automatically its own scope like each iteration of a ",[39,11029,240],{},"-based loop is.",[15,11032,11033,11043,11084,11133],{"language":247},[18,11034,11036,11037,11039,11040,11042],{"id":11035},"q12-what-happens-when-break-is-used-outside-of-a-loop-or-switch-without-a-label","Q12. What happens when ",[39,11038,8880],{}," is used outside of a loop or ",[39,11041,8884],{},", without a label?",[257,11044,11045],{"language":247},[260,11046,11048],{"className":262,"code":11047,"language":247,"meta":264,"style":264},"function test() {\n  if (true) {\n    break;\n  }\n}\n",[39,11049,11050,11059,11069,11076,11080],{"__ignoreMap":264},[268,11051,11052,11054,11057],{"class":270,"line":271},[268,11053,275],{"class":274},[268,11055,11056],{"class":278}," test",[268,11058,283],{"class":282},[268,11060,11061,11063,11065,11067],{"class":270,"line":286},[268,11062,9863],{"class":274},[268,11064,2182],{"class":282},[268,11066,2185],{"class":305},[268,11068,1235],{"class":282},[268,11070,11071,11074],{"class":270,"line":296},[268,11072,11073],{"class":274},"    break",[268,11075,293],{"class":282},[268,11077,11078],{"class":270,"line":311},[268,11079,1948],{"class":282},[268,11081,11082],{"class":270,"line":788},[268,11083,314],{"class":282},[23,11085,11087,11098,11116,11124],{"className":11086},[26],[28,11088,11090,11092,11093,11095,11096],{"className":11089},[31],[33,11091],{"disabled":35,"type":36}," It simply exits the ",[39,11094,2179],{}," block, like a scoped ",[39,11097,9151],{},[28,11099,11101,355,11103,11106,11107,11109,11110,11112,11113,11115],{"className":11100},[31],[33,11102],{"disabled":35,"type":36},[39,11104,11105],{},"SyntaxError: Illegal break statement"," — unlabeled ",[39,11108,8880],{}," is only valid inside a loop or ",[39,11111,8884],{},", not inside a bare ",[39,11114,2179],{}," block",[28,11117,11119,11121,11122],{"className":11118},[31],[33,11120],{"disabled":35,"type":36}," It exits the entire function, behaving like ",[39,11123,9151],{},[28,11125,11127,11129,11130,11132],{"className":11126},[31],[33,11128],{"disabled":35,"type":36}," It throws a runtime ",[39,11131,827],{}," when the function is called, but parses fine",[66,11134,11135,11137,11149],{},[69,11136,71],{},[73,11138,11139,1727,11141,11143,11144,11146,11147],{},[76,11140,78],{},[39,11142,1274],{},", since unlabeled ",[39,11145,8880],{}," requires an enclosing loop or ",[39,11148,8884],{},[73,11150,11151,355,11153,11155,11156,42,11158,42,11161,11164,11165,11167,11168,11170,11171,355,11174,11177],{},[76,11152,84],{},[39,11154,8880],{}," (without a label) is only legal directly inside a loop (",[39,11157,6926],{},[39,11159,11160],{},"while",[39,11162,11163],{},"do...while",") or a ",[39,11166,8884],{}," statement — it cannot be used to exit an arbitrary block like a bare ",[39,11169,2179],{},". This is caught at parse time, so the function never even becomes callable (ruling out D, which wrongly assumes it parses). A labeled ",[39,11172,11173],{},"break label;",[104,11175,11176],{},"can"," target an arbitrary labeled block\u002Fstatement (not just loops), but that requires an explicit label, which this example doesn't have.",[15,11179,11180,11187,11247,11290],{"language":247},[18,11181,11183,11184,11186],{"id":11182},"q13-what-is-the-output-of-a-dowhile-loop-when-the-condition-is-false-from-the-start","Q13. What is the output of a ",[39,11185,11163],{}," loop when the condition is false from the start?",[257,11188,11189],{"language":247},[260,11190,11192],{"className":262,"code":11191,"language":247,"meta":264,"style":264},"let i = 10;\ndo {\n  console.log(i);\n  i++;\n} while (i \u003C 5);\n",[39,11193,11194,11206,11213,11222,11231],{"__ignoreMap":264},[268,11195,11196,11198,11200,11202,11204],{"class":270,"line":271},[268,11197,240],{"class":274},[268,11199,9384],{"class":282},[268,11201,302],{"class":274},[268,11203,306],{"class":305},[268,11205,293],{"class":282},[268,11207,11208,11211],{"class":270,"line":286},[268,11209,11210],{"class":274},"do",[268,11212,9914],{"class":282},[268,11214,11215,11217,11219],{"class":270,"line":296},[268,11216,5556],{"class":282},[268,11218,1356],{"class":278},[268,11220,11221],{"class":282},"(i);\n",[268,11223,11224,11227,11229],{"class":270,"line":311},[268,11225,11226],{"class":282},"  i",[268,11228,9401],{"class":274},[268,11230,293],{"class":282},[268,11232,11233,11236,11238,11241,11243,11245],{"class":270,"line":788},[268,11234,11235],{"class":282},"} ",[268,11237,11160],{"class":274},[268,11239,11240],{"class":282}," (i ",[268,11242,1076],{"class":274},[268,11244,2387],{"class":305},[268,11246,628],{"class":282},[23,11248,11250,11260,11271,11280],{"className":11249},[26],[28,11251,11253,11255,11256,11259],{"className":11252},[31],[33,11254],{"disabled":35,"type":36}," Nothing is logged, since the condition ",[39,11257,11258],{},"i \u003C 5"," is false immediately",[28,11261,11263,355,11265,11267,11268,11270],{"className":11262},[31],[33,11264],{"disabled":35,"type":36},[39,11266,5825],{}," is logged exactly once, because ",[39,11269,11163],{}," always executes the body at least once before checking the condition",[28,11272,11274,11276,11277,11279],{"className":11273},[31],[33,11275],{"disabled":35,"type":36}," It loops forever, since ",[39,11278,9509],{}," starts above the threshold",[28,11281,11283,355,11285,4387,11287,11289],{"className":11282},[31],[33,11284],{"disabled":35,"type":36},[39,11286,1274],{},[39,11288,11163],{}," requires the condition to be true initially",[66,11291,11292,11294,11304],{},[69,11293,71],{},[73,11295,11296,1727,11298,11300,11301,11303],{},[76,11297,78],{},[39,11299,5825],{}," is logged once; ",[39,11302,11163],{}," guarantees at least one execution before checking",[73,11305,11306,11308,11309,11311,11312,11315,11316,11318,11319,11321,11322,11324,11325,7083,11327,11329,11330,11333,11334,11336,11337,11339,11340,11342],{},[76,11307,84],{}," Unlike a ",[39,11310,11160],{}," loop (which checks the condition ",[104,11313,11314],{},"before"," the first iteration and may never execute its body), ",[39,11317,11163],{}," checks the condition ",[104,11320,1747],{}," running the body, guaranteeing at least one execution regardless of the initial condition. Here, ",[39,11323,5825],{}," is logged, ",[39,11326,9509],{},[39,11328,6879],{},", then the condition ",[39,11331,11332],{},"11 \u003C 5"," is checked and is ",[39,11335,2986],{},", so the loop stops after exactly one iteration. Option A describes what a ",[39,11338,11160],{}," loop would do in the same situation. This basic-vs-while distinction is the main reason to reach for ",[39,11341,11163],{}," — when you need \"run at least once, then maybe repeat\" semantics (e.g., prompting a user at least once).",[15,11344,11345,11352,11397,11451],{"language":247},[18,11346,11348,11349,11351],{"id":11347},"q14-what-is-the-idiomatic-and-safest-way-to-iterate-a-maps-entries-with-both-key-and-value","Q14. What is the idiomatic and safest way to iterate a ",[39,11350,2672],{},"'s entries with both key and value?",[257,11353,11354],{"language":247},[260,11355,11357],{"className":262,"code":11356,"language":247,"meta":264,"style":264},"const inventory = new Map([[\"apples\", 10], [\"bananas\", 5]]);\n",[39,11358,11359],{"__ignoreMap":264},[268,11360,11361,11363,11366,11368,11371,11374,11377,11380,11382,11384,11387,11390,11392,11394],{"class":270,"line":271},[268,11362,243],{"class":274},[268,11364,11365],{"class":305}," inventory",[268,11367,616],{"class":274},[268,11369,11370],{"class":274}," new",[268,11372,11373],{"class":278}," Map",[268,11375,11376],{"class":282},"([[",[268,11378,11379],{"class":289},"\"apples\"",[268,11381,42],{"class":282},[268,11383,5825],{"class":305},[268,11385,11386],{"class":282},"], [",[268,11388,11389],{"class":289},"\"bananas\"",[268,11391,42],{"class":282},[268,11393,2429],{"class":305},[268,11395,11396],{"class":282},"]]);\n",[23,11398,11400,11409,11427,11441],{"className":11399},[26],[28,11401,11403,355,11405,11408],{"className":11402},[31],[33,11404],{"disabled":35,"type":36},[39,11406,11407],{},"for (const item in inventory) console.log(item);"," — same as arrays",[28,11410,11412,355,11414,3990,11417,11419,11420,11423,11424,11426],{"className":11411},[31],[33,11413],{"disabled":35,"type":36},[39,11415,11416],{},"for (const [key, value] of inventory) console.log(key, value);",[39,11418,2672],{}," is iterable and yields ",[39,11421,11422],{},"[key, value]"," pairs by default, which destructure cleanly in a ",[39,11425,9163],{}," loop",[28,11428,11430,355,11432,11435,11436,11438,11439],{"className":11429},[31],[33,11431],{"disabled":35,"type":36},[39,11433,11434],{},"inventory.forEach((key, value) => ...)"," is the only correct approach; ",[39,11437,9163],{}," doesn't work on ",[39,11440,2672],{},[28,11442,11444,11446,11447,11450],{"className":11443},[31],[33,11445],{"disabled":35,"type":36}," Convert to an array first with ",[39,11448,11449],{},"Array.from(inventory.keys())"," before any iteration is possible",[66,11452,11453,11455,11468],{},[69,11454,71],{},[73,11456,11457,1727,11459,4387,11462,11464,11465,11467],{},[76,11458,78],{},[39,11460,11461],{},"for (const [key, value] of inventory)",[39,11463,2672],{}," yields ",[39,11466,11422],{}," pairs by default",[73,11469,11470,355,11472,355,11474,11476,11477,11479,11480,11482,11483,11485,11486,11488,11489,11492,11493,11496,11497,11499,11500,11502,11503,11505],{},[76,11471,84],{},[76,11473,930],{},[39,11475,2672],{},"'s default iterator (used by ",[39,11478,9163],{},") yields ",[39,11481,11422],{}," two-element arrays, which pair perfectly with array destructuring in the loop variable. Option A is wrong — ",[39,11484,4728],{}," is for enumerable object properties, and ",[39,11487,2672],{}," instances don't expose their entries that way (it would iterate nothing meaningful here). Option C is misleading — ",[39,11490,11491],{},"Map.prototype.forEach"," does exist and works, but note its callback argument order is ",[39,11494,11495],{},"(value, key)",", the reverse of the ",[39,11498,11422],{}," pairs from iteration — a frequent source of confusion; and ",[39,11501,9163],{}," absolutely does work on ",[39,11504,2672],{},", contrary to the claim. Option D is unnecessarily indirect.",[15,11507,11508,11515,11614,11662],{"language":247},[18,11509,11511,11512,11514],{"id":11510},"q15-what-is-the-idiomatic-way-to-avoid-switch-fallthrough-bugs-in-production-code","Q15. What is the idiomatic way to avoid ",[39,11513,8884],{}," fallthrough bugs in production code?",[257,11516,11517],{"language":247},[260,11518,11520],{"className":262,"code":11519,"language":247,"meta":264,"style":264},"function getShippingCost(zone) {\n  switch (zone) {\n    case \"domestic\":\n      return 5;\n    case \"international\":\n      return 25;\n    default:\n      throw new Error(`Unknown zone: ${zone}`);\n  }\n}\n",[39,11521,11522,11536,11543,11552,11560,11569,11578,11584,11606,11610],{"__ignoreMap":264},[268,11523,11524,11526,11529,11531,11534],{"class":270,"line":271},[268,11525,275],{"class":274},[268,11527,11528],{"class":278}," getShippingCost",[268,11530,622],{"class":282},[268,11532,11533],{"class":1222},"zone",[268,11535,1235],{"class":282},[268,11537,11538,11540],{"class":270,"line":286},[268,11539,8917],{"class":274},[268,11541,11542],{"class":282}," (zone) {\n",[268,11544,11545,11547,11550],{"class":270,"line":296},[268,11546,8925],{"class":274},[268,11548,11549],{"class":289}," \"domestic\"",[268,11551,8931],{"class":282},[268,11553,11554,11556,11558],{"class":270,"line":311},[268,11555,10451],{"class":274},[268,11557,2387],{"class":305},[268,11559,293],{"class":282},[268,11561,11562,11564,11567],{"class":270,"line":788},[268,11563,8925],{"class":274},[268,11565,11566],{"class":289}," \"international\"",[268,11568,8931],{"class":282},[268,11570,11571,11573,11576],{"class":270,"line":1951},[268,11572,10451],{"class":274},[268,11574,11575],{"class":305}," 25",[268,11577,293],{"class":282},[268,11579,11580,11582],{"class":270,"line":8955},[268,11581,8969],{"class":274},[268,11583,8931],{"class":282},[268,11585,11586,11589,11591,11594,11596,11599,11601,11604],{"class":270,"line":8966},[268,11587,11588],{"class":274},"      throw",[268,11590,11370],{"class":274},[268,11592,11593],{"class":278}," Error",[268,11595,622],{"class":282},[268,11597,11598],{"class":289},"`Unknown zone: ${",[268,11600,11533],{"class":282},[268,11602,11603],{"class":289},"}`",[268,11605,628],{"class":282},[268,11607,11608],{"class":270,"line":8974},[268,11609,1948],{"class":282},[268,11611,11612],{"class":270,"line":8985},[268,11613,314],{"class":282},[23,11615,11617,11633,11650,11656],{"className":11616},[26],[28,11618,11620,11622,11623,11625,11626,11629,11630,11632],{"className":11619},[31],[33,11621],{"disabled":35,"type":36}," Never use ",[39,11624,8884],{},"; always use ",[39,11627,11628],{},"if\u002Felse if"," chains instead, since ",[39,11631,8884],{}," is inherently unsafe",[28,11634,11636,11638,11639,11641,11642,99,11644,11646,11647,11649],{"className":11635},[31],[33,11637],{"disabled":35,"type":36}," Always end every ",[39,11640,9109],{}," with an explicit ",[39,11643,9151],{},[39,11645,8880],{}," (as shown), and always include a ",[39,11648,9046],{}," case — ideally one that throws or logs on an unexpected value rather than silently doing nothing, to surface unhandled cases immediately",[28,11651,11653,11655],{"className":11652},[31],[33,11654],{"disabled":35,"type":36}," Fallthrough is rarely a real issue in practice, so no special precaution is needed",[28,11657,11659,11661],{"className":11658},[31],[33,11660],{"disabled":35,"type":36}," Rely on linters alone; no code-level pattern is necessary",[66,11663,11664,11666,11674],{},[69,11665,71],{},[73,11667,11668,11670,11671,11673],{},[76,11669,78],{}," B — Terminate every case explicitly and include a ",[39,11672,9046],{}," that surfaces unexpected values (e.g., by throwing)",[73,11675,11676,355,11678,11680,11681,11683,11684,11686,11687,11689,11690,11692,11693,11695,11696,11699],{},[76,11677,84],{},[76,11679,930],{}," using ",[39,11682,9151],{}," (inside a function, as shown) or ",[39,11685,8880],{}," after every case body eliminates unintended fallthrough entirely, and — just as important — an explicit ",[39,11688,9046],{}," branch that throws (rather than silently falling through to nothing) turns an unhandled case into a loud, immediate failure instead of a silent bug discovered much later. Option A overcorrects; ",[39,11691,8884],{}," is fine and often more readable than long ",[39,11694,11628],{}," chains when used with this discipline. Option C dismisses a genuinely common bug class (Q2 of this file demonstrates exactly this). Option D is incomplete — linters (e.g., ",[39,11697,11698],{},"no-fallthrough",") are a good complementary safety net, but relying on tooling alone instead of also writing defensive code is weaker than doing both.",[15,11701,11702,11712,11813,11856],{"language":247},[18,11703,11705,11706,11708,11709,11711],{"id":11704},"q16-why-is-forof-generally-preferred-over-indexed-for-loops-when-iterating-arrays-in-modern-code-and-whats-the-tradeoff","Q16. Why is ",[39,11707,9163],{}," generally preferred over indexed ",[39,11710,6926],{}," loops when iterating arrays in modern code, and what's the tradeoff?",[257,11713,11714],{"language":247},[260,11715,11717],{"className":262,"code":11716,"language":247,"meta":264,"style":264},"const items = [\"a\", \"b\", \"c\"];\nfor (let i = 0; i \u003C items.length; i++) {\n  console.log(items[i]);\n}\nfor (const item of items) {\n  console.log(item);\n}\n",[39,11718,11719,11742,11771,11780,11784,11800,11809],{"__ignoreMap":264},[268,11720,11721,11723,11726,11728,11730,11732,11734,11736,11738,11740],{"class":270,"line":271},[268,11722,243],{"class":274},[268,11724,11725],{"class":305}," items",[268,11727,616],{"class":274},[268,11729,8710],{"class":282},[268,11731,7582],{"class":289},[268,11733,42],{"class":282},[268,11735,9188],{"class":289},[268,11737,42],{"class":282},[268,11739,9193],{"class":289},[268,11741,8737],{"class":282},[268,11743,11744,11746,11748,11750,11752,11754,11756,11758,11760,11763,11765,11767,11769],{"class":270,"line":286},[268,11745,6926],{"class":274},[268,11747,2182],{"class":282},[268,11749,240],{"class":274},[268,11751,9384],{"class":282},[268,11753,302],{"class":274},[268,11755,5728],{"class":305},[268,11757,9391],{"class":282},[268,11759,1076],{"class":274},[268,11761,11762],{"class":282}," items.",[268,11764,3567],{"class":305},[268,11766,9398],{"class":282},[268,11768,9401],{"class":274},[268,11770,1235],{"class":282},[268,11772,11773,11775,11777],{"class":270,"line":296},[268,11774,5556],{"class":282},[268,11776,1356],{"class":278},[268,11778,11779],{"class":282},"(items[i]);\n",[268,11781,11782],{"class":270,"line":311},[268,11783,314],{"class":282},[268,11785,11786,11788,11790,11792,11795,11797],{"class":270,"line":788},[268,11787,6926],{"class":274},[268,11789,2182],{"class":282},[268,11791,243],{"class":274},[268,11793,11794],{"class":305}," item",[268,11796,9229],{"class":274},[268,11798,11799],{"class":282}," items) {\n",[268,11801,11802,11804,11806],{"class":270,"line":1951},[268,11803,5556],{"class":282},[268,11805,1356],{"class":278},[268,11807,11808],{"class":282},"(item);\n",[268,11810,11811],{"class":270,"line":8955},[268,11812,314],{"class":282},[23,11814,11816,11824,11835,11850],{"className":11815},[26],[28,11817,11819,355,11821,11823],{"className":11818},[31],[33,11820],{"disabled":35,"type":36},[39,11822,9163],{}," is always strictly faster, so it should always be used",[28,11825,11827,355,11829,11831,11832,11834],{"className":11826},[31],[33,11828],{"disabled":35,"type":36},[39,11830,9163],{}," is more concise and less error-prone (no manual index bookkeeping, no off-by-one risk), but the classic indexed ",[39,11833,6926],{}," loop is still preferable when you need the index itself, need to skip\u002Fstep irregularly, or need to mutate the array while iterating",[28,11836,11838,11840,11841,11843,11844,11846,11847,11849],{"className":11837},[31],[33,11839],{"disabled":35,"type":36}," Indexed ",[39,11842,6926],{}," loops cannot be used with ",[39,11845,243],{}," items, only ",[39,11848,9163],{}," can",[28,11851,11853,11855],{"className":11852},[31],[33,11854],{"disabled":35,"type":36}," There's no meaningful tradeoff; they're fully interchangeable in every scenario",[66,11857,11858,11860,11867],{},[69,11859,71],{},[73,11861,11862,1727,11864,11866],{},[76,11863,78],{},[39,11865,9163],{}," is more concise and avoids index bugs, but indexed loops are still preferable when the index, custom stepping, or safe in-place mutation is needed",[73,11868,11869,355,11871,355,11873,11875,11876,11879,11880,11883,11884,11887,11888,11890,11891,11894],{},[76,11870,84],{},[76,11872,930],{},[39,11874,9163],{}," removes an entire class of bugs tied to manual index management (off-by-one errors, forgetting ",[39,11877,11878],{},"i++",", wrong comparison operator). However, it doesn't expose the current index directly (use ",[39,11881,11882],{},"array.entries()"," with destructuring, ",[39,11885,11886],{},"for (const [i, item] of items.entries())",", if both are needed), and classic ",[39,11889,6926],{}," loops remain the right tool for non-sequential stepping (",[39,11892,11893],{},"i += 2",") or careful in-place array mutation during iteration. Option A is an unfounded blanket performance claim — differences are typically negligible and engine\u002Fversion dependent. Option C is fabricated; both loop types work fine regardless of how the array variable itself was declared.",[15,11896,11897,11909,11989,12023],{"language":247},[18,11898,11900,11901,446,11903,11905,11906,11908],{"id":11899},"q17-what-is-the-best-practice-explanation-for-preferring-early-returncontinue-guard-clauses-over-deeply-nested-if-blocks","Q17. What is the best-practice explanation for preferring early ",[39,11902,9151],{},[39,11904,9615],{}," guard clauses over deeply nested ",[39,11907,2179],{}," blocks?",[257,11910,11911],{"language":247},[260,11912,11914],{"className":262,"code":11913,"language":247,"meta":264,"style":264},"function processOrder(order) {\n  if (order.isValid) {\n    if (order.inStock) {\n      if (order.paymentConfirmed) {\n        return shipOrder(order);\n      }\n    }\n  }\n  return null;\n}\n",[39,11915,11916,11930,11937,11944,11952,11963,11968,11973,11977,11985],{"__ignoreMap":264},[268,11917,11918,11920,11923,11925,11928],{"class":270,"line":271},[268,11919,275],{"class":274},[268,11921,11922],{"class":278}," processOrder",[268,11924,622],{"class":282},[268,11926,11927],{"class":1222},"order",[268,11929,1235],{"class":282},[268,11931,11932,11934],{"class":270,"line":286},[268,11933,9863],{"class":274},[268,11935,11936],{"class":282}," (order.isValid) {\n",[268,11938,11939,11941],{"class":270,"line":296},[268,11940,9686],{"class":274},[268,11942,11943],{"class":282}," (order.inStock) {\n",[268,11945,11946,11949],{"class":270,"line":311},[268,11947,11948],{"class":274},"      if",[268,11950,11951],{"class":282}," (order.paymentConfirmed) {\n",[268,11953,11954,11957,11960],{"class":270,"line":788},[268,11955,11956],{"class":274},"        return",[268,11958,11959],{"class":278}," shipOrder",[268,11961,11962],{"class":282},"(order);\n",[268,11964,11965],{"class":270,"line":1951},[268,11966,11967],{"class":282},"      }\n",[268,11969,11970],{"class":270,"line":8955},[268,11971,11972],{"class":282},"    }\n",[268,11974,11975],{"class":270,"line":8966},[268,11976,1948],{"class":282},[268,11978,11979,11981,11983],{"class":270,"line":8974},[268,11980,1240],{"class":274},[268,11982,4794],{"class":305},[268,11984,293],{"class":282},[268,11986,11987],{"class":270,"line":8985},[268,11988,314],{"class":282},[23,11990,11992,11998,12008,12014],{"className":11991},[26],[28,11993,11995,11997],{"className":11994},[31],[33,11996],{"disabled":35,"type":36}," Nested conditionals are always faster to execute, so this style should be kept for performance",[28,11999,12001,12003,12004,12007],{"className":12000},[31],[33,12002],{"disabled":35,"type":36}," Guard clauses (",[39,12005,12006],{},"if (!order.isValid) return null;"," etc., checked early and returned immediately) reduce nesting depth, keep the \"happy path\" flush against the left margin, and make each precondition's failure case easy to locate and reason about independently",[28,12009,12011,12013],{"className":12010},[31],[33,12012],{"disabled":35,"type":36}," Nesting depth has no effect on readability or maintainability; it's purely a stylistic preference with no practical benefit either way",[28,12015,12017,12019,12020,12022],{"className":12016},[31],[33,12018],{"disabled":35,"type":36}," Guard clauses are an anti-pattern because they create multiple ",[39,12021,9151],{}," points in a function, which should always be avoided",[66,12024,12025,12027,12032],{},[69,12026,71],{},[73,12028,12029,12031],{},[76,12030,78],{}," B — Guard clauses reduce nesting, keep the happy path readable, and isolate each failure condition",[73,12033,12034,355,12036,12038,12039,12042,12043,12045],{},[76,12035,84],{},[76,12037,930],{}," rewriting the above as ",[39,12040,12041],{},"if (!order.isValid) return null; if (!order.inStock) return null; if (!order.paymentConfirmed) return null; return shipOrder(order);"," flattens three levels of nesting into a linear list of independently-readable preconditions — widely considered more maintainable, especially as more conditions are added over time (each nested ",[39,12044,2179],{}," version requires increasing indentation for every check). Option A is false; nesting has no meaningful runtime performance implication either way — this is a readability\u002Fmaintainability concern, not a performance one. Option D states an outdated, overly rigid \"single return point\" rule that most modern style guides have moved away from in favor of guard clauses precisely because they improve clarity.",[15,12047,12048,12055,12136,12194],{"language":247},[18,12049,12051,12052,12054],{"id":12050},"q18-what-is-the-idiomatic-best-practice-regarding-forin-and-arrays-specifically","Q18. What is the idiomatic best practice regarding ",[39,12053,4728],{}," and arrays specifically?",[257,12056,12057],{"language":247},[260,12058,12060],{"className":262,"code":12059,"language":247,"meta":264,"style":264},"Array.prototype.customHelper = function () {};\nconst nums = [1, 2, 3];\nfor (const key in nums) {\n  console.log(key);\n}\n",[39,12061,12062,12084,12107,12123,12132],{"__ignoreMap":264},[268,12063,12064,12066,12068,12071,12073,12076,12078,12081],{"class":270,"line":271},[268,12065,88],{"class":305},[268,12067,462],{"class":282},[268,12069,12070],{"class":305},"prototype",[268,12072,462],{"class":282},[268,12074,12075],{"class":278},"customHelper",[268,12077,616],{"class":274},[268,12079,12080],{"class":274}," function",[268,12082,12083],{"class":282}," () {};\n",[268,12085,12086,12088,12091,12093,12095,12097,12099,12101,12103,12105],{"class":270,"line":286},[268,12087,243],{"class":274},[268,12089,12090],{"class":305}," nums",[268,12092,616],{"class":274},[268,12094,8710],{"class":282},[268,12096,2255],{"class":305},[268,12098,42],{"class":282},[268,12100,2258],{"class":305},[268,12102,42],{"class":282},[268,12104,3423],{"class":305},[268,12106,8737],{"class":282},[268,12108,12109,12111,12113,12115,12118,12120],{"class":270,"line":296},[268,12110,6926],{"class":274},[268,12112,2182],{"class":282},[268,12114,243],{"class":274},[268,12116,12117],{"class":305}," key",[268,12119,9209],{"class":274},[268,12121,12122],{"class":282}," nums) {\n",[268,12124,12125,12127,12129],{"class":270,"line":311},[268,12126,5556],{"class":282},[268,12128,1356],{"class":278},[268,12130,12131],{"class":282},"(key);\n",[268,12133,12134],{"class":270,"line":788},[268,12135,314],{"class":282},[23,12137,12139,12147,12178,12186],{"className":12138},[26],[28,12140,12142,355,12144,12146],{"className":12141},[31],[33,12143],{"disabled":35,"type":36},[39,12145,4728],{}," is the recommended way to iterate arrays because it's the oldest, most universally supported syntax",[28,12148,12150,12152,12153,12155,12156,12158,12159,12162,12163,42,12165,383,12168,446,12171,446,12174,12177],{"className":12149},[31],[33,12151],{"disabled":35,"type":36}," Avoid ",[39,12154,4728],{}," on arrays: it iterates enumerable keys including inherited ones (like ",[39,12157,12075],{}," added to ",[39,12160,12161],{},"Array.prototype"," here would also show up), doesn't guarantee numeric order across engines for non-standard cases, and yields string indices rather than values — prefer ",[39,12164,9163],{},[39,12166,12167],{},".forEach()",[39,12169,12170],{},".map()",[39,12172,12173],{},".filter()",[39,12175,12176],{},".reduce()"," instead",[28,12179,12181,355,12183,12185],{"className":12180},[31],[33,12182],{"disabled":35,"type":36},[39,12184,4728],{}," never includes inherited properties, so this concern doesn't apply",[28,12187,12189,2398,12191,12193],{"className":12188},[31],[33,12190],{"disabled":35,"type":36},[39,12192,827],{}," because you can't add custom methods to built-in prototypes",[66,12195,12196,12198,12206],{},[69,12197,71],{},[73,12199,12200,12202,12203,12205],{},[76,12201,78],{}," B — Avoid ",[39,12204,4728],{}," on arrays due to inherited enumerable properties, ordering caveats, and index-not-value semantics",[73,12207,12208,355,12210,355,12212,12214,12215,12217,12218,12220,12221,12223,12224,12226,12227,12229],{},[76,12209,84],{},[76,12211,930],{},[39,12213,4728],{}," walks the prototype chain for enumerable properties by design, meaning any enumerable property added to ",[39,12216,12161],{}," (as ",[39,12219,12075],{}," is here) would actually surface as a \"key\" alongside the numeric indices during iteration — a subtle and surprising bug if a library or polyfill augments a built-in prototype non-defensively. Combined with the index-vs-value confusion from Q3, this is why ",[39,12222,9163],{}," or array iteration methods are the idiomatic default for arrays, reserving ",[39,12225,4728],{}," for genuinely enumerating plain object keys. Option C is false — this exact \"leaking through the prototype chain\" behavior is ",[39,12228,4728],{},"'s defining (and risky) characteristic. Option D is false — augmenting built-in prototypes is legal JavaScript (if generally discouraged practice), not an error.",[15,12231,12232,12236,12293,12347],{"language":247},[18,12233,12235],{"id":12234},"q19-given-asynchronous-work-inside-a-loop-what-is-the-best-practice-pattern-to-run-iterations-sequentially-waiting-for-each-to-finish-before-starting-the-next","Q19. Given asynchronous work inside a loop, what is the best-practice pattern to run iterations sequentially (waiting for each to finish before starting the next)?",[257,12237,12238],{"language":247},[260,12239,12241],{"className":262,"code":12240,"language":247,"meta":264,"style":264},"async function processAll(ids) {\n  for (const id of ids) {\n    await processOne(id);\n  }\n}\n",[39,12242,12243,12259,12274,12285,12289],{"__ignoreMap":264},[268,12244,12245,12247,12249,12252,12254,12257],{"class":270,"line":271},[268,12246,379],{"class":274},[268,12248,12080],{"class":274},[268,12250,12251],{"class":278}," processAll",[268,12253,622],{"class":282},[268,12255,12256],{"class":1222},"ids",[268,12258,1235],{"class":282},[268,12260,12261,12263,12265,12267,12269,12271],{"class":270,"line":286},[268,12262,9659],{"class":274},[268,12264,2182],{"class":282},[268,12266,243],{"class":274},[268,12268,4632],{"class":305},[268,12270,9229],{"class":274},[268,12272,12273],{"class":282}," ids) {\n",[268,12275,12276,12279,12282],{"class":270,"line":296},[268,12277,12278],{"class":274},"    await",[268,12280,12281],{"class":278}," processOne",[268,12283,12284],{"class":282},"(id);\n",[268,12286,12287],{"class":270,"line":311},[268,12288,1948],{"class":282},[268,12290,12291],{"class":270,"line":788},[268,12292,314],{"class":282},[23,12294,12296,12308,12332,12341],{"className":12295},[26],[28,12297,12299,12301,12302,12305,12306,11426],{"className":12298},[31],[33,12300],{"disabled":35,"type":36}," This is a bug — ",[39,12303,12304],{},"await"," cannot be used inside a ",[39,12307,9163],{},[28,12309,12311,12313,12314,12316,12317,99,12319,12321,12322,12324,12325,12327,12328,12331],{"className":12310},[31],[33,12312],{"disabled":35,"type":36}," This correctly processes items one at a time, in order, because ",[39,12315,12304],{}," inside a standard ",[39,12318,6926],{},[39,12320,9163],{}," loop pauses that iteration until the promise resolves before continuing to the next; using ",[39,12323,12167],{}," with an ",[39,12326,379],{}," callback would NOT achieve this, since ",[39,12329,12330],{},"forEach"," ignores returned promises and fires all callbacks immediately",[28,12333,12335,355,12337,12340],{"className":12334},[31],[33,12336],{"disabled":35,"type":36},[39,12338,12339],{},"ids.forEach(async (id) => await processOne(id))"," is equivalent and preferred for readability",[28,12342,12344,12346],{"className":12343},[31],[33,12345],{"disabled":35,"type":36}," Both approaches are equally sequential; the choice is purely stylistic",[66,12348,12349,12351,12364],{},[69,12350,71],{},[73,12352,12353,1727,12355,2029,12357,12359,12360,2029,12362,5302],{},[76,12354,78],{},[39,12356,9163],{},[39,12358,12304],{}," correctly sequences the work; ",[39,12361,12167],{},[39,12363,379],{},[73,12365,12366,355,12368,1243,12370,12372,12373,12375,12376,12378,12379,12381,12382,12385,12386,12388,12389,12392,12393,12395,12396,446,12398,446,12400,12402,12403,12406],{},[76,12367,84],{},[76,12369,365],{},[39,12371,9163],{}," (or classic ",[39,12374,6926],{},") loop with ",[39,12377,12304],{}," inside genuinely pauses the loop's execution at each ",[39,12380,12304],{},", so iterations run strictly one after another. ",[39,12383,12384],{},"Array.prototype.forEach",", by contrast, invokes its callback for every element immediately and synchronously, ignoring any promise the callback returns — marking the callback ",[39,12387,379],{}," doesn't change this, it just means each callback silently returns an unhandled\u002Funawaited promise, so all the ",[39,12390,12391],{},"processOne"," calls actually fire concurrently, not sequentially, which is almost never the intended behavior when this mistake is made. Option A is false — ",[39,12394,12304],{}," works fine inside ",[39,12397,6926],{},[39,12399,9163],{},[39,12401,11160],{}," loops in an ",[39,12404,12405],{},"async function",". Option C is exactly the trap the explanation warns against.",[15,12408,12409,12416,12522,12559],{"language":247},[18,12410,12412,12413,12415],{"id":12411},"q20-in-error-prone-control-flow-involving-trycatch-inside-a-loop-what-is-the-best-practice-when-one-iterations-failure-shouldnt-stop-the-rest","Q20. In error-prone control flow involving ",[39,12414,2081],{}," inside a loop, what is the best practice when one iteration's failure shouldn't stop the rest?",[257,12417,12418],{"language":247},[260,12419,12421],{"className":262,"code":12420,"language":247,"meta":264,"style":264},"function importAll(records) {\n  const errors = [];\n  for (const record of records) {\n    try {\n      saveRecord(record);\n    } catch (err) {\n      errors.push({ record, error: err.message });\n    }\n  }\n  return errors;\n}\n",[39,12422,12423,12437,12450,12466,12473,12481,12492,12503,12507,12511,12518],{"__ignoreMap":264},[268,12424,12425,12427,12430,12432,12435],{"class":270,"line":271},[268,12426,275],{"class":274},[268,12428,12429],{"class":278}," importAll",[268,12431,622],{"class":282},[268,12433,12434],{"class":1222},"records",[268,12436,1235],{"class":282},[268,12438,12439,12442,12445,12447],{"class":270,"line":286},[268,12440,12441],{"class":274},"  const",[268,12443,12444],{"class":305}," errors",[268,12446,616],{"class":274},[268,12448,12449],{"class":282}," [];\n",[268,12451,12452,12454,12456,12458,12461,12463],{"class":270,"line":296},[268,12453,9659],{"class":274},[268,12455,2182],{"class":282},[268,12457,243],{"class":274},[268,12459,12460],{"class":305}," record",[268,12462,9229],{"class":274},[268,12464,12465],{"class":282}," records) {\n",[268,12467,12468,12471],{"class":270,"line":311},[268,12469,12470],{"class":274},"    try",[268,12472,9914],{"class":282},[268,12474,12475,12478],{"class":270,"line":788},[268,12476,12477],{"class":278},"      saveRecord",[268,12479,12480],{"class":282},"(record);\n",[268,12482,12483,12486,12489],{"class":270,"line":1951},[268,12484,12485],{"class":282},"    } ",[268,12487,12488],{"class":274},"catch",[268,12490,12491],{"class":282}," (err) {\n",[268,12493,12494,12497,12500],{"class":270,"line":8955},[268,12495,12496],{"class":282},"      errors.",[268,12498,12499],{"class":278},"push",[268,12501,12502],{"class":282},"({ record, error: err.message });\n",[268,12504,12505],{"class":270,"line":8966},[268,12506,11972],{"class":282},[268,12508,12509],{"class":270,"line":8974},[268,12510,1948],{"class":282},[268,12512,12513,12515],{"class":270,"line":8985},[268,12514,1240],{"class":274},[268,12516,12517],{"class":282}," errors;\n",[268,12519,12520],{"class":270,"line":8990},[268,12521,314],{"class":282},[23,12523,12525,12534,12543,12551],{"className":12524},[26],[28,12526,12528,12530,12531,12533],{"className":12527},[31],[33,12529],{"disabled":35,"type":36}," Put the ",[39,12532,2081],{}," outside the loop entirely, wrapping the whole loop once",[28,12535,12537,12539,12540,12542],{"className":12536},[31],[33,12538],{"disabled":35,"type":36}," Put ",[39,12541,2081],{}," inside the loop body around just the risky operation (as shown), so a single record's failure is caught, recorded, and the loop continues to the next record rather than aborting the entire batch",[28,12544,12546,11622,12548,12550],{"className":12545},[31],[33,12547],{"disabled":35,"type":36},[39,12549,2081],{}," in loops; instead let the first error propagate and stop everything, since partial failures are always worse than total failure",[28,12552,12554,4353,12556,12558],{"className":12553},[31],[33,12555],{"disabled":35,"type":36},[39,12557,2081],{}," outside the loop, but also inside — redundantly duplicating error handling at both levels",[66,12560,12561,12563,12571],{},[69,12562,71],{},[73,12564,12565,12567,12568,12570],{},[76,12566,78],{}," B — Place ",[39,12569,2081],{}," inside the loop around just the risky call so one failure doesn't abort the whole batch",[73,12572,12573,355,12575,12577,12578,12580,12581,12584,12585,12587,12588,12591,12592,12594],{},[76,12574,84],{},[76,12576,930],{}," wrapping the ",[39,12579,2081],{}," around only ",[39,12582,12583],{},"saveRecord(record)"," inside the loop means an exception on one iteration is caught, logged\u002Fcollected, and execution proceeds to the next record — appropriate for batch\u002Fbulk-import scenarios where partial success is valuable and one bad record shouldn't sink the whole batch. Option A is a common mistake: a ",[39,12586,2081],{}," wrapped around the entire loop instead means the ",[104,12589,12590],{},"first"," error thrown anywhere aborts the rest of the loop immediately (the ",[39,12593,12488],{}," block only runs once, and the loop never resumes), losing all remaining records' processing. Option C is an oversimplified rule that ignores real use cases (like bulk imports) where collecting partial results and continuing is the desired, correct behavior — not every error should be fatal to the whole operation.",[2107,12596,12597],{},"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 .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-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 .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 .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}",{"title":264,"searchDepth":286,"depth":286,"links":12599},[12600,12602,12604,12606,12608,12610,12612,12614,12616,12618,12620,12622,12624,12626,12628,12630,12632,12634,12636,12637],{"id":8687,"depth":296,"text":12601},"Q1. Which of these values is falsy in a boolean context (e.g., inside an if)?",{"id":8876,"depth":296,"text":12603},"Q2. What happens without break statements in a switch?",{"id":9157,"depth":296,"text":12605},"Q3. What's the key difference between for...in and for...of?",{"id":9359,"depth":296,"text":12607},"Q4. What is the classic closure-in-loop bug with var, and how does let fix it?",{"id":9611,"depth":296,"text":12609},"Q5. What does a labeled continue statement do inside nested loops?",{"id":9833,"depth":296,"text":12611},"Q6. What is the output of this if\u002Felse if\u002Felse chain, given JavaScript's truthy\u002Ffalsy coercion?",{"id":10073,"depth":296,"text":12613},"Q7. What does a for loop do when the condition is omitted entirely?",{"id":10248,"depth":296,"text":12615},"Q8. What happens when a for...of loop is used on a plain object (not an array, Map, or Set)?",{"id":10408,"depth":296,"text":12617},"Q9. What is the output when a switch uses strict comparison against mixed types?",{"id":10632,"depth":296,"text":12619},"Q10. What does an empty for loop body with a semicolon do?",{"id":10830,"depth":296,"text":12621},"Q11. What is the scoping behavior of a variable declared with let inside a switch block with no per-case braces?",{"id":11035,"depth":296,"text":12623},"Q12. What happens when break is used outside of a loop or switch, without a label?",{"id":11182,"depth":296,"text":12625},"Q13. What is the output of a do...while loop when the condition is false from the start?",{"id":11347,"depth":296,"text":12627},"Q14. What is the idiomatic and safest way to iterate a Map's entries with both key and value?",{"id":11510,"depth":296,"text":12629},"Q15. What is the idiomatic way to avoid switch fallthrough bugs in production code?",{"id":11704,"depth":296,"text":12631},"Q16. Why is for...of generally preferred over indexed for loops when iterating arrays in modern code, and what's the tradeoff?",{"id":11899,"depth":296,"text":12633},"Q17. What is the best-practice explanation for preferring early return\u002Fcontinue guard clauses over deeply nested if blocks?",{"id":12050,"depth":296,"text":12635},"Q18. What is the idiomatic best practice regarding for...in and arrays specifically?",{"id":12234,"depth":296,"text":12235},{"id":12411,"depth":296,"text":12638},"Q20. In error-prone control flow involving try\u002Fcatch inside a loop, what is the best practice when one iteration's failure shouldn't stop the rest?",{},"\u002Fjs\u002F04-control-flow",{"title":8677,"description":264},"js\u002F04-control-flow","ZRiqqBfgrDeuJ9n6qFbntIsp9ZX3QAin1k4_wCnnjEE",{"id":12645,"title":12646,"body":12647,"description":264,"extension":2144,"meta":16043,"navigation":35,"path":16044,"seo":16045,"stem":16046,"__hash__":16047},"content\u002Fjs\u002F05-functions-and-scope.md","05 — Functions & Scope",{"type":8,"value":12648,"toc":16020},[12649,12652,12732,12872,13027,13176,13316,13523,13724,13922,14085,14219,14377,14533,14769,14929,15126,15306,15496,15644,15788,16017],[11,12650,12646],{"id":12651},"_05-functions-scope",[15,12653,12654,12658,12689],{},[18,12655,12657],{"id":12656},"q1-which-statement-correctly-describes-the-difference-between-how-function-declarations-and-function-expressions-are-hoisted","Q1. Which statement correctly describes the difference between how function declarations and function expressions are hoisted?",[23,12659,12661,12671,12677,12683],{"className":12660},[26],[28,12662,12664,12666,12667,446,12669,2690],{"className":12663},[31],[33,12665],{"disabled":35,"type":36}," Function declarations are hoisted complete with their implementation and can be called before their textual position; function expressions are only as hoisted as the variable they're assigned to (or not hoisted at all for ",[39,12668,243],{},[39,12670,240],{},[28,12672,12674,12676],{"className":12673},[31],[33,12675],{"disabled":35,"type":36}," Neither declarations nor expressions are hoisted; both must appear in the source before they're used",[28,12678,12680,12682],{"className":12679},[31],[33,12681],{"disabled":35,"type":36}," Both are fully hoisted with their implementation, so both can be called before their textual position in the code",[28,12684,12686,12688],{"className":12685},[31],[33,12687],{"disabled":35,"type":36}," Function expressions are hoisted complete with their implementation, but declarations are not hoisted at all",[66,12690,12691,12693,12702],{},[69,12692,71],{},[73,12694,12695,12697,12698,446,12700,2690],{},[76,12696,78],{}," A — Function declarations are hoisted complete with their implementation and can be called before their textual position; function expressions are only as hoisted as the variable they're assigned to (or not hoisted at all for ",[39,12699,243],{},[39,12701,240],{},[73,12703,12704,12706,12707,12710,12711,12714,12715,99,12718,12721,12722,12724,12725,42,12727,446,12729,12731],{},[76,12705,84],{}," During the creation phase, the JS engine hoists an entire ",[39,12708,12709],{},"function foo() {}"," declaration — name and body — to the top of its enclosing scope, so it's fully callable before its line in the source. A function ",[104,12712,12713],{},"expression",", like ",[39,12716,12717],{},"const foo = function () {}",[39,12719,12720],{},"var foo = function () {}",", is just a variable assignment; only the variable binding follows that variable's own hoisting rules (",[39,12723,1440],{}," → hoisted and ",[39,12726,833],{},[39,12728,240],{},[39,12730,243],{}," → hoisted into the temporal dead zone), and the function value itself only exists once the assignment line runs. Options C and D describe hoisting behavior that doesn't apply to either form.",[15,12733,12734,12738,12793,12832],{"language":247},[18,12735,12737],{"id":12736},"q2-what-does-this-log","Q2. What does this log?",[257,12739,12740],{"language":247},[260,12741,12743],{"className":262,"code":12742,"language":247,"meta":264,"style":264},"console.log(typeof greet);\ngreet();\n\nfunction greet() {\n  console.log(\"hello from a declaration\");\n}\n",[39,12744,12745,12757,12764,12768,12776,12789],{"__ignoreMap":264},[268,12746,12747,12749,12751,12753,12755],{"class":270,"line":271},[268,12748,1353],{"class":282},[268,12750,1356],{"class":278},[268,12752,622],{"class":282},[268,12754,1361],{"class":274},[268,12756,3695],{"class":282},[268,12758,12759,12762],{"class":270,"line":286},[268,12760,12761],{"class":278},"greet",[268,12763,794],{"class":282},[268,12765,12766],{"class":270,"line":296},[268,12767,5033],{"emptyLinePlaceholder":35},[268,12769,12770,12772,12774],{"class":270,"line":311},[268,12771,275],{"class":274},[268,12773,3679],{"class":278},[268,12775,283],{"class":282},[268,12777,12778,12780,12782,12784,12787],{"class":270,"line":788},[268,12779,5556],{"class":282},[268,12781,1356],{"class":278},[268,12783,622],{"class":282},[268,12785,12786],{"class":289},"\"hello from a declaration\"",[268,12788,628],{"class":282},[268,12790,12791],{"class":270,"line":1951},[268,12792,314],{"class":282},[23,12794,12796,12806,12815,12823],{"className":12795},[26],[28,12797,12799,355,12801,12803,12804],{"className":12798},[31],[33,12800],{"disabled":35,"type":36},[39,12802,1397],{}," then a ",[39,12805,827],{},[28,12807,12809,355,12811,1133,12813],{"className":12808},[31],[33,12810],{"disabled":35,"type":36},[39,12812,3732],{},[39,12814,12786],{},[28,12816,12818,1243,12820,12822],{"className":12817},[31],[33,12819],{"disabled":35,"type":36},[39,12821,815],{}," before anything logs",[28,12824,12826,355,12828,12803,12830],{"className":12825},[31],[33,12827],{"disabled":35,"type":36},[39,12829,3732],{},[39,12831,815],{},[66,12833,12834,12836,12844],{},[69,12835,71],{},[73,12837,12838,1727,12840,1133,12842],{},[76,12839,78],{},[39,12841,3732],{},[39,12843,12786],{},[73,12845,12846,12848,12849,12851,12852,12855,12856,2472,12859,12861,12862,830,12865,12867,12868,12871],{},[76,12847,84],{}," Because ",[39,12850,12761],{}," is a function ",[104,12853,12854],{},"declaration",", both its name and its full implementation are hoisted to the top of the module\u002Fscript scope during the creation phase. By the time ",[39,12857,12858],{},"console.log(typeof greet)",[39,12860,12761],{}," already refers to a callable function, so ",[39,12863,12864],{},"typeof greet",[39,12866,3732],{},", and calling ",[39,12869,12870],{},"greet()"," immediately afterward executes normally even though the call appears above the declaration in the source.",[15,12873,12874,12878,12941,12980],{"language":247},[18,12875,12877],{"id":12876},"q3-what-does-this-log","Q3. What does this log?",[257,12879,12880],{"language":247},[260,12881,12883],{"className":262,"code":12882,"language":247,"meta":264,"style":264},"console.log(typeof sayHi);\nsayHi();\n\nvar sayHi = function () {\n  console.log(\"hi from an expression\");\n};\n",[39,12884,12885,12898,12905,12909,12923,12936],{"__ignoreMap":264},[268,12886,12887,12889,12891,12893,12895],{"class":270,"line":271},[268,12888,1353],{"class":282},[268,12890,1356],{"class":278},[268,12892,622],{"class":282},[268,12894,1361],{"class":274},[268,12896,12897],{"class":282}," sayHi);\n",[268,12899,12900,12903],{"class":270,"line":286},[268,12901,12902],{"class":278},"sayHi",[268,12904,794],{"class":282},[268,12906,12907],{"class":270,"line":296},[268,12908,5033],{"emptyLinePlaceholder":35},[268,12910,12911,12913,12916,12918,12920],{"class":270,"line":311},[268,12912,1440],{"class":274},[268,12914,12915],{"class":278}," sayHi",[268,12917,616],{"class":274},[268,12919,12080],{"class":274},[268,12921,12922],{"class":282}," () {\n",[268,12924,12925,12927,12929,12931,12934],{"class":270,"line":788},[268,12926,5556],{"class":282},[268,12928,1356],{"class":278},[268,12930,622],{"class":282},[268,12932,12933],{"class":289},"\"hi from an expression\"",[268,12935,628],{"class":282},[268,12937,12938],{"class":270,"line":1951},[268,12939,12940],{"class":282},"};\n",[23,12942,12944,12953,12962,12972],{"className":12943},[26],[28,12945,12947,355,12949,1133,12951],{"className":12946},[31],[33,12948],{"disabled":35,"type":36},[39,12950,3732],{},[39,12952,12933],{},[28,12954,12956,355,12958,1133,12960],{"className":12955},[31],[33,12957],{"disabled":35,"type":36},[39,12959,1397],{},[39,12961,12933],{},[28,12963,12965,355,12967,1133,12969],{"className":12964},[31],[33,12966],{"disabled":35,"type":36},[39,12968,1397],{},[39,12970,12971],{},"TypeError: sayHi is not a function",[28,12973,12975,355,12977],{"className":12974},[31],[33,12976],{"disabled":35,"type":36},[39,12978,12979],{},"ReferenceError: sayHi is not defined",[66,12981,12982,12984,12992],{},[69,12983,71],{},[73,12985,12986,1004,12988,1133,12990],{},[76,12987,78],{},[39,12989,1397],{},[39,12991,12971],{},[73,12993,12994,355,12996,12998,12999,13002,13003,13005,13006,1179,13008,830,13011,13013,13014,13017,13018,13020,13021,13023,13024,13026],{},[76,12995,84],{},[76,12997,365],{}," only the ",[39,13000,13001],{},"var sayHi"," declaration is hoisted here, not the function it's assigned — ",[39,13004,1440],{}," bindings are hoisted and pre-initialized to ",[39,13007,833],{},[39,13009,13010],{},"typeof sayHi",[39,13012,1397],{}," at the top. The actual function value isn't attached until the assignment line executes, so calling ",[39,13015,13016],{},"sayHi()"," before that line tries to invoke ",[39,13019,833],{},", throwing a ",[39,13022,827],{},". This is the key contrast with Q2: swapping a declaration for a ",[39,13025,1440],{},"-assigned expression turns \"works before its position\" into a runtime crash.",[15,13028,13029,13033,13095,13136],{"language":247},[18,13030,13032],{"id":13031},"q4-what-does-this-log","Q4. What does this log?",[257,13034,13035],{"language":247},[260,13036,13038],{"className":262,"code":13037,"language":247,"meta":264,"style":264},"function reportStatus() {\n  console.log(status);\n  var status = \"pending\";\n  console.log(status);\n}\n\nreportStatus();\n",[39,13039,13040,13049,13058,13072,13080,13084,13088],{"__ignoreMap":264},[268,13041,13042,13044,13047],{"class":270,"line":271},[268,13043,275],{"class":274},[268,13045,13046],{"class":278}," reportStatus",[268,13048,283],{"class":282},[268,13050,13051,13053,13055],{"class":270,"line":286},[268,13052,5556],{"class":282},[268,13054,1356],{"class":278},[268,13056,13057],{"class":282},"(status);\n",[268,13059,13060,13062,13065,13067,13070],{"class":270,"line":296},[268,13061,2192],{"class":274},[268,13063,13064],{"class":282}," status ",[268,13066,302],{"class":274},[268,13068,13069],{"class":289}," \"pending\"",[268,13071,293],{"class":282},[268,13073,13074,13076,13078],{"class":270,"line":311},[268,13075,5556],{"class":282},[268,13077,1356],{"class":278},[268,13079,13057],{"class":282},[268,13081,13082],{"class":270,"line":788},[268,13083,314],{"class":282},[268,13085,13086],{"class":270,"line":1951},[268,13087,5033],{"emptyLinePlaceholder":35},[268,13089,13090,13093],{"class":270,"line":8955},[268,13091,13092],{"class":278},"reportStatus",[268,13094,794],{"class":282},[23,13096,13098,13108,13118,13127],{"className":13097},[26],[28,13099,13101,355,13103,1133,13106],{"className":13100},[31],[33,13102],{"disabled":35,"type":36},[39,13104,13105],{},"\"pending\"",[39,13107,13105],{},[28,13109,13111,1243,13113,13115,13116],{"className":13110},[31],[33,13112],{"disabled":35,"type":36},[39,13114,815],{}," on the first ",[39,13117,5627],{},[28,13119,13121,355,13123,1133,13125],{"className":13120},[31],[33,13122],{"disabled":35,"type":36},[39,13124,833],{},[39,13126,833],{},[28,13128,13130,355,13132,1133,13134],{"className":13129},[31],[33,13131],{"disabled":35,"type":36},[39,13133,833],{},[39,13135,13105],{},[66,13137,13138,13140,13148],{},[69,13139,71],{},[73,13141,13142,6901,13144,1133,13146],{},[76,13143,78],{},[39,13145,833],{},[39,13147,13105],{},[73,13149,13150,355,13152,13155,13156,13158,13159,13161,13162,13165,13166,13169,13170,13172,13173,13175],{},[76,13151,84],{},[39,13153,13154],{},"var status"," is hoisted to the top of ",[39,13157,13092],{},"'s function body and initialized to ",[39,13160,833],{}," before any code runs, so the first ",[39,13163,13164],{},"console.log(status)"," reads that placeholder value rather than throwing. Only the assignment ",[39,13167,13168],{},"status = \"pending\""," happens where it's textually written, so the second ",[39,13171,5627],{}," sees the updated value. Contrast this with Q5 below, where ",[39,13174,240],{}," behaves very differently for the same shape of code.",[15,13177,13178,13182,13239,13277],{"language":247},[18,13179,13181],{"id":13180},"q5-what-does-this-log","Q5. What does this log?",[257,13183,13184],{"language":247},[260,13185,13187],{"className":262,"code":13186,"language":247,"meta":264,"style":264},"function reportStatus() {\n  console.log(status);\n  let status = \"pending\";\n  console.log(status);\n}\n\nreportStatus();\n",[39,13188,13189,13197,13205,13217,13225,13229,13233],{"__ignoreMap":264},[268,13190,13191,13193,13195],{"class":270,"line":271},[268,13192,275],{"class":274},[268,13194,13046],{"class":278},[268,13196,283],{"class":282},[268,13198,13199,13201,13203],{"class":270,"line":286},[268,13200,5556],{"class":282},[268,13202,1356],{"class":278},[268,13204,13057],{"class":282},[268,13206,13207,13209,13211,13213,13215],{"class":270,"line":296},[268,13208,2206],{"class":274},[268,13210,13064],{"class":282},[268,13212,302],{"class":274},[268,13214,13069],{"class":289},[268,13216,293],{"class":282},[268,13218,13219,13221,13223],{"class":270,"line":311},[268,13220,5556],{"class":282},[268,13222,1356],{"class":278},[268,13224,13057],{"class":282},[268,13226,13227],{"class":270,"line":788},[268,13228,314],{"class":282},[268,13230,13231],{"class":270,"line":1951},[268,13232,5033],{"emptyLinePlaceholder":35},[268,13234,13235,13237],{"class":270,"line":8955},[268,13236,13092],{"class":278},[268,13238,794],{"class":282},[23,13240,13242,13250,13259,13268],{"className":13241},[26],[28,13243,13245,355,13247],{"className":13244},[31],[33,13246],{"disabled":35,"type":36},[39,13248,13249],{},"ReferenceError: Cannot access 'status' before initialization",[28,13251,13253,355,13255,1133,13257],{"className":13252},[31],[33,13254],{"disabled":35,"type":36},[39,13256,833],{},[39,13258,13105],{},[28,13260,13262,355,13264,1133,13266],{"className":13261},[31],[33,13263],{"disabled":35,"type":36},[39,13265,13105],{},[39,13267,13105],{},[28,13269,13271,355,13273,1133,13275],{"className":13270},[31],[33,13272],{"disabled":35,"type":36},[39,13274,833],{},[39,13276,833],{},[66,13278,13279,13281,13287],{},[69,13280,71],{},[73,13282,13283,3459,13285],{},[76,13284,78],{},[39,13286,13249],{},[73,13288,13289,355,13291,355,13293,2338,13295,13297,13298,2586,13300,13302,13303,13306,13307,13309,13310,13312,13313,13315],{},[76,13290,84],{},[76,13292,582],{},[39,13294,240],{},[39,13296,243],{},") bindings are hoisted too, but unlike ",[39,13299,1440],{},[39,13301,833],{}," — they sit in the \"temporal dead zone\" (TDZ) from the top of the block until their declaration line actually runs. Reading ",[39,13304,13305],{},"status"," anywhere in that window throws a ",[39,13308,815],{}," rather than silently returning ",[39,13311,833],{},". This is a deliberate safety improvement over ",[39,13314,1440],{},": it turns an easy-to-miss ordering bug into a loud, immediate failure.",[15,13317,13318,13322,13421,13466],{"language":247},[18,13319,13321],{"id":13320},"q6-what-does-this-log","Q6. What does this log?",[257,13323,13324],{"language":247},[260,13325,13327],{"className":262,"code":13326,"language":247,"meta":264,"style":264},"const factorial = function calc(n) {\n  return n \u003C= 1 ? 1 : n * calc(n - 1);\n};\n\nconsole.log(factorial(5));\nconsole.log(typeof calc);\n",[39,13328,13329,13349,13383,13387,13391,13408],{"__ignoreMap":264},[268,13330,13331,13333,13336,13338,13340,13343,13345,13347],{"class":270,"line":271},[268,13332,243],{"class":274},[268,13334,13335],{"class":278}," factorial",[268,13337,616],{"class":274},[268,13339,12080],{"class":274},[268,13341,13342],{"class":278}," calc",[268,13344,622],{"class":282},[268,13346,4599],{"class":1222},[268,13348,1235],{"class":282},[268,13350,13351,13353,13356,13358,13360,13363,13365,13368,13370,13372,13374,13377,13379,13381],{"class":270,"line":286},[268,13352,1240],{"class":274},[268,13354,13355],{"class":282}," n ",[268,13357,6776],{"class":274},[268,13359,2199],{"class":305},[268,13361,13362],{"class":274}," ?",[268,13364,2199],{"class":305},[268,13366,13367],{"class":274}," :",[268,13369,13355],{"class":282},[268,13371,6134],{"class":274},[268,13373,13342],{"class":278},[268,13375,13376],{"class":282},"(n ",[268,13378,6244],{"class":274},[268,13380,2199],{"class":305},[268,13382,628],{"class":282},[268,13384,13385],{"class":270,"line":296},[268,13386,12940],{"class":282},[268,13388,13389],{"class":270,"line":311},[268,13390,5033],{"emptyLinePlaceholder":35},[268,13392,13393,13395,13397,13399,13402,13404,13406],{"class":270,"line":788},[268,13394,1353],{"class":282},[268,13396,1356],{"class":278},[268,13398,622],{"class":282},[268,13400,13401],{"class":278},"factorial",[268,13403,622],{"class":282},[268,13405,2429],{"class":305},[268,13407,4818],{"class":282},[268,13409,13410,13412,13414,13416,13418],{"class":270,"line":1951},[268,13411,1353],{"class":282},[268,13413,1356],{"class":278},[268,13415,622],{"class":282},[268,13417,1361],{"class":274},[268,13419,13420],{"class":282}," calc);\n",[23,13422,13424,13434,13443,13455],{"className":13423},[26],[28,13425,13427,355,13429,1133,13432],{"className":13426},[31],[33,13428],{"disabled":35,"type":36},[39,13430,13431],{},"120",[39,13433,3732],{},[28,13435,13437,355,13439,1133,13441],{"className":13436},[31],[33,13438],{"disabled":35,"type":36},[39,13440,13431],{},[39,13442,1397],{},[28,13444,13446,1243,13448,13450,13451,13454],{"className":13445},[31],[33,13447],{"disabled":35,"type":36},[39,13449,815],{}," on the ",[39,13452,13453],{},"factorial(5)"," call",[28,13456,13458,355,13460,13462,13463],{"className":13457},[31],[33,13459],{"disabled":35,"type":36},[39,13461,13431],{}," then it throws ",[39,13464,13465],{},"ReferenceError: calc is not defined",[66,13467,13468,13470,13478],{},[69,13469,71],{},[73,13471,13472,1727,13474,1133,13476],{},[76,13473,78],{},[39,13475,13431],{},[39,13477,1397],{},[73,13479,13480,2436,13482,13485,13486,13489,13490,13492,13493,13495,13496,13498,13499,13501,13502,13505,13506,3990,13508,13510,13511,13513,13514,13516,13517,13520,13521,6232],{},[76,13481,84],{},[104,13483,13484],{},"named function expression",": the name ",[39,13487,13488],{},"calc"," is bound only inside the function's own body (useful for recursion), it is never added to the enclosing scope. So ",[39,13491,13453],{}," works fine and recurses via ",[39,13494,13488],{}," internally, correctly producing ",[39,13497,13431],{},". But outside, ",[39,13500,13488],{}," was never declared, so ",[39,13503,13504],{},"typeof calc"," safely evaluates to ",[39,13507,1397],{},[39,13509,1361],{}," never throws on an unresolvable identifier, it only returns ",[39,13512,1397],{},", unlike directly referencing ",[39,13515,13488],{}," (which ",[104,13518,13519],{},"would"," throw a ",[39,13522,815],{},[15,13524,13525,13529,13645,13678],{"language":247},[18,13526,13528],{"id":13527},"q7-what-does-this-log","Q7. What does this log?",[257,13530,13531],{"language":247},[260,13532,13534],{"className":262,"code":13533,"language":247,"meta":264,"style":264},"let compute = function run(n) {\n  if (n \u003C= 0) return 0;\n  return n + run(n - 1);\n};\n\nconst backup = compute;\ncompute = null;\n\nconsole.log(backup(3));\n",[39,13535,13536,13556,13575,13593,13597,13601,13613,13624,13628],{"__ignoreMap":264},[268,13537,13538,13540,13543,13545,13547,13550,13552,13554],{"class":270,"line":271},[268,13539,240],{"class":274},[268,13541,13542],{"class":278}," compute",[268,13544,616],{"class":274},[268,13546,12080],{"class":274},[268,13548,13549],{"class":278}," run",[268,13551,622],{"class":282},[268,13553,4599],{"class":1222},[268,13555,1235],{"class":282},[268,13557,13558,13560,13563,13565,13567,13569,13571,13573],{"class":270,"line":286},[268,13559,9863],{"class":274},[268,13561,13562],{"class":282}," (n ",[268,13564,6776],{"class":274},[268,13566,5728],{"class":305},[268,13568,6131],{"class":282},[268,13570,9151],{"class":274},[268,13572,5728],{"class":305},[268,13574,293],{"class":282},[268,13576,13577,13579,13581,13583,13585,13587,13589,13591],{"class":270,"line":296},[268,13578,1240],{"class":274},[268,13580,13355],{"class":282},[268,13582,1246],{"class":274},[268,13584,13549],{"class":278},[268,13586,13376],{"class":282},[268,13588,6244],{"class":274},[268,13590,2199],{"class":305},[268,13592,628],{"class":282},[268,13594,13595],{"class":270,"line":311},[268,13596,12940],{"class":282},[268,13598,13599],{"class":270,"line":788},[268,13600,5033],{"emptyLinePlaceholder":35},[268,13602,13603,13605,13608,13610],{"class":270,"line":1951},[268,13604,243],{"class":274},[268,13606,13607],{"class":305}," backup",[268,13609,616],{"class":274},[268,13611,13612],{"class":282}," compute;\n",[268,13614,13615,13618,13620,13622],{"class":270,"line":8955},[268,13616,13617],{"class":282},"compute ",[268,13619,302],{"class":274},[268,13621,4794],{"class":305},[268,13623,293],{"class":282},[268,13625,13626],{"class":270,"line":8966},[268,13627,5033],{"emptyLinePlaceholder":35},[268,13629,13630,13632,13634,13636,13639,13641,13643],{"class":270,"line":8974},[268,13631,1353],{"class":282},[268,13633,1356],{"class":278},[268,13635,622],{"class":282},[268,13637,13638],{"class":278},"backup",[268,13640,622],{"class":282},[268,13642,3423],{"class":305},[268,13644,4818],{"class":282},[23,13646,13648,13656,13664,13671],{"className":13647},[26],[28,13649,13651,355,13653],{"className":13650},[31],[33,13652],{"disabled":35,"type":36},[39,13654,13655],{},"TypeError: run is not a function",[28,13657,13659,355,13661],{"className":13658},[31],[33,13660],{"disabled":35,"type":36},[39,13662,13663],{},"6",[28,13665,13667,355,13669],{"className":13666},[31],[33,13668],{"disabled":35,"type":36},[39,13670,2650],{},[28,13672,13674,355,13676],{"className":13673},[31],[33,13675],{"disabled":35,"type":36},[39,13677,3307],{},[66,13679,13680,13682,13688],{},[69,13681,71],{},[73,13683,13684,1727,13686],{},[76,13685,78],{},[39,13687,13663],{},[73,13689,13690,12848,13692,358,13695,13698,13699,13702,13703,13705,13706,13709,13710,13712,13713,13715,13716,13719,13720,13723],{},[76,13691,84],{},[39,13693,13694],{},"compute",[104,13696,13697],{},"named"," function expression, the recursive calls inside its body reference the stable internal name ",[39,13700,13701],{},"run",", not the outer ",[39,13704,13694],{}," variable. Reassigning ",[39,13707,13708],{},"compute = null"," has no effect on what ",[39,13711,13701],{}," points to inside the function — ",[39,13714,13701],{}," always refers back to the function itself. So ",[39,13717,13718],{},"backup(3)"," still recurses correctly: ",[39,13721,13722],{},"3 + 2 + 1 + 0 = 6",". This is exactly why named function expressions are the safer choice for recursion over relying on an outer, reassignable binding.",[15,13725,13726,13730,13840,13880],{"language":247},[18,13727,13729],{"id":13728},"q8-what-does-this-log","Q8. What does this log?",[257,13731,13732],{"language":247},[260,13733,13735],{"className":262,"code":13734,"language":247,"meta":264,"style":264},"let count = 10;\n\nfunction addCount(base, extra = count) {\n  return base + extra;\n}\n\nconsole.log(addCount(1));\ncount = 100;\nconsole.log(addCount(1));\n",[39,13736,13737,13749,13753,13775,13787,13791,13795,13812,13824],{"__ignoreMap":264},[268,13738,13739,13741,13743,13745,13747],{"class":270,"line":271},[268,13740,240],{"class":274},[268,13742,10091],{"class":282},[268,13744,302],{"class":274},[268,13746,306],{"class":305},[268,13748,293],{"class":282},[268,13750,13751],{"class":270,"line":286},[268,13752,5033],{"emptyLinePlaceholder":35},[268,13754,13755,13757,13760,13762,13765,13767,13770,13772],{"class":270,"line":296},[268,13756,275],{"class":274},[268,13758,13759],{"class":278}," addCount",[268,13761,622],{"class":282},[268,13763,13764],{"class":1222},"base",[268,13766,42],{"class":282},[268,13768,13769],{"class":1222},"extra",[268,13771,616],{"class":274},[268,13773,13774],{"class":282}," count) {\n",[268,13776,13777,13779,13782,13784],{"class":270,"line":311},[268,13778,1240],{"class":274},[268,13780,13781],{"class":282}," base ",[268,13783,1246],{"class":274},[268,13785,13786],{"class":282}," extra;\n",[268,13788,13789],{"class":270,"line":788},[268,13790,314],{"class":282},[268,13792,13793],{"class":270,"line":1951},[268,13794,5033],{"emptyLinePlaceholder":35},[268,13796,13797,13799,13801,13803,13806,13808,13810],{"class":270,"line":8955},[268,13798,1353],{"class":282},[268,13800,1356],{"class":278},[268,13802,622],{"class":282},[268,13804,13805],{"class":278},"addCount",[268,13807,622],{"class":282},[268,13809,2255],{"class":305},[268,13811,4818],{"class":282},[268,13813,13814,13817,13819,13822],{"class":270,"line":8966},[268,13815,13816],{"class":282},"count ",[268,13818,302],{"class":274},[268,13820,13821],{"class":305}," 100",[268,13823,293],{"class":282},[268,13825,13826,13828,13830,13832,13834,13836,13838],{"class":270,"line":8974},[268,13827,1353],{"class":282},[268,13829,1356],{"class":278},[268,13831,622],{"class":282},[268,13833,13805],{"class":278},[268,13835,622],{"class":282},[268,13837,2255],{"class":305},[268,13839,4818],{"class":282},[23,13841,13843,13852,13862,13871],{"className":13842},[26],[28,13844,13846,355,13848,1133,13850],{"className":13845},[31],[33,13847],{"disabled":35,"type":36},[39,13849,6879],{},[39,13851,6879],{},[28,13853,13855,355,13857,1133,13860],{"className":13854},[31],[33,13856],{"disabled":35,"type":36},[39,13858,13859],{},"101",[39,13861,13859],{},[28,13863,13865,355,13867,1133,13869],{"className":13864},[31],[33,13866],{"disabled":35,"type":36},[39,13868,3040],{},[39,13870,3040],{},[28,13872,13874,355,13876,1133,13878],{"className":13873},[31],[33,13875],{"disabled":35,"type":36},[39,13877,6879],{},[39,13879,13859],{},[66,13881,13882,13884,13892],{},[69,13883,71],{},[73,13885,13886,6901,13888,1133,13890],{},[76,13887,78],{},[39,13889,6879],{},[39,13891,13859],{},[73,13893,13894,355,13896,13898,13899,2182,13901,6588,13903,13906,13907,13909,13910,13913,13914,13917,13918,13921],{},[76,13895,84],{},[76,13897,365],{}," a default parameter expression is not evaluated once and cached when the function is defined — it's re-evaluated fresh every time the function is called with that argument omitted. The first call reads the current ",[39,13900,10191],{},[39,13902,5825],{},[39,13904,13905],{},"1 + 10 = 11",". After ",[39,13908,10191],{}," is reassigned to ",[39,13911,13912],{},"100",", the second call re-evaluates ",[39,13915,13916],{},"extra = count"," and picks up the new value, giving ",[39,13919,13920],{},"1 + 100 = 101",". Treating default values as \"baked in once\" is a common but incorrect assumption.",[15,13923,13924,13928,14014,14049],{"language":247},[18,13925,13927],{"id":13926},"q9-what-does-this-log","Q9. What does this log?",[257,13929,13930],{"language":247},[260,13931,13933],{"className":262,"code":13932,"language":247,"meta":264,"style":264},"function createRange(start, end = start + 10, step = (end - start) \u002F 5) {\n  return { start, end, step };\n}\n\nconsole.log(createRange(0));\n",[39,13934,13935,13982,13989,13993,13997],{"__ignoreMap":264},[268,13936,13937,13939,13942,13944,13947,13949,13952,13954,13957,13959,13961,13963,13966,13968,13971,13973,13976,13978,13980],{"class":270,"line":271},[268,13938,275],{"class":274},[268,13940,13941],{"class":278}," createRange",[268,13943,622],{"class":282},[268,13945,13946],{"class":1222},"start",[268,13948,42],{"class":282},[268,13950,13951],{"class":1222},"end",[268,13953,616],{"class":274},[268,13955,13956],{"class":282}," start ",[268,13958,1246],{"class":274},[268,13960,306],{"class":305},[268,13962,42],{"class":282},[268,13964,13965],{"class":1222},"step",[268,13967,616],{"class":274},[268,13969,13970],{"class":282}," (end ",[268,13972,6244],{"class":274},[268,13974,13975],{"class":282}," start) ",[268,13977,446],{"class":274},[268,13979,2387],{"class":305},[268,13981,1235],{"class":282},[268,13983,13984,13986],{"class":270,"line":286},[268,13985,1240],{"class":274},[268,13987,13988],{"class":282}," { start, end, step };\n",[268,13990,13991],{"class":270,"line":296},[268,13992,314],{"class":282},[268,13994,13995],{"class":270,"line":311},[268,13996,5033],{"emptyLinePlaceholder":35},[268,13998,13999,14001,14003,14005,14008,14010,14012],{"class":270,"line":788},[268,14000,1353],{"class":282},[268,14002,1356],{"class":278},[268,14004,622],{"class":282},[268,14006,14007],{"class":278},"createRange",[268,14009,622],{"class":282},[268,14011,3307],{"class":305},[268,14013,4818],{"class":282},[23,14015,14017,14025,14033,14041],{"className":14016},[26],[28,14018,14020,355,14022],{"className":14019},[31],[33,14021],{"disabled":35,"type":36},[39,14023,14024],{},"{ start: 0, end: 10, step: 2 }",[28,14026,14028,355,14030],{"className":14027},[31],[33,14029],{"disabled":35,"type":36},[39,14031,14032],{},"{ start: 0, end: undefined, step: NaN }",[28,14034,14036,355,14038],{"className":14035},[31],[33,14037],{"disabled":35,"type":36},[39,14039,14040],{},"ReferenceError: Cannot access 'end' before initialization",[28,14042,14044,355,14046],{"className":14043},[31],[33,14045],{"disabled":35,"type":36},[39,14047,14048],{},"{ start: 0, end: 10, step: undefined }",[66,14050,14051,14053,14059],{},[69,14052,71],{},[73,14054,14055,3459,14057],{},[76,14056,78],{},[39,14058,14024],{},[73,14060,14061,14063,14064,4001,14066,14069,14070,14072,14073,186,14075,14077,14078,14081,14082,14084],{},[76,14062,84],{}," Default parameters are evaluated left to right, and each one can freely reference any parameter to its left that has already been initialized. ",[39,14065,13951],{},[39,14067,14068],{},"start + 10 = 10",", and by the time ",[39,14071,13965],{},"'s default runs, both ",[39,14074,13946],{},[39,14076,13951],{}," are already initialized, so ",[39,14079,14080],{},"step = (10 - 0) \u002F 5 = 2",". This only works in this left-to-right direction — see Q10 for what happens when a default tries to reference a parameter declared ",[104,14083,1747],{}," it.",[15,14086,14087,14091,14158,14190],{"language":247},[18,14088,14090],{"id":14089},"q10-what-happens-when-this-runs","Q10. What happens when this runs?",[257,14092,14093],{"language":247},[260,14094,14096],{"className":262,"code":14095,"language":247,"meta":264,"style":264},"function build(a = b + 1, b = 5) {\n  return a + b;\n}\n\nconsole.log(build());\n",[39,14097,14098,14127,14137,14141,14145],{"__ignoreMap":264},[268,14099,14100,14102,14105,14107,14109,14111,14113,14115,14117,14119,14121,14123,14125],{"class":270,"line":271},[268,14101,275],{"class":274},[268,14103,14104],{"class":278}," build",[268,14106,622],{"class":282},[268,14108,1223],{"class":1222},[268,14110,616],{"class":274},[268,14112,2209],{"class":282},[268,14114,1246],{"class":274},[268,14116,2199],{"class":305},[268,14118,42],{"class":282},[268,14120,1232],{"class":1222},[268,14122,616],{"class":274},[268,14124,2387],{"class":305},[268,14126,1235],{"class":282},[268,14128,14129,14131,14133,14135],{"class":270,"line":286},[268,14130,1240],{"class":274},[268,14132,1243],{"class":282},[268,14134,1246],{"class":274},[268,14136,1249],{"class":282},[268,14138,14139],{"class":270,"line":296},[268,14140,314],{"class":282},[268,14142,14143],{"class":270,"line":311},[268,14144,5033],{"emptyLinePlaceholder":35},[268,14146,14147,14149,14151,14153,14156],{"class":270,"line":788},[268,14148,1353],{"class":282},[268,14150,1356],{"class":278},[268,14152,622],{"class":282},[268,14154,14155],{"class":278},"build",[268,14157,8174],{"class":282},[23,14159,14161,14168,14176,14183],{"className":14160},[26],[28,14162,14164,3578,14166],{"className":14163},[31],[33,14165],{"disabled":35,"type":36},[39,14167,13663],{},[28,14169,14171,6738,14173],{"className":14170},[31],[33,14172],{"disabled":35,"type":36},[39,14174,14175],{},"ReferenceError: Cannot access 'b' before initialization",[28,14177,14179,3578,14181],{"className":14178},[31],[33,14180],{"disabled":35,"type":36},[39,14182,3040],{},[28,14184,14186,3578,14188],{"className":14185},[31],[33,14187],{"disabled":35,"type":36},[39,14189,6879],{},[66,14191,14192,14194,14201],{},[69,14193,71],{},[73,14195,14196,14198,14199],{},[76,14197,78],{}," B — Throws ",[39,14200,14175],{},[73,14202,14203,355,14205,14207,14208,14210,14211,14213,14214,42,14216,14218],{},[76,14204,84],{},[76,14206,582],{}," parameters form their own scope, evaluated in declaration order, and each parameter sits in a temporal dead zone until its own initialization runs — just like ",[39,14209,240],{}," inside a block. When ",[39,14212,1223],{},"'s default tries to read ",[39,14215,1232],{},[39,14217,1232],{}," hasn't been initialized yet, so it's still in the TDZ and the read throws. Defaults are not hoisted or resolved out of order; they only work looking backward at already-initialized parameters (Q9), never forward.",[15,14220,14221,14225,14304,14339],{"language":247},[18,14222,14224],{"id":14223},"q11-what-does-this-log","Q11. What does this log?",[257,14226,14227],{"language":247},[260,14228,14230],{"className":262,"code":14229,"language":247,"meta":264,"style":264},"function connect(host, port = 8080) {\n  return `${host}:${port}`;\n}\n\nconsole.log(connect(\"db\", null));\n",[39,14231,14232,14256,14274,14278,14282],{"__ignoreMap":264},[268,14233,14234,14236,14239,14241,14244,14246,14249,14251,14254],{"class":270,"line":271},[268,14235,275],{"class":274},[268,14237,14238],{"class":278}," connect",[268,14240,622],{"class":282},[268,14242,14243],{"class":1222},"host",[268,14245,42],{"class":282},[268,14247,14248],{"class":1222},"port",[268,14250,616],{"class":274},[268,14252,14253],{"class":305}," 8080",[268,14255,1235],{"class":282},[268,14257,14258,14260,14263,14265,14268,14270,14272],{"class":270,"line":286},[268,14259,1240],{"class":274},[268,14261,14262],{"class":289}," `${",[268,14264,14243],{"class":282},[268,14266,14267],{"class":289},"}:${",[268,14269,14248],{"class":282},[268,14271,11603],{"class":289},[268,14273,293],{"class":282},[268,14275,14276],{"class":270,"line":296},[268,14277,314],{"class":282},[268,14279,14280],{"class":270,"line":311},[268,14281,5033],{"emptyLinePlaceholder":35},[268,14283,14284,14286,14288,14290,14293,14295,14298,14300,14302],{"class":270,"line":788},[268,14285,1353],{"class":282},[268,14287,1356],{"class":278},[268,14289,622],{"class":282},[268,14291,14292],{"class":278},"connect",[268,14294,622],{"class":282},[268,14296,14297],{"class":289},"\"db\"",[268,14299,42],{"class":282},[268,14301,2650],{"class":305},[268,14303,4818],{"class":282},[23,14305,14307,14315,14323,14331],{"className":14306},[26],[28,14308,14310,355,14312],{"className":14309},[31],[33,14311],{"disabled":35,"type":36},[39,14313,14314],{},"\"db:8080\"",[28,14316,14318,355,14320],{"className":14317},[31],[33,14319],{"disabled":35,"type":36},[39,14321,14322],{},"\"db:undefined\"",[28,14324,14326,355,14328],{"className":14325},[31],[33,14327],{"disabled":35,"type":36},[39,14329,14330],{},"\"db:null\"",[28,14332,14334,355,14336],{"className":14333},[31],[33,14335],{"disabled":35,"type":36},[39,14337,14338],{},"TypeError: cannot use null as port",[66,14340,14341,14343,14349],{},[69,14342,71],{},[73,14344,14345,1004,14347],{},[76,14346,78],{},[39,14348,14330],{},[73,14350,14351,355,14353,14355,14356,14358,14359,14361,14362,14364,14365,14367,14368,14371,14372,5425,14374,14376],{},[76,14352,84],{},[76,14354,365],{}," default parameters only kick in when the argument is exactly ",[39,14357,833],{}," (including simply being omitted) — not for any other \"empty-ish\" value. ",[39,14360,2650],{}," is a perfectly valid, explicitly passed value, so ",[39,14363,14248],{}," is set to ",[39,14366,2650],{}," and the default ",[39,14369,14370],{},"8080"," is never used; the template literal then stringifies ",[39,14373,2650],{},[39,14375,14330],{},". This is a common trap for anyone assuming defaults behave like a general null-coalescing fallback.",[15,14378,14379,14383,14459,14493],{"language":247},[18,14380,14382],{"id":14381},"q12-what-does-this-log","Q12. What does this log?",[257,14384,14385],{"language":247},[260,14386,14388],{"className":262,"code":14387,"language":247,"meta":264,"style":264},"function createTimer(label, retries = 3) {\n  return `${label} retries=${retries}`;\n}\n\nconsole.log(createTimer(\"job\", 0));\n",[39,14389,14390,14412,14429,14433,14437],{"__ignoreMap":264},[268,14391,14392,14394,14397,14399,14402,14404,14406,14408,14410],{"class":270,"line":271},[268,14393,275],{"class":274},[268,14395,14396],{"class":278}," createTimer",[268,14398,622],{"class":282},[268,14400,14401],{"class":1222},"label",[268,14403,42],{"class":282},[268,14405,7423],{"class":1222},[268,14407,616],{"class":274},[268,14409,3396],{"class":305},[268,14411,1235],{"class":282},[268,14413,14414,14416,14418,14420,14423,14425,14427],{"class":270,"line":286},[268,14415,1240],{"class":274},[268,14417,14262],{"class":289},[268,14419,14401],{"class":282},[268,14421,14422],{"class":289},"} retries=${",[268,14424,7423],{"class":282},[268,14426,11603],{"class":289},[268,14428,293],{"class":282},[268,14430,14431],{"class":270,"line":296},[268,14432,314],{"class":282},[268,14434,14435],{"class":270,"line":311},[268,14436,5033],{"emptyLinePlaceholder":35},[268,14438,14439,14441,14443,14445,14448,14450,14453,14455,14457],{"class":270,"line":788},[268,14440,1353],{"class":282},[268,14442,1356],{"class":278},[268,14444,622],{"class":282},[268,14446,14447],{"class":278},"createTimer",[268,14449,622],{"class":282},[268,14451,14452],{"class":289},"\"job\"",[268,14454,42],{"class":282},[268,14456,3307],{"class":305},[268,14458,4818],{"class":282},[23,14460,14462,14470,14478,14485],{"className":14461},[26],[28,14463,14465,355,14467],{"className":14464},[31],[33,14466],{"disabled":35,"type":36},[39,14468,14469],{},"\"job retries=3\"",[28,14471,14473,355,14475],{"className":14472},[31],[33,14474],{"disabled":35,"type":36},[39,14476,14477],{},"\"job retries=NaN\"",[28,14479,14481,355,14483],{"className":14480},[31],[33,14482],{"disabled":35,"type":36},[39,14484,827],{},[28,14486,14488,355,14490],{"className":14487},[31],[33,14489],{"disabled":35,"type":36},[39,14491,14492],{},"\"job retries=0\"",[66,14494,14495,14497,14503],{},[69,14496,71],{},[73,14498,14499,6901,14501],{},[76,14500,78],{},[39,14502,14492],{},[73,14504,14505,355,14507,14509,14510,14512,14513,14515,14516,14518,14519,14522,14523,14525,14526,7255,14528,383,14530,14532],{},[76,14506,84],{},[76,14508,365],{}," default parameters check specifically for ",[39,14511,833],{},", not general falsiness. ",[39,14514,3307],{}," is a legitimate, explicitly passed argument, so it's kept as-is and ",[39,14517,3423],{}," is never substituted. This is the crucial difference from the common ",[39,14520,14521],{},"retries = retries || 3"," fallback idiom, which ",[104,14524,13519],{}," incorrectly replace a passed ",[39,14527,3307],{},[39,14529,3294],{},[39,14531,2986],{},") with the fallback — a classic source of bugs when zero is a meaningful value.",[15,14534,14535,14539,14689,14720],{"language":247},[18,14536,14538],{"id":14537},"q13-what-does-this-log","Q13. What does this log?",[257,14540,14541],{"language":247},[260,14542,14544],{"className":262,"code":14543,"language":247,"meta":264,"style":264},"let calls = 0;\nfunction nextId() {\n  calls += 1;\n  return calls;\n}\n\nfunction createUser(name, id = nextId()) {\n  return { name, id };\n}\n\ncreateUser(\"alice\", 5);\ncreateUser(\"bob\");\ncreateUser(\"carol\", 9);\n\nconsole.log(calls);\n",[39,14545,14546,14559,14568,14580,14587,14591,14595,14618,14625,14629,14633,14648,14659,14674,14679],{"__ignoreMap":264},[268,14547,14548,14550,14553,14555,14557],{"class":270,"line":271},[268,14549,240],{"class":274},[268,14551,14552],{"class":282}," calls ",[268,14554,302],{"class":274},[268,14556,5728],{"class":305},[268,14558,293],{"class":282},[268,14560,14561,14563,14566],{"class":270,"line":286},[268,14562,275],{"class":274},[268,14564,14565],{"class":278}," nextId",[268,14567,283],{"class":282},[268,14569,14570,14573,14576,14578],{"class":270,"line":296},[268,14571,14572],{"class":282},"  calls ",[268,14574,14575],{"class":274},"+=",[268,14577,2199],{"class":305},[268,14579,293],{"class":282},[268,14581,14582,14584],{"class":270,"line":311},[268,14583,1240],{"class":274},[268,14585,14586],{"class":282}," calls;\n",[268,14588,14589],{"class":270,"line":788},[268,14590,314],{"class":282},[268,14592,14593],{"class":270,"line":1951},[268,14594,5033],{"emptyLinePlaceholder":35},[268,14596,14597,14599,14601,14603,14606,14608,14611,14613,14615],{"class":270,"line":8955},[268,14598,275],{"class":274},[268,14600,7886],{"class":278},[268,14602,622],{"class":282},[268,14604,14605],{"class":1222},"name",[268,14607,42],{"class":282},[268,14609,14610],{"class":1222},"id",[268,14612,616],{"class":274},[268,14614,14565],{"class":278},[268,14616,14617],{"class":282},"()) {\n",[268,14619,14620,14622],{"class":270,"line":8966},[268,14621,1240],{"class":274},[268,14623,14624],{"class":282}," { name, id };\n",[268,14626,14627],{"class":270,"line":8974},[268,14628,314],{"class":282},[268,14630,14631],{"class":270,"line":8985},[268,14632,5033],{"emptyLinePlaceholder":35},[268,14634,14635,14637,14639,14642,14644,14646],{"class":270,"line":8990},[268,14636,7983],{"class":278},[268,14638,622],{"class":282},[268,14640,14641],{"class":289},"\"alice\"",[268,14643,42],{"class":282},[268,14645,2429],{"class":305},[268,14647,628],{"class":282},[268,14649,14650,14652,14654,14657],{"class":270,"line":8997},[268,14651,7983],{"class":278},[268,14653,622],{"class":282},[268,14655,14656],{"class":289},"\"bob\"",[268,14658,628],{"class":282},[268,14660,14661,14663,14665,14668,14670,14672],{"class":270,"line":9002},[268,14662,7983],{"class":278},[268,14664,622],{"class":282},[268,14666,14667],{"class":289},"\"carol\"",[268,14669,42],{"class":282},[268,14671,6360],{"class":305},[268,14673,628],{"class":282},[268,14675,14677],{"class":270,"line":14676},14,[268,14678,5033],{"emptyLinePlaceholder":35},[268,14680,14682,14684,14686],{"class":270,"line":14681},15,[268,14683,1353],{"class":282},[268,14685,1356],{"class":278},[268,14687,14688],{"class":282},"(calls);\n",[23,14690,14692,14699,14706,14713],{"className":14691},[26],[28,14693,14695,355,14697],{"className":14694},[31],[33,14696],{"disabled":35,"type":36},[39,14698,2255],{},[28,14700,14702,355,14704],{"className":14701},[31],[33,14703],{"disabled":35,"type":36},[39,14705,3423],{},[28,14707,14709,355,14711],{"className":14708},[31],[33,14710],{"disabled":35,"type":36},[39,14712,3307],{},[28,14714,14716,355,14718],{"className":14715},[31],[33,14717],{"disabled":35,"type":36},[39,14719,2258],{},[66,14721,14722,14724,14730],{},[69,14723,71],{},[73,14725,14726,3459,14728],{},[76,14727,78],{},[39,14729,2255],{},[73,14731,14732,14734,14735,14738,14739,10819,14741,186,14744,14747,14748,1179,14750,14752,14753,14756,14757,14759,14760,9138,14762,14765,14766,14768],{},[76,14733,84],{}," A default parameter expression — including a function call like ",[39,14736,14737],{},"nextId()"," — only runs when its argument is actually omitted (or explicitly ",[39,14740,833],{},[39,14742,14743],{},"createUser(\"alice\", 5)",[39,14745,14746],{},"createUser(\"carol\", 9)"," both pass an explicit ",[39,14749,14610],{},[39,14751,14737],{}," never executes for them. Only ",[39,14754,14755],{},"createUser(\"bob\")"," omits ",[39,14758,14610],{},", triggering exactly one call to ",[39,14761,14737],{},[39,14763,14764],{},"calls"," at ",[39,14767,2255],{},". This side-effect timing is easy to get wrong if you assume the default expression runs on every invocation regardless of whether it's needed.",[15,14770,14771,14775,14862,14903],{"language":247},[18,14772,14774],{"id":14773},"q14-what-does-this-log","Q14. What does this log?",[257,14776,14777],{"language":247},[260,14778,14780],{"className":262,"code":14779,"language":247,"meta":264,"style":264},"function addItem(item, cart = []) {\n  cart.push(item);\n  return cart;\n}\n\nconsole.log(addItem(\"apple\"));\nconsole.log(addItem(\"banana\"));\n",[39,14781,14782,14803,14812,14819,14823,14827,14845],{"__ignoreMap":264},[268,14783,14784,14786,14789,14791,14794,14796,14798,14800],{"class":270,"line":271},[268,14785,275],{"class":274},[268,14787,14788],{"class":278}," addItem",[268,14790,622],{"class":282},[268,14792,14793],{"class":1222},"item",[268,14795,42],{"class":282},[268,14797,8318],{"class":1222},[268,14799,616],{"class":274},[268,14801,14802],{"class":282}," []) {\n",[268,14804,14805,14808,14810],{"class":270,"line":286},[268,14806,14807],{"class":282},"  cart.",[268,14809,12499],{"class":278},[268,14811,11808],{"class":282},[268,14813,14814,14816],{"class":270,"line":296},[268,14815,1240],{"class":274},[268,14817,14818],{"class":282}," cart;\n",[268,14820,14821],{"class":270,"line":311},[268,14822,314],{"class":282},[268,14824,14825],{"class":270,"line":788},[268,14826,5033],{"emptyLinePlaceholder":35},[268,14828,14829,14831,14833,14835,14838,14840,14843],{"class":270,"line":1951},[268,14830,1353],{"class":282},[268,14832,1356],{"class":278},[268,14834,622],{"class":282},[268,14836,14837],{"class":278},"addItem",[268,14839,622],{"class":282},[268,14841,14842],{"class":289},"\"apple\"",[268,14844,4818],{"class":282},[268,14846,14847,14849,14851,14853,14855,14857,14860],{"class":270,"line":8955},[268,14848,1353],{"class":282},[268,14850,1356],{"class":278},[268,14852,622],{"class":282},[268,14854,14837],{"class":278},[268,14856,622],{"class":282},[268,14858,14859],{"class":289},"\"banana\"",[268,14861,4818],{"class":282},[23,14863,14865,14876,14886,14895],{"className":14864},[26],[28,14866,14868,355,14870,1133,14873],{"className":14867},[31],[33,14869],{"disabled":35,"type":36},[39,14871,14872],{},"[\"apple\"]",[39,14874,14875],{},"[\"apple\", \"banana\"]",[28,14877,14879,355,14881,1133,14883],{"className":14878},[31],[33,14880],{"disabled":35,"type":36},[39,14882,14872],{},[39,14884,14885],{},"[\"banana\"]",[28,14887,14889,355,14891,1133,14893],{"className":14888},[31],[33,14890],{"disabled":35,"type":36},[39,14892,14875],{},[39,14894,14875],{},[28,14896,14898,355,14900],{"className":14897},[31],[33,14899],{"disabled":35,"type":36},[39,14901,14902],{},"TypeError: cart is not extensible",[66,14904,14905,14907,14915],{},[69,14906,71],{},[73,14908,14909,1727,14911,1133,14913],{},[76,14910,78],{},[39,14912,14872],{},[39,14914,14885],{},[73,14916,14917,355,14919,14921,14922,14925,14926,14928],{},[76,14918,84],{},[76,14920,930],{}," unlike Python's infamous mutable-default-argument footgun (where a default ",[39,14923,14924],{},"list"," is created once and reused across every call), JavaScript re-evaluates a default parameter expression fresh every time it's needed. Each call that omits ",[39,14927,8318],{}," gets its own brand-new empty array — nothing accumulates or leaks between calls. Option A is exactly the Python-style behavior a learner might expect, but it does not happen in JavaScript.",[15,14930,14931,14935,15039,15072],{"language":247},[18,14932,14934],{"id":14933},"q15-what-happens-when-this-runs","Q15. What happens when this runs?",[257,14936,14937],{"language":247},[260,14938,14940],{"className":262,"code":14939,"language":247,"meta":264,"style":264},"function sumAll() {\n  return arguments.filter(n => n > 0).reduce((a, b) => a + b, 0);\n}\n\nconsole.log(sumAll(1, -2, 3));\n",[39,14941,14942,14951,15004,15008,15012],{"__ignoreMap":264},[268,14943,14944,14946,14949],{"class":270,"line":271},[268,14945,275],{"class":274},[268,14947,14948],{"class":278}," sumAll",[268,14950,283],{"class":282},[268,14952,14953,14955,14958,14960,14963,14965,14967,14970,14972,14974,14976,14978,14981,14983,14985,14987,14989,14991,14993,14995,14997,15000,15002],{"class":270,"line":286},[268,14954,1240],{"class":274},[268,14956,14957],{"class":305}," arguments",[268,14959,462],{"class":282},[268,14961,14962],{"class":278},"filter",[268,14964,622],{"class":282},[268,14966,4599],{"class":1222},[268,14968,14969],{"class":274}," =>",[268,14971,13355],{"class":282},[268,14973,6435],{"class":274},[268,14975,5728],{"class":305},[268,14977,6232],{"class":282},[268,14979,14980],{"class":278},"reduce",[268,14982,6122],{"class":282},[268,14984,1223],{"class":1222},[268,14986,42],{"class":282},[268,14988,1232],{"class":1222},[268,14990,6131],{"class":282},[268,14992,9414],{"class":274},[268,14994,1243],{"class":282},[268,14996,1246],{"class":274},[268,14998,14999],{"class":282}," b, ",[268,15001,3307],{"class":305},[268,15003,628],{"class":282},[268,15005,15006],{"class":270,"line":296},[268,15007,314],{"class":282},[268,15009,15010],{"class":270,"line":311},[268,15011,5033],{"emptyLinePlaceholder":35},[268,15013,15014,15016,15018,15020,15023,15025,15027,15029,15031,15033,15035,15037],{"class":270,"line":788},[268,15015,1353],{"class":282},[268,15017,1356],{"class":278},[268,15019,622],{"class":282},[268,15021,15022],{"class":278},"sumAll",[268,15024,622],{"class":282},[268,15026,2255],{"class":305},[268,15028,42],{"class":282},[268,15030,6244],{"class":274},[268,15032,2258],{"class":305},[268,15034,42],{"class":282},[268,15036,3423],{"class":305},[268,15038,4818],{"class":282},[23,15040,15042,15050,15057,15065],{"className":15041},[26],[28,15043,15045,3578,15047],{"className":15044},[31],[33,15046],{"disabled":35,"type":36},[39,15048,15049],{},"4",[28,15051,15053,3578,15055],{"className":15052},[31],[33,15054],{"disabled":35,"type":36},[39,15056,3040],{},[28,15058,15060,355,15062],{"className":15059},[31],[33,15061],{"disabled":35,"type":36},[39,15063,15064],{},"TypeError: arguments.filter is not a function",[28,15066,15068,3578,15070],{"className":15067},[31],[33,15069],{"disabled":35,"type":36},[39,15071,2255],{},[66,15073,15074,15076,15082],{},[69,15075,71],{},[73,15077,15078,1004,15080],{},[76,15079,78],{},[39,15081,15064],{},[73,15083,15084,355,15086,355,15088,830,15091,15094,15095,15097,15098,15100,15101,15103,15104,99,15106,15108,15109,15112,15113,15115,15116,99,15119,15122,15123,15125],{},[76,15085,84],{},[76,15087,365],{},[39,15089,15090],{},"arguments",[104,15092,15093],{},"array-like"," — it has a ",[39,15096,3567],{}," and indexed properties — but it is not an actual ",[39,15099,88],{}," instance, so it doesn't inherit ",[39,15102,12161],{}," methods like ",[39,15105,14962],{},[39,15107,14980],{},". Calling ",[39,15110,15111],{},".filter"," directly on it throws a ",[39,15114,827],{},". To use array methods you'd need to convert it first (",[39,15117,15118],{},"Array.from(arguments)",[39,15120,15121],{},"[...arguments]","), or better yet, avoid ",[39,15124,15090],{}," entirely in favor of a rest parameter (see Q17), which is a real array from the start.",[15,15127,15128,15132,15220,15252],{"language":247},[18,15129,15131],{"id":15130},"q16-what-does-this-log","Q16. What does this log?",[257,15133,15134],{"language":247},[260,15135,15137],{"className":262,"code":15136,"language":247,"meta":264,"style":264},"function outer() {\n  const inner = () => {\n    console.log(arguments[0]);\n  };\n  inner(\"z\");\n}\n\nouter(\"a\", \"b\");\n",[39,15138,15139,15147,15163,15181,15186,15198,15202,15206],{"__ignoreMap":264},[268,15140,15141,15143,15145],{"class":270,"line":271},[268,15142,275],{"class":274},[268,15144,9700],{"class":278},[268,15146,283],{"class":282},[268,15148,15149,15151,15154,15156,15159,15161],{"class":270,"line":286},[268,15150,12441],{"class":274},[268,15152,15153],{"class":278}," inner",[268,15155,616],{"class":274},[268,15157,15158],{"class":282}," () ",[268,15160,9414],{"class":274},[268,15162,9914],{"class":282},[268,15164,15165,15167,15169,15171,15173,15176,15178],{"class":270,"line":296},[268,15166,9707],{"class":282},[268,15168,1356],{"class":278},[268,15170,622],{"class":282},[268,15172,15090],{"class":305},[268,15174,15175],{"class":282},"[",[268,15177,3307],{"class":305},[268,15179,15180],{"class":282},"]);\n",[268,15182,15183],{"class":270,"line":311},[268,15184,15185],{"class":282},"  };\n",[268,15187,15188,15191,15193,15196],{"class":270,"line":788},[268,15189,15190],{"class":278},"  inner",[268,15192,622],{"class":282},[268,15194,15195],{"class":289},"\"z\"",[268,15197,628],{"class":282},[268,15199,15200],{"class":270,"line":1951},[268,15201,314],{"class":282},[268,15203,15204],{"class":270,"line":8955},[268,15205,5033],{"emptyLinePlaceholder":35},[268,15207,15208,15210,15212,15214,15216,15218],{"class":270,"line":8966},[268,15209,9628],{"class":278},[268,15211,622],{"class":282},[268,15213,7582],{"class":289},[268,15215,42],{"class":282},[268,15217,9188],{"class":289},[268,15219,628],{"class":282},[23,15221,15223,15230,15237,15245],{"className":15222},[26],[28,15224,15226,355,15228],{"className":15225},[31],[33,15227],{"disabled":35,"type":36},[39,15229,15195],{},[28,15231,15233,355,15235],{"className":15232},[31],[33,15234],{"disabled":35,"type":36},[39,15236,833],{},[28,15238,15240,355,15242],{"className":15239},[31],[33,15241],{"disabled":35,"type":36},[39,15243,15244],{},"ReferenceError: arguments is not defined",[28,15246,15248,355,15250],{"className":15247},[31],[33,15249],{"disabled":35,"type":36},[39,15251,7582],{},[66,15253,15254,15256,15262],{},[69,15255,71],{},[73,15257,15258,6901,15260],{},[76,15259,78],{},[39,15261,7582],{},[73,15263,15264,355,15266,15268,15269,15271,15272,15274,15275,15278,15279,15281,15282,15284,15285,15287,15288,1179,15291,830,15294,2464,15296,15298,15299,15302,15303,15305],{},[76,15265,84],{},[76,15267,365],{}," arrow functions never get their own ",[39,15270,15090],{}," object. Any ",[39,15273,15090],{}," reference inside an arrow function is resolved lexically, walking up to the nearest enclosing ",[104,15276,15277],{},"regular"," (non-arrow) function's ",[39,15280,15090],{}," — here, ",[39,15283,9628],{},"'s. ",[39,15286,9628],{}," was called with ",[39,15289,15290],{},"(\"a\", \"b\")",[39,15292,15293],{},"arguments[0]",[39,15295,7582],{},[39,15297,15195],{}," passed directly to ",[39,15300,15301],{},"inner"," is irrelevant because ",[39,15304,15301],{}," never captures its own arguments at all. This is a frequent source of confusion when refactoring a regular function into an arrow function.",[15,15307,15308,15312,15416,15448],{"language":247},[18,15309,15311],{"id":15310},"q17-what-does-this-log","Q17. What does this log?",[257,15313,15314],{"language":247},[260,15315,15317],{"className":262,"code":15316,"language":247,"meta":264,"style":264},"function sumAll(...nums) {\n  return nums.filter(n => n > 0).reduce((a, b) => a + b, 0);\n}\n\nconsole.log(sumAll(1, -2, 3));\n",[39,15318,15319,15335,15382,15386,15390],{"__ignoreMap":264},[268,15320,15321,15323,15325,15327,15330,15333],{"class":270,"line":271},[268,15322,275],{"class":274},[268,15324,14948],{"class":278},[268,15326,622],{"class":282},[268,15328,15329],{"class":274},"...",[268,15331,15332],{"class":1222},"nums",[268,15334,1235],{"class":282},[268,15336,15337,15339,15342,15344,15346,15348,15350,15352,15354,15356,15358,15360,15362,15364,15366,15368,15370,15372,15374,15376,15378,15380],{"class":270,"line":286},[268,15338,1240],{"class":274},[268,15340,15341],{"class":282}," nums.",[268,15343,14962],{"class":278},[268,15345,622],{"class":282},[268,15347,4599],{"class":1222},[268,15349,14969],{"class":274},[268,15351,13355],{"class":282},[268,15353,6435],{"class":274},[268,15355,5728],{"class":305},[268,15357,6232],{"class":282},[268,15359,14980],{"class":278},[268,15361,6122],{"class":282},[268,15363,1223],{"class":1222},[268,15365,42],{"class":282},[268,15367,1232],{"class":1222},[268,15369,6131],{"class":282},[268,15371,9414],{"class":274},[268,15373,1243],{"class":282},[268,15375,1246],{"class":274},[268,15377,14999],{"class":282},[268,15379,3307],{"class":305},[268,15381,628],{"class":282},[268,15383,15384],{"class":270,"line":296},[268,15385,314],{"class":282},[268,15387,15388],{"class":270,"line":311},[268,15389,5033],{"emptyLinePlaceholder":35},[268,15391,15392,15394,15396,15398,15400,15402,15404,15406,15408,15410,15412,15414],{"class":270,"line":788},[268,15393,1353],{"class":282},[268,15395,1356],{"class":278},[268,15397,622],{"class":282},[268,15399,15022],{"class":278},[268,15401,622],{"class":282},[268,15403,2255],{"class":305},[268,15405,42],{"class":282},[268,15407,6244],{"class":274},[268,15409,2258],{"class":305},[268,15411,42],{"class":282},[268,15413,3423],{"class":305},[268,15415,4818],{"class":282},[23,15417,15419,15426,15434,15441],{"className":15418},[26],[28,15420,15422,355,15424],{"className":15421},[31],[33,15423],{"disabled":35,"type":36},[39,15425,15049],{},[28,15427,15429,355,15431],{"className":15428},[31],[33,15430],{"disabled":35,"type":36},[39,15432,15433],{},"TypeError: nums.filter is not a function",[28,15435,15437,355,15439],{"className":15436},[31],[33,15438],{"disabled":35,"type":36},[39,15440,3040],{},[28,15442,15444,355,15446],{"className":15443},[31],[33,15445],{"disabled":35,"type":36},[39,15447,2258],{},[66,15449,15450,15452,15458],{},[69,15451,71],{},[73,15453,15454,3459,15456],{},[76,15455,78],{},[39,15457,15049],{},[73,15459,15460,355,15462,15464,15465,15468,15469,1179,15471,186,15473,15475,15476,15479,15480,186,15482,137,15484,15486,15487,15489,15490,15492,15493,15495],{},[76,15461,84],{},[76,15463,930],{}," a rest parameter (",[39,15466,15467],{},"...nums",") collects the remaining arguments into a genuine ",[39,15470,88],{},[39,15472,14962],{},[39,15474,14980],{}," work directly with no conversion step — ",[39,15477,15478],{},"filter(n => n > 0)"," keeps ",[39,15481,2255],{},[39,15483,3423],{},[39,15485,14980],{}," sums them to ",[39,15488,15049],{},". This is exactly why rest parameters are the recommended, more readable replacement for the legacy ",[39,15491,15090],{}," object (contrast with Q15, where the equivalent code using ",[39,15494,15090],{}," throws).",[15,15497,15498,15506,15573,15604],{"language":247},[18,15499,15501,15502,15505],{"id":15500},"q18-what-is-requestlength-in-this-snippet","Q18. What is ",[39,15503,15504],{},"request.length"," in this snippet?",[257,15507,15508],{"language":247},[260,15509,15511],{"className":262,"code":15510,"language":247,"meta":264,"style":264},"function request(url, method = \"GET\", headers = {}) {\n  return method;\n}\n\nconsole.log(request.length);\n",[39,15512,15513,15545,15552,15556,15560],{"__ignoreMap":264},[268,15514,15515,15517,15520,15522,15525,15527,15530,15532,15535,15537,15540,15542],{"class":270,"line":271},[268,15516,275],{"class":274},[268,15518,15519],{"class":278}," request",[268,15521,622],{"class":282},[268,15523,15524],{"class":1222},"url",[268,15526,42],{"class":282},[268,15528,15529],{"class":1222},"method",[268,15531,616],{"class":274},[268,15533,15534],{"class":289}," \"GET\"",[268,15536,42],{"class":282},[268,15538,15539],{"class":1222},"headers",[268,15541,616],{"class":274},[268,15543,15544],{"class":282}," {}) {\n",[268,15546,15547,15549],{"class":270,"line":286},[268,15548,1240],{"class":274},[268,15550,15551],{"class":282}," method;\n",[268,15553,15554],{"class":270,"line":296},[268,15555,314],{"class":282},[268,15557,15558],{"class":270,"line":311},[268,15559,5033],{"emptyLinePlaceholder":35},[268,15561,15562,15564,15566,15569,15571],{"class":270,"line":788},[268,15563,1353],{"class":282},[268,15565,1356],{"class":278},[268,15567,15568],{"class":282},"(request.",[268,15570,3567],{"class":305},[268,15572,628],{"class":282},[23,15574,15576,15583,15590,15597],{"className":15575},[26],[28,15577,15579,355,15581],{"className":15578},[31],[33,15580],{"disabled":35,"type":36},[39,15582,3423],{},[28,15584,15586,355,15588],{"className":15585},[31],[33,15587],{"disabled":35,"type":36},[39,15589,2255],{},[28,15591,15593,355,15595],{"className":15592},[31],[33,15594],{"disabled":35,"type":36},[39,15596,2258],{},[28,15598,15600,355,15602],{"className":15599},[31],[33,15601],{"disabled":35,"type":36},[39,15603,3307],{},[66,15605,15606,15608,15614],{},[69,15607,71],{},[73,15609,15610,1727,15612],{},[76,15611,78],{},[39,15613,2255],{},[73,15615,15616,355,15618,355,15620,15623,15624,15626,15627,186,15629,15631,15632,15634,15635,15637,15638,15640,15641,15643],{},[76,15617,84],{},[76,15619,365],{},[39,15621,15622],{},"Function.prototype.length"," only counts the parameters that appear ",[104,15625,11314],{}," the first one with a default value (and rest parameters are never counted either). Here ",[39,15628,15529],{},[39,15630,15539],{}," both have defaults, so counting stops immediately after ",[39,15633,15524],{},", giving a length of ",[39,15636,2255],{}," — not ",[39,15639,3423],{},", even though the function accepts up to three arguments. This surprises people who expect ",[39,15642,3643],{}," to reflect the full parameter list; it's really reporting the number of \"required-looking\" leading parameters.",[15,15645,15646,15650,15719,15751],{"language":247},[18,15647,15649],{"id":15648},"q19-this-entire-file-is-in-strict-mode-what-does-it-log","Q19. This entire file is in strict mode. What does it log?",[257,15651,15652],{"language":247},[260,15653,15655],{"className":262,"code":15654,"language":247,"meta":264,"style":264},"\"use strict\";\n\nif (true) {\n  function greet() {\n    return \"hi\";\n  }\n}\n\nconsole.log(typeof greet);\n",[39,15656,15657,15663,15667,15677,15686,15695,15699,15703,15707],{"__ignoreMap":264},[268,15658,15659,15661],{"class":270,"line":271},[268,15660,254],{"class":289},[268,15662,293],{"class":282},[268,15664,15665],{"class":270,"line":286},[268,15666,5033],{"emptyLinePlaceholder":35},[268,15668,15669,15671,15673,15675],{"class":270,"line":296},[268,15670,2179],{"class":274},[268,15672,2182],{"class":282},[268,15674,2185],{"class":305},[268,15676,1235],{"class":282},[268,15678,15679,15682,15684],{"class":270,"line":311},[268,15680,15681],{"class":274},"  function",[268,15683,3679],{"class":278},[268,15685,283],{"class":282},[268,15687,15688,15690,15693],{"class":270,"line":788},[268,15689,9871],{"class":274},[268,15691,15692],{"class":289}," \"hi\"",[268,15694,293],{"class":282},[268,15696,15697],{"class":270,"line":1951},[268,15698,1948],{"class":282},[268,15700,15701],{"class":270,"line":8955},[268,15702,314],{"class":282},[268,15704,15705],{"class":270,"line":8966},[268,15706,5033],{"emptyLinePlaceholder":35},[268,15708,15709,15711,15713,15715,15717],{"class":270,"line":8974},[268,15710,1353],{"class":282},[268,15712,1356],{"class":278},[268,15714,622],{"class":282},[268,15716,1361],{"class":274},[268,15718,3695],{"class":282},[23,15720,15722,15729,15736,15743],{"className":15721},[26],[28,15723,15725,355,15727],{"className":15724},[31],[33,15726],{"disabled":35,"type":36},[39,15728,3732],{},[28,15730,15732,355,15734],{"className":15731},[31],[33,15733],{"disabled":35,"type":36},[39,15735,2761],{},[28,15737,15739,355,15741],{"className":15738},[31],[33,15740],{"disabled":35,"type":36},[39,15742,1397],{},[28,15744,15746,15748,15749],{"className":15745},[31],[33,15747],{"disabled":35,"type":36}," it throws a ",[39,15750,815],{},[66,15752,15753,15755,15761],{},[69,15754,71],{},[73,15756,15757,1004,15759],{},[76,15758,78],{},[39,15760,1397],{},[73,15762,15763,355,15765,15767,15768,15770,15771,15773,15774,15776,15777,15779,15780,2338,15782,15784,15785,15787],{},[76,15764,84],{},[76,15766,182],{}," in strict mode, the ECMAScript spec requires a function declaration inside a block (like this ",[39,15769,2179],{},") to be properly block-scoped, behaving essentially like ",[39,15772,240],{}," — it does not exist outside the ",[39,15775,2179],{}," block. So ",[39,15778,12864],{}," outside is ",[39,15781,1397],{},[39,15783,1361],{}," never throws on an unresolvable identifier, ruling out option D). In legacy non-strict (\"sloppy\") code, engines instead apply Annex B compatibility semantics, which additionally leak the function's name into the enclosing function\u002Fglobal scope initialized to ",[39,15786,833],{}," — a long-standing, easy-to-forget inconsistency between strict and sloppy mode that's best avoided by not declaring functions inside blocks at all.",[15,15789,15790,15794,15910,15967],{"language":247},[18,15791,15793],{"id":15792},"q20-what-does-this-log-and-what-is-the-pattern-accomplishing","Q20. What does this log, and what is the pattern accomplishing?",[257,15795,15796],{"language":247},[260,15797,15799],{"className":262,"code":15798,"language":247,"meta":264,"style":264},"const cache = {};\n\n(function initCache() {\n  const secretSalt = \"xyz123\";\n  cache.hash = str => str.length + secretSalt.length;\n})();\n\nconsole.log(typeof secretSalt);\nconsole.log(cache.hash(\"abc\"));\n",[39,15800,15801,15813,15817,15828,15842,15871,15876,15880,15893],{"__ignoreMap":264},[268,15802,15803,15805,15808,15810],{"class":270,"line":271},[268,15804,243],{"class":274},[268,15806,15807],{"class":305}," cache",[268,15809,616],{"class":274},[268,15811,15812],{"class":282}," {};\n",[268,15814,15815],{"class":270,"line":286},[268,15816,5033],{"emptyLinePlaceholder":35},[268,15818,15819,15821,15823,15826],{"class":270,"line":296},[268,15820,622],{"class":282},[268,15822,275],{"class":274},[268,15824,15825],{"class":278}," initCache",[268,15827,283],{"class":282},[268,15829,15830,15832,15835,15837,15840],{"class":270,"line":311},[268,15831,12441],{"class":274},[268,15833,15834],{"class":305}," secretSalt",[268,15836,616],{"class":274},[268,15838,15839],{"class":289}," \"xyz123\"",[268,15841,293],{"class":282},[268,15843,15844,15847,15850,15852,15855,15857,15860,15862,15864,15867,15869],{"class":270,"line":788},[268,15845,15846],{"class":282},"  cache.",[268,15848,15849],{"class":278},"hash",[268,15851,616],{"class":274},[268,15853,15854],{"class":1222}," str",[268,15856,14969],{"class":274},[268,15858,15859],{"class":282}," str.",[268,15861,3567],{"class":305},[268,15863,3350],{"class":274},[268,15865,15866],{"class":282}," secretSalt.",[268,15868,3567],{"class":305},[268,15870,293],{"class":282},[268,15872,15873],{"class":270,"line":1951},[268,15874,15875],{"class":282},"})();\n",[268,15877,15878],{"class":270,"line":8955},[268,15879,5033],{"emptyLinePlaceholder":35},[268,15881,15882,15884,15886,15888,15890],{"class":270,"line":8966},[268,15883,1353],{"class":282},[268,15885,1356],{"class":278},[268,15887,622],{"class":282},[268,15889,1361],{"class":274},[268,15891,15892],{"class":282}," secretSalt);\n",[268,15894,15895,15897,15899,15902,15904,15906,15908],{"class":270,"line":8974},[268,15896,1353],{"class":282},[268,15898,1356],{"class":278},[268,15900,15901],{"class":282},"(cache.",[268,15903,15849],{"class":278},[268,15905,622],{"class":282},[268,15907,7004],{"class":289},[268,15909,4818],{"class":282},[23,15911,15913,15927,15937,15950],{"className":15912},[26],[28,15914,15916,355,15918,1133,15920,15922,15923,15926],{"className":15915},[31],[33,15917],{"disabled":35,"type":36},[39,15919,2761],{},[39,15921,6360],{}," — the IIFE leaks its inner variables onto ",[39,15924,15925],{},"cache"," automatically",[28,15928,15930,15748,15932,15934,15935],{"className":15929},[31],[33,15931],{"disabled":35,"type":36},[39,15933,815],{},", then nothing logs — IIFEs cannot reach outer variables like ",[39,15936,15925],{},[28,15938,15940,355,15942,1133,15944,3990,15946,15949],{"className":15939},[31],[33,15941],{"disabled":35,"type":36},[39,15943,3732],{},[39,15945,6360],{},[39,15947,15948],{},"secretSalt"," is hoisted as a function",[28,15951,15953,355,15955,1133,15957,15959,15960,15962,15963,15966],{"className":15952},[31],[33,15954],{"disabled":35,"type":36},[39,15956,1397],{},[39,15958,6360],{}," — the IIFE runs immediately and creates a private scope, so ",[39,15961,15948],{}," never escapes, while ",[39,15964,15965],{},"cache.hash"," retains a reference to it",[66,15968,15969,15971,15983],{},[69,15970,71],{},[73,15972,15973,6901,15975,1133,15977,15959,15979,15962,15981,15966],{},[76,15974,78],{},[39,15976,1397],{},[39,15978,6360],{},[39,15980,15948],{},[39,15982,15965],{},[73,15984,15985,355,15987,15989,15990,15992,15993,15996,15997,355,16000,16002,16003,16005,16006,16008,16009,16012,16013,16016],{},[76,15986,84],{},[76,15988,930],{}," an IIFE (immediately invoked function expression) is defined and called in one step specifically to create an isolated, private scope — a pattern that predates block scoping and is still useful for module-style encapsulation. ",[39,15991,15948],{}," lives only inside ",[39,15994,15995],{},"initCache","'s scope, so it's never visible outside, making ",[39,15998,15999],{},"typeof secretSalt",[39,16001,1397],{},". The function assigned to ",[39,16004,15965],{}," was created inside that same scope though, so it can still read ",[39,16007,15948],{}," when it's called later, producing ",[39,16010,16011],{},"3 + 6 = 9",". Option A gets the mechanism backwards — the whole point of an IIFE is to ",[104,16014,16015],{},"prevent"," leakage, not cause it.",[2107,16018,16019],{},"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 pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}",{"title":264,"searchDepth":286,"depth":286,"links":16021},[16022,16023,16024,16025,16026,16027,16028,16029,16030,16031,16032,16033,16034,16035,16036,16037,16038,16039,16041,16042],{"id":12656,"depth":296,"text":12657},{"id":12736,"depth":296,"text":12737},{"id":12876,"depth":296,"text":12877},{"id":13031,"depth":296,"text":13032},{"id":13180,"depth":296,"text":13181},{"id":13320,"depth":296,"text":13321},{"id":13527,"depth":296,"text":13528},{"id":13728,"depth":296,"text":13729},{"id":13926,"depth":296,"text":13927},{"id":14089,"depth":296,"text":14090},{"id":14223,"depth":296,"text":14224},{"id":14381,"depth":296,"text":14382},{"id":14537,"depth":296,"text":14538},{"id":14773,"depth":296,"text":14774},{"id":14933,"depth":296,"text":14934},{"id":15130,"depth":296,"text":15131},{"id":15310,"depth":296,"text":15311},{"id":15500,"depth":296,"text":16040},"Q18. What is request.length in this snippet?",{"id":15648,"depth":296,"text":15649},{"id":15792,"depth":296,"text":15793},{},"\u002Fjs\u002F05-functions-and-scope",{"title":12646,"description":264},"js\u002F05-functions-and-scope","6xws2YRG2sebawVwbCa7OP71onkvRltqmwayd9JWW58",{"id":16049,"title":16050,"body":16051,"description":264,"extension":2144,"meta":19502,"navigation":35,"path":19503,"seo":19504,"stem":19505,"__hash__":19506},"content\u002Fjs\u002F06-strings-and-template-literals.md","06 — Strings & Template Literals",{"type":8,"value":16052,"toc":19479},[16053,16056,16145,16338,16524,16700,16878,17054,17308,17473,17614,17770,17920,18048,18212,18412,18607,18790,18975,19192,19296,19476],[11,16054,16050],{"id":16055},"_06-strings-template-literals",[15,16057,16058,16062,16111],{},[18,16059,16061],{"id":16060},"q1-which-statement-correctly-describes-string-mutability-in-javascript","Q1. Which statement correctly describes string mutability in JavaScript?",[23,16063,16065,16078,16089,16100],{"className":16064},[26],[28,16066,16068,16070,16071,186,16074,16077],{"className":16067},[31],[33,16069],{"disabled":35,"type":36}," String methods like ",[39,16072,16073],{},".toUpperCase()",[39,16075,16076],{},".slice()"," mutate the original string in place and also return the modified string for chaining",[28,16079,16081,16083,16084,186,16086,16088],{"className":16080},[31],[33,16082],{"disabled":35,"type":36}," Strings are immutable — methods like ",[39,16085,16073],{},[39,16087,16076],{}," always return a new string, leaving the original string unchanged",[28,16090,16092,16094,16095,16097,16098],{"className":16091},[31],[33,16093],{"disabled":35,"type":36}," Strings are mutable only when declared with ",[39,16096,240],{},", but immutable when declared with ",[39,16099,243],{},[28,16101,16103,16105,16106,16108,16109,5302],{"className":16102},[31],[33,16104],{"disabled":35,"type":36}," Whether a string method mutates depends on the method — ",[39,16107,16076],{}," mutates the original but ",[39,16110,16073],{},[66,16112,16113,16115,16124],{},[69,16114,71],{},[73,16116,16117,16119,16120,186,16122,16088],{},[76,16118,78],{}," B — Strings are immutable — methods like ",[39,16121,16073],{},[39,16123,16076],{},[73,16125,16126,16128,16129,2182,16132,16134,16135,16137,16138,16141,16142,16144],{},[76,16127,84],{}," Strings are a primitive type in JavaScript, and primitives are immutable — no operation can change the characters of an existing string value. Every \"transforming\" string method actually builds and returns a brand-new string, leaving the original untouched unless you reassign the variable. Option C confuses variable ",[104,16130,16131],{},"reassignability",[39,16133,240],{}," vs. ",[39,16136,243],{},") with value ",[104,16139,16140],{},"mutability",", which are unrelated concerns — even a ",[39,16143,240],{},"-bound string's underlying value can never be mutated in place. Option D is wrong because no built-in string method mutates, regardless of which one you pick.",[15,16146,16147,16149,16255,16303],{"language":247},[18,16148,12737],{"id":12736},[257,16150,16151],{"language":247},[260,16152,16154],{"className":262,"code":16153,"language":247,"meta":264,"style":264},"function shout(word) {\n  return word.toUpperCase() + \"!\";\n}\n\nconst name = \"ava\";\nconst msg = `Hello, ${shout(name)}\nWelcome aboard.`;\n\nconsole.log(msg);\n",[39,16155,16156,16170,16190,16194,16198,16212,16235,16242,16246],{"__ignoreMap":264},[268,16157,16158,16160,16163,16165,16168],{"class":270,"line":271},[268,16159,275],{"class":274},[268,16161,16162],{"class":278}," shout",[268,16164,622],{"class":282},[268,16166,16167],{"class":1222},"word",[268,16169,1235],{"class":282},[268,16171,16172,16174,16177,16180,16183,16185,16188],{"class":270,"line":286},[268,16173,1240],{"class":274},[268,16175,16176],{"class":282}," word.",[268,16178,16179],{"class":278},"toUpperCase",[268,16181,16182],{"class":282},"() ",[268,16184,1246],{"class":274},[268,16186,16187],{"class":289}," \"!\"",[268,16189,293],{"class":282},[268,16191,16192],{"class":270,"line":296},[268,16193,314],{"class":282},[268,16195,16196],{"class":270,"line":311},[268,16197,5033],{"emptyLinePlaceholder":35},[268,16199,16200,16202,16205,16207,16210],{"class":270,"line":788},[268,16201,243],{"class":274},[268,16203,16204],{"class":305}," name",[268,16206,616],{"class":274},[268,16208,16209],{"class":289}," \"ava\"",[268,16211,293],{"class":282},[268,16213,16214,16216,16219,16221,16224,16227,16229,16231,16233],{"class":270,"line":1951},[268,16215,243],{"class":274},[268,16217,16218],{"class":305}," msg",[268,16220,616],{"class":274},[268,16222,16223],{"class":289}," `Hello, ${",[268,16225,16226],{"class":278},"shout",[268,16228,622],{"class":289},[268,16230,14605],{"class":282},[268,16232,2690],{"class":289},[268,16234,314],{"class":289},[268,16236,16237,16240],{"class":270,"line":8955},[268,16238,16239],{"class":289},"Welcome aboard.`",[268,16241,293],{"class":282},[268,16243,16244],{"class":270,"line":8966},[268,16245,5033],{"emptyLinePlaceholder":35},[268,16247,16248,16250,16252],{"class":270,"line":8974},[268,16249,1353],{"class":282},[268,16251,1356],{"class":278},[268,16253,16254],{"class":282},"(msg);\n",[23,16256,16258,16270,16278,16289],{"className":16257},[26],[28,16259,16261,355,16263,186,16266,16269],{"className":16260},[31],[33,16262],{"disabled":35,"type":36},[39,16264,16265],{},"Hello, AVA!",[39,16267,16268],{},"Welcome aboard."," printed on the same line, separated by a space",[28,16271,16273,812,16275,16277],{"className":16272},[31],[33,16274],{"disabled":35,"type":36},[39,16276,1274],{},", because template literals cannot span multiple lines",[28,16279,16281,355,16283,16285,16286,16288],{"className":16280},[31],[33,16282],{"disabled":35,"type":36},[39,16284,16265],{}," followed by a literal newline, then ",[39,16287,16268],{}," on the next line",[28,16290,16292,16294,16295,16298,16299,16302],{"className":16291},[31],[33,16293],{"disabled":35,"type":36}," The literal text ",[39,16296,16297],{},"Hello, ${shout(name)}",", because a function call inside ",[39,16300,16301],{},"${}"," is not evaluated",[66,16304,16305,16307,16315],{},[69,16306,71],{},[73,16308,16309,1004,16311,16285,16313,16288],{},[76,16310,78],{},[39,16312,16265],{},[39,16314,16268],{},[73,16316,16317,16319,16320,16323,16324,16326,16327,16330,16331,16334,16335,16337],{},[76,16318,84],{}," Template literals preserve any newline characters typed between the backticks as an actual ",[39,16321,16322],{},"\\n"," in the resulting string, so the output spans two lines. A ",[39,16325,16301],{}," placeholder can hold any valid JS expression, including function calls — they're evaluated and the result is coerced to a string before splicing in, so ",[39,16328,16329],{},"shout(\"ava\")"," contributes ",[39,16332,16333],{},"\"AVA!\"",". Option B is wrong because multi-line strings without escape sequences are one of the main reasons template literals exist. Option D is wrong because expressions inside ",[39,16336,16301],{}," are always evaluated — that's the entire point of interpolation, not literal text substitution.",[15,16339,16340,16342,16417,16452],{"language":247},[18,16341,12877],{"id":12876},[257,16343,16344],{"language":247},[260,16345,16347],{"className":262,"code":16346,"language":247,"meta":264,"style":264},"const a = \"10\" + 5;\nconst b = \"10\" - 5;\nconst c = \"10\" + 5 - 3;\n\nconsole.log(a, b, c);\n",[39,16348,16349,16366,16383,16404,16408],{"__ignoreMap":264},[268,16350,16351,16353,16355,16357,16360,16362,16364],{"class":270,"line":271},[268,16352,243],{"class":274},[268,16354,7203],{"class":305},[268,16356,616],{"class":274},[268,16358,16359],{"class":289}," \"10\"",[268,16361,3350],{"class":274},[268,16363,2387],{"class":305},[268,16365,293],{"class":282},[268,16367,16368,16370,16373,16375,16377,16379,16381],{"class":270,"line":286},[268,16369,243],{"class":274},[268,16371,16372],{"class":305}," b",[268,16374,616],{"class":274},[268,16376,16359],{"class":289},[268,16378,6286],{"class":274},[268,16380,2387],{"class":305},[268,16382,293],{"class":282},[268,16384,16385,16387,16390,16392,16394,16396,16398,16400,16402],{"class":270,"line":296},[268,16386,243],{"class":274},[268,16388,16389],{"class":305}," c",[268,16391,616],{"class":274},[268,16393,16359],{"class":289},[268,16395,3350],{"class":274},[268,16397,2387],{"class":305},[268,16399,6286],{"class":274},[268,16401,3396],{"class":305},[268,16403,293],{"class":282},[268,16405,16406],{"class":270,"line":311},[268,16407,5033],{"emptyLinePlaceholder":35},[268,16409,16410,16412,16414],{"class":270,"line":788},[268,16411,1353],{"class":282},[268,16413,1356],{"class":278},[268,16415,16416],{"class":282},"(a, b, c);\n",[23,16418,16420,16428,16436,16444],{"className":16419},[26],[28,16421,16423,355,16425],{"className":16422},[31],[33,16424],{"disabled":35,"type":36},[39,16426,16427],{},"\"105\" 5 102",[28,16429,16431,355,16433],{"className":16430},[31],[33,16432],{"disabled":35,"type":36},[39,16434,16435],{},"15 5 12",[28,16437,16439,355,16441],{"className":16438},[31],[33,16440],{"disabled":35,"type":36},[39,16442,16443],{},"\"105\" 5 \"1023\"",[28,16445,16447,355,16449],{"className":16446},[31],[33,16448],{"disabled":35,"type":36},[39,16450,16451],{},"15 5 \"1023\"",[66,16453,16454,16456,16462],{},[69,16455,71],{},[73,16457,16458,3459,16460],{},[76,16459,78],{},[39,16461,16427],{},[73,16463,16464,355,16466,16468,16469,7159,16472,3277,16475,16477,16478,16481,16482,16485,16486,16488,16489,16491,16492,5422,16495,16497,16498,16501,16502,15637,16505,4387,16508,16510,16511,16514,16515,16517,16518,16520,16521],{},[76,16465,84],{},[39,16467,1246],{}," is overloaded: if either operand is a string, it performs string concatenation, so ",[39,16470,16471],{},"\"10\" + 5",[39,16473,16474],{},"\"105\"",[39,16476,6244],{}," has no concatenation meaning, so both operands go through ToNumber, giving ",[39,16479,16480],{},"10 - 5 = 5",". For ",[39,16483,16484],{},"c",", evaluation runs left-to-right: ",[39,16487,16471],{}," first yields the string ",[39,16490,16474],{},", and then ",[39,16493,16494],{},"\"105\" - 3",[39,16496,16474],{}," back to the number ",[39,16499,16500],{},"105"," for subtraction, producing ",[39,16503,16504],{},"102",[39,16506,16507],{},"\"1023\"",[39,16509,6244],{}," never concatenates, and not ",[39,16512,16513],{},"12",", since the first ",[39,16516,1246],{}," already stringified the ",[39,16519,5825],{},". This string-then-number flip mid-expression is a classic coercion trap. ",[76,16522,16523],{},"Debug",[15,16525,16526,16528,16607,16642],{"language":247},[18,16527,13032],{"id":13031},[257,16529,16530],{"language":247},[260,16531,16533],{"className":262,"code":16532,"language":247,"meta":264,"style":264},"const results = [\n  \"5\" == 5,\n  \"5\" === 5,\n  \"5\" == \"5.0\",\n  5 == \"5.0\",\n];\n\nconsole.log(results);\n",[39,16534,16535,16547,16558,16568,16579,16590,16594,16598],{"__ignoreMap":264},[268,16536,16537,16539,16542,16544],{"class":270,"line":271},[268,16538,243],{"class":274},[268,16540,16541],{"class":305}," results",[268,16543,616],{"class":274},[268,16545,16546],{"class":282}," [\n",[268,16548,16549,16552,16554,16556],{"class":270,"line":286},[268,16550,16551],{"class":289},"  \"5\"",[268,16553,3165],{"class":274},[268,16555,2387],{"class":305},[268,16557,1789],{"class":282},[268,16559,16560,16562,16564,16566],{"class":270,"line":296},[268,16561,16551],{"class":289},[268,16563,3043],{"class":274},[268,16565,2387],{"class":305},[268,16567,1789],{"class":282},[268,16569,16570,16572,16574,16577],{"class":270,"line":311},[268,16571,16551],{"class":289},[268,16573,3165],{"class":274},[268,16575,16576],{"class":289}," \"5.0\"",[268,16578,1789],{"class":282},[268,16580,16581,16584,16586,16588],{"class":270,"line":788},[268,16582,16583],{"class":305},"  5",[268,16585,3165],{"class":274},[268,16587,16576],{"class":289},[268,16589,1789],{"class":282},[268,16591,16592],{"class":270,"line":1951},[268,16593,8737],{"class":282},[268,16595,16596],{"class":270,"line":8955},[268,16597,5033],{"emptyLinePlaceholder":35},[268,16599,16600,16602,16604],{"class":270,"line":8966},[268,16601,1353],{"class":282},[268,16603,1356],{"class":278},[268,16605,16606],{"class":282},"(results);\n",[23,16608,16610,16618,16626,16634],{"className":16609},[26],[28,16611,16613,355,16615],{"className":16612},[31],[33,16614],{"disabled":35,"type":36},[39,16616,16617],{},"[true, true, false, true]",[28,16619,16621,355,16623],{"className":16620},[31],[33,16622],{"disabled":35,"type":36},[39,16624,16625],{},"[false, false, false, true]",[28,16627,16629,355,16631],{"className":16628},[31],[33,16630],{"disabled":35,"type":36},[39,16632,16633],{},"[true, false, true, true]",[28,16635,16637,355,16639],{"className":16636},[31],[33,16638],{"disabled":35,"type":36},[39,16640,16641],{},"[true, false, false, true]",[66,16643,16644,16646,16652],{},[69,16645,71],{},[73,16647,16648,6901,16650],{},[76,16649,78],{},[39,16651,16641],{},[73,16653,16654,355,16656,16658,16659,830,16661,3277,16663,16665,16666,830,16669,16671,16672,16675,16676,16679,16680,16682,16683,5422,16686,5338,16689,16691,16692,16694,16695,16697,16698],{},[76,16655,84],{},[39,16657,3197],{}," triggers ToNumber coercion when comparing a string and a number, so ",[39,16660,3273],{},[39,16662,2185],{},[39,16664,3280],{}," requires matching types with no coercion, so ",[39,16667,16668],{},"\"5\" === 5",[39,16670,2986],{}," since the operand types differ. ",[39,16673,16674],{},"\"5\" == \"5.0\""," compares two strings with ",[76,16677,16678],{},"no"," coercion at all — they're different character sequences, so it's ",[39,16681,2986],{}," even though they'd represent the same numeric value. ",[39,16684,16685],{},"5 == \"5.0\"",[39,16687,16688],{},"\"5.0\"",[39,16690,2429],{},", matching, so it's ",[39,16693,2185],{},". The trap is assuming string-to-string ",[39,16696,3197],{}," behaves like numeric equality — coercion only kicks in when the operand types actually differ. ",[76,16699,16523],{},[15,16701,16702,16704,16790,16825],{"language":247},[18,16703,13181],{"id":13180},[257,16705,16706],{"language":247},[260,16707,16709],{"className":262,"code":16708,"language":247,"meta":264,"style":264},"console.log(String(null));\nconsole.log(`${null}`);\nconsole.log(null + \"\");\nconsole.log(String(undefined) === (undefined + \"\"));\n",[39,16710,16711,16728,16745,16762],{"__ignoreMap":264},[268,16712,16713,16715,16717,16719,16722,16724,16726],{"class":270,"line":271},[268,16714,1353],{"class":282},[268,16716,1356],{"class":278},[268,16718,622],{"class":282},[268,16720,16721],{"class":278},"String",[268,16723,622],{"class":282},[268,16725,2650],{"class":305},[268,16727,4818],{"class":282},[268,16729,16730,16732,16734,16736,16739,16741,16743],{"class":270,"line":286},[268,16731,1353],{"class":282},[268,16733,1356],{"class":278},[268,16735,622],{"class":282},[268,16737,16738],{"class":289},"`${",[268,16740,2650],{"class":305},[268,16742,11603],{"class":289},[268,16744,628],{"class":282},[268,16746,16747,16749,16751,16753,16755,16757,16760],{"class":270,"line":296},[268,16748,1353],{"class":282},[268,16750,1356],{"class":278},[268,16752,622],{"class":282},[268,16754,2650],{"class":305},[268,16756,3350],{"class":274},[268,16758,16759],{"class":289}," \"\"",[268,16761,628],{"class":282},[268,16763,16764,16766,16768,16770,16772,16774,16776,16778,16780,16782,16784,16786,16788],{"class":270,"line":311},[268,16765,1353],{"class":282},[268,16767,1356],{"class":278},[268,16769,622],{"class":282},[268,16771,16721],{"class":278},[268,16773,622],{"class":282},[268,16775,833],{"class":305},[268,16777,6131],{"class":282},[268,16779,3280],{"class":274},[268,16781,2182],{"class":282},[268,16783,833],{"class":305},[268,16785,3350],{"class":274},[268,16787,16759],{"class":289},[268,16789,4818],{"class":282},[23,16791,16793,16801,16809,16817],{"className":16792},[26],[28,16794,16796,355,16798],{"className":16795},[31],[33,16797],{"disabled":35,"type":36},[39,16799,16800],{},"\"null\" \"null\" \"\" true",[28,16802,16804,355,16806],{"className":16803},[31],[33,16805],{"disabled":35,"type":36},[39,16807,16808],{},"\"null\" \"null\" \"null\" true",[28,16810,16812,355,16814],{"className":16811},[31],[33,16813],{"disabled":35,"type":36},[39,16815,16816],{},"\"\" \"\" \"\" true",[28,16818,16820,355,16822],{"className":16819},[31],[33,16821],{"disabled":35,"type":36},[39,16823,16824],{},"\"null\" \"null\" \"null\" false",[66,16826,16827,16829,16835],{},[69,16828,71],{},[73,16830,16831,1727,16833],{},[76,16832,78],{},[39,16834,16808],{},[73,16836,16837,355,16839,16842,16843,16846,16847,16849,16850,16852,16853,16855,16856,16859,16860,16862,16863,186,16866,16869,16870,16872,16873,16875,16876],{},[76,16838,84],{},[39,16840,16841],{},"String(x)"," and template-literal interpolation both invoke the same ToString operation, and ",[39,16844,16845],{},"ToString(null)"," is specified to return the literal string ",[39,16848,2931],{}," — not an empty string, despite ",[39,16851,2650],{}," being falsy. The ",[39,16854,1246],{}," operator, when one operand is a string, also converts the other operand through ToPrimitive → ToString, so ",[39,16857,16858],{},"null + \"\""," likewise yields ",[39,16861,2931],{},". The same logic makes ",[39,16864,16865],{},"String(undefined)",[39,16867,16868],{},"undefined + \"\""," both produce ",[39,16871,1397],{},", so the strict-equality check is ",[39,16874,2185],{},". Option C's empty-string result is the trap for anyone who conflates \"falsy\" with \"stringifies to empty\" — falsiness is a boolean-context concept, unrelated to how a value stringifies. ",[76,16877,16523],{},[15,16879,16880,16882,16979,17014],{"language":247},[18,16881,13321],{"id":13320},[257,16883,16884],{"language":247},[260,16885,16887],{"className":262,"code":16886,"language":247,"meta":264,"style":264},"let n = 0;\nfunction next() {\n  n += 1;\n  return n;\n}\n\nconst log = `${next()}-${next()}-${next()}`;\nconsole.log(log);\n",[39,16888,16889,16901,16910,16921,16928,16932,16936,16970],{"__ignoreMap":264},[268,16890,16891,16893,16895,16897,16899],{"class":270,"line":271},[268,16892,240],{"class":274},[268,16894,13355],{"class":282},[268,16896,302],{"class":274},[268,16898,5728],{"class":305},[268,16900,293],{"class":282},[268,16902,16903,16905,16908],{"class":270,"line":286},[268,16904,275],{"class":274},[268,16906,16907],{"class":278}," next",[268,16909,283],{"class":282},[268,16911,16912,16915,16917,16919],{"class":270,"line":296},[268,16913,16914],{"class":282},"  n ",[268,16916,14575],{"class":274},[268,16918,2199],{"class":305},[268,16920,293],{"class":282},[268,16922,16923,16925],{"class":270,"line":311},[268,16924,1240],{"class":274},[268,16926,16927],{"class":282}," n;\n",[268,16929,16930],{"class":270,"line":788},[268,16931,314],{"class":282},[268,16933,16934],{"class":270,"line":1951},[268,16935,5033],{"emptyLinePlaceholder":35},[268,16937,16938,16940,16943,16945,16947,16950,16953,16956,16958,16960,16962,16964,16966,16968],{"class":270,"line":8955},[268,16939,243],{"class":274},[268,16941,16942],{"class":305}," log",[268,16944,616],{"class":274},[268,16946,14262],{"class":289},[268,16948,16949],{"class":278},"next",[268,16951,16952],{"class":289},"()",[268,16954,16955],{"class":289},"}-${",[268,16957,16949],{"class":278},[268,16959,16952],{"class":289},[268,16961,16955],{"class":289},[268,16963,16949],{"class":278},[268,16965,16952],{"class":289},[268,16967,11603],{"class":289},[268,16969,293],{"class":282},[268,16971,16972,16974,16976],{"class":270,"line":8966},[268,16973,1353],{"class":282},[268,16975,1356],{"class":278},[268,16977,16978],{"class":282},"(log);\n",[23,16980,16982,16990,16998,17006],{"className":16981},[26],[28,16983,16985,355,16987],{"className":16984},[31],[33,16986],{"disabled":35,"type":36},[39,16988,16989],{},"\"3-3-3\"",[28,16991,16993,355,16995],{"className":16992},[31],[33,16994],{"disabled":35,"type":36},[39,16996,16997],{},"\"3-2-1\"",[28,16999,17001,355,17003],{"className":17000},[31],[33,17002],{"disabled":35,"type":36},[39,17004,17005],{},"\"1-2-3\"",[28,17007,17009,355,17011],{"className":17008},[31],[33,17010],{"disabled":35,"type":36},[39,17012,17013],{},"\"0-1-2\"",[66,17015,17016,17018,17024],{},[69,17017,71],{},[73,17019,17020,1004,17022],{},[76,17021,78],{},[39,17023,17005],{},[73,17025,17026,17028,17029,17031,17032,17035,17036,5425,17038,17040,17041,17043,17044,17040,17046,17048,17049,17051,17052],{},[76,17027,84],{}," Each ",[39,17030,16301],{}," slot in a template literal is evaluated in strict left-to-right textual order, with no batching or deferred evaluation. The first ",[39,17033,17034],{},"next()"," call mutates ",[39,17037,4599],{},[39,17039,2255],{}," and returns ",[39,17042,2255],{},"; the second call sees the already-mutated ",[39,17045,4599],{},[39,17047,2258],{},"; the third returns ",[39,17050,3423],{},". This matters whenever interpolated expressions have side effects — reordering placeholders in the template changes the actual side-effect order, not just the visual layout. Option A wrongly assumes templates resolve every placeholder against some final state rather than evaluating each in place as encountered. ",[76,17053,16523],{},[15,17055,17056,17058,17231,17267],{"language":247},[18,17057,13528],{"id":13527},[257,17059,17060],{"language":247},[260,17061,17063],{"className":262,"code":17062,"language":247,"meta":264,"style":264},"function tag(strings, ...values) {\n  return strings.reduce(\n    (out, str, i) => out + str + (values[i] !== undefined ? `[${values[i]}]` : \"\"),\n    \"\"\n  );\n}\n\nconst price = 42;\nconst item = \"mug\";\nconsole.log(tag`The ${item} costs $${price}.`);\n",[39,17064,17065,17085,17097,17160,17165,17170,17174,17178,17191,17204],{"__ignoreMap":264},[268,17066,17067,17069,17072,17074,17077,17079,17081,17083],{"class":270,"line":271},[268,17068,275],{"class":274},[268,17070,17071],{"class":278}," tag",[268,17073,622],{"class":282},[268,17075,17076],{"class":1222},"strings",[268,17078,42],{"class":282},[268,17080,15329],{"class":274},[268,17082,9275],{"class":1222},[268,17084,1235],{"class":282},[268,17086,17087,17089,17092,17094],{"class":270,"line":286},[268,17088,1240],{"class":274},[268,17090,17091],{"class":282}," strings.",[268,17093,14980],{"class":278},[268,17095,17096],{"class":282},"(\n",[268,17098,17099,17102,17105,17107,17110,17112,17114,17116,17118,17121,17123,17126,17128,17131,17133,17136,17138,17141,17143,17145,17147,17150,17153,17155,17157],{"class":270,"line":296},[268,17100,17101],{"class":282},"    (",[268,17103,17104],{"class":1222},"out",[268,17106,42],{"class":282},[268,17108,17109],{"class":1222},"str",[268,17111,42],{"class":282},[268,17113,9509],{"class":1222},[268,17115,6131],{"class":282},[268,17117,9414],{"class":274},[268,17119,17120],{"class":282}," out ",[268,17122,1246],{"class":274},[268,17124,17125],{"class":282}," str ",[268,17127,1246],{"class":274},[268,17129,17130],{"class":282}," (values[i] ",[268,17132,4327],{"class":274},[268,17134,17135],{"class":305}," undefined",[268,17137,13362],{"class":274},[268,17139,17140],{"class":289}," `[${",[268,17142,9275],{"class":282},[268,17144,15175],{"class":289},[268,17146,9509],{"class":282},[268,17148,17149],{"class":289},"]",[268,17151,17152],{"class":289},"}]`",[268,17154,13367],{"class":274},[268,17156,16759],{"class":289},[268,17158,17159],{"class":282},"),\n",[268,17161,17162],{"class":270,"line":311},[268,17163,17164],{"class":289},"    \"\"\n",[268,17166,17167],{"class":270,"line":788},[268,17168,17169],{"class":282},"  );\n",[268,17171,17172],{"class":270,"line":1951},[268,17173,314],{"class":282},[268,17175,17176],{"class":270,"line":8955},[268,17177,5033],{"emptyLinePlaceholder":35},[268,17179,17180,17182,17185,17187,17189],{"class":270,"line":8966},[268,17181,243],{"class":274},[268,17183,17184],{"class":305}," price",[268,17186,616],{"class":274},[268,17188,779],{"class":305},[268,17190,293],{"class":282},[268,17192,17193,17195,17197,17199,17202],{"class":270,"line":8974},[268,17194,243],{"class":274},[268,17196,11794],{"class":305},[268,17198,616],{"class":274},[268,17200,17201],{"class":289}," \"mug\"",[268,17203,293],{"class":282},[268,17205,17206,17208,17210,17212,17215,17218,17220,17223,17226,17229],{"class":270,"line":8985},[268,17207,1353],{"class":282},[268,17209,1356],{"class":278},[268,17211,622],{"class":282},[268,17213,17214],{"class":278},"tag",[268,17216,17217],{"class":289},"`The ${",[268,17219,14793],{"class":282},[268,17221,17222],{"class":289},"} costs $${",[268,17224,17225],{"class":282},"price",[268,17227,17228],{"class":289},"}.`",[268,17230,628],{"class":282},[23,17232,17234,17242,17250,17258],{"className":17233},[26],[28,17235,17237,355,17239],{"className":17236},[31],[33,17238],{"disabled":35,"type":36},[39,17240,17241],{},"\"The [mug] costs $[42].\"",[28,17243,17245,812,17247,17249],{"className":17244},[31],[33,17246],{"disabled":35,"type":36},[39,17248,827],{},", because tag functions can't accept a variable number of interpolated values",[28,17251,17253,355,17255],{"className":17252},[31],[33,17254],{"disabled":35,"type":36},[39,17256,17257],{},"\"The mug costs $42.\"",[28,17259,17261,355,17263,17266],{"className":17260},[31],[33,17262],{"disabled":35,"type":36},[39,17264,17265],{},"\"The costs $.\"",", because the tag function drops the interpolated values entirely",[66,17268,17269,17271,17277],{},[69,17270,71],{},[73,17272,17273,3459,17275],{},[76,17274,78],{},[39,17276,17241],{},[73,17278,17279,17281,17282,17285,17286,17289,17290,17293,17294,17297,17298,17301,17302,17304,17305],{},[76,17280,84],{}," A tag function receives the literal string segments as its first argument (here ",[39,17283,17284],{},"[\"The \", \" costs $\", \".\"]",") and each interpolated expression's ",[104,17287,17288],{},"evaluated value"," as the subsequent arguments, which the rest parameter ",[39,17291,17292],{},"...values"," collects into ",[39,17295,17296],{},"[\"mug\", 42]",". The tag function fully controls how those pieces combine — nothing happens automatically the way an untagged template works. Option C describes what an ",[104,17299,17300],{},"untagged"," template would produce; tagging replaces that default behavior entirely with whatever the function returns. Option D wrongly assumes rest parameters can't capture the interpolated values — ",[39,17303,17292],{}," works exactly like in any other function signature. ",[76,17306,17307],{},"Idiom",[15,17309,17310,17312,17381,17429],{"language":247},[18,17311,13729],{"id":13728},[257,17313,17314],{"language":247},[260,17315,17317],{"className":262,"code":17316,"language":247,"meta":264,"style":264},"function inspect(strings) {\n  console.log(strings[0]);\n  console.log(strings.raw[0]);\n}\n\ninspect`Line1\\nLine2`;\n",[39,17318,17319,17332,17345,17358,17362,17366],{"__ignoreMap":264},[268,17320,17321,17323,17326,17328,17330],{"class":270,"line":271},[268,17322,275],{"class":274},[268,17324,17325],{"class":278}," inspect",[268,17327,622],{"class":282},[268,17329,17076],{"class":1222},[268,17331,1235],{"class":282},[268,17333,17334,17336,17338,17341,17343],{"class":270,"line":286},[268,17335,5556],{"class":282},[268,17337,1356],{"class":278},[268,17339,17340],{"class":282},"(strings[",[268,17342,3307],{"class":305},[268,17344,15180],{"class":282},[268,17346,17347,17349,17351,17354,17356],{"class":270,"line":296},[268,17348,5556],{"class":282},[268,17350,1356],{"class":278},[268,17352,17353],{"class":282},"(strings.raw[",[268,17355,3307],{"class":305},[268,17357,15180],{"class":282},[268,17359,17360],{"class":270,"line":311},[268,17361,314],{"class":282},[268,17363,17364],{"class":270,"line":788},[268,17365,5033],{"emptyLinePlaceholder":35},[268,17367,17368,17371,17374,17376,17379],{"class":270,"line":1951},[268,17369,17370],{"class":278},"inspect",[268,17372,17373],{"class":289},"`Line1",[268,17375,16322],{"class":305},[268,17377,17378],{"class":289},"Line2`",[268,17380,293],{"class":282},[23,17382,17384,17394,17404,17413],{"className":17383},[26],[28,17385,17387,17389,17390,17393],{"className":17386},[31],[33,17388],{"disabled":35,"type":36}," Both lines print identically as ",[39,17391,17392],{},"Line1\\nLine2",", since raw and cooked are always the same for tagged templates",[28,17395,17397,812,17399,2833,17401,17403],{"className":17396},[31],[33,17398],{"disabled":35,"type":36},[39,17400,1274],{},[39,17402,16322],{}," cannot appear in a tagged template literal",[28,17405,17407,17409,17410,17412],{"className":17406},[31],[33,17408],{"disabled":35,"type":36}," The first log prints the literal text ",[39,17411,17392],{},"; the second log prints across two lines",[28,17414,17416,17418,17419,1133,17422,17425,17426,17428],{"className":17415},[31],[33,17417],{"disabled":35,"type":36}," The first log prints across two lines (",[39,17420,17421],{},"Line1",[39,17423,17424],{},"Line2","); the second log prints the literal text ",[39,17427,17392],{}," on one line with a visible backslash",[66,17430,17431,17433,17444],{},[69,17432,71],{},[73,17434,17435,17437,17438,1133,17440,17425,17442,17428],{},[76,17436,78],{}," D — The first log prints across two lines (",[39,17439,17421],{},[39,17441,17424],{},[39,17443,17392],{},[73,17445,17446,17448,17449,17452,17453,17455,17456,17459,17460,17463,17464,17467,17468,17470,17471],{},[76,17447,84],{}," Every tagged template gives the tag function two views of each segment: the \"cooked\" value (",[39,17450,17451],{},"strings[i]","), where escapes like ",[39,17454,16322],{}," are interpreted per normal string rules, and the \"raw\" value (",[39,17457,17458],{},"strings.raw[i]","), which preserves the exact source characters with no escape processing. So ",[39,17461,17462],{},"strings[0]"," contains an actual newline, printing across two lines, while ",[39,17465,17466],{},"strings.raw[0]"," still contains the literal backslash-",[39,17469,4599],{}," characters, printing on one line. This raw\u002Fcooked split is what libraries like styled-components and SQL template tags rely on to recover the original source text. ",[76,17472,17307],{},[15,17474,17475,17477,17529,17568],{"language":247},[18,17476,13927],{"id":13926},[257,17478,17479],{"language":247},[260,17480,17482],{"className":262,"code":17481,"language":247,"meta":264,"style":264},"const emoji = \"😀\";\nconsole.log(emoji.length);\nconsole.log([...emoji].length);\n",[39,17483,17484,17498,17511],{"__ignoreMap":264},[268,17485,17486,17488,17491,17493,17496],{"class":270,"line":271},[268,17487,243],{"class":274},[268,17489,17490],{"class":305}," emoji",[268,17492,616],{"class":274},[268,17494,17495],{"class":289}," \"😀\"",[268,17497,293],{"class":282},[268,17499,17500,17502,17504,17507,17509],{"class":270,"line":286},[268,17501,1353],{"class":282},[268,17503,1356],{"class":278},[268,17505,17506],{"class":282},"(emoji.",[268,17508,3567],{"class":305},[268,17510,628],{"class":282},[268,17512,17513,17515,17517,17520,17522,17525,17527],{"class":270,"line":296},[268,17514,1353],{"class":282},[268,17516,1356],{"class":278},[268,17518,17519],{"class":282},"([",[268,17521,15329],{"class":274},[268,17523,17524],{"class":282},"emoji].",[268,17526,3567],{"class":305},[268,17528,628],{"class":282},[23,17530,17532,17541,17550,17559],{"className":17531},[26],[28,17533,17535,355,17537,1133,17539],{"className":17534},[31],[33,17536],{"disabled":35,"type":36},[39,17538,2255],{},[39,17540,2255],{},[28,17542,17544,355,17546,1133,17548],{"className":17543},[31],[33,17545],{"disabled":35,"type":36},[39,17547,2258],{},[39,17549,2255],{},[28,17551,17553,355,17555,1133,17557],{"className":17552},[31],[33,17554],{"disabled":35,"type":36},[39,17556,2258],{},[39,17558,2258],{},[28,17560,17562,355,17564,1133,17566],{"className":17561},[31],[33,17563],{"disabled":35,"type":36},[39,17565,2255],{},[39,17567,2258],{},[66,17569,17570,17572,17580],{},[69,17571,71],{},[73,17573,17574,1727,17576,1133,17578],{},[76,17575,78],{},[39,17577,2258],{},[39,17579,2255],{},[73,17581,17582,17584,17585,17587,17588,17591,17592,17594,17595,17597,17598,17601,17602,830,17605,17607,17608,17610,17611],{},[76,17583,84],{}," JavaScript strings are UTF-16 internally, and ",[39,17586,3643],{}," counts 16-bit code units, not visible characters. 😀 lies outside the Basic Multilingual Plane, so it's encoded as a ",[104,17589,17590],{},"surrogate pair"," — two UTF-16 code units representing one code point — making ",[39,17593,3643],{}," report ",[39,17596,2258],{}," for what looks like a single character. Spreading a string (",[39,17599,17600],{},"[...emoji]",") uses the string's default iterator, which is defined to yield whole Unicode code points, correctly treating the pair as one element, so ",[39,17603,17604],{},"[...emoji].length",[39,17606,2255],{},". This gap between ",[39,17609,3643],{}," and perceived-character count is why naive truncation of user text containing emoji is a common source of bugs. ",[76,17612,17613],{},"Safety",[15,17615,17616,17620,17686,17734],{"language":247},[18,17617,17619],{"id":17618},"q10-what-does-this-log","Q10. What does this log?",[257,17621,17622],{"language":247},[260,17623,17625],{"className":262,"code":17624,"language":247,"meta":264,"style":264},"const emoji = \"😀\";\nconsole.log(emoji[0]);\nconsole.log(emoji.charCodeAt(0));\nconsole.log(emoji.codePointAt(0));\n",[39,17626,17627,17639,17652,17669],{"__ignoreMap":264},[268,17628,17629,17631,17633,17635,17637],{"class":270,"line":271},[268,17630,243],{"class":274},[268,17632,17490],{"class":305},[268,17634,616],{"class":274},[268,17636,17495],{"class":289},[268,17638,293],{"class":282},[268,17640,17641,17643,17645,17648,17650],{"class":270,"line":286},[268,17642,1353],{"class":282},[268,17644,1356],{"class":278},[268,17646,17647],{"class":282},"(emoji[",[268,17649,3307],{"class":305},[268,17651,15180],{"class":282},[268,17653,17654,17656,17658,17660,17663,17665,17667],{"class":270,"line":296},[268,17655,1353],{"class":282},[268,17657,1356],{"class":278},[268,17659,17506],{"class":282},[268,17661,17662],{"class":278},"charCodeAt",[268,17664,622],{"class":282},[268,17666,3307],{"class":305},[268,17668,4818],{"class":282},[268,17670,17671,17673,17675,17677,17680,17682,17684],{"class":270,"line":311},[268,17672,1353],{"class":282},[268,17674,1356],{"class":278},[268,17676,17506],{"class":282},[268,17678,17679],{"class":278},"codePointAt",[268,17681,622],{"class":282},[268,17683,3307],{"class":305},[268,17685,4818],{"class":282},[23,17687,17689,17695,17708,17723],{"className":17688},[26],[28,17690,17692,17694],{"className":17691},[31],[33,17693],{"disabled":35,"type":36}," All three return the same value, since JS treats emoji as single units for every string API",[28,17696,17698,355,17700,17703,17704,17707],{"className":17697},[31],[33,17699],{"disabled":35,"type":36},[39,17701,17702],{},"charCodeAt(0)"," returns the full code point; ",[39,17705,17706],{},"codePointAt(0)"," returns just the high surrogate half",[28,17709,17711,355,17713,17716,17717,17719,17720,17722],{"className":17710},[31],[33,17712],{"disabled":35,"type":36},[39,17714,17715],{},"emoji[0]"," prints a lone\u002Fgarbled surrogate half; ",[39,17718,17702],{}," returns the high surrogate's code unit value; ",[39,17721,17706],{}," returns the full emoji's actual code point",[28,17724,17726,355,17728,2278,17730,17733],{"className":17725},[31],[33,17727],{"disabled":35,"type":36},[39,17729,17715],{},[39,17731,17732],{},"RangeError",", because indexing into a surrogate pair is invalid",[66,17735,17736,17738,17748],{},[69,17737,71],{},[73,17739,17740,1004,17742,17716,17744,17719,17746,17722],{},[76,17741,78],{},[39,17743,17715],{},[39,17745,17702],{},[39,17747,17706],{},[73,17749,17750,17752,17753,17756,17757,17759,17760,17763,17764,17767,17768],{},[76,17751,84],{}," Bracket indexing and ",[39,17754,17755],{},".charCodeAt()"," both operate on raw UTF-16 code units with no concept of surrogate pairs, so index ",[39,17758,3307],{}," returns just the first unit — a lone high surrogate that doesn't form a valid character on its own. ",[39,17761,17762],{},".codePointAt()",", added specifically to fix this gap, checks whether the code unit at the given index starts a surrogate pair and, if so, combines it with the following low surrogate to return the true code point (",[39,17765,17766],{},"128512","). Nothing throws — string indexing never validates surrogate boundaries, it silently returns whatever unit sits at that position, which is exactly the trap. ",[76,17769,17613],{},[15,17771,17772,17774,17831,17866],{"language":247},[18,17773,14224],{"id":14223},[257,17775,17776],{"language":247},[260,17777,17779],{"className":262,"code":17778,"language":247,"meta":264,"style":264},"console.log(\"Z\" \u003C \"a\");\nconsole.log(\"apple\" \u003C \"Apple\");\nconsole.log(\"2\" \u003C \"10\");\n",[39,17780,17781,17798,17815],{"__ignoreMap":264},[268,17782,17783,17785,17787,17789,17792,17794,17796],{"class":270,"line":271},[268,17784,1353],{"class":282},[268,17786,1356],{"class":278},[268,17788,622],{"class":282},[268,17790,17791],{"class":289},"\"Z\"",[268,17793,6457],{"class":274},[268,17795,10871],{"class":289},[268,17797,628],{"class":282},[268,17799,17800,17802,17804,17806,17808,17810,17813],{"class":270,"line":286},[268,17801,1353],{"class":282},[268,17803,1356],{"class":278},[268,17805,622],{"class":282},[268,17807,14842],{"class":289},[268,17809,6457],{"class":274},[268,17811,17812],{"class":289}," \"Apple\"",[268,17814,628],{"class":282},[268,17816,17817,17819,17821,17823,17825,17827,17829],{"class":270,"line":296},[268,17818,1353],{"class":282},[268,17820,1356],{"class":278},[268,17822,622],{"class":282},[268,17824,9269],{"class":289},[268,17826,6457],{"class":274},[268,17828,16359],{"class":289},[268,17830,628],{"class":282},[23,17832,17834,17842,17850,17858],{"className":17833},[26],[28,17835,17837,355,17839],{"className":17836},[31],[33,17838],{"disabled":35,"type":36},[39,17840,17841],{},"true, true, true",[28,17843,17845,355,17847],{"className":17844},[31],[33,17846],{"disabled":35,"type":36},[39,17848,17849],{},"false, true, false",[28,17851,17853,355,17855],{"className":17852},[31],[33,17854],{"disabled":35,"type":36},[39,17856,17857],{},"false, false, true",[28,17859,17861,355,17863],{"className":17860},[31],[33,17862],{"disabled":35,"type":36},[39,17864,17865],{},"true, false, false",[66,17867,17868,17870,17876],{},[69,17869,71],{},[73,17871,17872,6901,17874],{},[76,17873,78],{},[39,17875,17865],{},[73,17877,17878,17880,17881,17883,17884,17886,17887,17889,17890,830,17893,17895,17896,17899,17900,17903,17904,830,17907,17909,17910,17913,17914,17917,17918],{},[76,17879,84],{}," String comparison operators compare lexicographically by UTF-16 code unit value, not by alphabetical or locale-aware rules. Uppercase ASCII letters (65–90) all have lower code points than lowercase letters (97–122), so ",[39,17882,17791],{}," (90) sorts before ",[39,17885,7582],{}," (97) — ",[39,17888,2185],{},". For the same reason ",[39,17891,17892],{},"\"apple\" \u003C \"Apple\"",[39,17894,2986],{},": comparing first characters, lowercase ",[39,17897,17898],{},"'a'"," (97) is greater than uppercase ",[39,17901,17902],{},"'A'"," (65). And ",[39,17905,17906],{},"\"2\" \u003C \"10\"",[39,17908,2986],{}," because string comparison never parses numeric value — it compares character-by-character, and ",[39,17911,17912],{},"'2'"," (50) is greater than ",[39,17915,17916],{},"'1'"," (49), regardless of 2 being numerically less than 10. ",[76,17919,16523],{},[15,17921,17922,17924,17981,18016],{"language":247},[18,17923,14382],{"id":14381},[257,17925,17926],{"language":247},[260,17927,17929],{"className":262,"code":17928,"language":247,"meta":264,"style":264},"const input = \"2024-06-15\";\nconst parts = input.split(\u002F(-)\u002F);\nconsole.log(parts);\n",[39,17930,17931,17945,17972],{"__ignoreMap":264},[268,17932,17933,17935,17938,17940,17943],{"class":270,"line":271},[268,17934,243],{"class":274},[268,17936,17937],{"class":305}," input",[268,17939,616],{"class":274},[268,17941,17942],{"class":289}," \"2024-06-15\"",[268,17944,293],{"class":282},[268,17946,17947,17949,17952,17954,17957,17960,17962,17964,17968,17970],{"class":270,"line":286},[268,17948,243],{"class":274},[268,17950,17951],{"class":305}," parts",[268,17953,616],{"class":274},[268,17955,17956],{"class":282}," input.",[268,17958,17959],{"class":278},"split",[268,17961,622],{"class":282},[268,17963,446],{"class":289},[268,17965,17967],{"class":17966},"svAP2","(-)",[268,17969,446],{"class":289},[268,17971,628],{"class":282},[268,17973,17974,17976,17978],{"class":270,"line":296},[268,17975,1353],{"class":282},[268,17977,1356],{"class":278},[268,17979,17980],{"class":282},"(parts);\n",[23,17982,17984,17992,18000,18008],{"className":17983},[26],[28,17985,17987,355,17989],{"className":17986},[31],[33,17988],{"disabled":35,"type":36},[39,17990,17991],{},"[\"2024\", \"-\", \"06\", \"-\", \"15\"]",[28,17993,17995,355,17997],{"className":17994},[31],[33,17996],{"disabled":35,"type":36},[39,17998,17999],{},"[\"2024\", \"06\", \"15\"]",[28,18001,18003,355,18005],{"className":18002},[31],[33,18004],{"disabled":35,"type":36},[39,18006,18007],{},"[\"2024-06-15\"]",[28,18009,18011,355,18013],{"className":18010},[31],[33,18012],{"disabled":35,"type":36},[39,18014,18015],{},"[\"2024\", \"06\", \"15\", \"-\", \"-\"]",[66,18017,18018,18020,18026],{},[69,18019,71],{},[73,18021,18022,3459,18024],{},[76,18023,78],{},[39,18025,17991],{},[73,18027,18028,18030,18031,18034,18035,18038,18039,18042,18043,18045,18046],{},[76,18029,84],{}," When the separator passed to ",[39,18032,18033],{},".split()"," is a regex with a ",[104,18036,18037],{},"capturing group",", the spec splices the captured groups into the result array between the surrounding pieces — a deliberate feature for retaining delimiters when needed. A plain non-capturing ",[39,18040,18041],{},"\u002F-\u002F "," would produce ",[39,18044,17999],{}," with the dashes discarded, which is what most people expect and what trips them up when they add parentheses for grouping without realizing it changes the output shape. Option D's ordering is wrong because captures are interleaved at the position they occurred, not appended at the end. ",[76,18047,17307],{},[15,18049,18050,18052,18120,18166],{"language":247},[18,18051,14538],{"id":14537},[257,18053,18054],{"language":247},[260,18055,18057],{"className":262,"code":18056,"language":247,"meta":264,"style":264},"const text = \"Hi😀!\";\nconsole.log(text.split(\"\").length);\nconsole.log(text.split(\"\").join(\"|\"));\n",[39,18058,18059,18073,18094],{"__ignoreMap":264},[268,18060,18061,18063,18066,18068,18071],{"class":270,"line":271},[268,18062,243],{"class":274},[268,18064,18065],{"class":305}," text",[268,18067,616],{"class":274},[268,18069,18070],{"class":289}," \"Hi😀!\"",[268,18072,293],{"class":282},[268,18074,18075,18077,18079,18082,18084,18086,18088,18090,18092],{"class":270,"line":286},[268,18076,1353],{"class":282},[268,18078,1356],{"class":278},[268,18080,18081],{"class":282},"(text.",[268,18083,17959],{"class":278},[268,18085,622],{"class":282},[268,18087,3294],{"class":289},[268,18089,6232],{"class":282},[268,18091,3567],{"class":305},[268,18093,628],{"class":282},[268,18095,18096,18098,18100,18102,18104,18106,18108,18110,18113,18115,18118],{"class":270,"line":296},[268,18097,1353],{"class":282},[268,18099,1356],{"class":278},[268,18101,18081],{"class":282},[268,18103,17959],{"class":278},[268,18105,622],{"class":282},[268,18107,3294],{"class":289},[268,18109,6232],{"class":282},[268,18111,18112],{"class":278},"join",[268,18114,622],{"class":282},[268,18116,18117],{"class":289},"\"|\"",[268,18119,4818],{"class":282},[23,18121,18123,18131,18143,18154],{"className":18122},[26],[28,18124,18126,355,18128,18130],{"className":18125},[31],[33,18127],{"disabled":35,"type":36},[39,18129,15049],{}," and the emoji renders intact in the joined string",[28,18132,18134,355,18136,18138,18139,18142],{"className":18133},[31],[33,18135],{"disabled":35,"type":36},[39,18137,2429],{}," and the emoji is split apart, appearing as two broken glyphs separated by a ",[39,18140,18141],{},"|"," in the joined string",[28,18144,18146,355,18148,18150,18151],{"className":18145},[31],[33,18147],{"disabled":35,"type":36},[39,18149,2429],{}," and the emoji renders intact between two pipes, e.g. ",[39,18152,18153],{},"H|i|😀|!",[28,18155,18157,812,18159,18161,18162,18165],{"className":18156},[31],[33,18158],{"disabled":35,"type":36},[39,18160,17732],{}," is thrown, because ",[39,18163,18164],{},"split(\"\")"," cannot split a surrogate pair",[66,18167,18168,18170,18178],{},[69,18169,71],{},[73,18171,18172,1727,18174,18138,18176,18142],{},[76,18173,78],{},[39,18175,2429],{},[39,18177,18141],{},[73,18179,18180,355,18182,18185,18186,42,18189,18191,18192,18194,18195,18198,18199,18202,18203,99,18206,18209,18210],{},[76,18181,84],{},[39,18183,18184],{},".split(\"\")"," breaks a string at every UTF-16 code unit boundary, exactly like indexing — it has no awareness of surrogate pairs. Since 😀 is stored as two code units, splitting produces five array elements (",[39,18187,18188],{},"H",[39,18190,9509],{},", high surrogate, low surrogate, ",[39,18193,5418],{},"), not four, and ",[39,18196,18197],{},".join(\"|\")"," inserts a pipe ",[104,18200,18201],{},"between"," the two surrogate halves, visibly corrupting the emoji into two broken glyphs. Nothing throws — string operations never validate surrogate boundaries. The safe way to split into user-perceived characters is ",[39,18204,18205],{},"[...text]",[39,18207,18208],{},"Array.from(text)",", which iterate by code point. ",[76,18211,17613],{},[15,18213,18214,18216,18312,18364],{"language":247},[18,18215,14774],{"id":14773},[257,18217,18218],{"language":247},[260,18219,18221],{"className":262,"code":18220,"language":247,"meta":264,"style":264},"const log = \"error: retrying... error: retrying... error: done\";\nconst withString = log.replace(\"error\", \"OK\");\nconst withRegex = log.replace(\u002Ferror\u002Fg, \"OK\");\nconsole.log(withString);\nconsole.log(withRegex);\n",[39,18222,18223,18236,18263,18294,18303],{"__ignoreMap":264},[268,18224,18225,18227,18229,18231,18234],{"class":270,"line":271},[268,18226,243],{"class":274},[268,18228,16942],{"class":305},[268,18230,616],{"class":274},[268,18232,18233],{"class":289}," \"error: retrying... error: retrying... error: done\"",[268,18235,293],{"class":282},[268,18237,18238,18240,18243,18245,18248,18251,18253,18256,18258,18261],{"class":270,"line":286},[268,18239,243],{"class":274},[268,18241,18242],{"class":305}," withString",[268,18244,616],{"class":274},[268,18246,18247],{"class":282}," log.",[268,18249,18250],{"class":278},"replace",[268,18252,622],{"class":282},[268,18254,18255],{"class":289},"\"error\"",[268,18257,42],{"class":282},[268,18259,18260],{"class":289},"\"OK\"",[268,18262,628],{"class":282},[268,18264,18265,18267,18270,18272,18274,18276,18278,18280,18283,18285,18288,18290,18292],{"class":270,"line":296},[268,18266,243],{"class":274},[268,18268,18269],{"class":305}," withRegex",[268,18271,616],{"class":274},[268,18273,18247],{"class":282},[268,18275,18250],{"class":278},[268,18277,622],{"class":282},[268,18279,446],{"class":289},[268,18281,18282],{"class":17966},"error",[268,18284,446],{"class":289},[268,18286,18287],{"class":274},"g",[268,18289,42],{"class":282},[268,18291,18260],{"class":289},[268,18293,628],{"class":282},[268,18295,18296,18298,18300],{"class":270,"line":311},[268,18297,1353],{"class":282},[268,18299,1356],{"class":278},[268,18301,18302],{"class":282},"(withString);\n",[268,18304,18305,18307,18309],{"class":270,"line":788},[268,18306,1353],{"class":282},[268,18308,1356],{"class":278},[268,18310,18311],{"class":282},"(withRegex);\n",[23,18313,18315,18325,18335,18353],{"className":18314},[26],[28,18316,18318,18320,18321,2029,18323],{"className":18317},[31],[33,18319],{"disabled":35,"type":36}," Both replace every occurrence of ",[39,18322,18255],{},[39,18324,18260],{},[28,18326,18328,18330,18331,18334],{"className":18327},[31],[33,18329],{"disabled":35,"type":36}," Both replace only the first occurrence, since ",[39,18332,18333],{},".replace()"," never replaces more than one match regardless of pattern type",[28,18336,18338,355,18340,18343,18344,2272,18346,18349,18350,18352],{"className":18337},[31],[33,18339],{"disabled":35,"type":36},[39,18341,18342],{},"withString"," replaces only the first ",[39,18345,18255],{},[39,18347,18348],{},"withRegex"," replaces every occurrence because of the ",[39,18351,18287],{}," flag",[28,18354,18356,355,18358,18360,18361,18363],{"className":18355},[31],[33,18357],{"disabled":35,"type":36},[39,18359,18342],{}," replaces every occurrence; ",[39,18362,18348],{}," replaces only the first, because regex patterns default to single-match unless quoted",[66,18365,18366,18368,18380],{},[69,18367,71],{},[73,18369,18370,1004,18372,18343,18374,2272,18376,18349,18378,18352],{},[76,18371,78],{},[39,18373,18342],{},[39,18375,18255],{},[39,18377,18348],{},[39,18379,18287],{},[73,18381,18382,18384,18385,18387,18388,18390,18391,18393,18394,18397,18398,18400,18401,446,18403,18405,18406,18409,18410],{},[76,18383,84],{}," When the search pattern passed to ",[39,18386,18333],{}," is a plain string, it's treated as a literal, single-match search — only the first occurrence is replaced no matter how many times it appears. To replace every match you need a regex with the global (",[39,18389,18287],{},") flag; without ",[39,18392,18287],{},", even a regex would only replace the first match. This trips people up because ",[39,18395,18396],{},".replaceAll()"," (ES2021) ",[104,18399,10043],{}," replace every occurrence with a string pattern, so confusing ",[39,18402,18333],{},[39,18404,18396],{}," semantics, or forgetting ",[39,18407,18408],{},"\u002Fg",", is a common \"why did only one get replaced\" bug. ",[76,18411,16523],{},[15,18413,18414,18418,18523,18572],{"language":247},[18,18415,18417],{"id":18416},"q15-what-does-this-log","Q15. What does this log?",[257,18419,18420],{"language":247},[260,18421,18423],{"className":262,"code":18422,"language":247,"meta":264,"style":264},"const raw = \"price: 42 dollars\";\nconst withCapture = raw.replace(\u002F(\\d+)\u002F, \"[$1]\");\nconst withMatch = raw.replace(\u002F\\d+\u002F, \"\u003C$&>\");\nconsole.log(withCapture);\nconsole.log(withMatch);\n",[39,18424,18425,18439,18475,18505,18514],{"__ignoreMap":264},[268,18426,18427,18429,18432,18434,18437],{"class":270,"line":271},[268,18428,243],{"class":274},[268,18430,18431],{"class":305}," raw",[268,18433,616],{"class":274},[268,18435,18436],{"class":289}," \"price: 42 dollars\"",[268,18438,293],{"class":282},[268,18440,18441,18443,18446,18448,18451,18453,18455,18457,18459,18462,18464,18466,18468,18470,18473],{"class":270,"line":286},[268,18442,243],{"class":274},[268,18444,18445],{"class":305}," withCapture",[268,18447,616],{"class":274},[268,18449,18450],{"class":282}," raw.",[268,18452,18250],{"class":278},[268,18454,622],{"class":282},[268,18456,446],{"class":289},[268,18458,622],{"class":17966},[268,18460,18461],{"class":305},"\\d",[268,18463,1246],{"class":274},[268,18465,2690],{"class":17966},[268,18467,446],{"class":289},[268,18469,42],{"class":282},[268,18471,18472],{"class":289},"\"[$1]\"",[268,18474,628],{"class":282},[268,18476,18477,18479,18482,18484,18486,18488,18490,18492,18494,18496,18498,18500,18503],{"class":270,"line":296},[268,18478,243],{"class":274},[268,18480,18481],{"class":305}," withMatch",[268,18483,616],{"class":274},[268,18485,18450],{"class":282},[268,18487,18250],{"class":278},[268,18489,622],{"class":282},[268,18491,446],{"class":289},[268,18493,18461],{"class":305},[268,18495,1246],{"class":274},[268,18497,446],{"class":289},[268,18499,42],{"class":282},[268,18501,18502],{"class":289},"\"\u003C$&>\"",[268,18504,628],{"class":282},[268,18506,18507,18509,18511],{"class":270,"line":311},[268,18508,1353],{"class":282},[268,18510,1356],{"class":278},[268,18512,18513],{"class":282},"(withCapture);\n",[268,18515,18516,18518,18520],{"class":270,"line":788},[268,18517,1353],{"class":282},[268,18519,1356],{"class":278},[268,18521,18522],{"class":282},"(withMatch);\n",[23,18524,18526,18537,18551,18562],{"className":18525},[26],[28,18527,18529,355,18531,186,18534],{"className":18528},[31],[33,18530],{"disabled":35,"type":36},[39,18532,18533],{},"\"price: [$1] dollars\"",[39,18535,18536],{},"\"price: \u003C$&> dollars\"",[28,18538,18540,812,18542,2833,18544,186,18547,18550],{"className":18539},[31],[33,18541],{"disabled":35,"type":36},[39,18543,1274],{},[39,18545,18546],{},"$1",[39,18548,18549],{},"$&"," are not valid inside replacement strings",[28,18552,18554,355,18556,186,18559],{"className":18553},[31],[33,18555],{"disabled":35,"type":36},[39,18557,18558],{},"\"price: [42] dollars\"",[39,18560,18561],{},"\"price: \u003Cdollars> dollars\"",[28,18563,18565,355,18567,186,18569],{"className":18564},[31],[33,18566],{"disabled":35,"type":36},[39,18568,18558],{},[39,18570,18571],{},"\"price: \u003C42> dollars\"",[66,18573,18574,18576,18584],{},[69,18575,71],{},[73,18577,18578,6901,18580,186,18582],{},[76,18579,78],{},[39,18581,18558],{},[39,18583,18571],{},[73,18585,18586,18588,18589,18591,18592,18594,18595,18598,18599,18601,18602,18604,18605],{},[76,18587,84],{}," In a ",[39,18590,18333],{}," replacement string, ",[39,18593,18546],{}," (through ",[39,18596,18597],{},"$9",") refers to the text captured by the corresponding parenthesized group, and ",[39,18600,18549],{}," refers to the entire matched substring — these are special tokens the engine substitutes, not literal characters. Both examples correctly substitute the matched number, ",[39,18603,4659],{},". Someone unfamiliar with these tokens might assume they render as literal text (option A) or that they require a callback function to work — but this replacement-string mini-syntax handles it without one. ",[76,18606,17307],{},[15,18608,18609,18611,18688,18739],{"language":247},[18,18610,15131],{"id":15130},[257,18612,18613],{"language":247},[260,18614,18616],{"className":262,"code":18615,"language":247,"meta":264,"style":264},"console.log(\"5\".padStart(3));\nconsole.log(\"5\".padStart(3, \"0\"));\nconsole.log(\"5\".padEnd(3, \"0\"));\n",[39,18617,18618,18639,18663],{"__ignoreMap":264},[268,18619,18620,18622,18624,18626,18628,18630,18633,18635,18637],{"class":270,"line":271},[268,18621,1353],{"class":282},[268,18623,1356],{"class":278},[268,18625,622],{"class":282},[268,18627,3162],{"class":289},[268,18629,462],{"class":282},[268,18631,18632],{"class":278},"padStart",[268,18634,622],{"class":282},[268,18636,3423],{"class":305},[268,18638,4818],{"class":282},[268,18640,18641,18643,18645,18647,18649,18651,18653,18655,18657,18659,18661],{"class":270,"line":286},[268,18642,1353],{"class":282},[268,18644,1356],{"class":278},[268,18646,622],{"class":282},[268,18648,3162],{"class":289},[268,18650,462],{"class":282},[268,18652,18632],{"class":278},[268,18654,622],{"class":282},[268,18656,3423],{"class":305},[268,18658,42],{"class":282},[268,18660,8721],{"class":289},[268,18662,4818],{"class":282},[268,18664,18665,18667,18669,18671,18673,18675,18678,18680,18682,18684,18686],{"class":270,"line":296},[268,18666,1353],{"class":282},[268,18668,1356],{"class":278},[268,18670,622],{"class":282},[268,18672,3162],{"class":289},[268,18674,462],{"class":282},[268,18676,18677],{"class":278},"padEnd",[268,18679,622],{"class":282},[268,18681,3423],{"class":305},[268,18683,42],{"class":282},[268,18685,8721],{"class":289},[268,18687,4818],{"class":282},[23,18689,18691,18705,18716,18728],{"className":18690},[26],[28,18692,18694,355,18696,42,18699,42,18702],{"className":18693},[31],[33,18695],{"disabled":35,"type":36},[39,18697,18698],{},"\"  5\"",[39,18700,18701],{},"\"005\"",[39,18703,18704],{},"\"500\"",[28,18706,18708,355,18710,42,18712,42,18714],{"className":18707},[31],[33,18709],{"disabled":35,"type":36},[39,18711,18701],{},[39,18713,18701],{},[39,18715,18704],{},[28,18717,18719,355,18721,42,18724,42,18726],{"className":18718},[31],[33,18720],{"disabled":35,"type":36},[39,18722,18723],{},"\"5  \"",[39,18725,18701],{},[39,18727,18704],{},[28,18729,18731,355,18733,42,18735,42,18737],{"className":18730},[31],[33,18732],{"disabled":35,"type":36},[39,18734,18698],{},[39,18736,18704],{},[39,18738,18701],{},[66,18740,18741,18743,18753],{},[69,18742,71],{},[73,18744,18745,3459,18747,42,18749,42,18751],{},[76,18746,78],{},[39,18748,18698],{},[39,18750,18701],{},[39,18752,18704],{},[73,18754,18755,355,18757,446,18760,18763,18764,15637,18767,18769,18770,7159,18773,18775,18776,18778,18779,18781,18782,18784,18785,18787,18788],{},[76,18756,84],{},[39,18758,18759],{},".padStart()",[39,18761,18762],{},".padEnd()"," take an optional second argument for the pad string, and when it's omitted the default pad character is a plain space ",[39,18765,18766],{},"\" \"",[39,18768,8721],{}," as many assume from seeing it used for zero-padding numbers. So ",[39,18771,18772],{},"\"5\".padStart(3)",[39,18774,18698],{}," (two leading spaces), not ",[39,18777,18701],{},"; you must explicitly pass ",[39,18780,8721],{}," for numeric zero-padding. ",[39,18783,18632],{}," pads at the beginning (right-aligning, e.g. clock digits), while ",[39,18786,18677],{}," pads at the end (left-aligning fixed-width output); mixing them up is a common off-by-direction bug. ",[76,18789,17307],{},[15,18791,18792,18794,18885,18933],{"language":247},[18,18793,15311],{"id":15310},[257,18795,18796],{"language":247},[260,18797,18799],{"className":262,"code":18798,"language":247,"meta":264,"style":264},"const raw = \"   pending review   \";\nconsole.log(`[${raw.trim()}]`);\nconsole.log(`[${raw.trimStart()}]`);\nconsole.log(`[${raw.trimEnd()}]`);\n",[39,18800,18801,18814,18839,18862],{"__ignoreMap":264},[268,18802,18803,18805,18807,18809,18812],{"class":270,"line":271},[268,18804,243],{"class":274},[268,18806,18431],{"class":305},[268,18808,616],{"class":274},[268,18810,18811],{"class":289}," \"   pending review   \"",[268,18813,293],{"class":282},[268,18815,18816,18818,18820,18822,18825,18828,18830,18833,18835,18837],{"class":270,"line":286},[268,18817,1353],{"class":282},[268,18819,1356],{"class":278},[268,18821,622],{"class":282},[268,18823,18824],{"class":289},"`[${",[268,18826,18827],{"class":282},"raw",[268,18829,462],{"class":289},[268,18831,18832],{"class":278},"trim",[268,18834,16952],{"class":289},[268,18836,17152],{"class":289},[268,18838,628],{"class":282},[268,18840,18841,18843,18845,18847,18849,18851,18853,18856,18858,18860],{"class":270,"line":296},[268,18842,1353],{"class":282},[268,18844,1356],{"class":278},[268,18846,622],{"class":282},[268,18848,18824],{"class":289},[268,18850,18827],{"class":282},[268,18852,462],{"class":289},[268,18854,18855],{"class":278},"trimStart",[268,18857,16952],{"class":289},[268,18859,17152],{"class":289},[268,18861,628],{"class":282},[268,18863,18864,18866,18868,18870,18872,18874,18876,18879,18881,18883],{"class":270,"line":311},[268,18865,1353],{"class":282},[268,18867,1356],{"class":278},[268,18869,622],{"class":282},[268,18871,18824],{"class":289},[268,18873,18827],{"class":282},[268,18875,462],{"class":289},[268,18877,18878],{"class":278},"trimEnd",[268,18880,16952],{"class":289},[268,18882,17152],{"class":289},[268,18884,628],{"class":282},[23,18886,18888,18897,18911,18922],{"className":18887},[26],[28,18889,18891,355,18893,18896],{"className":18890},[31],[33,18892],{"disabled":35,"type":36},[39,18894,18895],{},"[   pending review   ]"," for all three, since trim variants only affect console output, not the actual string",[28,18898,18900,355,18902,42,18905,42,18908],{"className":18899},[31],[33,18901],{"disabled":35,"type":36},[39,18903,18904],{},"[pending review]",[39,18906,18907],{},"[pending review   ]",[39,18909,18910],{},"[   pending review]",[28,18912,18914,355,18916,42,18918,42,18920],{"className":18913},[31],[33,18915],{"disabled":35,"type":36},[39,18917,18904],{},[39,18919,18904],{},[39,18921,18904],{},[28,18923,18925,355,18927,42,18929,42,18931],{"className":18924},[31],[33,18926],{"disabled":35,"type":36},[39,18928,18904],{},[39,18930,18910],{},[39,18932,18907],{},[66,18934,18935,18937,18947],{},[69,18936,71],{},[73,18938,18939,1727,18941,42,18943,42,18945],{},[76,18940,78],{},[39,18942,18904],{},[39,18944,18907],{},[39,18946,18910],{},[73,18948,18949,355,18951,18954,18955,18958,18959,18962,18963,18958,18966,18969,18970,18972,18973],{},[76,18950,84],{},[39,18952,18953],{},".trim()"," strips whitespace from both ends. ",[39,18956,18957],{},".trimStart()"," removes only ",[104,18960,18961],{},"leading"," whitespace, leaving trailing spaces intact, while ",[39,18964,18965],{},".trimEnd()",[104,18967,18968],{},"trailing"," whitespace, leaving leading spaces intact. All three return a new string — none mutate ",[39,18971,18827],{}," — so each call in the example operates on the original, still-padded string, not on a progressively trimmed one. This distinction matters when formatting user input where indentation on one side is intentional. ",[76,18974,17307],{},[15,18976,18977,18981,19067,19134],{"language":247},[18,18978,18980],{"id":18979},"q18-what-does-this-log","Q18. What does this log?",[257,18982,18983],{"language":247},[260,18984,18986],{"className":262,"code":18985,"language":247,"meta":264,"style":264},"const words = [\"café\", \"cafe\", \"cafz\"];\nconsole.log([...words].sort());\nconsole.log([...words].sort((a, b) => a.localeCompare(b)));\n",[39,18987,18988,19014,19032],{"__ignoreMap":264},[268,18989,18990,18992,18995,18997,18999,19002,19004,19007,19009,19012],{"class":270,"line":271},[268,18991,243],{"class":274},[268,18993,18994],{"class":305}," words",[268,18996,616],{"class":274},[268,18998,8710],{"class":282},[268,19000,19001],{"class":289},"\"café\"",[268,19003,42],{"class":282},[268,19005,19006],{"class":289},"\"cafe\"",[268,19008,42],{"class":282},[268,19010,19011],{"class":289},"\"cafz\"",[268,19013,8737],{"class":282},[268,19015,19016,19018,19020,19022,19024,19027,19030],{"class":270,"line":286},[268,19017,1353],{"class":282},[268,19019,1356],{"class":278},[268,19021,17519],{"class":282},[268,19023,15329],{"class":274},[268,19025,19026],{"class":282},"words].",[268,19028,19029],{"class":278},"sort",[268,19031,8174],{"class":282},[268,19033,19034,19036,19038,19040,19042,19044,19046,19048,19050,19052,19054,19056,19058,19061,19064],{"class":270,"line":296},[268,19035,1353],{"class":282},[268,19037,1356],{"class":278},[268,19039,17519],{"class":282},[268,19041,15329],{"class":274},[268,19043,19026],{"class":282},[268,19045,19029],{"class":278},[268,19047,6122],{"class":282},[268,19049,1223],{"class":1222},[268,19051,42],{"class":282},[268,19053,1232],{"class":1222},[268,19055,6131],{"class":282},[268,19057,9414],{"class":274},[268,19059,19060],{"class":282}," a.",[268,19062,19063],{"class":278},"localeCompare",[268,19065,19066],{"class":282},"(b)));\n",[23,19068,19070,19083,19094,19118],{"className":19069},[26],[28,19071,19073,19075,19076,4387,19079,19082],{"className":19072},[31],[33,19074],{"disabled":35,"type":36}," Both produce the same alphabetically correct order, ",[39,19077,19078],{},"[\"cafe\", \"café\", \"cafz\"]",[39,19080,19081],{},".sort()"," is locale-aware by default in modern engines",[28,19084,19086,19088,19089,2278,19091,19093],{"className":19085},[31],[33,19087],{"disabled":35,"type":36}," Default ",[39,19090,19081],{},[39,19092,827],{},", because it cannot compare strings containing accented characters",[28,19095,19097,19088,19099,2906,19101,19104,19105,19108,19109,5789,19112,2906,19115,19117],{"className":19096},[31],[33,19098],{"disabled":35,"type":36},[39,19100,19081],{},[39,19102,19103],{},"[\"cafe\", \"cafz\", \"café\"]"," (comparing raw UTF-16 code points, where ",[39,19106,19107],{},"'é'"," sorts after ",[39,19110,19111],{},"'z'",[39,19113,19114],{},".localeCompare()",[39,19116,19078],{}," (locale-aware, alphabetically correct)",[28,19119,19121,355,19123,2906,19125,19127,19128,19130,19131,19133],{"className":19120},[31],[33,19122],{"disabled":35,"type":36},[39,19124,19114],{},[39,19126,19103],{},"; default ",[39,19129,19081],{}," gives the alphabetically correct ",[39,19132,19078],{}," — the two are swapped from what most people expect",[66,19135,19136,19138,19155],{},[69,19137,71],{},[73,19139,19140,19142,19143,2906,19145,19104,19147,19108,19149,5789,19151,2906,19153,19117],{},[76,19141,78],{}," C — Default ",[39,19144,19081],{},[39,19146,19103],{},[39,19148,19107],{},[39,19150,19111],{},[39,19152,19114],{},[39,19154,19078],{},[73,19156,19157,19159,19160,19162,19163,19166,19167,19170,19171,19173,19174,19108,19176,19178,19179,3277,19181,19183,19184,99,19186,19189,19190],{},[76,19158,84],{}," The default ",[39,19161,19081],{}," comparator converts elements to strings and compares them by UTF-16 code unit value. Accented ",[39,19164,19165],{},"é"," (U+00E9 = 233) has a higher code point than both ",[39,19168,19169],{},"'e'"," (101) and ",[39,19172,19111],{}," (122), so ",[39,19175,19001],{},[39,19177,19011],{}," even though a human expects it right next to ",[39,19180,19006],{},[39,19182,19114],{}," uses the environment's locale-aware collation (ICU), which treats diacritics as minor variations of a base letter for sorting, producing the intuitive order. This is why user-facing lists of names\u002Fwords should be sorted with ",[39,19185,19114],{},[39,19187,19188],{},"Intl.Collator",", not the default comparator. ",[76,19191,17307],{},[15,19193,19194,19201,19239],{},[18,19195,19197,19198,19200],{"id":19196},"q19-which-statement-best-captures-why-template-literals-are-generally-preferred-over-concatenation-for-building-strings-with-embedded-values","Q19. Which statement best captures why template literals are generally preferred over ",[39,19199,1246],{}," concatenation for building strings with embedded values?",[23,19202,19204,19213,19222,19230],{"className":19203},[26],[28,19205,19207,19209,19210,19212],{"className":19206},[31],[33,19208],{"disabled":35,"type":36}," String concatenation with ",[39,19211,1246],{}," should always be preferred because it performs better than template literals in every JS engine",[28,19214,19216,19218,19219,19221],{"className":19215},[31],[33,19217],{"disabled":35,"type":36}," Template literals are purely syntactic sugar with no practical benefit over ",[39,19220,1246],{}," concatenation, so the choice is only about personal style",[28,19223,19225,355,19227,19229],{"className":19224},[31],[33,19226],{"disabled":35,"type":36},[39,19228,1246],{}," concatenation should be preferred whenever numbers are involved, since template literals silently convert numbers to strings and lose precision",[28,19231,19233,19235,19236,19238],{"className":19232},[31],[33,19234],{"disabled":35,"type":36}," Template literals read closer to the final output, avoid ",[39,19237,1246],{},"'s string\u002Fnumber coercion ambiguity when concatenating operands, and support multi-line text without escape characters",[66,19240,19241,19243,19250],{},[69,19242,71],{},[73,19244,19245,19247,19248,19238],{},[76,19246,78],{}," D — Template literals read closer to the final output, avoid ",[39,19249,1246],{},[73,19251,19252,19254,19255,16134,19258,19261,19262,19264,19265,19267,19268,19271,19272,446,19274,19276,19277,4977,19280,2758,19283,19286,19287,19290,19291,19293,19294],{},[76,19253,84],{}," Template literals let you see the shape of the final string directly in the source (",[39,19256,19257],{},"`Hello, ${name}!`",[39,19259,19260],{},"\"Hello, \" + name + \"!\"","), reducing bugs from misplaced quotes or operators in longer chains. They also sidestep a specific ",[39,19263,1246],{}," trap: because ",[39,19266,1246],{}," is overloaded for both numeric addition and string concatenation, expressions like ",[39,19269,19270],{},"\"Total: \" + a + b"," can silently produce wrong results if ",[39,19273,1223],{},[39,19275,1232],{}," were meant to be summed first (",[39,19278,19279],{},"\"Total: \" + 1 + 2",[39,19281,19282],{},"\"Total: 12\"",[39,19284,19285],{},"\"Total: 3\"","), whereas ",[39,19288,19289],{},"`Total: ${a + b}`"," makes the intended arithmetic explicit. Multi-line strings are also native, with no ",[39,19292,16322],{}," escapes needed. Neither performance (A) nor precision loss (C) are legitimate concerns — both forms convert values via the same ToString semantics, and modern engines optimize both similarly. ",[76,19295,17307],{},[15,19297,19298,19302,19391,19443],{"language":247},[18,19299,19301],{"id":19300},"q20-what-does-this-log","Q20. What does this log?",[257,19303,19304],{"language":247},[260,19305,19307],{"className":262,"code":19306,"language":247,"meta":264,"style":264},"function reverse(str) {\n  return str.split(\"\").reverse().join(\"\");\n}\n\nconsole.log(reverse(\"abc\"));\nconsole.log(reverse(\"Hi😀\"));\n",[39,19308,19309,19322,19350,19354,19358,19374],{"__ignoreMap":264},[268,19310,19311,19313,19316,19318,19320],{"class":270,"line":271},[268,19312,275],{"class":274},[268,19314,19315],{"class":278}," reverse",[268,19317,622],{"class":282},[268,19319,17109],{"class":1222},[268,19321,1235],{"class":282},[268,19323,19324,19326,19328,19330,19332,19334,19336,19339,19342,19344,19346,19348],{"class":270,"line":286},[268,19325,1240],{"class":274},[268,19327,15859],{"class":282},[268,19329,17959],{"class":278},[268,19331,622],{"class":282},[268,19333,3294],{"class":289},[268,19335,6232],{"class":282},[268,19337,19338],{"class":278},"reverse",[268,19340,19341],{"class":282},"().",[268,19343,18112],{"class":278},[268,19345,622],{"class":282},[268,19347,3294],{"class":289},[268,19349,628],{"class":282},[268,19351,19352],{"class":270,"line":296},[268,19353,314],{"class":282},[268,19355,19356],{"class":270,"line":311},[268,19357,5033],{"emptyLinePlaceholder":35},[268,19359,19360,19362,19364,19366,19368,19370,19372],{"class":270,"line":788},[268,19361,1353],{"class":282},[268,19363,1356],{"class":278},[268,19365,622],{"class":282},[268,19367,19338],{"class":278},[268,19369,622],{"class":282},[268,19371,7004],{"class":289},[268,19373,4818],{"class":282},[268,19375,19376,19378,19380,19382,19384,19386,19389],{"class":270,"line":1951},[268,19377,1353],{"class":282},[268,19379,1356],{"class":278},[268,19381,622],{"class":282},[268,19383,19338],{"class":278},[268,19385,622],{"class":282},[268,19387,19388],{"class":289},"\"Hi😀\"",[268,19390,4818],{"class":282},[23,19392,19394,19407,19418,19432],{"className":19393},[26],[28,19395,19397,355,19399,19402,19403,19406],{"className":19396},[31],[33,19398],{"disabled":35,"type":36},[39,19400,19401],{},"\"cba\""," and a string beginning with two broken\u002Fgarbled surrogate halves in the wrong order, followed by ",[39,19404,19405],{},"\"iH\""," — not a valid emoji",[28,19408,19410,355,19412,186,19414,19417],{"className":19409},[31],[33,19411],{"disabled":35,"type":36},[39,19413,19401],{},[39,19415,19416],{},"\"😀iH\""," — both reverse correctly since JavaScript strings always reverse by visual character",[28,19419,19421,355,19423,186,19425,19428,19429,19431],{"className":19420},[31],[33,19422],{"disabled":35,"type":36},[39,19424,19401],{},[39,19426,19427],{},"\"iH😀\""," — the emoji is silently moved but stays visually intact because ",[39,19430,18184],{}," is code-point aware",[28,19433,19435,355,19437,19439,19440,19442],{"className":19434},[31],[33,19436],{"disabled":35,"type":36},[39,19438,19401],{}," and a ",[39,19441,17732],{},", because reversing a surrogate pair is not a defined operation",[66,19444,19445,19447,19455],{},[69,19446,71],{},[73,19448,19449,3459,19451,19402,19453,19406],{},[76,19450,78],{},[39,19452,19401],{},[39,19454,19405],{},[73,19456,19457,355,19459,19461,19462,19465,19466,19469,19470,19473,19474],{},[76,19458,84],{},[39,19460,18184],{}," operates on UTF-16 code units, so it tears the emoji's surrogate pair into two separate array entries; ",[39,19463,19464],{},".reverse()"," then treats those two halves as independent elements and flips their order along with everything else, reassembling them as ",[104,19467,19468],{},"low surrogate followed by high surrogate"," — the opposite of a valid pair — producing a broken result instead of the emoji. This is a real bug pattern in naive \"reverse a string\" utilities. The fix is to reverse by code point, e.g. ",[39,19471,19472],{},"[...str].reverse().join(\"\")",", since the spread iterator groups surrogate pairs into single elements before reversing, keeping each pair intact and correctly ordered. ",[76,19475,17613],{},[2107,19477,19478],{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .svAP2, html code.shiki .svAP2{--shiki-default:#032F62;--shiki-github-dark:#DBEDFF}",{"title":264,"searchDepth":286,"depth":286,"links":19480},[19481,19482,19483,19484,19485,19486,19487,19488,19489,19490,19491,19492,19493,19494,19495,19496,19497,19498,19499,19501],{"id":16060,"depth":296,"text":16061},{"id":12736,"depth":296,"text":12737},{"id":12876,"depth":296,"text":12877},{"id":13031,"depth":296,"text":13032},{"id":13180,"depth":296,"text":13181},{"id":13320,"depth":296,"text":13321},{"id":13527,"depth":296,"text":13528},{"id":13728,"depth":296,"text":13729},{"id":13926,"depth":296,"text":13927},{"id":17618,"depth":296,"text":17619},{"id":14223,"depth":296,"text":14224},{"id":14381,"depth":296,"text":14382},{"id":14537,"depth":296,"text":14538},{"id":14773,"depth":296,"text":14774},{"id":18416,"depth":296,"text":18417},{"id":15130,"depth":296,"text":15131},{"id":15310,"depth":296,"text":15311},{"id":18979,"depth":296,"text":18980},{"id":19196,"depth":296,"text":19500},"Q19. Which statement best captures why template literals are generally preferred over + concatenation for building strings with embedded values?",{"id":19300,"depth":296,"text":19301},{},"\u002Fjs\u002F06-strings-and-template-literals",{"title":16050,"description":264},"js\u002F06-strings-and-template-literals","kGNs5RXCwg8v9MNe4MGLdxxawd_9THM9tc14gs-IKog",{"id":19508,"title":19509,"body":19510,"description":264,"extension":2144,"meta":23343,"navigation":35,"path":23344,"seo":23345,"stem":23346,"__hash__":23347},"content\u002Fjs\u002F07-objects-and-properties.md","07 — Objects & Properties",{"type":8,"value":19511,"toc":23316},[19512,19515,19695,19867,19996,20156,20337,20573,20791,21008,21204,21414,21629,21806,21974,22176,22455,22631,22814,22982,23086,23313],[11,19513,19509],{"id":19514},"_07-objects-properties",[15,19516,19517,19525,19633,19666],{"language":247},[18,19518,19520,19521,19524],{"id":19519},"q1-what-does-objectkeysproduct-log","Q1. What does ",[39,19522,19523],{},"Object.keys(product)"," log?",[257,19526,19527],{"language":247},[260,19528,19530],{"className":262,"code":19529,"language":247,"meta":264,"style":264},"const price = 42;\nconst inStock = true;\n\nconst product = {\n  price,\n  inStock,\n  describe() {\n    return `$${this.price}`;\n  },\n};\n\nconsole.log(Object.keys(product));\n",[39,19531,19532,19544,19557,19561,19572,19577,19582,19589,19606,19611,19615,19619],{"__ignoreMap":264},[268,19533,19534,19536,19538,19540,19542],{"class":270,"line":271},[268,19535,243],{"class":274},[268,19537,17184],{"class":305},[268,19539,616],{"class":274},[268,19541,779],{"class":305},[268,19543,293],{"class":282},[268,19545,19546,19548,19551,19553,19555],{"class":270,"line":286},[268,19547,243],{"class":274},[268,19549,19550],{"class":305}," inStock",[268,19552,616],{"class":274},[268,19554,7905],{"class":305},[268,19556,293],{"class":282},[268,19558,19559],{"class":270,"line":296},[268,19560,5033],{"emptyLinePlaceholder":35},[268,19562,19563,19565,19568,19570],{"class":270,"line":311},[268,19564,243],{"class":274},[268,19566,19567],{"class":305}," product",[268,19569,616],{"class":274},[268,19571,9914],{"class":282},[268,19573,19574],{"class":270,"line":788},[268,19575,19576],{"class":282},"  price,\n",[268,19578,19579],{"class":270,"line":1951},[268,19580,19581],{"class":282},"  inStock,\n",[268,19583,19584,19587],{"class":270,"line":8955},[268,19585,19586],{"class":278},"  describe",[268,19588,283],{"class":282},[268,19590,19591,19593,19596,19598,19600,19602,19604],{"class":270,"line":8966},[268,19592,9871],{"class":274},[268,19594,19595],{"class":289}," `$${",[268,19597,950],{"class":305},[268,19599,462],{"class":289},[268,19601,17225],{"class":282},[268,19603,11603],{"class":289},[268,19605,293],{"class":282},[268,19607,19608],{"class":270,"line":8974},[268,19609,19610],{"class":282},"  },\n",[268,19612,19613],{"class":270,"line":8985},[268,19614,12940],{"class":282},[268,19616,19617],{"class":270,"line":8990},[268,19618,5033],{"emptyLinePlaceholder":35},[268,19620,19621,19623,19625,19628,19630],{"class":270,"line":8997},[268,19622,1353],{"class":282},[268,19624,1356],{"class":278},[268,19626,19627],{"class":282},"(Object.",[268,19629,9261],{"class":278},[268,19631,19632],{"class":282},"(product));\n",[23,19634,19636,19644,19652,19660],{"className":19635},[26],[28,19637,19639,355,19641],{"className":19638},[31],[33,19640],{"disabled":35,"type":36},[268,19642,19643],{},"\"price\", \"inStock\"",[28,19645,19647,355,19649],{"className":19646},[31],[33,19648],{"disabled":35,"type":36},[268,19650,19651],{},"\"price\", \"inStock\", \"describe\"",[28,19653,19655,355,19657],{"className":19654},[31],[33,19656],{"disabled":35,"type":36},[268,19658,19659],{},"\"describe\", \"price\", \"inStock\"",[28,19661,19663,19665],{"className":19662},[31],[33,19664],{"disabled":35,"type":36}," TypeError: describe is not a valid shorthand method",[66,19667,19668,19670,19676],{},[69,19669,71],{},[73,19671,19672,1727,19674],{},[76,19673,78],{},[268,19675,19651],{},[73,19677,19678,19680,19681,19684,19685,19688,19689,186,19691,19694],{},[76,19679,84],{}," Method shorthand (",[39,19682,19683],{},"describe() {}",") creates a regular own, enumerable, writable, configurable property whose value happens to be a function — it's collected by ",[39,19686,19687],{},"Object.keys"," exactly like ",[39,19690,17225],{},[39,19692,19693],{},"inStock",", listed without parentheses. Keys stay in insertion order since none of them are integer-like. Option A wrongly assumes methods aren't \"real\" properties; C wrongly reorders them (string keys keep insertion order, they aren't sorted); D is wrong because shorthand methods are valid ES6 syntax.",[15,19696,19697,19699,19798,19825],{"language":247},[18,19698,12737],{"id":12736},[257,19700,19701],{"language":247},[260,19702,19704],{"className":262,"code":19703,"language":247,"meta":264,"style":264},"const key = \"role\" + \"Id\";\nconst suffix = 2;\n\nconst user = {\n  [key]: 101,\n  [`level${suffix}`]: \"admin\",\n};\n\nconsole.log(user);\n",[39,19705,19706,19724,19737,19741,19751,19760,19781,19785,19789],{"__ignoreMap":264},[268,19707,19708,19710,19712,19714,19717,19719,19722],{"class":270,"line":271},[268,19709,243],{"class":274},[268,19711,12117],{"class":305},[268,19713,616],{"class":274},[268,19715,19716],{"class":289}," \"role\"",[268,19718,3350],{"class":274},[268,19720,19721],{"class":289}," \"Id\"",[268,19723,293],{"class":282},[268,19725,19726,19728,19731,19733,19735],{"class":270,"line":286},[268,19727,243],{"class":274},[268,19729,19730],{"class":305}," suffix",[268,19732,616],{"class":274},[268,19734,2214],{"class":305},[268,19736,293],{"class":282},[268,19738,19739],{"class":270,"line":296},[268,19740,5033],{"emptyLinePlaceholder":35},[268,19742,19743,19745,19747,19749],{"class":270,"line":311},[268,19744,243],{"class":274},[268,19746,4071],{"class":305},[268,19748,616],{"class":274},[268,19750,9914],{"class":282},[268,19752,19753,19756,19758],{"class":270,"line":788},[268,19754,19755],{"class":282},"  [key]: ",[268,19757,13859],{"class":305},[268,19759,1789],{"class":282},[268,19761,19762,19765,19768,19771,19773,19776,19779],{"class":270,"line":1951},[268,19763,19764],{"class":282},"  [",[268,19766,19767],{"class":289},"`level${",[268,19769,19770],{"class":282},"suffix",[268,19772,11603],{"class":289},[268,19774,19775],{"class":282},"]: ",[268,19777,19778],{"class":289},"\"admin\"",[268,19780,1789],{"class":282},[268,19782,19783],{"class":270,"line":8955},[268,19784,12940],{"class":282},[268,19786,19787],{"class":270,"line":8966},[268,19788,5033],{"emptyLinePlaceholder":35},[268,19790,19791,19793,19795],{"class":270,"line":8974},[268,19792,1353],{"class":282},[268,19794,1356],{"class":278},[268,19796,19797],{"class":282},"(user);\n",[23,19799,19801,19807,19813,19819],{"className":19800},[26],[28,19802,19804,19806],{"className":19803},[31],[33,19805],{"disabled":35,"type":36}," { key: 101, \"level2\": \"admin\" }",[28,19808,19810,19812],{"className":19809},[31],[33,19811],{"disabled":35,"type":36}," { roleId: 101, level: \"admin\" }",[28,19814,19816,19818],{"className":19815},[31],[33,19817],{"disabled":35,"type":36}," { roleId: 101, level2: \"admin\" }",[28,19820,19822,19824],{"className":19821},[31],[33,19823],{"disabled":35,"type":36}," SyntaxError: template literals cannot be used as computed keys",[66,19826,19827,19829,19834],{},[69,19828,71],{},[73,19830,19831,19833],{},[76,19832,78],{}," C — { roleId: 101, level2: \"admin\" }",[73,19835,19836,19838,19839,19842,19843,19846,19847,19850,19851,19854,19855,19858,19859,19861,19862,19864,19865,462],{},[76,19837,84],{}," A computed property name ",[39,19840,19841],{},"[expr]"," evaluates ",[39,19844,19845],{},"expr"," at the moment the object literal is constructed and uses the resulting string as the key — so ",[39,19848,19849],{},"key"," (the variable) evaluates to ",[39,19852,19853],{},"\"roleId\"",", and the template literal evaluates to ",[39,19856,19857],{},"\"level2\"",". Option A confuses the identifier ",[39,19860,19849],{}," with its computed string value. Option B forgets ",[39,19863,19770],{}," gets interpolated. Option D is wrong: any valid expression, including a template literal, is allowed inside ",[39,19866,3290],{},[15,19868,19869,19871,19947,19974],{"language":247},[18,19870,12877],{"id":12876},[257,19872,19873],{"language":247},[260,19874,19876],{"className":262,"code":19875,"language":247,"meta":264,"style":264},"const cache = {};\ncache[1] = \"first\";\ncache[\"1\"] = \"overwritten\";\n\nconsole.log(cache[1], Object.keys(cache).length);\n",[39,19877,19878,19888,19905,19920,19924],{"__ignoreMap":264},[268,19879,19880,19882,19884,19886],{"class":270,"line":271},[268,19881,243],{"class":274},[268,19883,15807],{"class":305},[268,19885,616],{"class":274},[268,19887,15812],{"class":282},[268,19889,19890,19893,19895,19898,19900,19903],{"class":270,"line":286},[268,19891,19892],{"class":282},"cache[",[268,19894,2255],{"class":305},[268,19896,19897],{"class":282},"] ",[268,19899,302],{"class":274},[268,19901,19902],{"class":289}," \"first\"",[268,19904,293],{"class":282},[268,19906,19907,19909,19911,19913,19915,19918],{"class":270,"line":296},[268,19908,19892],{"class":282},[268,19910,3387],{"class":289},[268,19912,19897],{"class":282},[268,19914,302],{"class":274},[268,19916,19917],{"class":289}," \"overwritten\"",[268,19919,293],{"class":282},[268,19921,19922],{"class":270,"line":311},[268,19923,5033],{"emptyLinePlaceholder":35},[268,19925,19926,19928,19930,19933,19935,19938,19940,19943,19945],{"class":270,"line":788},[268,19927,1353],{"class":282},[268,19929,1356],{"class":278},[268,19931,19932],{"class":282},"(cache[",[268,19934,2255],{"class":305},[268,19936,19937],{"class":282},"], Object.",[268,19939,9261],{"class":278},[268,19941,19942],{"class":282},"(cache).",[268,19944,3567],{"class":305},[268,19946,628],{"class":282},[23,19948,19950,19956,19962,19968],{"className":19949},[26],[28,19951,19953,19955],{"className":19952},[31],[33,19954],{"disabled":35,"type":36}," \"overwritten\" 1",[28,19957,19959,19961],{"className":19958},[31],[33,19960],{"disabled":35,"type":36}," \"first\" 2",[28,19963,19965,19967],{"className":19964},[31],[33,19966],{"disabled":35,"type":36}," \"overwritten\" 2",[28,19969,19971,19973],{"className":19970},[31],[33,19972],{"disabled":35,"type":36}," undefined 1",[66,19975,19976,19978,19983],{},[69,19977,71],{},[73,19979,19980,19982],{},[76,19981,78],{}," A — \"overwritten\" 1",[73,19984,19985,355,19987,19989,19990,19992,19993,19995],{},[76,19986,84],{},[76,19988,365],{}," every non-Symbol property key on a plain object is coerced to a string before it's stored, so the numeric key ",[39,19991,2255],{}," and the string key ",[39,19994,3387],{}," address the exact same property. The second assignment overwrites the first rather than creating a second entry, leaving one key and the latest value. Options B and C wrongly assume numeric and string keys are distinct slots.",[15,19997,19998,20000,20089,20116],{"language":247},[18,19999,13032],{"id":13031},[257,20001,20002],{"language":247},[260,20003,20005],{"className":262,"code":20004,"language":247,"meta":264,"style":264},"const config = Object.freeze({\n  name: \"app\",\n  limits: { maxUsers: 10 },\n});\n\nconfig.name = \"changed\";\nconfig.limits.maxUsers = 999;\n\nconsole.log(config.name, config.limits.maxUsers);\n",[39,20006,20007,20024,20033,20043,20048,20052,20064,20076,20080],{"__ignoreMap":264},[268,20008,20009,20011,20013,20015,20018,20021],{"class":270,"line":271},[268,20010,243],{"class":274},[268,20012,8029],{"class":305},[268,20014,616],{"class":274},[268,20016,20017],{"class":282}," Object.",[268,20019,20020],{"class":278},"freeze",[268,20022,20023],{"class":282},"({\n",[268,20025,20026,20029,20031],{"class":270,"line":286},[268,20027,20028],{"class":282},"  name: ",[268,20030,1786],{"class":289},[268,20032,1789],{"class":282},[268,20034,20035,20038,20040],{"class":270,"line":296},[268,20036,20037],{"class":282},"  limits: { maxUsers: ",[268,20039,5825],{"class":305},[268,20041,20042],{"class":282}," },\n",[268,20044,20045],{"class":270,"line":311},[268,20046,20047],{"class":282},"});\n",[268,20049,20050],{"class":270,"line":788},[268,20051,5033],{"emptyLinePlaceholder":35},[268,20053,20054,20057,20059,20062],{"class":270,"line":1951},[268,20055,20056],{"class":282},"config.name ",[268,20058,302],{"class":274},[268,20060,20061],{"class":289}," \"changed\"",[268,20063,293],{"class":282},[268,20065,20066,20069,20071,20074],{"class":270,"line":8955},[268,20067,20068],{"class":282},"config.limits.maxUsers ",[268,20070,302],{"class":274},[268,20072,20073],{"class":305}," 999",[268,20075,293],{"class":282},[268,20077,20078],{"class":270,"line":8966},[268,20079,5033],{"emptyLinePlaceholder":35},[268,20081,20082,20084,20086],{"class":270,"line":8974},[268,20083,1353],{"class":282},[268,20085,1356],{"class":278},[268,20087,20088],{"class":282},"(config.name, config.limits.maxUsers);\n",[23,20090,20092,20098,20104,20110],{"className":20091},[26],[28,20093,20095,20097],{"className":20094},[31],[33,20096],{"disabled":35,"type":36}," \"changed\" 999",[28,20099,20101,20103],{"className":20100},[31],[33,20102],{"disabled":35,"type":36}," \"app\" 10",[28,20105,20107,20109],{"className":20106},[31],[33,20108],{"disabled":35,"type":36}," \"changed\" 10",[28,20111,20113,20115],{"className":20112},[31],[33,20114],{"disabled":35,"type":36}," \"app\" 999",[66,20117,20118,20120,20125],{},[69,20119,71],{},[73,20121,20122,20124],{},[76,20123,78],{}," D — \"app\" 999",[73,20126,20127,355,20129,355,20131,20134,20135,20137,20138,7415,20141,20143,20144,20147,20148,20151,20152,20155],{},[76,20128,84],{},[76,20130,582],{},[39,20132,20133],{},"Object.freeze"," only locks the object's own top-level property slots — it makes ",[39,20136,14605],{}," non-writable, so the reassignment is silently ignored (in non-strict mode) and ",[39,20139,20140],{},"config.name",[39,20142,1786],{},". But ",[39,20145,20146],{},"limits"," itself is just a frozen ",[104,20149,20150],{},"reference"," to another, unfrozen object; freezing never cascades into values it points to, so mutating ",[39,20153,20154],{},"config.limits.maxUsers"," succeeds normally. Deep-freezing requires recursively freezing every nested object yourself.",[15,20157,20158,20160,20247,20281],{"language":247},[18,20159,13181],{"id":13180},[257,20161,20162],{"language":247},[260,20163,20165],{"className":262,"code":20164,"language":247,"meta":264,"style":264},"const original = { id: 1, meta: { tags: [\"a\"] } };\nconst copy = { ...original };\n\ncopy.id = 2;\ncopy.meta.tags.push(\"b\");\n\nconsole.log(original.id, original.meta.tags);\n",[39,20166,20167,20189,20206,20210,20221,20234,20238],{"__ignoreMap":264},[268,20168,20169,20171,20174,20176,20179,20181,20184,20186],{"class":270,"line":271},[268,20170,243],{"class":274},[268,20172,20173],{"class":305}," original",[268,20175,616],{"class":274},[268,20177,20178],{"class":282}," { id: ",[268,20180,2255],{"class":305},[268,20182,20183],{"class":282},", meta: { tags: [",[268,20185,7582],{"class":289},[268,20187,20188],{"class":282},"] } };\n",[268,20190,20191,20193,20196,20198,20201,20203],{"class":270,"line":286},[268,20192,243],{"class":274},[268,20194,20195],{"class":305}," copy",[268,20197,616],{"class":274},[268,20199,20200],{"class":282}," { ",[268,20202,15329],{"class":274},[268,20204,20205],{"class":282},"original };\n",[268,20207,20208],{"class":270,"line":296},[268,20209,5033],{"emptyLinePlaceholder":35},[268,20211,20212,20215,20217,20219],{"class":270,"line":311},[268,20213,20214],{"class":282},"copy.id ",[268,20216,302],{"class":274},[268,20218,2214],{"class":305},[268,20220,293],{"class":282},[268,20222,20223,20226,20228,20230,20232],{"class":270,"line":788},[268,20224,20225],{"class":282},"copy.meta.tags.",[268,20227,12499],{"class":278},[268,20229,622],{"class":282},[268,20231,9188],{"class":289},[268,20233,628],{"class":282},[268,20235,20236],{"class":270,"line":1951},[268,20237,5033],{"emptyLinePlaceholder":35},[268,20239,20240,20242,20244],{"class":270,"line":8955},[268,20241,1353],{"class":282},[268,20243,1356],{"class":278},[268,20245,20246],{"class":282},"(original.id, original.meta.tags);\n",[23,20248,20250,20258,20267,20274],{"className":20249},[26],[28,20251,20253,20255,20256],{"className":20252},[31],[33,20254],{"disabled":35,"type":36}," 2 ",[268,20257,7582],{},[28,20259,20261,20263,20264],{"className":20260},[31],[33,20262],{"disabled":35,"type":36}," 1 ",[268,20265,20266],{},"\"a\", \"b\"",[28,20268,20270,20255,20272],{"className":20269},[31],[33,20271],{"disabled":35,"type":36},[268,20273,20266],{},[28,20275,20277,20263,20279],{"className":20276},[31],[33,20278],{"disabled":35,"type":36},[268,20280,7582],{},[66,20282,20283,20285,20292],{},[69,20284,71],{},[73,20286,20287,20289,20290],{},[76,20288,78],{}," B — 1 ",[268,20291,20266],{},[73,20293,20294,355,20296,20298,20299,20302,20303,20306,20307,20310,20311,20314,20315,20317,20318,20321,20322,186,20325,20328,20329,20332,20333,20336],{},[76,20295,84],{},[76,20297,365],{}," the spread operator ",[39,20300,20301],{},"{ ...original }"," performs a ",[104,20304,20305],{},"shallow"," copy — each top-level value is copied into a new slot, so reassigning ",[39,20308,20309],{},"copy.id"," never touches ",[39,20312,20313],{},"original.id"," (still ",[39,20316,2255],{},"). But ",[39,20319,20320],{},"meta"," holds an object reference, and the shallow copy duplicates the reference itself, not the object it points to — ",[39,20323,20324],{},"copy.meta",[39,20326,20327],{},"original.meta"," are the same array's owner, so pushing onto ",[39,20330,20331],{},"copy.meta.tags"," is visible through ",[39,20334,20335],{},"original.meta.tags"," too. This is the classic shallow-copy trap with nested reference types.",[15,20338,20339,20341,20474,20515],{"language":247},[18,20340,13321],{"id":13320},[257,20342,20343],{"language":247},[260,20344,20346],{"className":262,"code":20345,"language":247,"meta":264,"style":264},"const obj = { visible: 1 };\nObject.defineProperty(obj, \"hidden\", {\n  value: 2,\n  enumerable: false,\n  writable: true,\n  configurable: true,\n});\n\nlet keys = [];\nfor (const k in obj) keys.push(k);\n\nconsole.log(keys, Object.keys(obj), obj.hidden);\n",[39,20347,20348,20363,20380,20389,20398,20407,20416,20420,20424,20435,20456,20460],{"__ignoreMap":264},[268,20349,20350,20352,20354,20356,20359,20361],{"class":270,"line":271},[268,20351,243],{"class":274},[268,20353,4651],{"class":305},[268,20355,616],{"class":274},[268,20357,20358],{"class":282}," { visible: ",[268,20360,2255],{"class":305},[268,20362,2790],{"class":282},[268,20364,20365,20368,20371,20374,20377],{"class":270,"line":286},[268,20366,20367],{"class":282},"Object.",[268,20369,20370],{"class":278},"defineProperty",[268,20372,20373],{"class":282},"(obj, ",[268,20375,20376],{"class":289},"\"hidden\"",[268,20378,20379],{"class":282},", {\n",[268,20381,20382,20385,20387],{"class":270,"line":296},[268,20383,20384],{"class":282},"  value: ",[268,20386,2258],{"class":305},[268,20388,1789],{"class":282},[268,20390,20391,20394,20396],{"class":270,"line":311},[268,20392,20393],{"class":282},"  enumerable: ",[268,20395,2986],{"class":305},[268,20397,1789],{"class":282},[268,20399,20400,20403,20405],{"class":270,"line":788},[268,20401,20402],{"class":282},"  writable: ",[268,20404,2185],{"class":305},[268,20406,1789],{"class":282},[268,20408,20409,20412,20414],{"class":270,"line":1951},[268,20410,20411],{"class":282},"  configurable: ",[268,20413,2185],{"class":305},[268,20415,1789],{"class":282},[268,20417,20418],{"class":270,"line":8955},[268,20419,20047],{"class":282},[268,20421,20422],{"class":270,"line":8966},[268,20423,5033],{"emptyLinePlaceholder":35},[268,20425,20426,20428,20431,20433],{"class":270,"line":8974},[268,20427,240],{"class":274},[268,20429,20430],{"class":282}," keys ",[268,20432,302],{"class":274},[268,20434,12449],{"class":282},[268,20436,20437,20439,20441,20443,20446,20448,20451,20453],{"class":270,"line":8985},[268,20438,6926],{"class":274},[268,20440,2182],{"class":282},[268,20442,243],{"class":274},[268,20444,20445],{"class":305}," k",[268,20447,9209],{"class":274},[268,20449,20450],{"class":282}," obj) keys.",[268,20452,12499],{"class":278},[268,20454,20455],{"class":282},"(k);\n",[268,20457,20458],{"class":270,"line":8990},[268,20459,5033],{"emptyLinePlaceholder":35},[268,20461,20462,20464,20466,20469,20471],{"class":270,"line":8997},[268,20463,1353],{"class":282},[268,20465,1356],{"class":278},[268,20467,20468],{"class":282},"(keys, Object.",[268,20470,9261],{"class":278},[268,20472,20473],{"class":282},"(obj), obj.hidden);\n",[23,20475,20477,20487,20497,20506],{"className":20476},[26],[28,20478,20480,355,20482,355,20485,2214],{"className":20479},[31],[33,20481],{"disabled":35,"type":36},[268,20483,20484],{},"\"visible\", \"hidden\"",[268,20486,20484],{},[28,20488,20490,355,20492,355,20495,2214],{"className":20489},[31],[33,20491],{"disabled":35,"type":36},[268,20493,20494],{},"\"visible\"",[268,20496,20484],{},[28,20498,20500,355,20502,355,20504,2214],{"className":20499},[31],[33,20501],{"disabled":35,"type":36},[268,20503,20494],{},[268,20505,20494],{},[28,20507,20509,355,20511,355,20513,17135],{"className":20508},[31],[33,20510],{"disabled":35,"type":36},[268,20512,20484],{},[268,20514,20494],{},[66,20516,20517,20519,20527],{},[69,20518,71],{},[73,20520,20521,1004,20523,355,20525,2214],{},[76,20522,78],{},[268,20524,20494],{},[268,20526,20494],{},[73,20528,20529,355,20531,20534,20535,20538,20539,20542,20543,42,20545,42,20547,446,20550,137,20553,20556,20557,20560,20561,20564,20565,20567,20568,186,20570,20572],{},[76,20530,84],{},[39,20532,20533],{},"enumerable: false"," hides ",[39,20536,20537],{},"hidden"," from anything that iterates ",[104,20540,20541],{},"enumerable"," properties — ",[39,20544,4728],{},[39,20546,19687],{},[39,20548,20549],{},"Object.values",[39,20551,20552],{},"entries",[39,20554,20555],{},"JSON.stringify"," all skip it identically. The property still fully exists though: it's directly readable and (since ",[39,20558,20559],{},"writable: true",") writable via ",[39,20562,20563],{},"obj.hidden",", which still returns ",[39,20566,2258],{},". Option D wrongly assumes non-enumerable also means inaccessible; A and the mixed variants wrongly assume ",[39,20569,4728],{},[39,20571,19687],{}," diverge here — for an own property, both honor the same enumerable flag the same way.",[15,20574,20575,20577,20707,20734],{"language":247},[18,20576,13528],{"id":13527},[257,20578,20579],{"language":247},[260,20580,20582],{"className":262,"code":20581,"language":247,"meta":264,"style":264},"function Base() {}\nBase.prototype.role = \"guest\";\n\nconst user = Object.create(Base.prototype);\nuser.name = \"Ana\";\n\nconsole.log(\n  \"role\" in user,\n  user.hasOwnProperty(\"role\"),\n  Object.hasOwn(user, \"role\")\n);\n",[39,20583,20584,20593,20612,20616,20639,20650,20654,20662,20672,20687,20703],{"__ignoreMap":264},[268,20585,20586,20588,20591],{"class":270,"line":271},[268,20587,275],{"class":274},[268,20589,20590],{"class":278}," Base",[268,20592,3682],{"class":282},[268,20594,20595,20598,20600,20602,20605,20607,20610],{"class":270,"line":286},[268,20596,20597],{"class":305},"Base",[268,20599,462],{"class":282},[268,20601,12070],{"class":305},[268,20603,20604],{"class":282},".role ",[268,20606,302],{"class":274},[268,20608,20609],{"class":289}," \"guest\"",[268,20611,293],{"class":282},[268,20613,20614],{"class":270,"line":296},[268,20615,5033],{"emptyLinePlaceholder":35},[268,20617,20618,20620,20622,20624,20626,20629,20631,20633,20635,20637],{"class":270,"line":311},[268,20619,243],{"class":274},[268,20621,4071],{"class":305},[268,20623,616],{"class":274},[268,20625,20017],{"class":282},[268,20627,20628],{"class":278},"create",[268,20630,622],{"class":282},[268,20632,20597],{"class":305},[268,20634,462],{"class":282},[268,20636,12070],{"class":305},[268,20638,628],{"class":282},[268,20640,20641,20643,20645,20648],{"class":270,"line":788},[268,20642,4086],{"class":282},[268,20644,302],{"class":274},[268,20646,20647],{"class":289}," \"Ana\"",[268,20649,293],{"class":282},[268,20651,20652],{"class":270,"line":1951},[268,20653,5033],{"emptyLinePlaceholder":35},[268,20655,20656,20658,20660],{"class":270,"line":8955},[268,20657,1353],{"class":282},[268,20659,1356],{"class":278},[268,20661,17096],{"class":282},[268,20663,20664,20667,20669],{"class":270,"line":8966},[268,20665,20666],{"class":289},"  \"role\"",[268,20668,9209],{"class":274},[268,20670,20671],{"class":282}," user,\n",[268,20673,20674,20677,20680,20682,20685],{"class":270,"line":8974},[268,20675,20676],{"class":282},"  user.",[268,20678,20679],{"class":278},"hasOwnProperty",[268,20681,622],{"class":282},[268,20683,20684],{"class":289},"\"role\"",[268,20686,17159],{"class":282},[268,20688,20689,20692,20695,20698,20700],{"class":270,"line":8985},[268,20690,20691],{"class":282},"  Object.",[268,20693,20694],{"class":278},"hasOwn",[268,20696,20697],{"class":282},"(user, ",[268,20699,20684],{"class":289},[268,20701,20702],{"class":282},")\n",[268,20704,20705],{"class":270,"line":8990},[268,20706,628],{"class":282},[23,20708,20710,20716,20722,20728],{"className":20709},[26],[28,20711,20713,20715],{"className":20712},[31],[33,20714],{"disabled":35,"type":36}," true false false",[28,20717,20719,20721],{"className":20718},[31],[33,20720],{"disabled":35,"type":36}," true true true",[28,20723,20725,20727],{"className":20724},[31],[33,20726],{"disabled":35,"type":36}," false false false",[28,20729,20731,20733],{"className":20730},[31],[33,20732],{"disabled":35,"type":36}," true false true",[66,20735,20736,20738,20743],{},[69,20737,71],{},[73,20739,20740,20742],{},[76,20741,78],{}," A — true false false",[73,20744,20745,4396,20747,20750,20751,20754,20755,830,20758,183,20760,20762,20763,20766,20767,20769,20770,186,20772,20775,20776,20778,20779,20782,20783,20786,20787,20790],{},[76,20746,84],{},[39,20748,20749],{},"in"," operator walks the ",[104,20752,20753],{},"entire"," prototype chain, so ",[39,20756,20757],{},"\"role\" in user",[39,20759,2185],{},[39,20761,7753],{}," is inherited from ",[39,20764,20765],{},"Base.prototype",", even though ",[39,20768,4155],{}," doesn't own it. ",[39,20771,20679],{},[39,20773,20774],{},"Object.hasOwn"," both check only the object's own properties, so both correctly return ",[39,20777,2986],{}," for an inherited property. ",[39,20780,20781],{},"Object.hasOwn(obj, key)"," is the modern (ES2022) replacement for ",[39,20784,20785],{},".hasOwnProperty()"," — it works even on objects with no prototype, where ",[39,20788,20789],{},".hasOwnProperty"," wouldn't exist to call.",[15,20792,20793,20795,20899,20940],{"language":247},[18,20794,13729],{"id":13728},[257,20796,20797],{"language":247},[260,20798,20800],{"className":262,"code":20799,"language":247,"meta":264,"style":264},"const defaults = { theme: \"dark\" };\nconst settings = Object.create(defaults);\nsettings.fontSize = 14;\n\nconst seen = [];\nfor (const key in settings) seen.push(key);\n\nconsole.log(seen, Object.keys(settings));\n",[39,20801,20802,20819,20835,20847,20851,20862,20881,20885],{"__ignoreMap":264},[268,20803,20804,20806,20809,20811,20814,20817],{"class":270,"line":271},[268,20805,243],{"class":274},[268,20807,20808],{"class":305}," defaults",[268,20810,616],{"class":274},[268,20812,20813],{"class":282}," { theme: ",[268,20815,20816],{"class":289},"\"dark\"",[268,20818,2790],{"class":282},[268,20820,20821,20823,20826,20828,20830,20832],{"class":270,"line":286},[268,20822,243],{"class":274},[268,20824,20825],{"class":305}," settings",[268,20827,616],{"class":274},[268,20829,20017],{"class":282},[268,20831,20628],{"class":278},[268,20833,20834],{"class":282},"(defaults);\n",[268,20836,20837,20840,20842,20845],{"class":270,"line":296},[268,20838,20839],{"class":282},"settings.fontSize ",[268,20841,302],{"class":274},[268,20843,20844],{"class":305}," 14",[268,20846,293],{"class":282},[268,20848,20849],{"class":270,"line":311},[268,20850,5033],{"emptyLinePlaceholder":35},[268,20852,20853,20855,20858,20860],{"class":270,"line":788},[268,20854,243],{"class":274},[268,20856,20857],{"class":305}," seen",[268,20859,616],{"class":274},[268,20861,12449],{"class":282},[268,20863,20864,20866,20868,20870,20872,20874,20877,20879],{"class":270,"line":1951},[268,20865,6926],{"class":274},[268,20867,2182],{"class":282},[268,20869,243],{"class":274},[268,20871,12117],{"class":305},[268,20873,9209],{"class":274},[268,20875,20876],{"class":282}," settings) seen.",[268,20878,12499],{"class":278},[268,20880,12131],{"class":282},[268,20882,20883],{"class":270,"line":8955},[268,20884,5033],{"emptyLinePlaceholder":35},[268,20886,20887,20889,20891,20894,20896],{"class":270,"line":8966},[268,20888,1353],{"class":282},[268,20890,1356],{"class":278},[268,20892,20893],{"class":282},"(seen, Object.",[268,20895,9261],{"class":278},[268,20897,20898],{"class":282},"(settings));\n",[23,20900,20902,20912,20922,20931],{"className":20901},[26],[28,20903,20905,355,20907,355,20910],{"className":20904},[31],[33,20906],{"disabled":35,"type":36},[268,20908,20909],{},"\"fontSize\"",[268,20911,20909],{},[28,20913,20915,355,20917,355,20920],{"className":20914},[31],[33,20916],{"disabled":35,"type":36},[268,20918,20919],{},"\"theme\", \"fontSize\"",[268,20921,20919],{},[28,20923,20925,355,20927,355,20929],{"className":20924},[31],[33,20926],{"disabled":35,"type":36},[268,20928,20909],{},[268,20930,20919],{},[28,20932,20934,355,20936,355,20938],{"className":20933},[31],[33,20935],{"disabled":35,"type":36},[268,20937,20919],{},[268,20939,20909],{},[66,20941,20942,20944,20952],{},[69,20943,71],{},[73,20945,20946,6901,20948,355,20950],{},[76,20947,78],{},[268,20949,20919],{},[268,20951,20909],{},[73,20953,20954,355,20956,355,20958,20960,20961,20964,20965,20968,20969,20972,20973,20976,20977,20980,20981,20983,20984,2338,20986,446,20989,20992,20993,20996,20997,21000,21001,446,21003,7728,21005,21007],{},[76,20955,84],{},[76,20957,365],{},[39,20959,4728],{}," walks the prototype chain and includes any ",[104,20962,20963],{},"inherited"," enumerable property, so it picks up ",[39,20966,20967],{},"theme"," from ",[39,20970,20971],{},"defaults"," in addition to ",[39,20974,20975],{},"settings","' own ",[39,20978,20979],{},"fontSize"," — this is the classic footgun that makes ",[39,20982,4728],{}," risky on objects with a non-trivial prototype. ",[39,20985,19687],{},[39,20987,20988],{},"Object.entries",[39,20990,20991],{},"for...of Object.entries(...)",") only ever return an object's ",[104,20994,20995],{},"own"," enumerable properties, giving the safer, predictable ",[39,20998,20999],{},"[\"fontSize\"]",". Prefer ",[39,21002,19687],{},[39,21004,20552],{},[39,21006,4728],{}," for plain data iteration.",[15,21009,21010,21014,21083,21137],{"language":247},[18,21011,21013],{"id":21012},"q9-given-this-code-what-actually-happens-when-it-runs","Q9. Given this code, what actually happens when it runs?",[257,21015,21016],{"language":247},[260,21017,21019],{"className":262,"code":21018,"language":247,"meta":264,"style":264},"const response = { data: null };\n\nconst a = response.data?.user?.name;\nconsole.log(a);\n\nconst b = response.data.user?.name;\nconsole.log(b);\n",[39,21020,21021,21037,21041,21052,21060,21064,21075],{"__ignoreMap":264},[268,21022,21023,21025,21028,21030,21033,21035],{"class":270,"line":271},[268,21024,243],{"class":274},[268,21026,21027],{"class":305}," response",[268,21029,616],{"class":274},[268,21031,21032],{"class":282}," { data: ",[268,21034,2650],{"class":305},[268,21036,2790],{"class":282},[268,21038,21039],{"class":270,"line":286},[268,21040,5033],{"emptyLinePlaceholder":35},[268,21042,21043,21045,21047,21049],{"class":270,"line":296},[268,21044,243],{"class":274},[268,21046,7203],{"class":305},[268,21048,616],{"class":274},[268,21050,21051],{"class":282}," response.data?.user?.name;\n",[268,21053,21054,21056,21058],{"class":270,"line":311},[268,21055,1353],{"class":282},[268,21057,1356],{"class":278},[268,21059,2229],{"class":282},[268,21061,21062],{"class":270,"line":788},[268,21063,5033],{"emptyLinePlaceholder":35},[268,21065,21066,21068,21070,21072],{"class":270,"line":1951},[268,21067,243],{"class":274},[268,21069,16372],{"class":305},[268,21071,616],{"class":274},[268,21073,21074],{"class":282}," response.data.user?.name;\n",[268,21076,21077,21079,21081],{"class":270,"line":8955},[268,21078,1353],{"class":282},[268,21080,1356],{"class":278},[268,21082,2238],{"class":282},[23,21084,21086,21099,21114,21127],{"className":21085},[26],[28,21087,21089,21091,21092,186,21094,21096,21097],{"className":21088},[31],[33,21090],{"disabled":35,"type":36}," Both lines log fine; ",[39,21093,1223],{},[39,21095,1232],{}," are both ",[39,21098,833],{},[28,21100,21102,355,21104,2269,21106,21108,21109,2278,21111,21113],{"className":21101},[31],[33,21103],{"disabled":35,"type":36},[39,21105,1223],{},[39,21107,833],{},"; the line defining ",[39,21110,1232],{},[39,21112,827],{}," before it can log",[28,21115,21117,21119,21120,183,21122,830,21125],{"className":21116},[31],[33,21118],{"disabled":35,"type":36}," Both lines throw a ",[39,21121,827],{},[39,21123,21124],{},"response.data",[39,21126,2650],{},[28,21128,21130,355,21132,21134,21135],{"className":21129},[31],[33,21131],{"disabled":35,"type":36},[39,21133,1223],{}," throws first, because optional chaining requires every link in a chain to use ",[39,21136,4972],{},[66,21138,21139,21141,21153],{},[69,21140,71],{},[73,21142,21143,1727,21145,2269,21147,21108,21149,2278,21151,21113],{},[76,21144,78],{},[39,21146,1223],{},[39,21148,833],{},[39,21150,1232],{},[39,21152,827],{},[73,21154,21155,355,21157,355,21159,21161,21162,446,21164,21166,21167,21169,21170,21173,21174,186,21176,21178,21179,21182,21183,21185,21186,21189,21190,21193,21194,21196,21197,21200,21201,21203],{},[76,21156,84],{},[76,21158,582],{},[39,21160,4972],{}," short-circuits the moment it hits a ",[39,21163,2650],{},[39,21165,833],{}," reference and returns ",[39,21168,833],{}," immediately, without evaluating the rest of the chain — so ",[39,21171,21172],{},"response.data?.user?.name"," safely yields ",[39,21175,833],{},[39,21177,1223],{}," logs fine. ",[39,21180,21181],{},"response.data.user"," has no ",[39,21184,4972],{}," after ",[39,21187,21188],{},"data",", so it accesses ",[39,21191,21192],{},".user"," directly on ",[39,21195,2650],{},", which throws ",[39,21198,21199],{},"TypeError: Cannot read properties of null (reading 'user')"," before ",[39,21202,1232],{}," is ever assigned. Optional chaining protects only the specific link it's placed on, not the whole expression.",[15,21205,21206,21208,21328,21355],{"language":247},[18,21207,17619],{"id":17618},[257,21209,21210],{"language":247},[260,21211,21213],{"className":262,"code":21212,"language":247,"meta":264,"style":264},"const settings = { retries: 0, label: \"\", timeout: null };\n\nconst retries = settings.retries || 3;\nconst retries2 = settings.retries ?? 3;\nconst label = settings.label || \"default\";\nconst label2 = settings.label ?? \"default\";\n\nconsole.log(retries, retries2, label, label2);\n",[39,21214,21215,21240,21244,21262,21279,21298,21315,21319],{"__ignoreMap":264},[268,21216,21217,21219,21221,21223,21226,21228,21231,21233,21236,21238],{"class":270,"line":271},[268,21218,243],{"class":274},[268,21220,20825],{"class":305},[268,21222,616],{"class":274},[268,21224,21225],{"class":282}," { retries: ",[268,21227,3307],{"class":305},[268,21229,21230],{"class":282},", label: ",[268,21232,3294],{"class":289},[268,21234,21235],{"class":282},", timeout: ",[268,21237,2650],{"class":305},[268,21239,2790],{"class":282},[268,21241,21242],{"class":270,"line":286},[268,21243,5033],{"emptyLinePlaceholder":35},[268,21245,21246,21248,21251,21253,21256,21258,21260],{"class":270,"line":296},[268,21247,243],{"class":274},[268,21249,21250],{"class":305}," retries",[268,21252,616],{"class":274},[268,21254,21255],{"class":282}," settings.retries ",[268,21257,5530],{"class":274},[268,21259,3396],{"class":305},[268,21261,293],{"class":282},[268,21263,21264,21266,21269,21271,21273,21275,21277],{"class":270,"line":311},[268,21265,243],{"class":274},[268,21267,21268],{"class":305}," retries2",[268,21270,616],{"class":274},[268,21272,21255],{"class":282},[268,21274,4969],{"class":274},[268,21276,3396],{"class":305},[268,21278,293],{"class":282},[268,21280,21281,21283,21286,21288,21291,21293,21296],{"class":270,"line":788},[268,21282,243],{"class":274},[268,21284,21285],{"class":305}," label",[268,21287,616],{"class":274},[268,21289,21290],{"class":282}," settings.label ",[268,21292,5530],{"class":274},[268,21294,21295],{"class":289}," \"default\"",[268,21297,293],{"class":282},[268,21299,21300,21302,21305,21307,21309,21311,21313],{"class":270,"line":1951},[268,21301,243],{"class":274},[268,21303,21304],{"class":305}," label2",[268,21306,616],{"class":274},[268,21308,21290],{"class":282},[268,21310,4969],{"class":274},[268,21312,21295],{"class":289},[268,21314,293],{"class":282},[268,21316,21317],{"class":270,"line":8955},[268,21318,5033],{"emptyLinePlaceholder":35},[268,21320,21321,21323,21325],{"class":270,"line":8966},[268,21322,1353],{"class":282},[268,21324,1356],{"class":278},[268,21326,21327],{"class":282},"(retries, retries2, label, label2);\n",[23,21329,21331,21337,21343,21349],{"className":21330},[26],[28,21332,21334,21336],{"className":21333},[31],[33,21335],{"disabled":35,"type":36}," 0 0 \"\" \"\"",[28,21338,21340,21342],{"className":21339},[31],[33,21341],{"disabled":35,"type":36}," 3 3 \"default\" \"default\"",[28,21344,21346,21348],{"className":21345},[31],[33,21347],{"disabled":35,"type":36}," 3 0 \"default\" \"\"",[28,21350,21352,21354],{"className":21351},[31],[33,21353],{"disabled":35,"type":36}," 0 3 \"\" \"default\"",[66,21356,21357,21359,21364],{},[69,21358,71],{},[73,21360,21361,21363],{},[76,21362,78],{}," C — 3 0 \"default\" \"\"",[73,21365,21366,355,21368,355,21370,21372,21373,21376,21377,42,21379,42,21381,42,21383,42,21385,42,21387,21389,21390,21392,21393,5854,21395,99,21397,1179,21399,21402,21403,186,21405,21402,21408,21410,21411,21413],{},[76,21367,84],{},[76,21369,365],{},[39,21371,5530],{}," falls back to its right-hand side on ",[104,21374,21375],{},"any"," falsy value — ",[39,21378,3307],{},[39,21380,3294],{},[39,21382,2986],{},[39,21384,3040],{},[39,21386,2650],{},[39,21388,833],{}," — so both the legitimate ",[39,21391,3307],{}," retry count and the legitimate empty-string label get incorrectly overridden. ",[39,21394,4969],{},[39,21396,2650],{},[39,21398,833],{},[39,21400,21401],{},"retries2"," correctly stays ",[39,21404,3307],{},[39,21406,21407],{},"label2",[39,21409,3294],{},". This is why ",[39,21412,4969],{}," is the safer default operator for fields (counts, flags, strings) that can hold a meaningful falsy value.",[15,21415,21416,21424,21503,21564],{"language":247},[18,21417,21419,21420,21423],{"id":21418},"q11-what-is-logged-and-what-happens-when-delete-total-runs-afterward-in-non-strict-mode","Q11. What is logged, and what happens when ",[39,21421,21422],{},"delete total;"," runs afterward in non-strict mode?",[257,21425,21426],{"language":247},[260,21427,21429],{"className":262,"code":21428,"language":247,"meta":264,"style":264},"const state = { count: 5 };\nconst result = delete state.count;\nconsole.log(result, state);\n\nlet total = 10;\ndelete total;\nconsole.log(total);\n",[39,21430,21431,21446,21460,21469,21473,21486,21494],{"__ignoreMap":264},[268,21432,21433,21435,21438,21440,21442,21444],{"class":270,"line":271},[268,21434,243],{"class":274},[268,21436,21437],{"class":305}," state",[268,21439,616],{"class":274},[268,21441,2785],{"class":282},[268,21443,2429],{"class":305},[268,21445,2790],{"class":282},[268,21447,21448,21450,21452,21454,21457],{"class":270,"line":286},[268,21449,243],{"class":274},[268,21451,5583],{"class":305},[268,21453,616],{"class":274},[268,21455,21456],{"class":274}," delete",[268,21458,21459],{"class":282}," state.count;\n",[268,21461,21462,21464,21466],{"class":270,"line":296},[268,21463,1353],{"class":282},[268,21465,1356],{"class":278},[268,21467,21468],{"class":282},"(result, state);\n",[268,21470,21471],{"class":270,"line":311},[268,21472,5033],{"emptyLinePlaceholder":35},[268,21474,21475,21477,21480,21482,21484],{"class":270,"line":788},[268,21476,240],{"class":274},[268,21478,21479],{"class":282}," total ",[268,21481,302],{"class":274},[268,21483,306],{"class":305},[268,21485,293],{"class":282},[268,21487,21488,21491],{"class":270,"line":1951},[268,21489,21490],{"class":274},"delete",[268,21492,21493],{"class":282}," total;\n",[268,21495,21496,21498,21500],{"class":270,"line":8955},[268,21497,1353],{"class":282},[268,21499,1356],{"class":278},[268,21501,21502],{"class":282},"(total);\n",[23,21504,21506,21519,21534,21547],{"className":21505},[26],[28,21507,21509,355,21511,1133,21514,3990,21516,21518],{"className":21508},[31],[33,21510],{"disabled":35,"type":36},[39,21512,21513],{},"true { }",[39,21515,5825],{},[39,21517,21490],{}," removes object properties but is a silent no-op on variable bindings",[28,21520,21522,355,21524,1133,21526,3990,21528,21530,21531,21533],{"className":21521},[31],[33,21523],{"disabled":35,"type":36},[39,21525,21513],{},[39,21527,833],{},[39,21529,21490],{}," also removes the ",[39,21532,805],{}," variable itself",[28,21535,21537,355,21539,1133,21542,3990,21544,21546],{"className":21536},[31],[33,21538],{"disabled":35,"type":36},[39,21540,21541],{},"false { count: 5 }",[39,21543,5825],{},[39,21545,21490],{}," can't remove a property declared with a value",[28,21548,21550,355,21552,21554,21555,2278,21557,183,21559,21561,21562],{"className":21549},[31],[33,21551],{"disabled":35,"type":36},[39,21553,21513],{}," — the second ",[39,21556,21490],{},[39,21558,1274],{},[39,21560,805],{}," was declared with ",[39,21563,240],{},[66,21565,21566,21568,21578],{},[69,21567,71],{},[73,21569,21570,3459,21572,1133,21574,3990,21576,21518],{},[76,21571,78],{},[39,21573,21513],{},[39,21575,5825],{},[39,21577,21490],{},[73,21579,21580,355,21582,355,21584,21586,21587,21589,21590,21592,21593,21595,21596,21599,21600,21603,21604,21607,21608,21610,21611,446,21613,446,21615,21617,21618,9138,21620,21622,21623,21625,21626,21628],{},[76,21581,84],{},[76,21583,365],{},[39,21585,21490],{}," operates on object properties, not bindings — it removes the configurable own property and returns ",[39,21588,2185],{}," on success (state becomes ",[39,21591,2328],{},"). Note ",[39,21594,243],{}," only prevents ",[104,21597,21598],{},"reassigning"," the ",[39,21601,21602],{},"state"," binding, it doesn't stop mutating or deleting its properties. ",[39,21605,21606],{},"delete total"," targets a variable, not a property; ",[39,21609,21490],{}," has no power over ",[39,21612,1440],{},[39,21614,240],{},[39,21616,243],{}," bindings, so in non-strict mode it's simply a no-op that returns ",[39,21619,2986],{},[39,21621,805],{}," unchanged at ",[39,21624,5825],{}," (in strict mode, deleting a bare identifier is a ",[39,21627,1274],{}," at parse time, but that's a different scenario than this sloppy-mode script).",[15,21630,21631,21633,21723,21748],{"language":247},[18,21632,14382],{"id":14381},[257,21634,21635],{"language":247},[260,21636,21638],{"className":262,"code":21637,"language":247,"meta":264,"style":264},"const a = { id: 1 };\nconst b = { id: 1 };\nconst c = a;\n\nconsole.log(a === b, a === c, JSON.stringify(a) === JSON.stringify(b));\n",[39,21639,21640,21654,21668,21678,21682],{"__ignoreMap":264},[268,21641,21642,21644,21646,21648,21650,21652],{"class":270,"line":271},[268,21643,243],{"class":274},[268,21645,7203],{"class":305},[268,21647,616],{"class":274},[268,21649,20178],{"class":282},[268,21651,2255],{"class":305},[268,21653,2790],{"class":282},[268,21655,21656,21658,21660,21662,21664,21666],{"class":270,"line":286},[268,21657,243],{"class":274},[268,21659,16372],{"class":305},[268,21661,616],{"class":274},[268,21663,20178],{"class":282},[268,21665,2255],{"class":305},[268,21667,2790],{"class":282},[268,21669,21670,21672,21674,21676],{"class":270,"line":296},[268,21671,243],{"class":274},[268,21673,16389],{"class":305},[268,21675,616],{"class":274},[268,21677,2801],{"class":282},[268,21679,21680],{"class":270,"line":311},[268,21681,5033],{"emptyLinePlaceholder":35},[268,21683,21684,21686,21688,21690,21692,21695,21697,21700,21703,21705,21708,21711,21713,21716,21718,21720],{"class":270,"line":788},[268,21685,1353],{"class":282},[268,21687,1356],{"class":278},[268,21689,7218],{"class":282},[268,21691,3280],{"class":274},[268,21693,21694],{"class":282}," b, a ",[268,21696,3280],{"class":274},[268,21698,21699],{"class":282}," c, ",[268,21701,21702],{"class":305},"JSON",[268,21704,462],{"class":282},[268,21706,21707],{"class":278},"stringify",[268,21709,21710],{"class":282},"(a) ",[268,21712,3280],{"class":274},[268,21714,21715],{"class":305}," JSON",[268,21717,462],{"class":282},[268,21719,21707],{"class":278},[268,21721,21722],{"class":282},"(b));\n",[23,21724,21726,21731,21736,21742],{"className":21725},[26],[28,21727,21729,20721],{"className":21728},[31],[33,21730],{"disabled":35,"type":36},[28,21732,21734,20733],{"className":21733},[31],[33,21735],{"disabled":35,"type":36},[28,21737,21739,21741],{"className":21738},[31],[33,21740],{"disabled":35,"type":36}," false false true",[28,21743,21745,21747],{"className":21744},[31],[33,21746],{"disabled":35,"type":36}," false true true",[66,21749,21750,21752,21757],{},[69,21751,71],{},[73,21753,21754,21756],{},[76,21755,78],{}," D — false true true",[73,21758,21759,355,21761,355,21763,21765,21766,21768,21769,186,21771,21773,21774,830,21777,21779,21780,21782,21783,21785,21786,830,21789,3277,21791,21793,21794,137,21797,21799,21800,21802,21803,21805],{},[76,21760,84],{},[76,21762,930],{},[39,21764,3280],{}," compares object operands by ",[104,21767,20150],{},", never by structural content — ",[39,21770,1223],{},[39,21772,1232],{}," are two distinct objects that merely look alike, so ",[39,21775,21776],{},"a === b",[39,21778,2986],{}," even though every property matches. ",[39,21781,16484],{}," was assigned the exact same reference as ",[39,21784,1223],{}," (no new object was created), so ",[39,21787,21788],{},"a === c",[39,21790,2185],{},[39,21792,20555],{}," converts both objects to the identical string ",[39,21795,21796],{},"'{\"id\":1}'",[104,21798,7690],{}," string comparison is ",[39,21801,2185],{}," — but that's comparing two strings, not testing object identity, and it breaks down for objects with functions, ",[39,21804,833],{},", or differently-ordered keys with different serializers.",[15,21807,21808,21814,21901,21936],{"language":247},[18,21809,21811,21812,19524],{"id":21810},"q13-what-does-objectkeysobj-log","Q13. What does ",[39,21813,10390],{},[257,21815,21816],{"language":247},[260,21817,21819],{"className":262,"code":21818,"language":247,"meta":264,"style":264},"const obj = {};\nobj.b = 1;\nobj[2] = \"two\";\nobj.a = 3;\nobj[1] = \"one\";\n\nconsole.log(Object.keys(obj));\n",[39,21820,21821,21831,21842,21858,21869,21884,21888],{"__ignoreMap":264},[268,21822,21823,21825,21827,21829],{"class":270,"line":271},[268,21824,243],{"class":274},[268,21826,4651],{"class":305},[268,21828,616],{"class":274},[268,21830,15812],{"class":282},[268,21832,21833,21836,21838,21840],{"class":270,"line":286},[268,21834,21835],{"class":282},"obj.b ",[268,21837,302],{"class":274},[268,21839,2199],{"class":305},[268,21841,293],{"class":282},[268,21843,21844,21847,21849,21851,21853,21856],{"class":270,"line":296},[268,21845,21846],{"class":282},"obj[",[268,21848,2258],{"class":305},[268,21850,19897],{"class":282},[268,21852,302],{"class":274},[268,21854,21855],{"class":289}," \"two\"",[268,21857,293],{"class":282},[268,21859,21860,21863,21865,21867],{"class":270,"line":311},[268,21861,21862],{"class":282},"obj.a ",[268,21864,302],{"class":274},[268,21866,3396],{"class":305},[268,21868,293],{"class":282},[268,21870,21871,21873,21875,21877,21879,21882],{"class":270,"line":788},[268,21872,21846],{"class":282},[268,21874,2255],{"class":305},[268,21876,19897],{"class":282},[268,21878,302],{"class":274},[268,21880,21881],{"class":289}," \"one\"",[268,21883,293],{"class":282},[268,21885,21886],{"class":270,"line":1951},[268,21887,5033],{"emptyLinePlaceholder":35},[268,21889,21890,21892,21894,21896,21898],{"class":270,"line":8955},[268,21891,1353],{"class":282},[268,21893,1356],{"class":278},[268,21895,19627],{"class":282},[268,21897,9261],{"class":278},[268,21899,21900],{"class":282},"(obj));\n",[23,21902,21904,21912,21920,21928],{"className":21903},[26],[28,21905,21907,355,21909],{"className":21906},[31],[33,21908],{"disabled":35,"type":36},[268,21910,21911],{},"\"b\", \"2\", \"a\", \"1\"",[28,21913,21915,355,21917],{"className":21914},[31],[33,21916],{"disabled":35,"type":36},[268,21918,21919],{},"\"1\", \"2\", \"b\", \"a\"",[28,21921,21923,355,21925],{"className":21922},[31],[33,21924],{"disabled":35,"type":36},[268,21926,21927],{},"\"1\", \"2\", \"a\", \"b\"",[28,21929,21931,355,21933],{"className":21930},[31],[33,21932],{"disabled":35,"type":36},[268,21934,21935],{},"\"2\", \"1\", \"b\", \"a\"",[66,21937,21938,21940,21946],{},[69,21939,71],{},[73,21941,21942,1727,21944],{},[76,21943,78],{},[268,21945,21919],{},[73,21947,21948,355,21950,21952,21953,21956,21957,186,21959,21961,21962,21200,21964,20766,21966,21968,21969,186,21971,21973],{},[76,21949,84],{},[76,21951,365],{}," own-property key ordering follows a fixed spec rule, not insertion order alone: integer-index-like string keys come first, sorted in ",[104,21954,21955],{},"ascending numeric"," order regardless of when they were added, followed by all other string keys in insertion order, then Symbol keys last. Here ",[39,21958,3387],{},[39,21960,9269],{}," are integer-like, so they're sorted numerically first (",[39,21963,2255],{},[39,21965,2258],{},[39,21967,2258],{}," was inserted first), and only then come ",[39,21970,9188],{},[39,21972,7582],{}," in the order they were actually assigned.",[15,21975,21976,21982,22107,22134],{"language":247},[18,21977,7516,21979,19524],{"id":21978},"q14-what-does-jsonstringifyaccount-log",[39,21980,21981],{},"JSON.stringify(account)",[257,21983,21984],{"language":247},[260,21985,21987],{"className":262,"code":21986,"language":247,"meta":264,"style":264},"const account = {\n  _balance: 100,\n  get balance() {\n    return `$${this._balance}`;\n  },\n  set balance(value) {\n    this._balance = value;\n  },\n};\n\naccount.balance = 250;\nconsole.log(JSON.stringify(account));\n",[39,21988,21989,22000,22009,22019,22036,22040,22053,22066,22070,22074,22078,22090],{"__ignoreMap":264},[268,21990,21991,21993,21996,21998],{"class":270,"line":271},[268,21992,243],{"class":274},[268,21994,21995],{"class":305}," account",[268,21997,616],{"class":274},[268,21999,9914],{"class":282},[268,22001,22002,22005,22007],{"class":270,"line":286},[268,22003,22004],{"class":282},"  _balance: ",[268,22006,13912],{"class":305},[268,22008,1789],{"class":282},[268,22010,22011,22014,22017],{"class":270,"line":296},[268,22012,22013],{"class":274},"  get",[268,22015,22016],{"class":278}," balance",[268,22018,283],{"class":282},[268,22020,22021,22023,22025,22027,22029,22032,22034],{"class":270,"line":311},[268,22022,9871],{"class":274},[268,22024,19595],{"class":289},[268,22026,950],{"class":305},[268,22028,462],{"class":289},[268,22030,22031],{"class":282},"_balance",[268,22033,11603],{"class":289},[268,22035,293],{"class":282},[268,22037,22038],{"class":270,"line":788},[268,22039,19610],{"class":282},[268,22041,22042,22045,22047,22049,22051],{"class":270,"line":1951},[268,22043,22044],{"class":274},"  set",[268,22046,22016],{"class":278},[268,22048,622],{"class":282},[268,22050,4780],{"class":1222},[268,22052,1235],{"class":282},[268,22054,22055,22058,22061,22063],{"class":270,"line":8955},[268,22056,22057],{"class":305},"    this",[268,22059,22060],{"class":282},"._balance ",[268,22062,302],{"class":274},[268,22064,22065],{"class":282}," value;\n",[268,22067,22068],{"class":270,"line":8966},[268,22069,19610],{"class":282},[268,22071,22072],{"class":270,"line":8974},[268,22073,12940],{"class":282},[268,22075,22076],{"class":270,"line":8985},[268,22077,5033],{"emptyLinePlaceholder":35},[268,22079,22080,22083,22085,22088],{"class":270,"line":8990},[268,22081,22082],{"class":282},"account.balance ",[268,22084,302],{"class":274},[268,22086,22087],{"class":305}," 250",[268,22089,293],{"class":282},[268,22091,22092,22094,22096,22098,22100,22102,22104],{"class":270,"line":8997},[268,22093,1353],{"class":282},[268,22095,1356],{"class":278},[268,22097,622],{"class":282},[268,22099,21702],{"class":305},[268,22101,462],{"class":282},[268,22103,21707],{"class":278},[268,22105,22106],{"class":282},"(account));\n",[23,22108,22110,22116,22122,22128],{"className":22109},[26],[28,22111,22113,22115],{"className":22112},[31],[33,22114],{"disabled":35,"type":36}," {\"_balance\":100,\"balance\":\"$100\"}",[28,22117,22119,22121],{"className":22118},[31],[33,22120],{"disabled":35,"type":36}," {\"balance\":\"$250\"}",[28,22123,22125,22127],{"className":22124},[31],[33,22126],{"disabled":35,"type":36}," {\"_balance\":250,\"balance\":\"$250\"}",[28,22129,22131,22133],{"className":22130},[31],[33,22132],{"disabled":35,"type":36}," {\"_balance\":250}",[66,22135,22136,22138,22143],{},[69,22137,71],{},[73,22139,22140,22142],{},[76,22141,78],{}," C — {\"_balance\":250,\"balance\":\"$250\"}",[73,22144,22145,355,22147,22149,22150,22153,22154,3277,22156,22158,22159,22161,22162,2182,22164,22167,22168,22171,22172,22175],{},[76,22146,84],{},[76,22148,930],{}," assigning ",[39,22151,22152],{},"account.balance = 250"," invokes the setter, which stores the raw number into ",[39,22155,22031],{},[39,22157,20555],{}," serializes every own enumerable property — including accessor (getter) properties — and for a getter it ",[104,22160,14764],{}," it and embeds the returned value, so both the updated ",[39,22163,22031],{},[39,22165,22166],{},"250",") and the computed ",[39,22169,22170],{},"balance"," getter output (",[39,22173,22174],{},"\"$250\"",") end up in the JSON. It neither skips getters (ruling out B and D) nor uses a stale pre-assignment snapshot (ruling out A).",[15,22177,22178,22182,22301,22389],{"language":247},[18,22179,22181],{"id":22180},"q15-which-statement-correctly-describes-what-happens","Q15. Which statement correctly describes what happens?",[257,22183,22184],{"language":247},[260,22185,22187],{"className":262,"code":22186,"language":247,"meta":264,"style":264},"const original = {\n  createdAt: new Date(\"2024-01-01\"),\n  greet: function () {},\n  count: undefined,\n  tag: Symbol(\"x\"),\n};\n\nconst viaJson = JSON.parse(JSON.stringify(original));\nconst viaClone = structuredClone(original);\n",[39,22188,22189,22199,22216,22228,22237,22251,22255,22259,22286],{"__ignoreMap":264},[268,22190,22191,22193,22195,22197],{"class":270,"line":271},[268,22192,243],{"class":274},[268,22194,20173],{"class":305},[268,22196,616],{"class":274},[268,22198,9914],{"class":282},[268,22200,22201,22204,22206,22209,22211,22214],{"class":270,"line":286},[268,22202,22203],{"class":282},"  createdAt: ",[268,22205,2689],{"class":274},[268,22207,22208],{"class":278}," Date",[268,22210,622],{"class":282},[268,22212,22213],{"class":289},"\"2024-01-01\"",[268,22215,17159],{"class":282},[268,22217,22218,22221,22223,22225],{"class":270,"line":296},[268,22219,22220],{"class":278},"  greet",[268,22222,1783],{"class":282},[268,22224,275],{"class":274},[268,22226,22227],{"class":282}," () {},\n",[268,22229,22230,22233,22235],{"class":270,"line":311},[268,22231,22232],{"class":282},"  count: ",[268,22234,833],{"class":305},[268,22236,1789],{"class":282},[268,22238,22239,22242,22244,22246,22249],{"class":270,"line":788},[268,22240,22241],{"class":282},"  tag: ",[268,22243,4618],{"class":278},[268,22245,622],{"class":282},[268,22247,22248],{"class":289},"\"x\"",[268,22250,17159],{"class":282},[268,22252,22253],{"class":270,"line":1951},[268,22254,12940],{"class":282},[268,22256,22257],{"class":270,"line":8955},[268,22258,5033],{"emptyLinePlaceholder":35},[268,22260,22261,22263,22266,22268,22270,22272,22275,22277,22279,22281,22283],{"class":270,"line":8966},[268,22262,243],{"class":274},[268,22264,22265],{"class":305}," viaJson",[268,22267,616],{"class":274},[268,22269,21715],{"class":305},[268,22271,462],{"class":282},[268,22273,22274],{"class":278},"parse",[268,22276,622],{"class":282},[268,22278,21702],{"class":305},[268,22280,462],{"class":282},[268,22282,21707],{"class":278},[268,22284,22285],{"class":282},"(original));\n",[268,22287,22288,22290,22293,22295,22298],{"class":270,"line":8974},[268,22289,243],{"class":274},[268,22291,22292],{"class":305}," viaClone",[268,22294,616],{"class":274},[268,22296,22297],{"class":278}," structuredClone",[268,22299,22300],{"class":282},"(original);\n",[23,22302,22304,22324,22350,22372],{"className":22303},[26],[28,22305,22307,355,22309,22312,22313,42,22315,137,22317,22319,22320,22323],{"className":22306},[31],[33,22308],{"disabled":35,"type":36},[39,22310,22311],{},"viaJson.createdAt"," becomes a string, and ",[39,22314,12761],{},[39,22316,10191],{},[39,22318,17214],{}," are dropped entirely; ",[39,22321,22322],{},"structuredClone"," throws because it can't clone a function",[28,22325,22327,355,22329,22331,22332,22334,22335,22337,22338,22340,22341,22344,22345,22347,22348],{"className":22326},[31],[33,22328],{"disabled":35,"type":36},[39,22330,22311],{}," stays a ",[39,22333,2669],{}," but ",[39,22336,12761],{}," is dropped; ",[39,22339,22322],{}," also preserves ",[39,22342,22343],{},"createdAt"," as a ",[39,22346,2669],{}," and drops ",[39,22349,12761],{},[28,22351,22353,2247,22355,186,22358,22361,22362,22344,22364,42,22366,22368,22369,22371],{"className":22352},[31],[33,22354],{"disabled":35,"type":36},[39,22356,22357],{},"viaJson",[39,22359,22360],{},"viaClone"," preserve ",[39,22363,22343],{},[39,22365,2669],{},[39,22367,12761],{}," as a function, and ",[39,22370,17214],{}," as a Symbol",[28,22373,22375,355,22377,2278,22379,183,22381,22383,22384,22386,22387],{"className":22374},[31],[33,22376],{"disabled":35,"type":36},[39,22378,20555],{},[39,22380,827],{},[39,22382,2669],{}," isn't valid JSON; ",[39,22385,22322],{}," succeeds and preserves everything, including ",[39,22388,12761],{},[66,22390,22391,22393,22407],{},[69,22392,71],{},[73,22394,22395,3459,22397,22312,22399,42,22401,137,22403,22319,22405,22323],{},[76,22396,78],{},[39,22398,22311],{},[39,22400,12761],{},[39,22402,10191],{},[39,22404,17214],{},[39,22406,22322],{},[73,22408,22409,355,22411,355,22413,14552,22415,9057,22417,22420,22421,22424,22425,22427,22428,22430,22431,22434,22435,22437,22438,22440,22441,2338,22443,446,22445,22447,22448,22450,22451,22454],{},[76,22410,84],{},[76,22412,582],{},[39,22414,20555],{},[39,22416,2669],{},[39,22418,22419],{},"toJSON",", converting it to an ISO string, so the round-trip through ",[39,22422,22423],{},"JSON.parse"," leaves ",[39,22426,22343],{}," as a plain string, not a ",[39,22429,2669],{},". It also ",[104,22432,22433],{},"silently"," omits any property whose value is ",[39,22436,833],{},", a function, or a Symbol — no error, they simply vanish from the output. ",[39,22439,22322],{}," uses the structured clone algorithm, which correctly deep-clones ",[39,22442,2669],{},[39,22444,2672],{},[39,22446,9306],{},"\u002Ftyped arrays\u002Fcircular references) as real ",[39,22449,2669],{}," objects — but functions (and Symbols) are explicitly unsupported and cause it to throw a ",[39,22452,22453],{},"DataCloneError",", so it can't be used as a drop-in replacement on objects that hold methods.",[15,22456,22457,22459,22531,22575],{"language":247},[18,22458,15131],{"id":15130},[257,22460,22461],{"language":247},[260,22462,22464],{"className":262,"code":22463,"language":247,"meta":264,"style":264},"const dict = Object.create(null);\ndict.apple = 1;\n\nconsole.log(dict.toString);\nconsole.log(dict.hasOwnProperty);\nconsole.log(Object.keys(dict));\n",[39,22465,22466,22485,22496,22500,22509,22518],{"__ignoreMap":264},[268,22467,22468,22470,22473,22475,22477,22479,22481,22483],{"class":270,"line":271},[268,22469,243],{"class":274},[268,22471,22472],{"class":305}," dict",[268,22474,616],{"class":274},[268,22476,20017],{"class":282},[268,22478,20628],{"class":278},[268,22480,622],{"class":282},[268,22482,2650],{"class":305},[268,22484,628],{"class":282},[268,22486,22487,22490,22492,22494],{"class":270,"line":286},[268,22488,22489],{"class":282},"dict.apple ",[268,22491,302],{"class":274},[268,22493,2199],{"class":305},[268,22495,293],{"class":282},[268,22497,22498],{"class":270,"line":296},[268,22499,5033],{"emptyLinePlaceholder":35},[268,22501,22502,22504,22506],{"class":270,"line":311},[268,22503,1353],{"class":282},[268,22505,1356],{"class":278},[268,22507,22508],{"class":282},"(dict.toString);\n",[268,22510,22511,22513,22515],{"class":270,"line":788},[268,22512,1353],{"class":282},[268,22514,1356],{"class":278},[268,22516,22517],{"class":282},"(dict.hasOwnProperty);\n",[268,22519,22520,22522,22524,22526,22528],{"class":270,"line":1951},[268,22521,1353],{"class":282},[268,22523,1356],{"class":278},[268,22525,19627],{"class":282},[268,22527,9261],{"class":278},[268,22529,22530],{"class":282},"(dict));\n",[23,22532,22534,22549,22557,22567],{"className":22533},[26],[28,22535,22537,22539,22540,22543,22544,355,22547],{"className":22536},[31],[33,22538],{"disabled":35,"type":36}," \"",[268,22541,22542],{},"object Object","\" ",[268,22545,22546],{},"Function: hasOwnProperty",[268,22548,14842],{},[28,22550,22552,22554,22555],{"className":22551},[31],[33,22553],{"disabled":35,"type":36}," TypeError TypeError ",[268,22556,14842],{},[28,22558,22560,22562,22563,355,22565],{"className":22559},[31],[33,22561],{"disabled":35,"type":36}," undefined ",[268,22564,22546],{},[268,22566,14842],{},[28,22568,22570,22572,22573],{"className":22569},[31],[33,22571],{"disabled":35,"type":36}," undefined undefined ",[268,22574,14842],{},[66,22576,22577,22579,22586],{},[69,22578,71],{},[73,22580,22581,22583,22584],{},[76,22582,78],{}," D — undefined undefined ",[268,22585,14842],{},[73,22587,22588,355,22590,355,22592,22595,22596,22598,22599,22601,22602,42,22605,42,22607,22610,22611,22613,22614,99,22617,22620,22621,8574,22624,22627,22628,462],{},[76,22589,84],{},[76,22591,582],{},[39,22593,22594],{},"Object.create(null)"," builds an object with ",[104,22597,16678],{}," prototype at all — not even ",[39,22600,3800],{}," — so it inherits none of the usual built-ins: ",[39,22603,22604],{},"toString",[39,22606,20679],{},[39,22608,22609],{},"valueOf",", etc. all simply don't exist on it, and accessing them returns ",[39,22612,833],{}," rather than throwing. This makes it a good \"pure dictionary\" that can safely use any string key — even ",[39,22615,22616],{},"\"toString\"",[39,22618,22619],{},"\"__proto__\""," — without colliding with inherited methods or enabling prototype pollution, but callers must use ",[39,22622,22623],{},"Object.hasOwn(dict, key)",[39,22625,22626],{},"dict.hasOwnProperty(key)",", since the latter would throw ",[39,22629,22630],{},"TypeError: dict.hasOwnProperty is not a function",[15,22632,22633,22635,22724,22751],{"language":247},[18,22634,15311],{"id":15310},[257,22636,22637],{"language":247},[260,22638,22640],{"className":262,"code":22639,"language":247,"meta":264,"style":264},"const original = { user: { name: \"Kim\" }, count: 1 };\nconst { user, ...rest } = original;\n\nuser.name = \"Lee\";\nrest.count = 99;\n\nconsole.log(original.user.name, original.count);\n",[39,22641,22642,22663,22685,22689,22700,22711,22715],{"__ignoreMap":264},[268,22643,22644,22646,22648,22650,22653,22656,22659,22661],{"class":270,"line":271},[268,22645,243],{"class":274},[268,22647,20173],{"class":305},[268,22649,616],{"class":274},[268,22651,22652],{"class":282}," { user: { name: ",[268,22654,22655],{"class":289},"\"Kim\"",[268,22657,22658],{"class":282}," }, count: ",[268,22660,2255],{"class":305},[268,22662,2790],{"class":282},[268,22664,22665,22667,22669,22671,22673,22675,22678,22680,22682],{"class":270,"line":286},[268,22666,243],{"class":274},[268,22668,20200],{"class":282},[268,22670,4155],{"class":305},[268,22672,42],{"class":282},[268,22674,15329],{"class":274},[268,22676,22677],{"class":305},"rest",[268,22679,7908],{"class":282},[268,22681,302],{"class":274},[268,22683,22684],{"class":282}," original;\n",[268,22686,22687],{"class":270,"line":296},[268,22688,5033],{"emptyLinePlaceholder":35},[268,22690,22691,22693,22695,22698],{"class":270,"line":311},[268,22692,4086],{"class":282},[268,22694,302],{"class":274},[268,22696,22697],{"class":289}," \"Lee\"",[268,22699,293],{"class":282},[268,22701,22702,22705,22707,22709],{"class":270,"line":788},[268,22703,22704],{"class":282},"rest.count ",[268,22706,302],{"class":274},[268,22708,2811],{"class":305},[268,22710,293],{"class":282},[268,22712,22713],{"class":270,"line":1951},[268,22714,5033],{"emptyLinePlaceholder":35},[268,22716,22717,22719,22721],{"class":270,"line":8955},[268,22718,1353],{"class":282},[268,22720,1356],{"class":278},[268,22722,22723],{"class":282},"(original.user.name, original.count);\n",[23,22725,22727,22733,22739,22745],{"className":22726},[26],[28,22728,22730,22732],{"className":22729},[31],[33,22731],{"disabled":35,"type":36}," \"Kim\" 1",[28,22734,22736,22738],{"className":22735},[31],[33,22737],{"disabled":35,"type":36}," \"Lee\" 1",[28,22740,22742,22744],{"className":22741},[31],[33,22743],{"disabled":35,"type":36}," \"Lee\" 99",[28,22746,22748,22750],{"className":22747},[31],[33,22749],{"disabled":35,"type":36}," \"Kim\" 99",[66,22752,22753,22755,22760],{},[69,22754,71],{},[73,22756,22757,22759],{},[76,22758,78],{}," B — \"Lee\" 1",[73,22761,22762,355,22764,22766,22767,22769,22770,22773,22774,22776,22777,22780,22781,22784,22785,22788,22789,22792,22793,22796,22797,22800,22801,22803,22804,22807,22808,14765,22811,22813],{},[76,22763,84],{},[76,22765,365],{}," destructuring ",[39,22768,4155],{}," out of ",[39,22771,22772],{},"original"," binds ",[39,22775,4155],{}," to the ",[104,22778,22779],{},"same"," object ",[39,22782,22783],{},"original.user"," already points to — no copy is made for nested objects — so mutating ",[39,22786,22787],{},"user.name"," mutates the shared object, and ",[39,22790,22791],{},"original.user.name"," reads back as ",[39,22794,22795],{},"\"Lee\"",". The rest pattern ",[39,22798,22799],{},"...rest",", however, builds a brand-new object whose ",[39,22802,10191],{}," is a freshly copied primitive value, so writing ",[39,22805,22806],{},"rest.count = 99"," only touches the new object and leaves ",[39,22809,22810],{},"original.count",[39,22812,2255],{},". The trap: primitives are safely copied by destructuring\u002Fspread, but nested object references are shared, not cloned.",[15,22815,22816,22818,22915,22950],{"language":247},[18,22817,18980],{"id":18979},[257,22819,22820],{"language":247},[260,22821,22823],{"className":262,"code":22822,"language":247,"meta":264,"style":264},"const id = Symbol(\"id\");\nconst user = {\n  name: \"Ana\",\n  [id]: 42,\n};\n\nconsole.log(Object.keys(user));\nconsole.log(JSON.stringify(user));\nconsole.log(user[id]);\n",[39,22824,22825,22842,22852,22860,22869,22873,22877,22890,22906],{"__ignoreMap":264},[268,22826,22827,22829,22831,22833,22835,22837,22840],{"class":270,"line":271},[268,22828,243],{"class":274},[268,22830,4632],{"class":305},[268,22832,616],{"class":274},[268,22834,4637],{"class":278},[268,22836,622],{"class":282},[268,22838,22839],{"class":289},"\"id\"",[268,22841,628],{"class":282},[268,22843,22844,22846,22848,22850],{"class":270,"line":286},[268,22845,243],{"class":274},[268,22847,4071],{"class":305},[268,22849,616],{"class":274},[268,22851,9914],{"class":282},[268,22853,22854,22856,22858],{"class":270,"line":296},[268,22855,20028],{"class":282},[268,22857,4079],{"class":289},[268,22859,1789],{"class":282},[268,22861,22862,22865,22867],{"class":270,"line":311},[268,22863,22864],{"class":282},"  [id]: ",[268,22866,4659],{"class":305},[268,22868,1789],{"class":282},[268,22870,22871],{"class":270,"line":788},[268,22872,12940],{"class":282},[268,22874,22875],{"class":270,"line":1951},[268,22876,5033],{"emptyLinePlaceholder":35},[268,22878,22879,22881,22883,22885,22887],{"class":270,"line":8955},[268,22880,1353],{"class":282},[268,22882,1356],{"class":278},[268,22884,19627],{"class":282},[268,22886,9261],{"class":278},[268,22888,22889],{"class":282},"(user));\n",[268,22891,22892,22894,22896,22898,22900,22902,22904],{"class":270,"line":8966},[268,22893,1353],{"class":282},[268,22895,1356],{"class":278},[268,22897,622],{"class":282},[268,22899,21702],{"class":305},[268,22901,462],{"class":282},[268,22903,21707],{"class":278},[268,22905,22889],{"class":282},[268,22907,22908,22910,22912],{"class":270,"line":8974},[268,22909,1353],{"class":282},[268,22911,1356],{"class":278},[268,22913,22914],{"class":282},"(user[id]);\n",[23,22916,22918,22927,22936,22944],{"className":22917},[26],[28,22919,22921,355,22923,22926],{"className":22920},[31],[33,22922],{"disabled":35,"type":36},[268,22924,22925],{},"\"name\", \"id\""," {\"name\":\"Ana\",\"id\":42} 42",[28,22928,22930,355,22932,22935],{"className":22929},[31],[33,22931],{"disabled":35,"type":36},[268,22933,22934],{},"\"name\""," {\"name\":\"Ana\",\"id\":42} undefined",[28,22937,22939,355,22941,22943],{"className":22938},[31],[33,22940],{"disabled":35,"type":36},[268,22942,22934],{}," {\"name\":\"Ana\"} 42",[28,22945,22947,22949],{"className":22946},[31],[33,22948],{"disabled":35,"type":36}," TypeError: Symbol keys are not allowed in object literals",[66,22951,22952,22954,22960],{},[69,22953,71],{},[73,22955,22956,1004,22958,22943],{},[76,22957,78],{},[268,22959,22934],{},[73,22961,22962,355,22964,22966,22967,446,22969,446,22971,42,22973,137,22975,22977,22978,22981],{},[76,22963,84],{},[76,22965,930],{}," Symbol-keyed properties are unconditionally excluded from ",[39,22968,19687],{},[39,22970,9275],{},[39,22972,20552],{},[39,22974,4728],{},[39,22976,20555],{}," — not because of an enumerable flag, but because Symbols are categorically skipped by all of those mechanisms. This makes Symbols useful for attaching metadata to an object that won't collide with string keys or accidentally leak into serialization or plain iteration. The property is still fully present and directly retrievable via ",[39,22979,22980],{},"user[id]",", since the caller holds a reference to the exact same Symbol.",[15,22983,22984,23003,23037],{},[18,22985,22987,22988,22991,22992,22994,22995,22997,22998,23000,23001,1685],{"id":22986},"q19-in-modern-js-es2022-which-is-the-most-robust-way-to-check-whether-obj-has-an-own-property-named-key-correct-even-when-obj-was-created-with-objectcreatenull","Q19. In modern JS (ES2022+), which is the most robust way to check whether ",[39,22989,22990],{},"obj"," has an ",[104,22993,20995],{}," property named ",[39,22996,19849],{},", correct even when ",[39,22999,22990],{}," was created with ",[39,23002,22594],{},[23,23004,23006,23013,23021,23029],{"className":23005},[26],[28,23007,23009,355,23011],{"className":23008},[31],[33,23010],{"disabled":35,"type":36},[39,23012,20781],{},[28,23014,23016,355,23018],{"className":23015},[31],[33,23017],{"disabled":35,"type":36},[39,23019,23020],{},"obj.hasOwnProperty(key)",[28,23022,23024,355,23026],{"className":23023},[31],[33,23025],{"disabled":35,"type":36},[39,23027,23028],{},"key in obj",[28,23030,23032,355,23034],{"className":23031},[31],[33,23033],{"disabled":35,"type":36},[39,23035,23036],{},"obj[key] !== undefined",[66,23038,23039,23041,23047],{},[69,23040,71],{},[73,23042,23043,3459,23045],{},[76,23044,78],{},[39,23046,20781],{},[73,23048,23049,355,23051,355,23053,23055,23056,23058,23059,23061,23062,3277,23064,23066,23067,23070,23071,23073,23074,23076,23077,23079,23080,23082,23083,23085],{},[76,23050,84],{},[76,23052,930],{},[39,23054,20774],{}," is a static method — it doesn't rely on ",[39,23057,22990],{}," inheriting anything, so it works correctly even on prototype-less objects, objects that shadow their own ",[39,23060,20679],{},", or objects retrieved from ",[39,23063,22594],{},[39,23065,23020],{}," breaks in exactly those cases, throwing ",[39,23068,23069],{},"TypeError: obj.hasOwnProperty is not a function"," when no prototype provides it. ",[39,23072,23028],{}," checks the ",[104,23075,20753],{}," prototype chain, so it produces false positives for inherited properties. ",[39,23078,23036],{}," is unreliable both ways: a property can exist with the value ",[39,23081,833],{}," (false negative) and a missing key also reads as ",[39,23084,833],{}," (indistinguishable).",[15,23087,23088,23092,23224,23258],{"language":247},[18,23089,23091],{"id":23090},"q20-in-strict-mode-what-is-logged","Q20. In strict mode, what is logged?",[257,23093,23094],{"language":247},[260,23095,23097],{"className":262,"code":23096,"language":247,"meta":264,"style":264},"\"use strict\";\n\nconst user = Object.freeze({ name: \"Ana\", roles: [\"admin\"] });\n\ntry {\n  user.name = \"Zoe\";\n  console.log(\"assigned\");\n} catch (err) {\n  console.log(err.constructor.name);\n}\n\nuser.roles.push(\"editor\");\nconsole.log(user.roles);\n",[39,23098,23099,23105,23109,23134,23138,23145,23157,23170,23178,23193,23197,23201,23215],{"__ignoreMap":264},[268,23100,23101,23103],{"class":270,"line":271},[268,23102,254],{"class":289},[268,23104,293],{"class":282},[268,23106,23107],{"class":270,"line":286},[268,23108,5033],{"emptyLinePlaceholder":35},[268,23110,23111,23113,23115,23117,23119,23121,23124,23126,23129,23131],{"class":270,"line":296},[268,23112,243],{"class":274},[268,23114,4071],{"class":305},[268,23116,616],{"class":274},[268,23118,20017],{"class":282},[268,23120,20020],{"class":278},[268,23122,23123],{"class":282},"({ name: ",[268,23125,4079],{"class":289},[268,23127,23128],{"class":282},", roles: [",[268,23130,19778],{"class":289},[268,23132,23133],{"class":282},"] });\n",[268,23135,23136],{"class":270,"line":311},[268,23137,5033],{"emptyLinePlaceholder":35},[268,23139,23140,23143],{"class":270,"line":788},[268,23141,23142],{"class":274},"try",[268,23144,9914],{"class":282},[268,23146,23147,23150,23152,23155],{"class":270,"line":1951},[268,23148,23149],{"class":282},"  user.name ",[268,23151,302],{"class":274},[268,23153,23154],{"class":289}," \"Zoe\"",[268,23156,293],{"class":282},[268,23158,23159,23161,23163,23165,23168],{"class":270,"line":8955},[268,23160,5556],{"class":282},[268,23162,1356],{"class":278},[268,23164,622],{"class":282},[268,23166,23167],{"class":289},"\"assigned\"",[268,23169,628],{"class":282},[268,23171,23172,23174,23176],{"class":270,"line":8966},[268,23173,11235],{"class":282},[268,23175,12488],{"class":274},[268,23177,12491],{"class":282},[268,23179,23180,23182,23184,23187,23190],{"class":270,"line":8974},[268,23181,5556],{"class":282},[268,23183,1356],{"class":278},[268,23185,23186],{"class":282},"(err.",[268,23188,23189],{"class":305},"constructor",[268,23191,23192],{"class":282},".name);\n",[268,23194,23195],{"class":270,"line":8985},[268,23196,314],{"class":282},[268,23198,23199],{"class":270,"line":8990},[268,23200,5033],{"emptyLinePlaceholder":35},[268,23202,23203,23206,23208,23210,23213],{"class":270,"line":8997},[268,23204,23205],{"class":282},"user.roles.",[268,23207,12499],{"class":278},[268,23209,622],{"class":282},[268,23211,23212],{"class":289},"\"editor\"",[268,23214,628],{"class":282},[268,23216,23217,23219,23221],{"class":270,"line":9002},[268,23218,1353],{"class":282},[268,23220,1356],{"class":278},[268,23222,23223],{"class":282},"(user.roles);\n",[23,23225,23227,23235,23243,23251],{"className":23226},[26],[28,23228,23230,23232,23233],{"className":23229},[31],[33,23231],{"disabled":35,"type":36}," \"assigned\" then ",[268,23234,19778],{},[28,23236,23238,23240,23241],{"className":23237},[31],[33,23239],{"disabled":35,"type":36}," \"TypeError\" then ",[268,23242,19778],{},[28,23244,23246,23232,23248],{"className":23245},[31],[33,23247],{"disabled":35,"type":36},[268,23249,23250],{},"\"admin\", \"editor\"",[28,23252,23254,23240,23256],{"className":23253},[31],[33,23255],{"disabled":35,"type":36},[268,23257,23250],{},[66,23259,23260,23262,23269],{},[69,23261,71],{},[73,23263,23264,23266,23267],{},[76,23265,78],{}," D — \"TypeError\" then ",[268,23268,23250],{},[73,23270,23271,355,23273,23275,23276,23278,23279,23281,23282,3277,23285,23287,23288,23290,23291,23293,23294,23296,23297,23300,23301,23304,23305,23308,23309,23312],{},[76,23272,84],{},[76,23274,582],{}," in strict mode, assigning to a non-writable property of a frozen object throws a ",[39,23277,827],{}," instead of failing silently (as it would in sloppy mode), so the ",[39,23280,12488],{}," block runs and logs ",[39,23283,23284],{},"\"TypeError\"",[39,23286,20133],{},", however, is shallow — it only locks ",[39,23289,4155],{},"'s own top-level slots (",[39,23292,14605],{},", and the ",[104,23295,20150],{}," stored in ",[39,23298,23299],{},"roles","), never the contents of objects those slots merely point to. ",[39,23302,23303],{},"user.roles"," is still a fully mutable array, so ",[39,23306,23307],{},"push(\"editor\")"," succeeds in place, producing ",[39,23310,23311],{},"[\"admin\", \"editor\"]",". Freezing an object never cascades into anything it references.",[2107,23314,23315],{},"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 pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-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 .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}",{"title":264,"searchDepth":286,"depth":286,"links":23317},[23318,23320,23321,23322,23323,23324,23325,23326,23327,23328,23329,23331,23332,23334,23336,23337,23338,23339,23340,23342],{"id":19519,"depth":296,"text":23319},"Q1. What does Object.keys(product) log?",{"id":12736,"depth":296,"text":12737},{"id":12876,"depth":296,"text":12877},{"id":13031,"depth":296,"text":13032},{"id":13180,"depth":296,"text":13181},{"id":13320,"depth":296,"text":13321},{"id":13527,"depth":296,"text":13528},{"id":13728,"depth":296,"text":13729},{"id":21012,"depth":296,"text":21013},{"id":17618,"depth":296,"text":17619},{"id":21418,"depth":296,"text":23330},"Q11. What is logged, and what happens when delete total; runs afterward in non-strict mode?",{"id":14381,"depth":296,"text":14382},{"id":21810,"depth":296,"text":23333},"Q13. What does Object.keys(obj) log?",{"id":21978,"depth":296,"text":23335},"Q14. What does JSON.stringify(account) log?",{"id":22180,"depth":296,"text":22181},{"id":15130,"depth":296,"text":15131},{"id":15310,"depth":296,"text":15311},{"id":18979,"depth":296,"text":18980},{"id":22986,"depth":296,"text":23341},"Q19. In modern JS (ES2022+), which is the most robust way to check whether obj has an own property named key, correct even when obj was created with Object.create(null)?",{"id":23090,"depth":296,"text":23091},{},"\u002Fjs\u002F07-objects-and-properties",{"title":19509,"description":264},"js\u002F07-objects-and-properties","QvSYnAvJKzt2BdQrnIt-ve_ZvpLjcE4omZZBmjmA2CY",{"id":23349,"title":23350,"body":23351,"description":264,"extension":2144,"meta":26803,"navigation":35,"path":26804,"seo":26805,"stem":26806,"__hash__":26807},"content\u002Fjs\u002F08-arrays-and-array-methods.md","08 — Arrays & Array Methods",{"type":8,"value":23352,"toc":26780},[23353,23356,23535,23667,23799,23958,24123,24296,24436,24641,24774,24909,25155,25343,25487,25636,25770,25920,26100,26301,26561,26777],[11,23354,23350],{"id":23355},"_08-arrays-array-methods",[15,23357,23358,23362,23463,23490],{"language":247},[18,23359,23361],{"id":23360},"q1-what-does-the-following-log","Q1. What does the following log?",[257,23363,23364],{"language":247},[260,23365,23367],{"className":262,"code":23366,"language":247,"meta":264,"style":264},"function addItem(cart, item) {\n  cart.push(item);\n  return cart;\n}\n\nconst original = ['apple'];\nconst updated = addItem(original, 'banana');\n\nconsole.log(original === updated, original.length);\n",[39,23368,23369,23385,23393,23399,23403,23407,23422,23441,23445],{"__ignoreMap":264},[268,23370,23371,23373,23375,23377,23379,23381,23383],{"class":270,"line":271},[268,23372,275],{"class":274},[268,23374,14788],{"class":278},[268,23376,622],{"class":282},[268,23378,8318],{"class":1222},[268,23380,42],{"class":282},[268,23382,14793],{"class":1222},[268,23384,1235],{"class":282},[268,23386,23387,23389,23391],{"class":270,"line":286},[268,23388,14807],{"class":282},[268,23390,12499],{"class":278},[268,23392,11808],{"class":282},[268,23394,23395,23397],{"class":270,"line":296},[268,23396,1240],{"class":274},[268,23398,14818],{"class":282},[268,23400,23401],{"class":270,"line":311},[268,23402,314],{"class":282},[268,23404,23405],{"class":270,"line":788},[268,23406,5033],{"emptyLinePlaceholder":35},[268,23408,23409,23411,23413,23415,23417,23420],{"class":270,"line":1951},[268,23410,243],{"class":274},[268,23412,20173],{"class":305},[268,23414,616],{"class":274},[268,23416,8710],{"class":282},[268,23418,23419],{"class":289},"'apple'",[268,23421,8737],{"class":282},[268,23423,23424,23426,23429,23431,23433,23436,23439],{"class":270,"line":8955},[268,23425,243],{"class":274},[268,23427,23428],{"class":305}," updated",[268,23430,616],{"class":274},[268,23432,14788],{"class":278},[268,23434,23435],{"class":282},"(original, ",[268,23437,23438],{"class":289},"'banana'",[268,23440,628],{"class":282},[268,23442,23443],{"class":270,"line":8966},[268,23444,5033],{"emptyLinePlaceholder":35},[268,23446,23447,23449,23451,23454,23456,23459,23461],{"class":270,"line":8974},[268,23448,1353],{"class":282},[268,23450,1356],{"class":278},[268,23452,23453],{"class":282},"(original ",[268,23455,3280],{"class":274},[268,23457,23458],{"class":282}," updated, original.",[268,23460,3567],{"class":305},[268,23462,628],{"class":282},[23,23464,23466,23472,23478,23484],{"className":23465},[26],[28,23467,23469,23471],{"className":23468},[31],[33,23470],{"disabled":35,"type":36}," true, 2",[28,23473,23475,23477],{"className":23474},[31],[33,23476],{"disabled":35,"type":36}," false, 1",[28,23479,23481,23483],{"className":23480},[31],[33,23482],{"disabled":35,"type":36}," true, 1",[28,23485,23487,23489],{"className":23486},[31],[33,23488],{"disabled":35,"type":36}," false, 2",[66,23491,23492,23494,23499],{},[69,23493,71],{},[73,23495,23496,23498],{},[76,23497,78],{}," A — true, 2",[73,23500,23501,23503,23504,23506,23507,23509,23510,3277,23512,23514,23515,23517,23518,186,23521,23523,23524,830,23526,23528,23529,23531,23532,23534],{},[76,23502,84],{}," Arrays are passed by reference, so ",[39,23505,8318],{}," inside ",[39,23508,14837],{}," refers to the very same array as ",[39,23511,22772],{},[39,23513,12499],{}," mutates that array in place and the function returns ",[39,23516,8318],{},", meaning ",[39,23519,23520],{},"updated",[39,23522,22772],{}," point to the identical object — hence ",[39,23525,3280],{},[39,23527,2185],{}," — and the length is now ",[39,23530,2258],{},". The distractors assume ",[39,23533,12499],{}," either returns a fresh array or silently fails to mutate the shared reference, which is the opposite of how mutating array methods work.",[15,23536,23537,23539,23596,23623],{"language":247},[18,23538,12737],{"id":12736},[257,23540,23541],{"language":247},[260,23542,23544],{"className":262,"code":23543,"language":247,"meta":264,"style":264},"const arr = [1, 2, 3];\nconsole.log(typeof arr);\nconsole.log(Array.isArray(arr));\n",[39,23545,23546,23568,23581],{"__ignoreMap":264},[268,23547,23548,23550,23552,23554,23556,23558,23560,23562,23564,23566],{"class":270,"line":271},[268,23549,243],{"class":274},[268,23551,9177],{"class":305},[268,23553,616],{"class":274},[268,23555,8710],{"class":282},[268,23557,2255],{"class":305},[268,23559,42],{"class":282},[268,23561,2258],{"class":305},[268,23563,42],{"class":282},[268,23565,3423],{"class":305},[268,23567,8737],{"class":282},[268,23569,23570,23572,23574,23576,23578],{"class":270,"line":286},[268,23571,1353],{"class":282},[268,23573,1356],{"class":278},[268,23575,622],{"class":282},[268,23577,1361],{"class":274},[268,23579,23580],{"class":282}," arr);\n",[268,23582,23583,23585,23587,23590,23593],{"class":270,"line":296},[268,23584,1353],{"class":282},[268,23586,1356],{"class":278},[268,23588,23589],{"class":282},"(Array.",[268,23591,23592],{"class":278},"isArray",[268,23594,23595],{"class":282},"(arr));\n",[23,23597,23599,23605,23611,23617],{"className":23598},[26],[28,23600,23602,23604],{"className":23601},[31],[33,23603],{"disabled":35,"type":36}," \"array\", true",[28,23606,23608,23610],{"className":23607},[31],[33,23609],{"disabled":35,"type":36}," \"object\", true",[28,23612,23614,23616],{"className":23613},[31],[33,23615],{"disabled":35,"type":36}," \"object\", false",[28,23618,23620,23622],{"className":23619},[31],[33,23621],{"disabled":35,"type":36}," \"array\", false",[66,23624,23625,23627,23632],{},[69,23626,71],{},[73,23628,23629,23631],{},[76,23630,78],{}," B — \"object\", true",[73,23633,23634,23636,23637,23639,23640,23643,23644,3277,23646,23649,23650,23652,23653,23656,23657,23659,23660,23662,23663,23666],{},[76,23635,84],{}," JavaScript has no distinct ",[39,23638,1361],{}," tag for arrays — they are a specialized kind of object, so ",[39,23641,23642],{},"typeof arr"," always returns ",[39,23645,2757],{},[39,23647,23648],{},"Array.isArray()"," is the correct and reliable way to detect an array because it inspects the actual internal class of the value rather than the loose ",[39,23651,1361],{}," result (it even works correctly across iframes\u002Frealms, where ",[39,23654,23655],{},"instanceof Array"," can fail). ",[76,23658,930],{}," always reach for ",[39,23661,23648],{},", never ",[39,23664,23665],{},"typeof x === 'object'",", when you need to confirm a value is an array.",[15,23668,23669,23676,23728,23763],{"language":247},[18,23670,23672,23673,23675],{"id":23671},"q3-what-does-sort-produce-here","Q3. What does ",[39,23674,19081],{}," produce here?",[257,23677,23678],{"language":247},[260,23679,23681],{"className":262,"code":23680,"language":247,"meta":264,"style":264},"const scores = [10, 2, 1, 20];\nscores.sort();\nconsole.log(scores);\n",[39,23682,23683,23710,23719],{"__ignoreMap":264},[268,23684,23685,23687,23690,23692,23694,23696,23698,23700,23702,23704,23706,23708],{"class":270,"line":271},[268,23686,243],{"class":274},[268,23688,23689],{"class":305}," scores",[268,23691,616],{"class":274},[268,23693,8710],{"class":282},[268,23695,5825],{"class":305},[268,23697,42],{"class":282},[268,23699,2258],{"class":305},[268,23701,42],{"class":282},[268,23703,2255],{"class":305},[268,23705,42],{"class":282},[268,23707,6149],{"class":305},[268,23709,8737],{"class":282},[268,23711,23712,23715,23717],{"class":270,"line":286},[268,23713,23714],{"class":282},"scores.",[268,23716,19029],{"class":278},[268,23718,794],{"class":282},[268,23720,23721,23723,23725],{"class":270,"line":296},[268,23722,1353],{"class":282},[268,23724,1356],{"class":278},[268,23726,23727],{"class":282},"(scores);\n",[23,23729,23731,23739,23747,23755],{"className":23730},[26],[28,23732,23734,355,23736],{"className":23733},[31],[33,23735],{"disabled":35,"type":36},[268,23737,23738],{},"1, 2, 10, 20",[28,23740,23742,355,23744],{"className":23741},[31],[33,23743],{"disabled":35,"type":36},[268,23745,23746],{},"10, 2, 1, 20",[28,23748,23750,355,23752],{"className":23749},[31],[33,23751],{"disabled":35,"type":36},[268,23753,23754],{},"1, 10, 2, 20",[28,23756,23758,355,23760],{"className":23757},[31],[33,23759],{"disabled":35,"type":36},[268,23761,23762],{},"20, 10, 2, 1",[66,23764,23765,23767,23773],{},[69,23766,71],{},[73,23768,23769,1004,23771],{},[76,23770,78],{},[268,23772,23754],{},[73,23774,23775,23777,23778,23780,23781,23784,23785,23787,23788,23790,23791,23794,23795,23798],{},[76,23776,84],{}," With no comparator, ",[39,23779,19081],{}," converts every element to a string and compares them by UTF-16 code unit, not numeric value: ",[39,23782,23783],{},"\"1\" \u003C \"10\" \u003C \"2\" \u003C \"20\""," lexicographically. ",[76,23786,365],{}," this is the single most common ",[39,23789,19081],{}," bug — to get real numeric order you must pass a comparator, e.g. ",[39,23792,23793],{},"scores.sort((a, b) => a - b)",". The tempting ",[39,23796,23797],{},"[1, 2, 10, 20]"," is what a numeric sort would give, not the default string sort.",[15,23800,23801,23803,23877,23912],{"language":247},[18,23802,13032],{"id":13031},[257,23804,23805],{"language":247},[260,23806,23808],{"className":262,"code":23807,"language":247,"meta":264,"style":264},"const nums = [3, 1, 2];\nconst result = nums.sort((a, b) => a - b);\nconsole.log(result === nums, nums);\n",[39,23809,23810,23832,23863],{"__ignoreMap":264},[268,23811,23812,23814,23816,23818,23820,23822,23824,23826,23828,23830],{"class":270,"line":271},[268,23813,243],{"class":274},[268,23815,12090],{"class":305},[268,23817,616],{"class":274},[268,23819,8710],{"class":282},[268,23821,3423],{"class":305},[268,23823,42],{"class":282},[268,23825,2255],{"class":305},[268,23827,42],{"class":282},[268,23829,2258],{"class":305},[268,23831,8737],{"class":282},[268,23833,23834,23836,23838,23840,23842,23844,23846,23848,23850,23852,23854,23856,23858,23860],{"class":270,"line":286},[268,23835,243],{"class":274},[268,23837,5583],{"class":305},[268,23839,616],{"class":274},[268,23841,15341],{"class":282},[268,23843,19029],{"class":278},[268,23845,6122],{"class":282},[268,23847,1223],{"class":1222},[268,23849,42],{"class":282},[268,23851,1232],{"class":1222},[268,23853,6131],{"class":282},[268,23855,9414],{"class":274},[268,23857,1243],{"class":282},[268,23859,6244],{"class":274},[268,23861,23862],{"class":282}," b);\n",[268,23864,23865,23867,23869,23872,23874],{"class":270,"line":296},[268,23866,1353],{"class":282},[268,23868,1356],{"class":278},[268,23870,23871],{"class":282},"(result ",[268,23873,3280],{"class":274},[268,23875,23876],{"class":282}," nums, nums);\n",[23,23878,23880,23889,23898,23905],{"className":23879},[26],[28,23881,23883,23885,23886],{"className":23882},[31],[33,23884],{"disabled":35,"type":36}," false, ",[268,23887,23888],{},"1, 2, 3",[28,23890,23892,23894,23895],{"className":23891},[31],[33,23893],{"disabled":35,"type":36}," true, ",[268,23896,23897],{},"3, 1, 2",[28,23899,23901,23885,23903],{"className":23900},[31],[33,23902],{"disabled":35,"type":36},[268,23904,23897],{},[28,23906,23908,23894,23910],{"className":23907},[31],[33,23909],{"disabled":35,"type":36},[268,23911,23888],{},[66,23913,23914,23916,23923],{},[69,23915,71],{},[73,23917,23918,23920,23921],{},[76,23919,78],{}," D — true, ",[268,23922,23888],{},[73,23924,23925,355,23927,23929,23930,830,23933,137,23935,23937,23938,23941,23942,23944,23945,23947,23948,446,23951,23953,23954,23957],{},[76,23926,84],{},[39,23928,19081],{}," reorders the array in place and returns a reference to that same array — it does not build a new one. So ",[39,23931,23932],{},"result === nums",[39,23934,2185],{},[39,23936,15332],{}," itself has been reordered to ",[39,23939,23940],{},"[1, 2, 3]",". The ",[39,23943,2986],{}," distractors wrongly assume ",[39,23946,19029],{}," behaves like ",[39,23949,23950],{},"map",[39,23952,14962],{}," and returns a new array; the ",[39,23955,23956],{},"[3, 1, 2]"," distractors wrongly assume the original stays untouched.",[15,23959,23960,23962,24047,24074],{"language":247},[18,23961,13181],{"id":13180},[257,23963,23964],{"language":247},[260,23965,23967],{"className":262,"code":23966,"language":247,"meta":264,"style":264},"const a = [1, 2, 3];\nconst b = [1, 2, 3];\nconsole.log(a === b, a == b, JSON.stringify(a) === JSON.stringify(b));\n",[39,23968,23969,23991,24013],{"__ignoreMap":264},[268,23970,23971,23973,23975,23977,23979,23981,23983,23985,23987,23989],{"class":270,"line":271},[268,23972,243],{"class":274},[268,23974,7203],{"class":305},[268,23976,616],{"class":274},[268,23978,8710],{"class":282},[268,23980,2255],{"class":305},[268,23982,42],{"class":282},[268,23984,2258],{"class":305},[268,23986,42],{"class":282},[268,23988,3423],{"class":305},[268,23990,8737],{"class":282},[268,23992,23993,23995,23997,23999,24001,24003,24005,24007,24009,24011],{"class":270,"line":286},[268,23994,243],{"class":274},[268,23996,16372],{"class":305},[268,23998,616],{"class":274},[268,24000,8710],{"class":282},[268,24002,2255],{"class":305},[268,24004,42],{"class":282},[268,24006,2258],{"class":305},[268,24008,42],{"class":282},[268,24010,3423],{"class":305},[268,24012,8737],{"class":282},[268,24014,24015,24017,24019,24021,24023,24025,24027,24029,24031,24033,24035,24037,24039,24041,24043,24045],{"class":270,"line":296},[268,24016,1353],{"class":282},[268,24018,1356],{"class":278},[268,24020,7218],{"class":282},[268,24022,3280],{"class":274},[268,24024,21694],{"class":282},[268,24026,3197],{"class":274},[268,24028,14999],{"class":282},[268,24030,21702],{"class":305},[268,24032,462],{"class":282},[268,24034,21707],{"class":278},[268,24036,21710],{"class":282},[268,24038,3280],{"class":274},[268,24040,21715],{"class":305},[268,24042,462],{"class":282},[268,24044,21707],{"class":278},[268,24046,21722],{"class":282},[23,24048,24050,24056,24062,24068],{"className":24049},[26],[28,24051,24053,24055],{"className":24052},[31],[33,24054],{"disabled":35,"type":36}," false, false, true",[28,24057,24059,24061],{"className":24058},[31],[33,24060],{"disabled":35,"type":36}," true, true, true",[28,24063,24065,24067],{"className":24064},[31],[33,24066],{"disabled":35,"type":36}," false, false, false",[28,24069,24071,24073],{"className":24070},[31],[33,24072],{"disabled":35,"type":36}," true, false, true",[66,24075,24076,24078,24083],{},[69,24077,71],{},[73,24079,24080,24082],{},[76,24081,78],{}," A — false, false, true",[73,24084,24085,2247,24087,186,24089,24091,24092,24094,24095,186,24097,24099,24100,24102,24103,24105,24106,24109,24110,3277,24112,24114,24115,446,24117,24119,24120,24122],{},[76,24086,84],{},[39,24088,3280],{},[39,24090,3197],{}," compare arrays (and objects in general) by reference, not by contents — since neither operand is a primitive, ",[39,24093,3197],{}," doesn't attempt any coercion and falls straight to a reference check. ",[39,24096,1223],{},[39,24098,1232],{}," are two distinct array instances, so both comparisons are ",[39,24101,2986],{}," even though the elements match. ",[39,24104,20555],{}," turns each into the identical string ",[39,24107,24108],{},"\"[1,2,3]\"",", so that comparison is ",[39,24111,2185],{},[76,24113,365],{}," this is why you never compare arrays with ",[39,24116,3280],{},[39,24118,3197],{}," for value equality — use a deep-equality check, or ",[39,24121,20555],{}," for simple cases.",[15,24124,24125,24129,24224,24251],{"language":247},[18,24126,24128],{"id":24127},"q6-what-happens-when-this-runs","Q6. What happens when this runs?",[257,24130,24131],{"language":247},[260,24132,24134],{"className":262,"code":24133,"language":247,"meta":264,"style":264},"function sumAll(nums) {\n  return nums.reduce((acc, n) => acc + n);\n}\n\nconsole.log(sumAll([5, 10, 15]));\nconsole.log(sumAll([]));\n",[39,24135,24136,24148,24177,24181,24185,24211],{"__ignoreMap":264},[268,24137,24138,24140,24142,24144,24146],{"class":270,"line":271},[268,24139,275],{"class":274},[268,24141,14948],{"class":278},[268,24143,622],{"class":282},[268,24145,15332],{"class":1222},[268,24147,1235],{"class":282},[268,24149,24150,24152,24154,24156,24158,24161,24163,24165,24167,24169,24172,24174],{"class":270,"line":286},[268,24151,1240],{"class":274},[268,24153,15341],{"class":282},[268,24155,14980],{"class":278},[268,24157,6122],{"class":282},[268,24159,24160],{"class":1222},"acc",[268,24162,42],{"class":282},[268,24164,4599],{"class":1222},[268,24166,6131],{"class":282},[268,24168,9414],{"class":274},[268,24170,24171],{"class":282}," acc ",[268,24173,1246],{"class":274},[268,24175,24176],{"class":282}," n);\n",[268,24178,24179],{"class":270,"line":296},[268,24180,314],{"class":282},[268,24182,24183],{"class":270,"line":311},[268,24184,5033],{"emptyLinePlaceholder":35},[268,24186,24187,24189,24191,24193,24195,24197,24199,24201,24203,24205,24208],{"class":270,"line":788},[268,24188,1353],{"class":282},[268,24190,1356],{"class":278},[268,24192,622],{"class":282},[268,24194,15022],{"class":278},[268,24196,17519],{"class":282},[268,24198,2429],{"class":305},[268,24200,42],{"class":282},[268,24202,5825],{"class":305},[268,24204,42],{"class":282},[268,24206,24207],{"class":305},"15",[268,24209,24210],{"class":282},"]));\n",[268,24212,24213,24215,24217,24219,24221],{"class":270,"line":1951},[268,24214,1353],{"class":282},[268,24216,1356],{"class":278},[268,24218,622],{"class":282},[268,24220,15022],{"class":278},[268,24222,24223],{"class":282},"([]));\n",[23,24225,24227,24233,24239,24245],{"className":24226},[26],[28,24228,24230,24232],{"className":24229},[31],[33,24231],{"disabled":35,"type":36}," 30 then 0",[28,24234,24236,24238],{"className":24235},[31],[33,24237],{"disabled":35,"type":36}," 30 then a TypeError is thrown",[28,24240,24242,24244],{"className":24241},[31],[33,24243],{"disabled":35,"type":36}," 30 then undefined",[28,24246,24248,24250],{"className":24247},[31],[33,24249],{"disabled":35,"type":36}," NaN then a TypeError is thrown",[66,24252,24253,24255,24260],{},[69,24254,71],{},[73,24256,24257,24259],{},[76,24258,78],{}," B — 30 then a TypeError is thrown",[73,24261,24262,24264,24265,24267,24268,24271,24272,24275,24276,4132,24278,24281,24282,99,24284,3277,24286,24288,24289,24292,24293,24295],{},[76,24263,84],{}," Without an initial value, ",[39,24266,12176],{}," uses the array's first element as the starting accumulator and begins iterating from index 1, so ",[39,24269,24270],{},"sumAll([5, 10, 15])"," correctly computes ",[39,24273,24274],{},"30",". But an empty array has no first element to seed the accumulator and nothing to iterate, so ",[39,24277,12176],{},[39,24279,24280],{},"TypeError: Reduce of empty array with no initial value"," instead of silently returning ",[39,24283,3307],{},[39,24285,833],{},[76,24287,582],{}," always pass an explicit initial value — ",[39,24290,24291],{},"nums.reduce((acc, n) => acc + n, 0)"," — to make ",[39,24294,14980],{}," safe on empty arrays.",[15,24297,24298,24300,24357,24384],{"language":247},[18,24299,13528],{"id":13527},[257,24301,24302],{"language":247},[260,24303,24305],{"className":262,"code":24304,"language":247,"meta":264,"style":264},"const values = [1, NaN, 3];\nconsole.log(values.indexOf(NaN), values.includes(NaN));\n",[39,24306,24307,24329],{"__ignoreMap":264},[268,24308,24309,24311,24313,24315,24317,24319,24321,24323,24325,24327],{"class":270,"line":271},[268,24310,243],{"class":274},[268,24312,8705],{"class":305},[268,24314,616],{"class":274},[268,24316,8710],{"class":282},[268,24318,2255],{"class":305},[268,24320,42],{"class":282},[268,24322,3040],{"class":305},[268,24324,42],{"class":282},[268,24326,3423],{"class":305},[268,24328,8737],{"class":282},[268,24330,24331,24333,24335,24338,24341,24343,24345,24348,24351,24353,24355],{"class":270,"line":286},[268,24332,1353],{"class":282},[268,24334,1356],{"class":278},[268,24336,24337],{"class":282},"(values.",[268,24339,24340],{"class":278},"indexOf",[268,24342,622],{"class":282},[268,24344,3040],{"class":305},[268,24346,24347],{"class":282},"), values.",[268,24349,24350],{"class":278},"includes",[268,24352,622],{"class":282},[268,24354,3040],{"class":305},[268,24356,4818],{"class":282},[23,24358,24360,24366,24372,24378],{"className":24359},[26],[28,24361,24363,24365],{"className":24362},[31],[33,24364],{"disabled":35,"type":36}," 1, true",[28,24367,24369,24371],{"className":24368},[31],[33,24370],{"disabled":35,"type":36}," -1, false",[28,24373,24375,24377],{"className":24374},[31],[33,24376],{"disabled":35,"type":36}," -1, true",[28,24379,24381,24383],{"className":24380},[31],[33,24382],{"disabled":35,"type":36}," 1, false",[66,24385,24386,24388,24393],{},[69,24387,71],{},[73,24389,24390,24392],{},[76,24391,78],{}," C — -1, true",[73,24394,24395,355,24397,24400,24401,24403,24404,4453,24406,24408,24409,24411,24412,17040,24414,3277,24417,24420,24421,24423,24424,3277,24426,24428,24429,24431,24432,2758,24434,462],{},[76,24396,84],{},[39,24398,24399],{},".indexOf()"," compares elements using strict equality (",[39,24402,3280],{},"), and ",[39,24405,3007],{},[39,24407,2986],{}," by IEEE-754 rules, so ",[39,24410,24399],{}," can never locate ",[39,24413,3040],{},[39,24415,24416],{},"-1",[39,24418,24419],{},".includes()"," uses the SameValueZero algorithm instead, which specifically treats ",[39,24422,3040],{}," as equal to itself, so it correctly returns ",[39,24425,2185],{},[76,24427,365],{}," if you need to check for ",[39,24430,3040],{}," membership, use ",[39,24433,24419],{},[39,24435,24399],{},[15,24437,24438,24440,24568,24595],{"language":247},[18,24439,13729],{"id":13728},[257,24441,24442],{"language":247},[260,24443,24445],{"className":262,"code":24444,"language":247,"meta":264,"style":264},"const sparse = new Array(3);\nlet count = 0;\nsparse.forEach(() => count++);\n\nlet loopCount = 0;\nfor (let i = 0; i \u003C sparse.length; i++) {\n  loopCount++;\n}\n\nconsole.log(count, loopCount);\n",[39,24446,24447,24467,24479,24496,24500,24513,24542,24551,24555,24559],{"__ignoreMap":264},[268,24448,24449,24451,24454,24456,24458,24461,24463,24465],{"class":270,"line":271},[268,24450,243],{"class":274},[268,24452,24453],{"class":305}," sparse",[268,24455,616],{"class":274},[268,24457,11370],{"class":274},[268,24459,24460],{"class":278}," Array",[268,24462,622],{"class":282},[268,24464,3423],{"class":305},[268,24466,628],{"class":282},[268,24468,24469,24471,24473,24475,24477],{"class":270,"line":286},[268,24470,240],{"class":274},[268,24472,10091],{"class":282},[268,24474,302],{"class":274},[268,24476,5728],{"class":305},[268,24478,293],{"class":282},[268,24480,24481,24484,24486,24488,24490,24492,24494],{"class":270,"line":296},[268,24482,24483],{"class":282},"sparse.",[268,24485,12330],{"class":278},[268,24487,9411],{"class":282},[268,24489,9414],{"class":274},[268,24491,5723],{"class":282},[268,24493,9401],{"class":274},[268,24495,628],{"class":282},[268,24497,24498],{"class":270,"line":311},[268,24499,5033],{"emptyLinePlaceholder":35},[268,24501,24502,24504,24507,24509,24511],{"class":270,"line":788},[268,24503,240],{"class":274},[268,24505,24506],{"class":282}," loopCount ",[268,24508,302],{"class":274},[268,24510,5728],{"class":305},[268,24512,293],{"class":282},[268,24514,24515,24517,24519,24521,24523,24525,24527,24529,24531,24534,24536,24538,24540],{"class":270,"line":1951},[268,24516,6926],{"class":274},[268,24518,2182],{"class":282},[268,24520,240],{"class":274},[268,24522,9384],{"class":282},[268,24524,302],{"class":274},[268,24526,5728],{"class":305},[268,24528,9391],{"class":282},[268,24530,1076],{"class":274},[268,24532,24533],{"class":282}," sparse.",[268,24535,3567],{"class":305},[268,24537,9398],{"class":282},[268,24539,9401],{"class":274},[268,24541,1235],{"class":282},[268,24543,24544,24547,24549],{"class":270,"line":8955},[268,24545,24546],{"class":282},"  loopCount",[268,24548,9401],{"class":274},[268,24550,293],{"class":282},[268,24552,24553],{"class":270,"line":8966},[268,24554,314],{"class":282},[268,24556,24557],{"class":270,"line":8974},[268,24558,5033],{"emptyLinePlaceholder":35},[268,24560,24561,24563,24565],{"class":270,"line":8985},[268,24562,1353],{"class":282},[268,24564,1356],{"class":278},[268,24566,24567],{"class":282},"(count, loopCount);\n",[23,24569,24571,24577,24583,24589],{"className":24570},[26],[28,24572,24574,24576],{"className":24573},[31],[33,24575],{"disabled":35,"type":36}," 3, 3",[28,24578,24580,24582],{"className":24579},[31],[33,24581],{"disabled":35,"type":36}," 0, 0",[28,24584,24586,24588],{"className":24585},[31],[33,24587],{"disabled":35,"type":36}," 3, 0",[28,24590,24592,24594],{"className":24591},[31],[33,24593],{"disabled":35,"type":36}," 0, 3",[66,24596,24597,24599,24604],{},[69,24598,71],{},[73,24600,24601,24603],{},[76,24602,78],{}," D — 0, 3",[73,24605,24606,355,24608,24611,24612,24614,24615,24617,24618,186,24620,24622,24623,14765,24625,24627,24628,24630,24631,24634,24635,24637,24638,24640],{},[76,24607,84],{},[39,24609,24610],{},"new Array(3)"," creates an array with ",[39,24613,3567],{}," 3 but no actual elements — just empty \"holes\" with no own property at any index. ",[39,24616,12167],{}," (like ",[39,24619,12170],{},[39,24621,12173],{},") only invokes its callback for indices that actually exist, so it skips every hole entirely, leaving ",[39,24624,10191],{},[39,24626,3307],{},". A classic index-based ",[39,24629,6926],{}," loop only checks ",[39,24632,24633],{},"i \u003C length",", with no awareness of holes, so it runs the full 3 iterations regardless. ",[76,24636,365],{}," iteration methods and manual index loops disagree on sparse arrays — this is a frequent source of \"why didn't my ",[39,24639,12167],{}," run\" bugs.",[15,24642,24643,24645,24710,24737],{"language":247},[18,24644,13927],{"id":13926},[257,24646,24647],{"language":247},[260,24648,24650],{"className":262,"code":24649,"language":247,"meta":264,"style":264},"const arr = [1, 2, 3];\narr.length = 5;\nconsole.log(arr.length, arr[3], arr[4]);\n",[39,24651,24652,24674,24687],{"__ignoreMap":264},[268,24653,24654,24656,24658,24660,24662,24664,24666,24668,24670,24672],{"class":270,"line":271},[268,24655,243],{"class":274},[268,24657,9177],{"class":305},[268,24659,616],{"class":274},[268,24661,8710],{"class":282},[268,24663,2255],{"class":305},[268,24665,42],{"class":282},[268,24667,2258],{"class":305},[268,24669,42],{"class":282},[268,24671,3423],{"class":305},[268,24673,8737],{"class":282},[268,24675,24676,24679,24681,24683,24685],{"class":270,"line":286},[268,24677,24678],{"class":282},"arr.",[268,24680,3567],{"class":305},[268,24682,616],{"class":274},[268,24684,2387],{"class":305},[268,24686,293],{"class":282},[268,24688,24689,24691,24693,24696,24698,24701,24703,24706,24708],{"class":270,"line":296},[268,24690,1353],{"class":282},[268,24692,1356],{"class":278},[268,24694,24695],{"class":282},"(arr.",[268,24697,3567],{"class":305},[268,24699,24700],{"class":282},", arr[",[268,24702,3423],{"class":305},[268,24704,24705],{"class":282},"], arr[",[268,24707,15049],{"class":305},[268,24709,15180],{"class":282},[23,24711,24713,24719,24725,24731],{"className":24712},[26],[28,24714,24716,24718],{"className":24715},[31],[33,24717],{"disabled":35,"type":36}," 5, undefined, undefined",[28,24720,24722,24724],{"className":24721},[31],[33,24723],{"disabled":35,"type":36}," 3, undefined, undefined",[28,24726,24728,24730],{"className":24727},[31],[33,24729],{"disabled":35,"type":36}," 5, 0, 0",[28,24732,24734,24736],{"className":24733},[31],[33,24735],{"disabled":35,"type":36}," 5, null, null",[66,24738,24739,24741,24746],{},[69,24740,71],{},[73,24742,24743,24745],{},[76,24744,78],{}," A — 5, undefined, undefined",[73,24747,24748,355,24750,24752,24753,24755,24756,24758,24759,24761,24762,24764,24765,24767,24768,24770,24771,24773],{},[76,24749,84],{},[39,24751,3643],{}," is a writable property; setting it larger than the current size extends the array with trailing empty slots (holes), and ",[39,24754,3643],{}," itself updates to reflect the new size (",[39,24757,2429],{},"). Reading a hole returns ",[39,24760,833],{},", the same value you'd get from reading any nonexistent property — not ",[39,24763,3307],{}," and not ",[39,24766,2650],{},", which are actual stored values, not \"nothing is there\" markers. ",[76,24769,365],{}," growing ",[39,24772,3643],{}," manually is a common way to accidentally introduce holes into what looked like a dense array.",[15,24775,24776,24778,24836,24870],{"language":247},[18,24777,17619],{"id":17618},[257,24779,24780],{"language":247},[260,24781,24783],{"className":262,"code":24782,"language":247,"meta":264,"style":264},"const arr = [1, 2, 3, 4, 5];\narr.length = 2;\nconsole.log(arr);\n",[39,24784,24785,24815,24827],{"__ignoreMap":264},[268,24786,24787,24789,24791,24793,24795,24797,24799,24801,24803,24805,24807,24809,24811,24813],{"class":270,"line":271},[268,24788,243],{"class":274},[268,24790,9177],{"class":305},[268,24792,616],{"class":274},[268,24794,8710],{"class":282},[268,24796,2255],{"class":305},[268,24798,42],{"class":282},[268,24800,2258],{"class":305},[268,24802,42],{"class":282},[268,24804,3423],{"class":305},[268,24806,42],{"class":282},[268,24808,15049],{"class":305},[268,24810,42],{"class":282},[268,24812,2429],{"class":305},[268,24814,8737],{"class":282},[268,24816,24817,24819,24821,24823,24825],{"class":270,"line":286},[268,24818,24678],{"class":282},[268,24820,3567],{"class":305},[268,24822,616],{"class":274},[268,24824,2214],{"class":305},[268,24826,293],{"class":282},[268,24828,24829,24831,24833],{"class":270,"line":296},[268,24830,1353],{"class":282},[268,24832,1356],{"class":278},[268,24834,24835],{"class":282},"(arr);\n",[23,24837,24839,24847,24855,24863],{"className":24838},[26],[28,24840,24842,355,24844],{"className":24841},[31],[33,24843],{"disabled":35,"type":36},[268,24845,24846],{},"1, 2, 3, 4, 5",[28,24848,24850,355,24852],{"className":24849},[31],[33,24851],{"disabled":35,"type":36},[268,24853,24854],{},"1, 2",[28,24856,24858,355,24860],{"className":24857},[31],[33,24859],{"disabled":35,"type":36},[268,24861,24862],{},"4, 5",[28,24864,24866,355,24868],{"className":24865},[31],[33,24867],{"disabled":35,"type":36},[268,24869],{},[66,24871,24872,24874,24880],{},[69,24873,71],{},[73,24875,24876,1727,24878],{},[76,24877,78],{},[268,24879,24854],{},[73,24881,24882,24884,24885,24887,24888,24890,24891,7083,24894,24897,24898,24901,24902,24904,24905,24908],{},[76,24883,84],{}," Setting ",[39,24886,3643],{}," to a value smaller than the current length truncates the array in place: every element at an index ",[39,24889,6779],{}," the new length is permanently deleted, keeping only the elements from the front. So ",[39,24892,24893],{},"[1, 2, 3, 4, 5]",[39,24895,24896],{},"[1, 2]",", not the tail ",[39,24899,24900],{},"[4, 5]"," and not fully emptied. ",[76,24903,930],{}," this truncation behavior is exactly what powers the ",[39,24906,24907],{},"arr.length = 0"," clear-in-place pattern covered next.",[15,24910,24911,24913,25041,25097],{"language":247},[18,24912,14224],{"id":14223},[257,24914,24915],{"language":247},[260,24916,24918],{"className":262,"code":24917,"language":247,"meta":264,"style":264},"let list = [1, 2, 3];\nconst ref = list;\n\nfunction clearWithReassign(a) { a = []; }\nfunction clearWithLength(a) { a.length = 0; }\n\nclearWithReassign(list);\nconsole.log(list, ref);\n\nclearWithLength(list);\nconsole.log(list, ref);\n",[39,24919,24920,24943,24955,24959,24978,25001,25005,25013,25022,25026,25033],{"__ignoreMap":264},[268,24921,24922,24924,24927,24929,24931,24933,24935,24937,24939,24941],{"class":270,"line":271},[268,24923,240],{"class":274},[268,24925,24926],{"class":282}," list ",[268,24928,302],{"class":274},[268,24930,8710],{"class":282},[268,24932,2255],{"class":305},[268,24934,42],{"class":282},[268,24936,2258],{"class":305},[268,24938,42],{"class":282},[268,24940,3423],{"class":305},[268,24942,8737],{"class":282},[268,24944,24945,24947,24950,24952],{"class":270,"line":286},[268,24946,243],{"class":274},[268,24948,24949],{"class":305}," ref",[268,24951,616],{"class":274},[268,24953,24954],{"class":282}," list;\n",[268,24956,24957],{"class":270,"line":296},[268,24958,5033],{"emptyLinePlaceholder":35},[268,24960,24961,24963,24966,24968,24970,24973,24975],{"class":270,"line":311},[268,24962,275],{"class":274},[268,24964,24965],{"class":278}," clearWithReassign",[268,24967,622],{"class":282},[268,24969,1223],{"class":1222},[268,24971,24972],{"class":282},") { a ",[268,24974,302],{"class":274},[268,24976,24977],{"class":282}," []; }\n",[268,24979,24980,24982,24985,24987,24989,24992,24994,24996,24998],{"class":270,"line":788},[268,24981,275],{"class":274},[268,24983,24984],{"class":278}," clearWithLength",[268,24986,622],{"class":282},[268,24988,1223],{"class":1222},[268,24990,24991],{"class":282},") { a.",[268,24993,3567],{"class":305},[268,24995,616],{"class":274},[268,24997,5728],{"class":305},[268,24999,25000],{"class":282},"; }\n",[268,25002,25003],{"class":270,"line":1951},[268,25004,5033],{"emptyLinePlaceholder":35},[268,25006,25007,25010],{"class":270,"line":8955},[268,25008,25009],{"class":278},"clearWithReassign",[268,25011,25012],{"class":282},"(list);\n",[268,25014,25015,25017,25019],{"class":270,"line":8966},[268,25016,1353],{"class":282},[268,25018,1356],{"class":278},[268,25020,25021],{"class":282},"(list, ref);\n",[268,25023,25024],{"class":270,"line":8974},[268,25025,5033],{"emptyLinePlaceholder":35},[268,25027,25028,25031],{"class":270,"line":8985},[268,25029,25030],{"class":278},"clearWithLength",[268,25032,25012],{"class":282},[268,25034,25035,25037,25039],{"class":270,"line":8990},[268,25036,1353],{"class":282},[268,25038,1356],{"class":278},[268,25040,25021],{"class":282},[23,25042,25044,25057,25071,25084],{"className":25043},[26],[28,25045,25047,355,25049,355,25051,1133,25053,355,25055],{"className":25046},[31],[33,25048],{"disabled":35,"type":36},[268,25050],{},[268,25052],{},[268,25054],{},[268,25056],{},[28,25058,25060,355,25062,355,25064,1133,25067,355,25069],{"className":25059},[31],[33,25061],{"disabled":35,"type":36},[268,25063],{},[268,25065,25066],{},"1,2,3",[268,25068],{},[268,25070],{},[28,25072,25074,355,25076,355,25078,1133,25080,355,25082],{"className":25073},[31],[33,25075],{"disabled":35,"type":36},[268,25077,25066],{},[268,25079,25066],{},[268,25081],{},[268,25083],{},[28,25085,25087,355,25089,355,25091,1133,25093,355,25095],{"className":25086},[31],[33,25088],{"disabled":35,"type":36},[268,25090,25066],{},[268,25092,25066],{},[268,25094,25066],{},[268,25096,25066],{},[66,25098,25099,25101,25113],{},[69,25100,71],{},[73,25102,25103,1004,25105,355,25107,1133,25109,355,25111],{},[76,25104,78],{},[268,25106,25066],{},[268,25108,25066],{},[268,25110],{},[268,25112],{},[73,25114,25115,355,25117,25119,25120,25122,25123,186,25125,25128,25129,3277,25131,25133,25134,25137,25138,186,25140,25142,25143,25145,25146,355,25148,25151,25152,25154],{},[76,25116,84],{},[39,25118,25009],{}," only rebinds its local parameter ",[39,25121,1223],{}," to a brand-new empty array; the object that ",[39,25124,14924],{},[39,25126,25127],{},"ref"," point to is never touched, so both still log ",[39,25130,23940],{},[39,25132,25030],{}," instead mutates the shared array object via ",[39,25135,25136],{},"a.length = 0",", so both ",[39,25139,14924],{},[39,25141,25127],{}," — which reference that same object — become ",[39,25144,3290],{}," together. ",[76,25147,930],{},[39,25149,25150],{},"array.length = 0"," is the standard way to clear an array in place precisely because other variables or closures holding the same reference need to observe the change; reassigning a local variable to ",[39,25153,3290],{}," never does.",[15,25156,25157,25161,25235,25288],{"language":247},[18,25158,25160],{"id":25159},"q12-what-do-these-two-calls-log","Q12. What do these two calls log?",[257,25162,25163],{"language":247},[260,25164,25166],{"className":262,"code":25165,"language":247,"meta":264,"style":264},"const nested = [1, [2, 3], [4, [5, 6]]];\nconsole.log(nested.flat());\nconsole.log(nested.flat(2));\n",[39,25167,25168,25205,25219],{"__ignoreMap":264},[268,25169,25170,25172,25175,25177,25179,25181,25184,25186,25188,25190,25192,25194,25196,25198,25200,25202],{"class":270,"line":271},[268,25171,243],{"class":274},[268,25173,25174],{"class":305}," nested",[268,25176,616],{"class":274},[268,25178,8710],{"class":282},[268,25180,2255],{"class":305},[268,25182,25183],{"class":282},", [",[268,25185,2258],{"class":305},[268,25187,42],{"class":282},[268,25189,3423],{"class":305},[268,25191,11386],{"class":282},[268,25193,15049],{"class":305},[268,25195,25183],{"class":282},[268,25197,2429],{"class":305},[268,25199,42],{"class":282},[268,25201,13663],{"class":305},[268,25203,25204],{"class":282},"]]];\n",[268,25206,25207,25209,25211,25214,25217],{"class":270,"line":286},[268,25208,1353],{"class":282},[268,25210,1356],{"class":278},[268,25212,25213],{"class":282},"(nested.",[268,25215,25216],{"class":278},"flat",[268,25218,8174],{"class":282},[268,25220,25221,25223,25225,25227,25229,25231,25233],{"class":270,"line":296},[268,25222,1353],{"class":282},[268,25224,1356],{"class":278},[268,25226,25213],{"class":282},[268,25228,25216],{"class":278},[268,25230,622],{"class":282},[268,25232,2258],{"class":305},[268,25234,4818],{"class":282},[23,25236,25238,25248,25261,25277],{"className":25237},[26],[28,25239,25241,355,25243,1133,25246],{"className":25240},[31],[33,25242],{"disabled":35,"type":36},[268,25244,25245],{},"1,2,3,4,5,6",[268,25247,25245],{},[28,25249,25251,355,25253,1133,25255],{"className":25250},[31],[33,25252],{"disabled":35,"type":36},[268,25254,25245],{},[268,25256,25257,25258],{},"1,2,3,4,",[268,25259,25260],{},"5,6",[28,25262,25264,355,25266,1133,25275],{"className":25263},[31],[33,25265],{"disabled":35,"type":36},[268,25267,25268,25269,25272,25273],{},"1,",[268,25270,25271],{},"2,3",",4,",[268,25274,25260],{},[268,25276,25245],{},[28,25278,25280,355,25282,1133,25286],{"className":25279},[31],[33,25281],{"disabled":35,"type":36},[268,25283,25257,25284],{},[268,25285,25260],{},[268,25287,25245],{},[66,25289,25290,25292,25302],{},[69,25291,71],{},[73,25293,25294,6901,25296,1133,25300],{},[76,25295,78],{},[268,25297,25257,25298],{},[268,25299,25260],{},[268,25301,25245],{},[73,25303,25304,355,25306,25309,25310,25312,25313,186,25316,25319,25320,25323,25324,25326,25327,25329,25330,25332,25333,25335,25336,25338,25339,25342],{},[76,25305,84],{},[39,25307,25308],{},".flat()"," called with no argument defaults to a depth of ",[39,25311,2255],{},", so it only unwraps one level: the top-level ",[39,25314,25315],{},"[2, 3]",[39,25317,25318],{},"[4, [5, 6]]"," each get flattened once, but the inner ",[39,25321,25322],{},"[5, 6]"," — nested two levels deep — stays wrapped. Passing an explicit depth of ",[39,25325,2258],{}," flattens two levels, fully unwrapping ",[39,25328,25322],{}," too. ",[76,25331,365],{}," forgetting that ",[39,25334,25308],{},"'s default depth is only ",[39,25337,2255],{},", not \"flatten completely,\" is a common surprise — use ",[39,25340,25341],{},"Infinity"," as the depth if you want to fully flatten an arbitrarily nested array.",[15,25344,25345,25347,25417,25453],{"language":247},[18,25346,14538],{"id":14537},[257,25348,25349],{"language":247},[260,25350,25352],{"className":262,"code":25351,"language":247,"meta":264,"style":264},"const sentences = ['hello world', 'foo bar baz'];\nconst words = sentences.flatMap(s => s.split(' '));\nconsole.log(words);\n",[39,25353,25354,25375,25408],{"__ignoreMap":264},[268,25355,25356,25358,25361,25363,25365,25368,25370,25373],{"class":270,"line":271},[268,25357,243],{"class":274},[268,25359,25360],{"class":305}," sentences",[268,25362,616],{"class":274},[268,25364,8710],{"class":282},[268,25366,25367],{"class":289},"'hello world'",[268,25369,42],{"class":282},[268,25371,25372],{"class":289},"'foo bar baz'",[268,25374,8737],{"class":282},[268,25376,25377,25379,25381,25383,25386,25389,25391,25394,25396,25399,25401,25403,25406],{"class":270,"line":286},[268,25378,243],{"class":274},[268,25380,18994],{"class":305},[268,25382,616],{"class":274},[268,25384,25385],{"class":282}," sentences.",[268,25387,25388],{"class":278},"flatMap",[268,25390,622],{"class":282},[268,25392,25393],{"class":1222},"s",[268,25395,14969],{"class":274},[268,25397,25398],{"class":282}," s.",[268,25400,17959],{"class":278},[268,25402,622],{"class":282},[268,25404,25405],{"class":289},"' '",[268,25407,4818],{"class":282},[268,25409,25410,25412,25414],{"class":270,"line":296},[268,25411,1353],{"class":282},[268,25413,1356],{"class":278},[268,25415,25416],{"class":282},"(words);\n",[23,25418,25420,25428,25437,25445],{"className":25419},[26],[28,25421,25423,355,25425],{"className":25422},[31],[33,25424],{"disabled":35,"type":36},[268,25426,25427],{},"'hello', 'world', 'foo', 'bar', 'baz'",[28,25429,25431,25433,25434,17149],{"className":25430},[31],[33,25432],{"disabled":35,"type":36}," [['hello','world'], ",[268,25435,25436],{},"'foo','bar','baz'",[28,25438,25440,355,25442],{"className":25439},[31],[33,25441],{"disabled":35,"type":36},[268,25443,25444],{},"'hello world', 'foo bar baz'",[28,25446,25448,355,25450],{"className":25447},[31],[33,25449],{"disabled":35,"type":36},[268,25451,25452],{},"5, 5, 3, 3, 3",[66,25454,25455,25457,25463],{},[69,25456,71],{},[73,25458,25459,3459,25461],{},[76,25460,78],{},[268,25462,25427],{},[73,25464,25465,355,25467,25470,25471,25474,25475,25477,25478,355,25480,25482,25483,25486],{},[76,25466,84],{},[39,25468,25469],{},".flatMap()"," first maps each element with the callback — here producing an array of words per sentence via ",[39,25472,25473],{},".split(' ')"," — then flattens the result by exactly one level, merging those per-sentence word arrays into a single flat array. Plain ",[39,25476,12170],{}," without the flattening step is what would give the nested array-of-arrays distractor. ",[76,25479,930],{},[39,25481,25469],{}," is more efficient than chaining ",[39,25484,25485],{},".map().flat()"," because it avoids building the intermediate nested array.",[15,25488,25489,25493,25566,25593],{"language":247},[18,25490,25492],{"id":25491},"q14-what-happens-when-this-runs","Q14. What happens when this runs?",[257,25494,25495],{"language":247},[260,25496,25498],{"className":262,"code":25497,"language":247,"meta":264,"style":264},"function sumPositive() {\n  return arguments.filter(n => n > 0).length;\n}\n\nsumPositive(1, -2, 3);\n",[39,25499,25500,25509,25537,25541,25545],{"__ignoreMap":264},[268,25501,25502,25504,25507],{"class":270,"line":271},[268,25503,275],{"class":274},[268,25505,25506],{"class":278}," sumPositive",[268,25508,283],{"class":282},[268,25510,25511,25513,25515,25517,25519,25521,25523,25525,25527,25529,25531,25533,25535],{"class":270,"line":286},[268,25512,1240],{"class":274},[268,25514,14957],{"class":305},[268,25516,462],{"class":282},[268,25518,14962],{"class":278},[268,25520,622],{"class":282},[268,25522,4599],{"class":1222},[268,25524,14969],{"class":274},[268,25526,13355],{"class":282},[268,25528,6435],{"class":274},[268,25530,5728],{"class":305},[268,25532,6232],{"class":282},[268,25534,3567],{"class":305},[268,25536,293],{"class":282},[268,25538,25539],{"class":270,"line":296},[268,25540,314],{"class":282},[268,25542,25543],{"class":270,"line":311},[268,25544,5033],{"emptyLinePlaceholder":35},[268,25546,25547,25550,25552,25554,25556,25558,25560,25562,25564],{"class":270,"line":788},[268,25548,25549],{"class":278},"sumPositive",[268,25551,622],{"class":282},[268,25553,2255],{"class":305},[268,25555,42],{"class":282},[268,25557,6244],{"class":274},[268,25559,2258],{"class":305},[268,25561,42],{"class":282},[268,25563,3423],{"class":305},[268,25565,628],{"class":282},[23,25567,25569,25575,25581,25587],{"className":25568},[26],[28,25570,25572,25574],{"className":25571},[31],[33,25573],{"disabled":35,"type":36}," Returns 2",[28,25576,25578,25580],{"className":25577},[31],[33,25579],{"disabled":35,"type":36}," Throws a TypeError because arguments has no filter method",[28,25582,25584,25586],{"className":25583},[31],[33,25585],{"disabled":35,"type":36}," Returns 3",[28,25588,25590,25592],{"className":25589},[31],[33,25591],{"disabled":35,"type":36}," Returns undefined silently",[66,25594,25595,25597,25602],{},[69,25596,71],{},[73,25598,25599,25601],{},[76,25600,78],{}," B — Throws a TypeError because arguments has no filter method",[73,25603,25604,355,25606,25608,25609,25611,25612,25614,25615,42,25617,137,25619,25621,25622,3277,25624,25626,25627,99,25629,25631,25632,25635],{},[76,25605,84],{},[39,25607,15090],{}," is array-like — it has indexed properties and a ",[39,25610,3567],{}," — but it does not inherit from ",[39,25613,12161],{},", so array methods like ",[39,25616,12173],{},[39,25618,12170],{},[39,25620,12176],{}," simply don't exist on it, and calling one throws ",[39,25623,15064],{},[76,25625,582],{}," convert it to a real array first with ",[39,25628,15118],{},[39,25630,15121],{}," (or just use a rest parameter ",[39,25633,25634],{},"...args",", which is already a real array) before using array methods on it.",[15,25637,25638,25642,25693,25720],{"language":247},[18,25639,25641],{"id":25640},"q15-what-happens-when-this-runs-in-a-browser","Q15. What happens when this runs in a browser?",[257,25643,25644],{"language":247},[260,25645,25647],{"className":262,"code":25646,"language":247,"meta":264,"style":264},"const items = document.querySelectorAll('li');\nconst texts = items.map(el => el.textContent);\n",[39,25648,25649,25670],{"__ignoreMap":264},[268,25650,25651,25653,25655,25657,25660,25663,25665,25668],{"class":270,"line":271},[268,25652,243],{"class":274},[268,25654,11725],{"class":305},[268,25656,616],{"class":274},[268,25658,25659],{"class":282}," document.",[268,25661,25662],{"class":278},"querySelectorAll",[268,25664,622],{"class":282},[268,25666,25667],{"class":289},"'li'",[268,25669,628],{"class":282},[268,25671,25672,25674,25677,25679,25681,25683,25685,25688,25690],{"class":270,"line":286},[268,25673,243],{"class":274},[268,25675,25676],{"class":305}," texts",[268,25678,616],{"class":274},[268,25680,11762],{"class":282},[268,25682,23950],{"class":278},[268,25684,622],{"class":282},[268,25686,25687],{"class":1222},"el",[268,25689,14969],{"class":274},[268,25691,25692],{"class":282}," el.textContent);\n",[23,25694,25696,25702,25708,25714],{"className":25695},[26],[28,25697,25699,25701],{"className":25698},[31],[33,25700],{"disabled":35,"type":36}," Works fine, texts is an array of strings",[28,25703,25705,25707],{"className":25704},[31],[33,25706],{"disabled":35,"type":36}," items is automatically a real Array so this always works",[28,25709,25711,25713],{"className":25710},[31],[33,25712],{"disabled":35,"type":36}," Throws a TypeError because NodeList has no map method",[28,25715,25717,25719],{"className":25716},[31],[33,25718],{"disabled":35,"type":36}," Returns a new NodeList instead of an array",[66,25721,25722,25724,25729],{},[69,25723,71],{},[73,25725,25726,25728],{},[76,25727,78],{}," C — Throws a TypeError because NodeList has no map method",[73,25730,25731,355,25733,25735,25736,25739,25740,25742,25743,1179,25745,42,25747,137,25749,25751,25752,3277,25754,830,25757,25759,25760,25762,25763,99,25766,25769],{},[76,25732,84],{},[39,25734,25662],{}," returns a static ",[39,25737,25738],{},"NodeList"," — an array-like, iterable object that supports ",[39,25741,12167],{}," in modern browsers but does not inherit from ",[39,25744,12161],{},[39,25746,12170],{},[39,25748,12173],{},[39,25750,12176],{}," are missing and calling them throws a ",[39,25753,827],{},[39,25755,25756],{},"Array.isArray(items)",[39,25758,2986],{},", confirming it isn't a real array. ",[76,25761,365],{}," convert with ",[39,25764,25765],{},"Array.from(items)",[39,25767,25768],{},"[...items]"," first to unlock the full array method set.",[15,25771,25772,25774,25838,25878],{"language":247},[18,25773,15131],{"id":15130},[257,25775,25776],{"language":247},[260,25777,25779],{"className":262,"code":25778,"language":247,"meta":264,"style":264},"const arr = [1, 2, 3, 4, 5];\nconsole.log(arr.slice(-2));\nconsole.log(arr);\n",[39,25780,25781,25811,25830],{"__ignoreMap":264},[268,25782,25783,25785,25787,25789,25791,25793,25795,25797,25799,25801,25803,25805,25807,25809],{"class":270,"line":271},[268,25784,243],{"class":274},[268,25786,9177],{"class":305},[268,25788,616],{"class":274},[268,25790,8710],{"class":282},[268,25792,2255],{"class":305},[268,25794,42],{"class":282},[268,25796,2258],{"class":305},[268,25798,42],{"class":282},[268,25800,3423],{"class":305},[268,25802,42],{"class":282},[268,25804,15049],{"class":305},[268,25806,42],{"class":282},[268,25808,2429],{"class":305},[268,25810,8737],{"class":282},[268,25812,25813,25815,25817,25819,25822,25824,25826,25828],{"class":270,"line":286},[268,25814,1353],{"class":282},[268,25816,1356],{"class":278},[268,25818,24695],{"class":282},[268,25820,25821],{"class":278},"slice",[268,25823,622],{"class":282},[268,25825,6244],{"class":274},[268,25827,2258],{"class":305},[268,25829,4818],{"class":282},[268,25831,25832,25834,25836],{"class":270,"line":296},[268,25833,1353],{"class":282},[268,25835,1356],{"class":278},[268,25837,24835],{"class":282},[23,25839,25841,25850,25859,25869],{"className":25840},[26],[28,25842,25844,355,25846,1133,25848],{"className":25843},[31],[33,25845],{"disabled":35,"type":36},[268,25847,23888],{},[268,25849,24846],{},[28,25851,25853,355,25855,1133,25857],{"className":25852},[31],[33,25854],{"disabled":35,"type":36},[268,25856,24862],{},[268,25858,23888],{},[28,25860,25862,355,25864,1133,25867],{"className":25861},[31],[33,25863],{"disabled":35,"type":36},[268,25865,25866],{},"3, 4, 5",[268,25868,24846],{},[28,25870,25872,355,25874,1133,25876],{"className":25871},[31],[33,25873],{"disabled":35,"type":36},[268,25875,24862],{},[268,25877,24846],{},[66,25879,25880,25882,25890],{},[69,25881,71],{},[73,25883,25884,6901,25886,1133,25888],{},[76,25885,78],{},[268,25887,24862],{},[268,25889,24846],{},[73,25891,25892,25894,25895,25897,25898,25901,25902,3277,25904,25906,25907,25910,25911,25913,25914,23947,25916,25919],{},[76,25893,84],{}," A negative index in ",[39,25896,16076],{}," counts back from the end, so ",[39,25899,25900],{},"slice(-2)"," extracts the last two elements, ",[39,25903,24900],{},[39,25905,16076],{}," never mutates its source — it always returns a shallow copy of the requested range — so ",[39,25908,25909],{},"arr"," is unchanged afterward. The ",[39,25912,23940],{},"-then-mutated distractor wrongly assumes ",[39,25915,16076],{},[39,25917,25918],{},".splice()",", which does mutate.",[15,25921,25922,25924,25996,26038],{"language":247},[18,25923,15311],{"id":15310},[257,25925,25926],{"language":247},[260,25927,25929],{"className":262,"code":25928,"language":247,"meta":264,"style":264},"const arr = [1, 2, 3, 4, 5];\nconst removed = arr.splice(-2, 1);\nconsole.log(removed, arr);\n",[39,25930,25931,25961,25987],{"__ignoreMap":264},[268,25932,25933,25935,25937,25939,25941,25943,25945,25947,25949,25951,25953,25955,25957,25959],{"class":270,"line":271},[268,25934,243],{"class":274},[268,25936,9177],{"class":305},[268,25938,616],{"class":274},[268,25940,8710],{"class":282},[268,25942,2255],{"class":305},[268,25944,42],{"class":282},[268,25946,2258],{"class":305},[268,25948,42],{"class":282},[268,25950,3423],{"class":305},[268,25952,42],{"class":282},[268,25954,15049],{"class":305},[268,25956,42],{"class":282},[268,25958,2429],{"class":305},[268,25960,8737],{"class":282},[268,25962,25963,25965,25968,25970,25972,25975,25977,25979,25981,25983,25985],{"class":270,"line":286},[268,25964,243],{"class":274},[268,25966,25967],{"class":305}," removed",[268,25969,616],{"class":274},[268,25971,10707],{"class":282},[268,25973,25974],{"class":278},"splice",[268,25976,622],{"class":282},[268,25978,6244],{"class":274},[268,25980,2258],{"class":305},[268,25982,42],{"class":282},[268,25984,2255],{"class":305},[268,25986,628],{"class":282},[268,25988,25989,25991,25993],{"class":270,"line":296},[268,25990,1353],{"class":282},[268,25992,1356],{"class":278},[268,25994,25995],{"class":282},"(removed, arr);\n",[23,25997,25999,26009,26018,26028],{"className":25998},[26],[28,26000,26002,355,26004,42,26006],{"className":26001},[31],[33,26003],{"disabled":35,"type":36},[268,26005,15049],{},[268,26007,26008],{},"1, 2, 3, 5",[28,26010,26012,355,26014,42,26016],{"className":26011},[31],[33,26013],{"disabled":35,"type":36},[268,26015,24862],{},[268,26017,23888],{},[28,26019,26021,355,26023,42,26025],{"className":26020},[31],[33,26022],{"disabled":35,"type":36},[268,26024,2429],{},[268,26026,26027],{},"1, 2, 3, 4",[28,26029,26031,355,26033,42,26036],{"className":26030},[31],[33,26032],{"disabled":35,"type":36},[268,26034,26035],{},"-2",[268,26037,24846],{},[66,26039,26040,26042,26050],{},[69,26041,71],{},[73,26043,26044,3459,26046,42,26048],{},[76,26045,78],{},[268,26047,15049],{},[268,26049,26008],{},[73,26051,26052,487,26054,26056,26057,25897,26059,26061,26062,26064,26065,10819,26067,26070,26071,26073,26074,26077,26078,42,26080,26082,26083,26085,26086,3277,26089,21599,26091,26093,26094,26096,26097,26099],{},[76,26053,84],{},[39,26055,16076],{},", a negative start in ",[39,26058,25918],{},[39,26060,26035],{}," points at index ",[39,26063,3423],{}," (the value ",[39,26066,15049],{},[39,26068,26069],{},".splice(-2, 1)"," deletes just ",[39,26072,2255],{}," element starting there and returns it as ",[39,26075,26076],{},"[4]"," — unlike ",[39,26079,16076],{},[39,26081,25918],{}," mutates the original array in place, leaving ",[39,26084,25909],{}," as ",[39,26087,26088],{},"[1, 2, 3, 5]",[76,26090,365],{},[39,26092,24900],{},"-removed distractor applies ",[39,26095,16076],{},"'s \"grab to the end\" instinct to ",[39,26098,25918],{},", forgetting that the second argument caps how many elements get deleted.",[15,26101,26102,26104,26218,26252],{"language":247},[18,26103,18980],{"id":18979},[257,26105,26106],{"language":247},[260,26107,26109],{"className":262,"code":26108,"language":247,"meta":264,"style":264},"const nums = [1, 2, 4, 3, 5];\nfor (let i = 0; i \u003C nums.length; i++) {\n  if (nums[i] % 2 === 0) {\n    nums.splice(i, 1);\n  }\n}\nconsole.log(nums);\n",[39,26110,26111,26141,26169,26187,26201,26205,26209],{"__ignoreMap":264},[268,26112,26113,26115,26117,26119,26121,26123,26125,26127,26129,26131,26133,26135,26137,26139],{"class":270,"line":271},[268,26114,243],{"class":274},[268,26116,12090],{"class":305},[268,26118,616],{"class":274},[268,26120,8710],{"class":282},[268,26122,2255],{"class":305},[268,26124,42],{"class":282},[268,26126,2258],{"class":305},[268,26128,42],{"class":282},[268,26130,15049],{"class":305},[268,26132,42],{"class":282},[268,26134,3423],{"class":305},[268,26136,42],{"class":282},[268,26138,2429],{"class":305},[268,26140,8737],{"class":282},[268,26142,26143,26145,26147,26149,26151,26153,26155,26157,26159,26161,26163,26165,26167],{"class":270,"line":286},[268,26144,6926],{"class":274},[268,26146,2182],{"class":282},[268,26148,240],{"class":274},[268,26150,9384],{"class":282},[268,26152,302],{"class":274},[268,26154,5728],{"class":305},[268,26156,9391],{"class":282},[268,26158,1076],{"class":274},[268,26160,15341],{"class":282},[268,26162,3567],{"class":305},[268,26164,9398],{"class":282},[268,26166,9401],{"class":274},[268,26168,1235],{"class":282},[268,26170,26171,26173,26176,26179,26181,26183,26185],{"class":270,"line":296},[268,26172,9863],{"class":274},[268,26174,26175],{"class":282}," (nums[i] ",[268,26177,26178],{"class":274},"%",[268,26180,2214],{"class":305},[268,26182,3043],{"class":274},[268,26184,5728],{"class":305},[268,26186,1235],{"class":282},[268,26188,26189,26192,26194,26197,26199],{"class":270,"line":311},[268,26190,26191],{"class":282},"    nums.",[268,26193,25974],{"class":278},[268,26195,26196],{"class":282},"(i, ",[268,26198,2255],{"class":305},[268,26200,628],{"class":282},[268,26202,26203],{"class":270,"line":788},[268,26204,1948],{"class":282},[268,26206,26207],{"class":270,"line":1951},[268,26208,314],{"class":282},[268,26210,26211,26213,26215],{"class":270,"line":8955},[268,26212,1353],{"class":282},[268,26214,1356],{"class":278},[268,26216,26217],{"class":282},"(nums);\n",[23,26219,26221,26229,26237,26245],{"className":26220},[26],[28,26222,26224,355,26226],{"className":26223},[31],[33,26225],{"disabled":35,"type":36},[268,26227,26228],{},"1, 3, 5",[28,26230,26232,355,26234],{"className":26231},[31],[33,26233],{"disabled":35,"type":36},[268,26235,26236],{},"1, 4, 3, 5",[28,26238,26240,355,26242],{"className":26239},[31],[33,26241],{"disabled":35,"type":36},[268,26243,26244],{},"1, 2, 4, 3, 5",[28,26246,26248,355,26250],{"className":26247},[31],[33,26249],{"disabled":35,"type":36},[268,26251],{},[66,26253,26254,26256,26262],{},[69,26255,71],{},[73,26257,26258,1727,26260],{},[76,26259,78],{},[268,26261,26236],{},[73,26263,26264,355,26266,26268,26269,26271,26272,26274,26275,26277,26278,26280,26281,26283,26284,26286,26287,2182,26289,26291,26292,26294,26295,26297,26298,26300],{},[76,26265,84],{},[39,26267,25918],{}," mutates the array in place, shifting every later element one index to the left. When the loop removes ",[39,26270,2258],{}," at index ",[39,26273,2255],{},", the next value ",[39,26276,15049],{}," slides into index ",[39,26279,2255],{}," — but the ",[39,26282,6926],{}," loop's counter has no idea a shift happened and moves straight on to index ",[39,26285,2258],{},", so the element now sitting at index ",[39,26288,2255],{},[39,26290,15049],{},") is never re-examined and survives untouched. ",[76,26293,365],{}," mutating an array with ",[39,26296,25918],{}," while walking it forward with a plain index loop silently skips the element that shifts into the just-vacated slot. The safe patterns are to loop backwards, iterate over a copy while mutating the original, or just use a non-mutating ",[39,26299,12173],{}," instead.",[15,26302,26303,26307,26475,26501],{"language":247},[18,26304,26306],{"id":26305},"q19-what-does-this-log","Q19. What does this log?",[257,26308,26309],{"language":247},[260,26310,26312],{"className":262,"code":26311,"language":247,"meta":264,"style":264},"const nums = [1, 2, 3, 4, 5];\nlet visits = 0;\nnums.forEach(n => {\n  visits++;\n  if (n === 3) return;\n});\n\nlet loopVisits = 0;\nfor (const n of nums) {\n  loopVisits++;\n  if (n === 3) break;\n}\n\nconsole.log(visits, loopVisits);\n",[39,26313,26314,26344,26357,26372,26381,26397,26401,26405,26418,26433,26442,26458,26462,26466],{"__ignoreMap":264},[268,26315,26316,26318,26320,26322,26324,26326,26328,26330,26332,26334,26336,26338,26340,26342],{"class":270,"line":271},[268,26317,243],{"class":274},[268,26319,12090],{"class":305},[268,26321,616],{"class":274},[268,26323,8710],{"class":282},[268,26325,2255],{"class":305},[268,26327,42],{"class":282},[268,26329,2258],{"class":305},[268,26331,42],{"class":282},[268,26333,3423],{"class":305},[268,26335,42],{"class":282},[268,26337,15049],{"class":305},[268,26339,42],{"class":282},[268,26341,2429],{"class":305},[268,26343,8737],{"class":282},[268,26345,26346,26348,26351,26353,26355],{"class":270,"line":286},[268,26347,240],{"class":274},[268,26349,26350],{"class":282}," visits ",[268,26352,302],{"class":274},[268,26354,5728],{"class":305},[268,26356,293],{"class":282},[268,26358,26359,26362,26364,26366,26368,26370],{"class":270,"line":296},[268,26360,26361],{"class":282},"nums.",[268,26363,12330],{"class":278},[268,26365,622],{"class":282},[268,26367,4599],{"class":1222},[268,26369,14969],{"class":274},[268,26371,9914],{"class":282},[268,26373,26374,26377,26379],{"class":270,"line":311},[268,26375,26376],{"class":282},"  visits",[268,26378,9401],{"class":274},[268,26380,293],{"class":282},[268,26382,26383,26385,26387,26389,26391,26393,26395],{"class":270,"line":788},[268,26384,9863],{"class":274},[268,26386,13562],{"class":282},[268,26388,3280],{"class":274},[268,26390,3396],{"class":305},[268,26392,6131],{"class":282},[268,26394,9151],{"class":274},[268,26396,293],{"class":282},[268,26398,26399],{"class":270,"line":1951},[268,26400,20047],{"class":282},[268,26402,26403],{"class":270,"line":8955},[268,26404,5033],{"emptyLinePlaceholder":35},[268,26406,26407,26409,26412,26414,26416],{"class":270,"line":8966},[268,26408,240],{"class":274},[268,26410,26411],{"class":282}," loopVisits ",[268,26413,302],{"class":274},[268,26415,5728],{"class":305},[268,26417,293],{"class":282},[268,26419,26420,26422,26424,26426,26429,26431],{"class":270,"line":8974},[268,26421,6926],{"class":274},[268,26423,2182],{"class":282},[268,26425,243],{"class":274},[268,26427,26428],{"class":305}," n",[268,26430,9229],{"class":274},[268,26432,12122],{"class":282},[268,26434,26435,26438,26440],{"class":270,"line":8985},[268,26436,26437],{"class":282},"  loopVisits",[268,26439,9401],{"class":274},[268,26441,293],{"class":282},[268,26443,26444,26446,26448,26450,26452,26454,26456],{"class":270,"line":8990},[268,26445,9863],{"class":274},[268,26447,13562],{"class":282},[268,26449,3280],{"class":274},[268,26451,3396],{"class":305},[268,26453,6131],{"class":282},[268,26455,8880],{"class":274},[268,26457,293],{"class":282},[268,26459,26460],{"class":270,"line":8997},[268,26461,314],{"class":282},[268,26463,26464],{"class":270,"line":9002},[268,26465,5033],{"emptyLinePlaceholder":35},[268,26467,26468,26470,26472],{"class":270,"line":14676},[268,26469,1353],{"class":282},[268,26471,1356],{"class":278},[268,26473,26474],{"class":282},"(visits, loopVisits);\n",[23,26476,26478,26484,26489,26495],{"className":26477},[26],[28,26479,26481,26483],{"className":26480},[31],[33,26482],{"disabled":35,"type":36}," 5, 5",[28,26485,26487,24576],{"className":26486},[31],[33,26488],{"disabled":35,"type":36},[28,26490,26492,26494],{"className":26491},[31],[33,26493],{"disabled":35,"type":36}," 5, 3",[28,26496,26498,26500],{"className":26497},[31],[33,26499],{"disabled":35,"type":36}," 3, 5",[66,26502,26503,26505,26510],{},[69,26504,71],{},[73,26506,26507,26509],{},[76,26508,78],{}," C — 5, 3",[73,26511,26512,26514,26515,26517,26518,26520,26521,26523,26524,5797,26526,26528,26529,26532,26533,26535,26536,26538,26539,26542,26543,6345,26546,3277,26549,26551,26552,26554,26555,26557,26558,26560],{},[76,26513,84],{}," Inside a ",[39,26516,12167],{}," callback, ",[39,26519,9151],{}," only exits that single invocation — it behaves like ",[39,26522,9615],{},", never like a loop-level ",[39,26525,8880],{},[39,26527,12167],{}," always calls the callback once per element no matter what, giving ",[39,26530,26531],{},"visits = 5",". A ",[39,26534,9163],{}," loop's ",[39,26537,8880],{}," is a genuine loop-control statement that exits the loop entirely, so ",[39,26540,26541],{},"loopVisits"," stops incrementing right after ",[39,26544,26545],{},"n === 3",[39,26547,26548],{},"loopVisits = 3",[76,26550,438],{}," there is no way to stop ",[39,26553,12167],{}," early — reaching for it when you actually need an early exit means either silently doing extra work or, worse, assuming it stopped when it didn't; use a ",[39,26556,9163],{}," or plain ",[39,26559,6926],{}," loop whenever short-circuiting matters.",[15,26562,26563,26565,26692,26719],{"language":247},[18,26564,19301],{"id":19300},[257,26566,26567],{"language":247},[260,26568,26570],{"className":262,"code":26569,"language":247,"meta":264,"style":264},"function renderLeaderboard(players) {\n  return players.sort((a, b) => b.score - a.score);\n}\n\nconst players = [{ name: 'A', score: 10 }, { name: 'B', score: 30 }];\nconst original = players;\n\nrenderLeaderboard(players);\nconsole.log(original[0].name);\n",[39,26571,26572,26586,26615,26619,26623,26655,26666,26670,26678],{"__ignoreMap":264},[268,26573,26574,26576,26579,26581,26584],{"class":270,"line":271},[268,26575,275],{"class":274},[268,26577,26578],{"class":278}," renderLeaderboard",[268,26580,622],{"class":282},[268,26582,26583],{"class":1222},"players",[268,26585,1235],{"class":282},[268,26587,26588,26590,26593,26595,26597,26599,26601,26603,26605,26607,26610,26612],{"class":270,"line":286},[268,26589,1240],{"class":274},[268,26591,26592],{"class":282}," players.",[268,26594,19029],{"class":278},[268,26596,6122],{"class":282},[268,26598,1223],{"class":1222},[268,26600,42],{"class":282},[268,26602,1232],{"class":1222},[268,26604,6131],{"class":282},[268,26606,9414],{"class":274},[268,26608,26609],{"class":282}," b.score ",[268,26611,6244],{"class":274},[268,26613,26614],{"class":282}," a.score);\n",[268,26616,26617],{"class":270,"line":296},[268,26618,314],{"class":282},[268,26620,26621],{"class":270,"line":311},[268,26622,5033],{"emptyLinePlaceholder":35},[268,26624,26625,26627,26630,26632,26635,26637,26640,26642,26645,26648,26650,26652],{"class":270,"line":788},[268,26626,243],{"class":274},[268,26628,26629],{"class":305}," players",[268,26631,616],{"class":274},[268,26633,26634],{"class":282}," [{ name: ",[268,26636,17902],{"class":289},[268,26638,26639],{"class":282},", score: ",[268,26641,5825],{"class":305},[268,26643,26644],{"class":282}," }, { name: ",[268,26646,26647],{"class":289},"'B'",[268,26649,26639],{"class":282},[268,26651,24274],{"class":305},[268,26653,26654],{"class":282}," }];\n",[268,26656,26657,26659,26661,26663],{"class":270,"line":1951},[268,26658,243],{"class":274},[268,26660,20173],{"class":305},[268,26662,616],{"class":274},[268,26664,26665],{"class":282}," players;\n",[268,26667,26668],{"class":270,"line":8955},[268,26669,5033],{"emptyLinePlaceholder":35},[268,26671,26672,26675],{"class":270,"line":8966},[268,26673,26674],{"class":278},"renderLeaderboard",[268,26676,26677],{"class":282},"(players);\n",[268,26679,26680,26682,26684,26687,26689],{"class":270,"line":8974},[268,26681,1353],{"class":282},[268,26683,1356],{"class":278},[268,26685,26686],{"class":282},"(original[",[268,26688,3307],{"class":305},[268,26690,26691],{"class":282},"].name);\n",[23,26693,26695,26701,26707,26713],{"className":26694},[26],[28,26696,26698,26700],{"className":26697},[31],[33,26699],{"disabled":35,"type":36}," \"A\" — original stays in its initial order since sort only affects the returned copy",[28,26702,26704,26706],{"className":26703},[31],[33,26705],{"disabled":35,"type":36}," undefined — sort empties the array before reordering it",[28,26708,26710,26712],{"className":26709},[31],[33,26711],{"disabled":35,"type":36}," \"A\" — renderLeaderboard receives a separate copy of the array by value",[28,26714,26716,26718],{"className":26715},[31],[33,26717],{"disabled":35,"type":36}," \"B\" — sort mutated the shared array in place, so original reflects the new order too",[66,26720,26721,26723,26728],{},[69,26722,71],{},[73,26724,26725,26727],{},[76,26726,78],{}," D — \"B\" — sort mutated the shared array in place, so original reflects the new order too",[73,26729,26730,26732,26733,26735,26736,186,26738,26740,26741,26743,26744,26746,26747,26750,26751,26754,26755,42,26758,137,26761,26764,26765,26767,26768,7728,26770,26772,26773,26776],{},[76,26731,84],{}," Arrays are passed by reference, and ",[39,26734,19081],{}," mutates in place rather than returning a new array; since ",[39,26737,26583],{},[39,26739,22772],{}," are the same array object, sorting inside ",[39,26742,26674],{}," silently reorders ",[39,26745,22772],{}," too, putting the higher-scoring ",[39,26748,26749],{},"\"B\""," first. This is exactly the bug that ES2023's ",[39,26752,26753],{},".toSorted()"," (along with ",[39,26756,26757],{},".toReversed()",[39,26759,26760],{},".toSpliced()",[39,26762,26763],{},".with()",") exists to prevent — these non-mutating counterparts return a new array and leave the original untouched. ",[76,26766,582],{}," prefer ",[39,26769,26753],{},[39,26771,19081],{}," (or explicitly copy first with ",[39,26774,26775],{},"[...players].sort(...)",") whenever a function receives an array reference that other code also holds onto.",[2107,26778,26779],{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-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 .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);}",{"title":264,"searchDepth":286,"depth":286,"links":26781},[26782,26783,26784,26786,26787,26788,26789,26790,26791,26792,26793,26794,26795,26796,26797,26798,26799,26800,26801,26802],{"id":23360,"depth":296,"text":23361},{"id":12736,"depth":296,"text":12737},{"id":23671,"depth":296,"text":26785},"Q3. What does .sort() produce here?",{"id":13031,"depth":296,"text":13032},{"id":13180,"depth":296,"text":13181},{"id":24127,"depth":296,"text":24128},{"id":13527,"depth":296,"text":13528},{"id":13728,"depth":296,"text":13729},{"id":13926,"depth":296,"text":13927},{"id":17618,"depth":296,"text":17619},{"id":14223,"depth":296,"text":14224},{"id":25159,"depth":296,"text":25160},{"id":14537,"depth":296,"text":14538},{"id":25491,"depth":296,"text":25492},{"id":25640,"depth":296,"text":25641},{"id":15130,"depth":296,"text":15131},{"id":15310,"depth":296,"text":15311},{"id":18979,"depth":296,"text":18980},{"id":26305,"depth":296,"text":26306},{"id":19300,"depth":296,"text":19301},{},"\u002Fjs\u002F08-arrays-and-array-methods",{"title":23350,"description":264},"js\u002F08-arrays-and-array-methods","4NA5TzpTKb2UeeZVnni4DRqjyvhkZrq3FeaTAC_Wj1U",{"id":26809,"title":26810,"body":26811,"description":264,"extension":2144,"meta":29534,"navigation":35,"path":29535,"seo":29536,"stem":29537,"__hash__":29538},"content\u002Fjs\u002F09-destructuring-and-spread.md","09 — Destructuring & Spread",{"type":8,"value":26812,"toc":29511},[26813,26816,26940,27059,27184,27359,27498,27615,27751,27877,27949,28080,28194,28319,28452,28622,28759,28882,29045,29190,29338,29508],[11,26814,26810],{"id":26815},"_09-destructuring-spread",[15,26817,26818,26822,26879,26908],{"language":247},[18,26819,26821],{"id":26820},"q1-what-does-this-log","Q1. What does this log?",[257,26823,26824],{"language":247},[260,26825,26827],{"className":262,"code":26826,"language":247,"meta":264,"style":264},"const arr = [10, 20, 30];\nconst [x, y] = arr;\nconsole.log(x, y);\n",[39,26828,26829,26851,26870],{"__ignoreMap":264},[268,26830,26831,26833,26835,26837,26839,26841,26843,26845,26847,26849],{"class":270,"line":271},[268,26832,243],{"class":274},[268,26834,9177],{"class":305},[268,26836,616],{"class":274},[268,26838,8710],{"class":282},[268,26840,5825],{"class":305},[268,26842,42],{"class":282},[268,26844,6149],{"class":305},[268,26846,42],{"class":282},[268,26848,24274],{"class":305},[268,26850,8737],{"class":282},[268,26852,26853,26855,26857,26859,26861,26863,26865,26867],{"class":270,"line":286},[268,26854,243],{"class":274},[268,26856,8710],{"class":282},[268,26858,2403],{"class":305},[268,26860,42],{"class":282},[268,26862,2909],{"class":305},[268,26864,19897],{"class":282},[268,26866,302],{"class":274},[268,26868,26869],{"class":282}," arr;\n",[268,26871,26872,26874,26876],{"class":270,"line":296},[268,26873,1353],{"class":282},[268,26875,1356],{"class":278},[268,26877,26878],{"class":282},"(x, y);\n",[23,26880,26882,26888,26894,26900],{"className":26881},[26],[28,26883,26885,26887],{"className":26884},[31],[33,26886],{"disabled":35,"type":36}," 10 20",[28,26889,26891,26893],{"className":26890},[31],[33,26892],{"disabled":35,"type":36}," 10 20 30",[28,26895,26897,26899],{"className":26896},[31],[33,26898],{"disabled":35,"type":36}," undefined undefined",[28,26901,26903,355,26905],{"className":26902},[31],[33,26904],{"disabled":35,"type":36},[268,26906,26907],{},"10, 20",[66,26909,26910,26912,26917],{},[69,26911,71],{},[73,26913,26914,26916],{},[76,26915,78],{}," A — 10 20",[73,26918,26919,26921,26922,26924,26925,42,26928,26924,26930,137,26933,26936,26937,26939],{},[76,26920,84],{}," Array destructuring binds by position, not by consuming the whole array. ",[39,26923,2403],{}," takes ",[39,26926,26927],{},"arr[0]",[39,26929,2909],{},[39,26931,26932],{},"arr[1]",[39,26934,26935],{},"arr[2]"," is simply left unbound — it still exists in ",[39,26938,25909],{},", 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.",[15,26941,26942,26944,26999,27025],{"language":247},[18,26943,12737],{"id":12736},[257,26945,26946],{"language":247},[260,26947,26949],{"className":262,"code":26948,"language":247,"meta":264,"style":264},"const user = { id: 7, name: 'Ada' };\nconst { name, id } = user;\nconsole.log(name, id);\n",[39,26950,26951,26971,26990],{"__ignoreMap":264},[268,26952,26953,26955,26957,26959,26961,26964,26966,26969],{"class":270,"line":271},[268,26954,243],{"class":274},[268,26956,4071],{"class":305},[268,26958,616],{"class":274},[268,26960,20178],{"class":282},[268,26962,26963],{"class":305},"7",[268,26965,4662],{"class":282},[268,26967,26968],{"class":289},"'Ada'",[268,26970,2790],{"class":282},[268,26972,26973,26975,26977,26979,26981,26983,26985,26987],{"class":270,"line":286},[268,26974,243],{"class":274},[268,26976,20200],{"class":282},[268,26978,14605],{"class":305},[268,26980,42],{"class":282},[268,26982,14610],{"class":305},[268,26984,7908],{"class":282},[268,26986,302],{"class":274},[268,26988,26989],{"class":282}," user;\n",[268,26991,26992,26994,26996],{"class":270,"line":296},[268,26993,1353],{"class":282},[268,26995,1356],{"class":278},[268,26997,26998],{"class":282},"(name, id);\n",[23,27000,27002,27007,27013,27019],{"className":27001},[26],[28,27003,27005,26899],{"className":27004},[31],[33,27006],{"disabled":35,"type":36},[28,27008,27010,27012],{"className":27009},[31],[33,27011],{"disabled":35,"type":36}," 7 Ada",[28,27014,27016,27018],{"className":27015},[31],[33,27017],{"disabled":35,"type":36}," Ada 7",[28,27020,27022,27024],{"className":27021},[31],[33,27023],{"disabled":35,"type":36}," TypeError: Cannot destructure",[66,27026,27027,27029,27034],{},[69,27028,71],{},[73,27030,27031,27033],{},[76,27032,78],{}," C — Ada 7",[73,27035,27036,355,27038,27041,27042,27045,27046,8574,27049,27052,27053,27055,27056,27058],{},[76,27037,84],{},[76,27039,27040],{},"Idiom."," Unlike array destructuring, object destructuring matches by ",[104,27043,27044],{},"key name",", not position — writing ",[39,27047,27048],{},"{ name, id }",[39,27050,27051],{},"{ id, name }"," has zero effect on the result because each identifier looks itself up on ",[39,27054,4155],{},". 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 ",[39,27057,4155],{}," were nullish.",[15,27060,27061,27065,27117,27147],{"language":247},[18,27062,27064],{"id":27063},"q3-what-happens-when-this-runs","Q3. What happens when this runs?",[257,27066,27067],{"language":247},[260,27068,27070],{"className":262,"code":27069,"language":247,"meta":264,"style":264},"const config = { url: 'https:\u002F\u002Fapi.example.com' };\nconst { url: endpoint } = config;\nconsole.log(url);\n",[39,27071,27072,27088,27108],{"__ignoreMap":264},[268,27073,27074,27076,27078,27080,27083,27086],{"class":270,"line":271},[268,27075,243],{"class":274},[268,27077,8029],{"class":305},[268,27079,616],{"class":274},[268,27081,27082],{"class":282}," { url: ",[268,27084,27085],{"class":289},"'https:\u002F\u002Fapi.example.com'",[268,27087,2790],{"class":282},[268,27089,27090,27092,27094,27096,27098,27101,27103,27105],{"class":270,"line":286},[268,27091,243],{"class":274},[268,27093,20200],{"class":282},[268,27095,15524],{"class":1222},[268,27097,1783],{"class":282},[268,27099,27100],{"class":305},"endpoint",[268,27102,7908],{"class":282},[268,27104,302],{"class":274},[268,27106,27107],{"class":282}," config;\n",[268,27109,27110,27112,27114],{"class":270,"line":296},[268,27111,1353],{"class":282},[268,27113,1356],{"class":278},[268,27115,27116],{"class":282},"(url);\n",[23,27118,27120,27126,27136,27141],{"className":27119},[26],[28,27121,27123,27125],{"className":27122},[31],[33,27124],{"disabled":35,"type":36}," ReferenceError: url is not defined",[28,27127,27129,355,27131],{"className":27128},[31],[33,27130],{"disabled":35,"type":36},[1223,27132,27133],{"href":27133,"rel":27134},"https:\u002F\u002Fapi.example.com",[27135],"nofollow",[28,27137,27139,17135],{"className":27138},[31],[33,27140],{"disabled":35,"type":36},[28,27142,27144,27146],{"className":27143},[31],[33,27145],{"disabled":35,"type":36}," endpoint",[66,27148,27149,27151,27156],{},[69,27150,71],{},[73,27152,27153,27155],{},[76,27154,78],{}," A — ReferenceError: url is not defined",[73,27157,27158,355,27160,27163,27164,27167,27168,27171,27172,27174,27175,27177,27178,27180,27181,27183],{},[76,27159,84],{},[76,27161,27162],{},"Debug."," Renaming with ",[39,27165,27166],{},"{ url: endpoint }"," means the value at ",[39,27169,27170],{},"config.url"," is bound ",[104,27173,3117],{}," to the new identifier ",[39,27176,27100],{}," — the name ",[39,27179,15524],{}," is never declared as a local binding. Logging ",[39,27182,15524],{}," 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.",[15,27185,27186,27188,27281,27308],{"language":247},[18,27187,13032],{"id":13031},[257,27189,27190],{"language":247},[260,27191,27193],{"className":262,"code":27192,"language":247,"meta":264,"style":264},"function connect({ port = 8080, host = 'localhost', timeout = 3000 } = {}) {\n  return `${host}:${port} (${timeout}ms)`;\n}\nconsole.log(connect({ port: null, host: undefined }));\n",[39,27194,27195,27232,27254,27258],{"__ignoreMap":264},[268,27196,27197,27199,27201,27203,27205,27207,27209,27211,27213,27215,27218,27220,27222,27224,27226,27228,27230],{"class":270,"line":271},[268,27198,275],{"class":274},[268,27200,14238],{"class":278},[268,27202,7889],{"class":282},[268,27204,14248],{"class":1222},[268,27206,616],{"class":274},[268,27208,14253],{"class":305},[268,27210,42],{"class":282},[268,27212,14243],{"class":1222},[268,27214,616],{"class":274},[268,27216,27217],{"class":289}," 'localhost'",[268,27219,42],{"class":282},[268,27221,7414],{"class":1222},[268,27223,616],{"class":274},[268,27225,7358],{"class":305},[268,27227,7908],{"class":282},[268,27229,302],{"class":274},[268,27231,15544],{"class":282},[268,27233,27234,27236,27238,27240,27242,27244,27247,27249,27252],{"class":270,"line":286},[268,27235,1240],{"class":274},[268,27237,14262],{"class":289},[268,27239,14243],{"class":282},[268,27241,14267],{"class":289},[268,27243,14248],{"class":282},[268,27245,27246],{"class":289},"} (${",[268,27248,7414],{"class":282},[268,27250,27251],{"class":289},"}ms)`",[268,27253,293],{"class":282},[268,27255,27256],{"class":270,"line":296},[268,27257,314],{"class":282},[268,27259,27260,27262,27264,27266,27268,27271,27273,27276,27278],{"class":270,"line":311},[268,27261,1353],{"class":282},[268,27263,1356],{"class":278},[268,27265,622],{"class":282},[268,27267,14292],{"class":278},[268,27269,27270],{"class":282},"({ port: ",[268,27272,2650],{"class":305},[268,27274,27275],{"class":282},", host: ",[268,27277,833],{"class":305},[268,27279,27280],{"class":282}," }));\n",[23,27282,27284,27290,27296,27302],{"className":27283},[26],[28,27285,27287,27289],{"className":27286},[31],[33,27288],{"disabled":35,"type":36}," localhost:8080 (3000ms)",[28,27291,27293,27295],{"className":27292},[31],[33,27294],{"disabled":35,"type":36}," null:8080 (3000ms)",[28,27297,27299,27301],{"className":27298},[31],[33,27300],{"disabled":35,"type":36}," TypeError: Cannot read properties of null",[28,27303,27305,27307],{"className":27304},[31],[33,27306],{"disabled":35,"type":36}," localhost:null (3000ms)",[66,27309,27310,27312,27317],{},[69,27311,71],{},[73,27313,27314,27316],{},[76,27315,78],{}," D — localhost:null (3000ms)",[73,27318,27319,355,27321,27323,27324,3277,27326,27329,27330,7415,27332,3277,27334,355,27337,355,27339,27341,27342,27345,27346,27348,27349,27351,27352,27355,27356,27358],{},[76,27320,84],{},[76,27322,27162],{}," Destructuring defaults trigger for exactly one value: ",[39,27325,833],{},[39,27327,27328],{},"port: null"," is an explicit, real value, so the default is skipped and ",[39,27331,14248],{},[39,27333,2650],{},[39,27335,27336],{},"host: undefined",[104,27338,4447],{},[39,27340,833],{},", so its default ",[39,27343,27344],{},"'localhost'"," kicks in. ",[39,27347,7414],{}," isn't passed at all, which is also ",[39,27350,833],{}," under the hood, so it defaults to ",[39,27353,27354],{},"3000",". A wrongly assumes ",[39,27357,2650],{}," behaves like a missing value; B mixes up which field falls back.",[15,27360,27361,27363,27441,27466],{"language":247},[18,27362,13181],{"id":13180},[257,27364,27365],{"language":247},[260,27366,27368],{"className":262,"code":27367,"language":247,"meta":264,"style":264},"const response = {\n  data: [{ id: 1, meta: { active: true } }],\n};\nconst {\n  data: [{ meta: { active } }],\n} = response;\nconsole.log(active);\n",[39,27369,27370,27380,27395,27399,27405,27423,27432],{"__ignoreMap":264},[268,27371,27372,27374,27376,27378],{"class":270,"line":271},[268,27373,243],{"class":274},[268,27375,21027],{"class":305},[268,27377,616],{"class":274},[268,27379,9914],{"class":282},[268,27381,27382,27385,27387,27390,27392],{"class":270,"line":286},[268,27383,27384],{"class":282},"  data: [{ id: ",[268,27386,2255],{"class":305},[268,27388,27389],{"class":282},", meta: { active: ",[268,27391,2185],{"class":305},[268,27393,27394],{"class":282}," } }],\n",[268,27396,27397],{"class":270,"line":296},[268,27398,12940],{"class":282},[268,27400,27401,27403],{"class":270,"line":311},[268,27402,243],{"class":274},[268,27404,9914],{"class":282},[268,27406,27407,27410,27413,27415,27418,27421],{"class":270,"line":788},[268,27408,27409],{"class":1222},"  data",[268,27411,27412],{"class":282},": [{ ",[268,27414,20320],{"class":1222},[268,27416,27417],{"class":282},": { ",[268,27419,27420],{"class":305},"active",[268,27422,27394],{"class":282},[268,27424,27425,27427,27429],{"class":270,"line":1951},[268,27426,11235],{"class":282},[268,27428,302],{"class":274},[268,27430,27431],{"class":282}," response;\n",[268,27433,27434,27436,27438],{"class":270,"line":8955},[268,27435,1353],{"class":282},[268,27437,1356],{"class":278},[268,27439,27440],{"class":282},"(active);\n",[23,27442,27444,27449,27454,27460],{"className":27443},[26],[28,27445,27447,17135],{"className":27446},[31],[33,27448],{"disabled":35,"type":36},[28,27450,27452,7905],{"className":27451},[31],[33,27453],{"disabled":35,"type":36},[28,27455,27457,27459],{"className":27456},[31],[33,27458],{"disabled":35,"type":36}," TypeError: Cannot destructure property 'meta' of undefined",[28,27461,27463,27465],{"className":27462},[31],[33,27464],{"disabled":35,"type":36}," { active: true }",[66,27467,27468,27470,27475],{},[69,27469,71],{},[73,27471,27472,27474],{},[76,27473,78],{}," B — true",[73,27476,27477,27479,27480,27482,27483,27485,27486,27488,27489,27492,27493,446,27495,27497],{},[76,27478,84],{}," Destructuring patterns can nest arbitrarily deep: ",[39,27481,21188],{}," is renamed by pattern position into an array pattern, whose single element is object-destructured for ",[39,27484,20320],{},", which is itself object-destructured for ",[39,27487,27420],{},". 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 ",[104,27490,27491],{},"intermediate"," value were ",[39,27494,2650],{},[39,27496,833],{},", which isn't the case here.",[15,27499,27500,27502,27560,27585],{"language":247},[18,27501,13321],{"id":13320},[257,27503,27504],{"language":247},[260,27505,27507],{"className":262,"code":27506,"language":247,"meta":264,"style":264},"const rgb = [255, 165, 0];\nconst [, green] = rgb;\nconsole.log(green);\n",[39,27508,27509,27534,27551],{"__ignoreMap":264},[268,27510,27511,27513,27516,27518,27520,27523,27525,27528,27530,27532],{"class":270,"line":271},[268,27512,243],{"class":274},[268,27514,27515],{"class":305}," rgb",[268,27517,616],{"class":274},[268,27519,8710],{"class":282},[268,27521,27522],{"class":305},"255",[268,27524,42],{"class":282},[268,27526,27527],{"class":305},"165",[268,27529,42],{"class":282},[268,27531,3307],{"class":305},[268,27533,8737],{"class":282},[268,27535,27536,27538,27541,27544,27546,27548],{"class":270,"line":286},[268,27537,243],{"class":274},[268,27539,27540],{"class":282}," [, ",[268,27542,27543],{"class":305},"green",[268,27545,19897],{"class":282},[268,27547,302],{"class":274},[268,27549,27550],{"class":282}," rgb;\n",[268,27552,27553,27555,27557],{"class":270,"line":296},[268,27554,1353],{"class":282},[268,27556,1356],{"class":278},[268,27558,27559],{"class":282},"(green);\n",[23,27561,27563,27569,27575,27580],{"className":27562},[26],[28,27564,27566,27568],{"className":27565},[31],[33,27567],{"disabled":35,"type":36}," 165",[28,27570,27572,27574],{"className":27571},[31],[33,27573],{"disabled":35,"type":36}," 255",[28,27576,27578,5728],{"className":27577},[31],[33,27579],{"disabled":35,"type":36},[28,27581,27583,17135],{"className":27582},[31],[33,27584],{"disabled":35,"type":36},[66,27586,27587,27589,27594],{},[69,27588,71],{},[73,27590,27591,27593],{},[76,27592,78],{}," A — 165",[73,27595,27596,355,27598,27600,27601,27604,27605,27607,27608,27611,27612,462],{},[76,27597,84],{},[76,27599,27040],{}," A leading comma with nothing before it is a valid \"elision\" — it holds the position for ",[39,27602,27603],{},"rgb[0]"," without binding it to any name, so the next identifier, ",[39,27606,27543],{},", lands on ",[39,27609,27610],{},"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 ",[39,27613,27614],{},"rgb",[15,27616,27617,27619,27697,27724],{"language":247},[18,27618,13528],{"id":13527},[257,27620,27621],{"language":247},[260,27622,27624],{"className":262,"code":27623,"language":247,"meta":264,"style":264},"const scores = [95, 88, 72, 60];\nconst [top, ...rest] = scores;\nconsole.log(rest.length, Array.isArray(rest));\n",[39,27625,27626,27656,27678],{"__ignoreMap":264},[268,27627,27628,27630,27632,27634,27636,27639,27641,27644,27646,27649,27651,27654],{"class":270,"line":271},[268,27629,243],{"class":274},[268,27631,23689],{"class":305},[268,27633,616],{"class":274},[268,27635,8710],{"class":282},[268,27637,27638],{"class":305},"95",[268,27640,42],{"class":282},[268,27642,27643],{"class":305},"88",[268,27645,42],{"class":282},[268,27647,27648],{"class":305},"72",[268,27650,42],{"class":282},[268,27652,27653],{"class":305},"60",[268,27655,8737],{"class":282},[268,27657,27658,27660,27662,27665,27667,27669,27671,27673,27675],{"class":270,"line":286},[268,27659,243],{"class":274},[268,27661,8710],{"class":282},[268,27663,27664],{"class":305},"top",[268,27666,42],{"class":282},[268,27668,15329],{"class":274},[268,27670,22677],{"class":305},[268,27672,19897],{"class":282},[268,27674,302],{"class":274},[268,27676,27677],{"class":282}," scores;\n",[268,27679,27680,27682,27684,27687,27689,27692,27694],{"class":270,"line":296},[268,27681,1353],{"class":282},[268,27683,1356],{"class":278},[268,27685,27686],{"class":282},"(rest.",[268,27688,3567],{"class":305},[268,27690,27691],{"class":282},", Array.",[268,27693,23592],{"class":278},[268,27695,27696],{"class":282},"(rest));\n",[23,27698,27700,27706,27712,27718],{"className":27699},[26],[28,27701,27703,27705],{"className":27702},[31],[33,27704],{"disabled":35,"type":36}," 4 true",[28,27707,27709,27711],{"className":27708},[31],[33,27710],{"disabled":35,"type":36}," 3 false",[28,27713,27715,27717],{"className":27714},[31],[33,27716],{"disabled":35,"type":36}," 3 true",[28,27719,27721,27723],{"className":27720},[31],[33,27722],{"disabled":35,"type":36}," undefined true",[66,27725,27726,27728,27733],{},[69,27727,71],{},[73,27729,27730,27732],{},[76,27731,78],{}," C — 3 true",[73,27734,27735,355,27737,27739,27740,27742,27743,27745,27746,27748,27749,462],{},[76,27736,84],{},[76,27738,27040],{}," The rest pattern ",[39,27741,22799],{}," collects every remaining element — here, three of the four — into a genuinely new ",[39,27744,88],{}," 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 ",[39,27747,27664],{},"'s element in ",[39,27750,22677],{},[15,27752,27753,27755,27821,27848],{"language":247},[18,27754,13729],{"id":13728},[257,27756,27757],{"language":247},[260,27758,27760],{"className":262,"code":27759,"language":247,"meta":264,"style":264},"const user = { id: 1, name: 'Kim', role: 'admin', active: true };\nconst { id, ...meta } = user;\nconsole.log(meta);\n",[39,27761,27762,27792,27812],{"__ignoreMap":264},[268,27763,27764,27766,27768,27770,27772,27774,27776,27779,27782,27785,27788,27790],{"class":270,"line":271},[268,27765,243],{"class":274},[268,27767,4071],{"class":305},[268,27769,616],{"class":274},[268,27771,20178],{"class":282},[268,27773,2255],{"class":305},[268,27775,4662],{"class":282},[268,27777,27778],{"class":289},"'Kim'",[268,27780,27781],{"class":282},", role: ",[268,27783,27784],{"class":289},"'admin'",[268,27786,27787],{"class":282},", active: ",[268,27789,2185],{"class":305},[268,27791,2790],{"class":282},[268,27793,27794,27796,27798,27800,27802,27804,27806,27808,27810],{"class":270,"line":286},[268,27795,243],{"class":274},[268,27797,20200],{"class":282},[268,27799,14610],{"class":305},[268,27801,42],{"class":282},[268,27803,15329],{"class":274},[268,27805,20320],{"class":305},[268,27807,7908],{"class":282},[268,27809,302],{"class":274},[268,27811,26989],{"class":282},[268,27813,27814,27816,27818],{"class":270,"line":296},[268,27815,1353],{"class":282},[268,27817,1356],{"class":278},[268,27819,27820],{"class":282},"(meta);\n",[23,27822,27824,27830,27836,27842],{"className":27823},[26],[28,27825,27827,27829],{"className":27826},[31],[33,27828],{"disabled":35,"type":36}," { id: 1, name: 'Kim', role: 'admin', active: true }",[28,27831,27833,27835],{"className":27832},[31],[33,27834],{"disabled":35,"type":36}," {}",[28,27837,27839,27841],{"className":27838},[31],[33,27840],{"disabled":35,"type":36}," TypeError: Rest element must be last",[28,27843,27845,27847],{"className":27844},[31],[33,27846],{"disabled":35,"type":36}," { name: 'Kim', role: 'admin', active: true }",[66,27849,27850,27852,27857],{},[69,27851,71],{},[73,27853,27854,27856],{},[76,27855,78],{}," D — { name: 'Kim', role: 'admin', active: true }",[73,27858,27859,355,27861,27863,27864,27867,27868,27870,27871,27873,27874,27876],{},[76,27860,84],{},[76,27862,27040],{}," Object rest works like array rest: it gathers every enumerable own property ",[104,27865,27866],{},"not already claimed"," by an earlier name in the pattern into a fresh plain object. ",[39,27869,14610],{}," was explicitly pulled out, so it's excluded from ",[39,27872,20320],{},". A is the mistake of assuming rest re-includes everything; C confuses the object-rest constraint (rest must be the ",[104,27875,6891],{}," property in the pattern, which it correctly is here) with an actual error.",[15,27878,27879,27893,27920],{},[18,27880,27882,27883,186,27886,27889,27890,27892],{"id":27881},"q9-in-const-a-b-arr-and-const-c-arr-99-what-role-does-the-play-in-each-statement-respectively","Q9. In ",[39,27884,27885],{},"const [a, ...b] = arr;",[39,27887,27888],{},"const c = [...arr, 99];",", what role does the ",[39,27891,15329],{}," play in each statement, respectively?",[23,27894,27896,27902,27908,27914],{"className":27895},[26],[28,27897,27899,27901],{"className":27898},[31],[33,27900],{"disabled":35,"type":36}," Rest syntax, then spread syntax",[28,27903,27905,27907],{"className":27904},[31],[33,27906],{"disabled":35,"type":36}," Spread syntax, then rest syntax",[28,27909,27911,27913],{"className":27910},[31],[33,27912],{"disabled":35,"type":36}," Rest syntax in both cases",[28,27915,27917,27919],{"className":27916},[31],[33,27918],{"disabled":35,"type":36}," Spread syntax in both cases",[66,27921,27922,27924,27929],{},[69,27923,71],{},[73,27925,27926,27928],{},[76,27927,78],{}," A — Rest syntax, then spread syntax",[73,27930,27931,355,27933,27935,27936,27938,27939,27941,27942,27945,27946,27948],{},[76,27932,84],{},[76,27934,27040],{}," The token ",[39,27937,15329],{}," is overloaded: on the left side of a destructuring assignment it's the ",[104,27940,22677],{}," pattern, collecting leftover elements into a new binding; inside an array or object literal (or a function call) it's ",[104,27943,27944],{},"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 ",[39,27947,302],{}," (or which kind of expression) you're looking at, not by the symbol itself.",[15,27950,27951,27955,28022,28049],{"language":247},[18,27952,27954],{"id":27953},"q10-what-happens-when-this-code-runs","Q10. What happens when this code runs?",[257,27956,27957],{"language":247},[260,27958,27960],{"className":262,"code":27959,"language":247,"meta":264,"style":264},"const a = { x: 1 };\nconst b = null;\nconst { x, y } = a;\nconst { z } = b;\n",[39,27961,27962,27977,27989,28007],{"__ignoreMap":264},[268,27963,27964,27966,27968,27970,27973,27975],{"class":270,"line":271},[268,27965,243],{"class":274},[268,27967,7203],{"class":305},[268,27969,616],{"class":274},[268,27971,27972],{"class":282}," { x: ",[268,27974,2255],{"class":305},[268,27976,2790],{"class":282},[268,27978,27979,27981,27983,27985,27987],{"class":270,"line":286},[268,27980,243],{"class":274},[268,27982,16372],{"class":305},[268,27984,616],{"class":274},[268,27986,4794],{"class":305},[268,27988,293],{"class":282},[268,27990,27991,27993,27995,27997,27999,28001,28003,28005],{"class":270,"line":296},[268,27992,243],{"class":274},[268,27994,20200],{"class":282},[268,27996,2403],{"class":305},[268,27998,42],{"class":282},[268,28000,2909],{"class":305},[268,28002,7908],{"class":282},[268,28004,302],{"class":274},[268,28006,2801],{"class":282},[268,28008,28009,28011,28013,28016,28018,28020],{"class":270,"line":311},[268,28010,243],{"class":274},[268,28012,20200],{"class":282},[268,28014,28015],{"class":305},"z",[268,28017,7908],{"class":282},[268,28019,302],{"class":274},[268,28021,1249],{"class":282},[23,28023,28025,28031,28037,28043],{"className":28024},[26],[28,28026,28028,28030],{"className":28027},[31],[33,28029],{"disabled":35,"type":36}," Both lines run fine; y is undefined, z is undefined",[28,28032,28034,28036],{"className":28033},[31],[33,28035],{"disabled":35,"type":36}," Line 3 runs fine (y is undefined); line 4 throws TypeError because null cannot be destructured",[28,28038,28040,28042],{"className":28039},[31],[33,28041],{"disabled":35,"type":36}," Both lines throw TypeError",[28,28044,28046,28048],{"className":28045},[31],[33,28047],{"disabled":35,"type":36}," Line 3 throws ReferenceError; line 4 runs fine",[66,28050,28051,28053,28058],{},[69,28052,71],{},[73,28054,28055,28057],{},[76,28056,78],{}," B — Line 3 runs fine (y is undefined); line 4 throws TypeError because null cannot be destructured",[73,28059,28060,355,28062,28065,28066,28068,28069,28071,28072,28074,28075,7255,28077,28079],{},[76,28061,84],{},[76,28063,28064],{},"Safety."," These two failure modes are easy to conflate but are opposites: destructuring an object for a key it doesn't have simply yields ",[39,28067,833],{}," for that binding (no error — ",[39,28070,1223],{}," is a valid object, ",[39,28073,2909],{}," just isn't one of its properties). Destructuring ",[39,28076,2650],{},[39,28078,833],{},") 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.",[15,28081,28082,28084,28129,28156],{"language":247},[18,28083,14224],{"id":14223},[257,28085,28086],{"language":247},[260,28087,28089],{"className":262,"code":28088,"language":247,"meta":264,"style":264},"let a = 1, b = 2;\n[a, b] = [b, a];\nconsole.log(a, b);\n",[39,28090,28091,28110,28120],{"__ignoreMap":264},[268,28092,28093,28095,28097,28099,28101,28104,28106,28108],{"class":270,"line":271},[268,28094,240],{"class":274},[268,28096,1243],{"class":282},[268,28098,302],{"class":274},[268,28100,2199],{"class":305},[268,28102,28103],{"class":282},", b ",[268,28105,302],{"class":274},[268,28107,2214],{"class":305},[268,28109,293],{"class":282},[268,28111,28112,28115,28117],{"class":270,"line":286},[268,28113,28114],{"class":282},"[a, b] ",[268,28116,302],{"class":274},[268,28118,28119],{"class":282}," [b, a];\n",[268,28121,28122,28124,28126],{"class":270,"line":296},[268,28123,1353],{"class":282},[268,28125,1356],{"class":278},[268,28127,28128],{"class":282},"(a, b);\n",[23,28130,28132,28138,28144,28150],{"className":28131},[26],[28,28133,28135,28137],{"className":28134},[31],[33,28136],{"disabled":35,"type":36}," 1 2",[28,28139,28141,28143],{"className":28140},[31],[33,28142],{"disabled":35,"type":36}," 1 1",[28,28145,28147,28149],{"className":28146},[31],[33,28148],{"disabled":35,"type":36}," 2 1",[28,28151,28153,28155],{"className":28152},[31],[33,28154],{"disabled":35,"type":36}," ReferenceError: Invalid destructuring assignment target",[66,28157,28158,28160,28165],{},[69,28159,71],{},[73,28161,28162,28164],{},[76,28163,78],{}," C — 2 1",[73,28166,28167,355,28169,28171,28172,28175,28176,28179,28180,28183,28184,186,28186,28188,28189,186,28191,28193],{},[76,28168,84],{},[76,28170,27040],{}," The right-hand side ",[39,28173,28174],{},"[b, a]"," is fully evaluated first, building a temporary array ",[39,28177,28178],{},"[2, 1]"," from the ",[104,28181,28182],{},"current"," values of ",[39,28185,1232],{},[39,28187,1223],{},"; only then does array destructuring assign its elements back into ",[39,28190,1223],{},[39,28192,1232],{}," 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.",[15,28195,28196,28200,28256,28283],{"language":247},[18,28197,28199],{"id":28198},"q12-what-happens-when-this-runs","Q12. What happens when this runs?",[257,28201,28202],{"language":247},[260,28203,28205],{"className":262,"code":28204,"language":247,"meta":264,"style":264},"function createUser({ id, name }) {\n  return `${id}-${name}`;\n}\nconsole.log(createUser());\n",[39,28206,28207,28224,28240,28244],{"__ignoreMap":264},[268,28208,28209,28211,28213,28215,28217,28219,28221],{"class":270,"line":271},[268,28210,275],{"class":274},[268,28212,7886],{"class":278},[268,28214,7889],{"class":282},[268,28216,14610],{"class":1222},[268,28218,42],{"class":282},[268,28220,14605],{"class":1222},[268,28222,28223],{"class":282}," }) {\n",[268,28225,28226,28228,28230,28232,28234,28236,28238],{"class":270,"line":286},[268,28227,1240],{"class":274},[268,28229,14262],{"class":289},[268,28231,14610],{"class":282},[268,28233,16955],{"class":289},[268,28235,14605],{"class":282},[268,28237,11603],{"class":289},[268,28239,293],{"class":282},[268,28241,28242],{"class":270,"line":296},[268,28243,314],{"class":282},[268,28245,28246,28248,28250,28252,28254],{"class":270,"line":311},[268,28247,1353],{"class":282},[268,28249,1356],{"class":278},[268,28251,622],{"class":282},[268,28253,7983],{"class":278},[268,28255,8174],{"class":282},[23,28257,28259,28265,28271,28277],{"className":28258},[26],[28,28260,28262,28264],{"className":28261},[31],[33,28263],{"disabled":35,"type":36}," undefined-undefined",[28,28266,28268,28270],{"className":28267},[31],[33,28269],{"disabled":35,"type":36}," TypeError: Cannot destructure property 'id' of 'undefined' as it is undefined",[28,28272,28274,28276],{"className":28273},[31],[33,28275],{"disabled":35,"type":36}," ReferenceError: id is not defined",[28,28278,28280,28282],{"className":28279},[31],[33,28281],{"disabled":35,"type":36}," 0-undefined",[66,28284,28285,28287,28292],{},[69,28286,71],{},[73,28288,28289,28291],{},[76,28290,78],{}," B — TypeError: Cannot destructure property 'id' of 'undefined' as it is undefined",[73,28293,28294,355,28296,28298,28299,28302,28303,28305,28306,28308,28309,28311,28312,28314,28315,28318],{},[76,28295,84],{},[76,28297,28064],{}," Calling ",[39,28300,28301],{},"createUser()"," with no argument means the parameter itself is ",[39,28304,833],{}," — and destructuring ",[39,28307,833],{}," throws for the same reason destructuring ",[39,28310,2650],{}," does, before the function body ever runs. A is the tempting guess for anyone assuming missing parameters just cascade into ",[39,28313,833],{}," fields, but that only holds once you're safely destructuring a ",[104,28316,28317],{},"real"," object.",[15,28320,28321,28325,28384,28408],{"language":247},[18,28322,28324],{"id":28323},"q13-what-happens-when-this-runs","Q13. What happens when this runs?",[257,28326,28327],{"language":247},[260,28328,28330],{"className":262,"code":28329,"language":247,"meta":264,"style":264},"function createUser({ id, name } = {}) {\n  return `${id}-${name}`;\n}\nconsole.log(createUser());\n",[39,28331,28332,28352,28368,28372],{"__ignoreMap":264},[268,28333,28334,28336,28338,28340,28342,28344,28346,28348,28350],{"class":270,"line":271},[268,28335,275],{"class":274},[268,28337,7886],{"class":278},[268,28339,7889],{"class":282},[268,28341,14610],{"class":1222},[268,28343,42],{"class":282},[268,28345,14605],{"class":1222},[268,28347,7908],{"class":282},[268,28349,302],{"class":274},[268,28351,15544],{"class":282},[268,28353,28354,28356,28358,28360,28362,28364,28366],{"class":270,"line":286},[268,28355,1240],{"class":274},[268,28357,14262],{"class":289},[268,28359,14610],{"class":282},[268,28361,16955],{"class":289},[268,28363,14605],{"class":282},[268,28365,11603],{"class":289},[268,28367,293],{"class":282},[268,28369,28370],{"class":270,"line":296},[268,28371,314],{"class":282},[268,28373,28374,28376,28378,28380,28382],{"class":270,"line":311},[268,28375,1353],{"class":282},[268,28377,1356],{"class":278},[268,28379,622],{"class":282},[268,28381,7983],{"class":278},[268,28383,8174],{"class":282},[23,28385,28387,28392,28397,28403],{"className":28386},[26],[28,28388,28390,28270],{"className":28389},[31],[33,28391],{"disabled":35,"type":36},[28,28393,28395,27835],{"className":28394},[31],[33,28396],{"disabled":35,"type":36},[28,28398,28400,28402],{"className":28399},[31],[33,28401],{"disabled":35,"type":36}," 0-0",[28,28404,28406,28264],{"className":28405},[31],[33,28407],{"disabled":35,"type":36},[66,28409,28410,28412,28417],{},[69,28411,71],{},[73,28413,28414,28416],{},[76,28415,78],{}," D — undefined-undefined",[73,28418,28419,355,28421,28423,28424,28427,28428,28431,28432,28434,28435,186,28437,28439,28440,28442,28443,28445,28446,21599,28449,28451],{},[76,28420,84],{},[76,28422,28064],{}," Adding ",[39,28425,28426],{},"= {}"," as the ",[104,28429,28430],{},"parameter's own"," default only fires when the argument itself is ",[39,28433,833],{}," — exactly the case of calling with no argument at all. That substitutes an empty object before destructuring runs, so ",[39,28436,14610],{},[39,28438,14605],{}," are destructured off ",[39,28441,2328],{}," and each comes out ",[39,28444,833],{}," (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 ",[104,28447,28448],{},"without",[39,28450,28426],{}," guard.",[15,28453,28454,28456,28552,28588],{"language":247},[18,28455,14774],{"id":14773},[257,28457,28458],{"language":247},[260,28459,28461],{"className":262,"code":28460,"language":247,"meta":264,"style":264},"function sum(a, b, c) {\n  return a + b + c;\n}\nconst nums = [1, 2, 3];\nconsole.log(sum(...nums), [...nums, 4]);\n",[39,28462,28463,28484,28499,28503,28525],{"__ignoreMap":264},[268,28464,28465,28467,28470,28472,28474,28476,28478,28480,28482],{"class":270,"line":271},[268,28466,275],{"class":274},[268,28468,28469],{"class":278}," sum",[268,28471,622],{"class":282},[268,28473,1223],{"class":1222},[268,28475,42],{"class":282},[268,28477,1232],{"class":1222},[268,28479,42],{"class":282},[268,28481,16484],{"class":1222},[268,28483,1235],{"class":282},[268,28485,28486,28488,28490,28492,28494,28496],{"class":270,"line":286},[268,28487,1240],{"class":274},[268,28489,1243],{"class":282},[268,28491,1246],{"class":274},[268,28493,2209],{"class":282},[268,28495,1246],{"class":274},[268,28497,28498],{"class":282}," c;\n",[268,28500,28501],{"class":270,"line":296},[268,28502,314],{"class":282},[268,28504,28505,28507,28509,28511,28513,28515,28517,28519,28521,28523],{"class":270,"line":311},[268,28506,243],{"class":274},[268,28508,12090],{"class":305},[268,28510,616],{"class":274},[268,28512,8710],{"class":282},[268,28514,2255],{"class":305},[268,28516,42],{"class":282},[268,28518,2258],{"class":305},[268,28520,42],{"class":282},[268,28522,3423],{"class":305},[268,28524,8737],{"class":282},[268,28526,28527,28529,28531,28533,28536,28538,28540,28543,28545,28548,28550],{"class":270,"line":788},[268,28528,1353],{"class":282},[268,28530,1356],{"class":278},[268,28532,622],{"class":282},[268,28534,28535],{"class":278},"sum",[268,28537,622],{"class":282},[268,28539,15329],{"class":274},[268,28541,28542],{"class":282},"nums), [",[268,28544,15329],{"class":274},[268,28546,28547],{"class":282},"nums, ",[268,28549,15049],{"class":305},[268,28551,15180],{"class":282},[23,28553,28555,28563,28572,28580],{"className":28554},[26],[28,28556,28558,28560,28561],{"className":28557},[31],[33,28559],{"disabled":35,"type":36}," 6 ",[268,28562,26027],{},[28,28564,28566,355,28568,355,28570],{"className":28565},[31],[33,28567],{"disabled":35,"type":36},[268,28569,23888],{},[268,28571,26027],{},[28,28573,28575,28577,28578],{"className":28574},[31],[33,28576],{"disabled":35,"type":36}," NaN ",[268,28579,26027],{},[28,28581,28583,28560,28585],{"className":28582},[31],[33,28584],{"disabled":35,"type":36},[268,28586,28587],{},"4, 1, 2, 3",[66,28589,28590,28592,28599],{},[69,28591,71],{},[73,28593,28594,28596,28597],{},[76,28595,78],{}," A — 6 ",[268,28598,26027],{},[73,28600,28601,355,28603,28605,28606,28608,28609,4977,28612,28614,28615,7159,28618,28621],{},[76,28602,84],{},[76,28604,27040],{}," The same ",[39,28607,15467],{}," spread means different things purely by context: inside a call's argument list it unpacks the array into three separate positional arguments (",[39,28610,28611],{},"sum(1, 2, 3)",[39,28613,13663],{},"), while inside an array literal it unpacks the array's elements in place, so ",[39,28616,28617],{},"[...nums, 4]",[39,28619,28620],{},"[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.",[15,28623,28624,28626,28695,28725],{"language":247},[18,28625,18417],{"id":18416},[257,28627,28628],{"language":247},[260,28629,28631],{"className":262,"code":28630,"language":247,"meta":264,"style":264},"const original = { name: 'A', tags: ['x', 'y'] };\nconst copy = { ...original };\ncopy.tags.push('z');\nconsole.log(original.tags);\n",[39,28632,28633,28659,28673,28686],{"__ignoreMap":264},[268,28634,28635,28637,28639,28641,28643,28645,28648,28651,28653,28656],{"class":270,"line":271},[268,28636,243],{"class":274},[268,28638,20173],{"class":305},[268,28640,616],{"class":274},[268,28642,4076],{"class":282},[268,28644,17902],{"class":289},[268,28646,28647],{"class":282},", tags: [",[268,28649,28650],{"class":289},"'x'",[268,28652,42],{"class":282},[268,28654,28655],{"class":289},"'y'",[268,28657,28658],{"class":282},"] };\n",[268,28660,28661,28663,28665,28667,28669,28671],{"class":270,"line":286},[268,28662,243],{"class":274},[268,28664,20195],{"class":305},[268,28666,616],{"class":274},[268,28668,20200],{"class":282},[268,28670,15329],{"class":274},[268,28672,20205],{"class":282},[268,28674,28675,28678,28680,28682,28684],{"class":270,"line":296},[268,28676,28677],{"class":282},"copy.tags.",[268,28679,12499],{"class":278},[268,28681,622],{"class":282},[268,28683,19111],{"class":289},[268,28685,628],{"class":282},[268,28687,28688,28690,28692],{"class":270,"line":311},[268,28689,1353],{"class":282},[268,28691,1356],{"class":278},[268,28693,28694],{"class":282},"(original.tags);\n",[23,28696,28698,28706,28714,28720],{"className":28697},[26],[28,28699,28701,355,28703],{"className":28700},[31],[33,28702],{"disabled":35,"type":36},[268,28704,28705],{},"'x', 'y'",[28,28707,28709,355,28711],{"className":28708},[31],[33,28710],{"disabled":35,"type":36},[268,28712,28713],{},"'x', 'y', 'z'",[28,28715,28717,28719],{"className":28716},[31],[33,28718],{"disabled":35,"type":36}," TypeError: Cannot push to a spread property",[28,28721,28723,17135],{"className":28722},[31],[33,28724],{"disabled":35,"type":36},[66,28726,28727,28729,28735],{},[69,28728,71],{},[73,28730,28731,1727,28733],{},[76,28732,78],{},[268,28734,28713],{},[73,28736,28737,355,28739,28741,28742,28744,28745,186,28748,28751,28752,28755,28756,28758],{},[76,28738,84],{},[76,28740,28064],{}," Object spread is a ",[104,28743,20305],{}," 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. ",[39,28746,28747],{},"copy.tags",[39,28749,28750],{},"original.tags"," point at the exact same array in memory, so mutating one through ",[39,28753,28754],{},".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. ",[39,28757,22322],{},") or spreading the nested array too.",[15,28760,28761,28763,28803,28830],{"language":247},[18,28762,15131],{"id":15130},[257,28764,28765],{"language":247},[260,28766,28768],{"className":262,"code":28767,"language":247,"meta":264,"style":264},"const emoji = '👍A';\nconsole.log(emoji.length, [...emoji].length);\n",[39,28769,28770,28783],{"__ignoreMap":264},[268,28771,28772,28774,28776,28778,28781],{"class":270,"line":271},[268,28773,243],{"class":274},[268,28775,17490],{"class":305},[268,28777,616],{"class":274},[268,28779,28780],{"class":289}," '👍A'",[268,28782,293],{"class":282},[268,28784,28785,28787,28789,28791,28793,28795,28797,28799,28801],{"class":270,"line":286},[268,28786,1353],{"class":282},[268,28788,1356],{"class":278},[268,28790,17506],{"class":282},[268,28792,3567],{"class":305},[268,28794,25183],{"class":282},[268,28796,15329],{"class":274},[268,28798,17524],{"class":282},[268,28800,3567],{"class":305},[268,28802,628],{"class":282},[23,28804,28806,28812,28818,28824],{"className":28805},[26],[28,28807,28809,28811],{"className":28808},[31],[33,28810],{"disabled":35,"type":36}," 2 2",[28,28813,28815,28817],{"className":28814},[31],[33,28816],{"disabled":35,"type":36}," 3 3",[28,28819,28821,28823],{"className":28820},[31],[33,28822],{"disabled":35,"type":36}," 3 2",[28,28825,28827,28829],{"className":28826},[31],[33,28828],{"disabled":35,"type":36}," 2 3",[66,28831,28832,28834,28839],{},[69,28833,71],{},[73,28835,28836,28838],{},[76,28837,78],{}," C — 3 2",[73,28840,28841,355,28843,355,28846,28848,28849,1783,28852,28855,28856,28858,28859,28861,28862,28865,28866,11464,28868,28871,28872,28874,28875,28878,28879,28881],{},[76,28842,84],{},[76,28844,28845],{},"Portability.",[39,28847,3643],{}," counts UTF-16 ",[104,28850,28851],{},"code units",[39,28853,28854],{},"👍"," lies outside the Basic Multilingual Plane, so it's stored as a surrogate pair (2 code units), plus ",[39,28857,17902],{}," (1 unit) gives ",[39,28860,3423],{},". Spreading a string, however, iterates by ",[104,28863,28864],{},"Unicode code point"," — the string iterator correctly recognizes the surrogate pair as one character — so ",[39,28867,17600],{},[39,28869,28870],{},"['👍', 'A']",", length ",[39,28873,2258],{},". This mismatch is why naive indexing (",[39,28876,28877],{},"str[i]",") can slice a surrogate pair in half while spread\u002F",[39,28880,9163],{}," never do.",[15,28883,28884,28886,28973,29003],{"language":247},[18,28885,15311],{"id":15310},[257,28887,28888],{"language":247},[260,28889,28891],{"className":262,"code":28890,"language":247,"meta":264,"style":264},"const map = new Map([['a', 1], ['b', 2]]);\nconst obj = { a: 1, b: 2 };\nconsole.log([...map].length);\nconsole.log([...obj]);\n",[39,28892,28893,28925,28943,28960],{"__ignoreMap":264},[268,28894,28895,28897,28900,28902,28904,28906,28908,28910,28912,28914,28916,28919,28921,28923],{"class":270,"line":271},[268,28896,243],{"class":274},[268,28898,28899],{"class":305}," map",[268,28901,616],{"class":274},[268,28903,11370],{"class":274},[268,28905,11373],{"class":278},[268,28907,11376],{"class":282},[268,28909,17898],{"class":289},[268,28911,42],{"class":282},[268,28913,2255],{"class":305},[268,28915,11386],{"class":282},[268,28917,28918],{"class":289},"'b'",[268,28920,42],{"class":282},[268,28922,2258],{"class":305},[268,28924,11396],{"class":282},[268,28926,28927,28929,28931,28933,28935,28937,28939,28941],{"class":270,"line":286},[268,28928,243],{"class":274},[268,28930,4651],{"class":305},[268,28932,616],{"class":274},[268,28934,10274],{"class":282},[268,28936,2255],{"class":305},[268,28938,10279],{"class":282},[268,28940,2258],{"class":305},[268,28942,2790],{"class":282},[268,28944,28945,28947,28949,28951,28953,28956,28958],{"class":270,"line":296},[268,28946,1353],{"class":282},[268,28948,1356],{"class":278},[268,28950,17519],{"class":282},[268,28952,15329],{"class":274},[268,28954,28955],{"class":282},"map].",[268,28957,3567],{"class":305},[268,28959,628],{"class":282},[268,28961,28962,28964,28966,28968,28970],{"class":270,"line":311},[268,28963,1353],{"class":282},[268,28965,1356],{"class":278},[268,28967,17519],{"class":282},[268,28969,15329],{"class":274},[268,28971,28972],{"class":282},"obj]);\n",[23,28974,28976,28985,28991,28997],{"className":28975},[26],[28,28977,28979,28981,28982],{"className":28978},[31],[33,28980],{"disabled":35,"type":36}," 2, then ",[268,28983,28984],{},"{ a: 1 }, { b: 2 }",[28,28986,28988,28990],{"className":28987},[31],[33,28989],{"disabled":35,"type":36}," 2, then TypeError: obj is not iterable",[28,28992,28994,28996],{"className":28993},[31],[33,28995],{"disabled":35,"type":36}," 4, then { a: 1, b: 2 }",[28,28998,29000,29002],{"className":28999},[31],[33,29001],{"disabled":35,"type":36}," TypeError on both lines",[66,29004,29005,29007,29012],{},[69,29006,71],{},[73,29008,29009,29011],{},[76,29010,78],{}," B — 2, then TypeError: obj is not iterable",[73,29013,29014,355,29016,355,29018,29020,29021,29023,29024,29026,29027,29029,29030,29032,29033,29036,29037,29040,29041,29044],{},[76,29015,84],{},[76,29017,27162],{},[39,29019,2672],{}," implements the iterable protocol, so spreading it into an array yields its ",[39,29022,11422],{}," entries — two entries, length ",[39,29025,2258],{},". A plain object does ",[104,29028,95],{}," implement ",[39,29031,10339],{}," at all; it only has enumerable own properties, which object spread (",[39,29034,29035],{},"{ ...obj }",") knows how to read but ",[104,29038,29039],{},"array"," spread (",[39,29042,29043],{},"[...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.",[15,29046,29047,29049,29129,29156],{"language":247},[18,29048,18980],{"id":18979},[257,29050,29051],{"language":247},[260,29052,29054],{"className":262,"code":29053,"language":247,"meta":264,"style":264},"const defaults = { theme: 'light', size: 'md' };\nconst overrides = { size: 'lg' };\nconst final = { ...defaults, size: 'sm', ...overrides };\nconsole.log(final);\n",[39,29055,29056,29077,29094,29120],{"__ignoreMap":264},[268,29057,29058,29060,29062,29064,29066,29069,29072,29075],{"class":270,"line":271},[268,29059,243],{"class":274},[268,29061,20808],{"class":305},[268,29063,616],{"class":274},[268,29065,20813],{"class":282},[268,29067,29068],{"class":289},"'light'",[268,29070,29071],{"class":282},", size: ",[268,29073,29074],{"class":289},"'md'",[268,29076,2790],{"class":282},[268,29078,29079,29081,29084,29086,29089,29092],{"class":270,"line":286},[268,29080,243],{"class":274},[268,29082,29083],{"class":305}," overrides",[268,29085,616],{"class":274},[268,29087,29088],{"class":282}," { size: ",[268,29090,29091],{"class":289},"'lg'",[268,29093,2790],{"class":282},[268,29095,29096,29098,29101,29103,29105,29107,29110,29113,29115,29117],{"class":270,"line":296},[268,29097,243],{"class":274},[268,29099,29100],{"class":305}," final",[268,29102,616],{"class":274},[268,29104,20200],{"class":282},[268,29106,15329],{"class":274},[268,29108,29109],{"class":282},"defaults, size: ",[268,29111,29112],{"class":289},"'sm'",[268,29114,42],{"class":282},[268,29116,15329],{"class":274},[268,29118,29119],{"class":282},"overrides };\n",[268,29121,29122,29124,29126],{"class":270,"line":311},[268,29123,1353],{"class":282},[268,29125,1356],{"class":278},[268,29127,29128],{"class":282},"(final);\n",[23,29130,29132,29138,29144,29150],{"className":29131},[26],[28,29133,29135,29137],{"className":29134},[31],[33,29136],{"disabled":35,"type":36}," { theme: 'light', size: 'sm' }",[28,29139,29141,29143],{"className":29140},[31],[33,29142],{"disabled":35,"type":36}," { theme: 'light', size: 'md' }",[28,29145,29147,29149],{"className":29146},[31],[33,29148],{"disabled":35,"type":36}," { theme: 'light', size: 'lg' }",[28,29151,29153,29155],{"className":29152},[31],[33,29154],{"disabled":35,"type":36}," SyntaxError: Duplicate key 'size'",[66,29157,29158,29160,29165],{},[69,29159,71],{},[73,29161,29162,29164],{},[76,29163,78],{}," C — { theme: 'light', size: 'lg' }",[73,29166,29167,355,29169,29171,29172,29175,29176,29179,29180,29182,29183,29186,29187,29189],{},[76,29168,84],{},[76,29170,27040],{}," 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 ",[39,29173,29174],{},"size"," is written by ",[39,29177,29178],{},"...defaults"," ('md'), then overwritten by the literal ",[39,29181,29112],{},", then overwritten again by ",[39,29184,29185],{},"...overrides"," ('lg'), which appears last and therefore wins. D is wrong because unlike duplicate ",[39,29188,240],{}," declarations, duplicate object keys are legal JavaScript, not a syntax error.",[15,29191,29192,29194,29258,29292],{"language":247},[18,29193,26306],{"id":26305},[257,29195,29196],{"language":247},[260,29197,29199],{"className":262,"code":29198,"language":247,"meta":264,"style":264},"const key = 'role';\nconst user = { role: 'admin', id: 42 };\nconst { [key]: value } = user;\nconsole.log(value);\n",[39,29200,29201,29214,29234,29249],{"__ignoreMap":264},[268,29202,29203,29205,29207,29209,29212],{"class":270,"line":271},[268,29204,243],{"class":274},[268,29206,12117],{"class":305},[268,29208,616],{"class":274},[268,29210,29211],{"class":289}," 'role'",[268,29213,293],{"class":282},[268,29215,29216,29218,29220,29222,29225,29227,29230,29232],{"class":270,"line":286},[268,29217,243],{"class":274},[268,29219,4071],{"class":305},[268,29221,616],{"class":274},[268,29223,29224],{"class":282}," { role: ",[268,29226,27784],{"class":289},[268,29228,29229],{"class":282},", id: ",[268,29231,4659],{"class":305},[268,29233,2790],{"class":282},[268,29235,29236,29238,29241,29243,29245,29247],{"class":270,"line":296},[268,29237,243],{"class":274},[268,29239,29240],{"class":282}," { [key]: ",[268,29242,4780],{"class":305},[268,29244,7908],{"class":282},[268,29246,302],{"class":274},[268,29248,26989],{"class":282},[268,29250,29251,29253,29255],{"class":270,"line":311},[268,29252,1353],{"class":282},[268,29254,1356],{"class":278},[268,29256,29257],{"class":282},"(value);\n",[23,29259,29261,29267,29276,29282],{"className":29260},[26],[28,29262,29264,29266],{"className":29263},[31],[33,29265],{"disabled":35,"type":36}," SyntaxError — computed keys cannot appear in a destructuring pattern",[28,29268,29270,29272,29273,29275],{"className":29269},[31],[33,29271],{"disabled":35,"type":36}," undefined, because ",[39,29274,19849],{}," refers to the variable name, not the object's property",[28,29277,29279,29281],{"className":29278},[31],[33,29280],{"disabled":35,"type":36}," 'role' — the destructured value takes the name of the computed key by default",[28,29283,29285,29287,29288,29291],{"className":29284},[31],[33,29286],{"disabled":35,"type":36}," 'admin' — computed property names are valid in destructuring, exactly as in object literals, but they require an explicit ",[39,29289,29290],{},": binding"," (no shorthand form is allowed)",[66,29293,29294,29296,29303],{},[69,29295,71],{},[73,29297,29298,29300,29301,29291],{},[76,29299,78],{}," D — 'admin' — computed property names are valid in destructuring, exactly as in object literals, but they require an explicit ",[39,29302,29290],{},[73,29304,29305,355,29307,29309,29310,29313,29314,29317,29318,2182,29321,29324,29325,29327,29328,29330,29331,29334,29335,29337],{},[76,29306,84],{},[76,29308,27162],{}," A common misconception is that computed keys only work in object ",[104,29311,29312],{},"literals",", not on the left side of a destructuring pattern — but ",[39,29315,29316],{},"{ [key]: value } = user"," is valid ES6 syntax: it looks up ",[39,29319,29320],{},"user[key]",[39,29322,29323],{},"user.role",", i.e. ",[39,29326,27784],{},") and binds it to ",[39,29329,4780],{},". The real, genuine limitation is that destructuring has no shorthand form for computed keys — you cannot write ",[39,29332,29333],{},"{ [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 ",[39,29336,29290],{}," is mandatory. A states the actual misconception as fact; C confuses the computed key's name with its resolved value.",[15,29339,29340,29344,29454,29457,29484],{"language":247},[18,29341,29343],{"id":29342},"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.",[257,29345,29346],{"language":247},[260,29347,29349],{"className":262,"code":29348,"language":247,"meta":264,"style":264},"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",[39,29350,29351,29395,29399],{"__ignoreMap":264},[268,29352,29353,29355,29358,29360,29362,29364,29366,29368,29371,29373,29375,29377,29380,29382,29385,29388,29392],{"class":270,"line":271},[268,29354,275],{"class":274},[268,29356,29357],{"class":278}," createWidget",[268,29359,622],{"class":282},[268,29361,14610],{"class":1222},[268,29363,42],{"class":282},[268,29365,14605],{"class":1222},[268,29367,42],{"class":282},[268,29369,29370],{"class":1222},"color",[268,29372,42],{"class":282},[268,29374,29174],{"class":1222},[268,29376,42],{"class":282},[268,29378,29379],{"class":1222},"isVisible",[268,29381,42],{"class":282},[268,29383,29384],{"class":1222},"onClick",[268,29386,29387],{"class":282},") { ",[268,29389,29391],{"class":29390},"sdCPZ","\u002F* ... *\u002F",[268,29393,29394],{"class":282}," }\n",[268,29396,29397],{"class":270,"line":286},[268,29398,5033],{"emptyLinePlaceholder":35},[268,29400,29401,29403,29405,29407,29409,29411,29413,29415,29417,29419,29422,29424,29426,29428,29431,29433,29435,29437,29439,29441,29443,29445,29447,29450,29452],{"class":270,"line":296},[268,29402,275],{"class":274},[268,29404,29357],{"class":278},[268,29406,7889],{"class":282},[268,29408,14610],{"class":1222},[268,29410,42],{"class":282},[268,29412,14605],{"class":1222},[268,29414,42],{"class":282},[268,29416,29370],{"class":1222},[268,29418,616],{"class":274},[268,29420,29421],{"class":289}," 'blue'",[268,29423,42],{"class":282},[268,29425,29174],{"class":1222},[268,29427,616],{"class":274},[268,29429,29430],{"class":289}," 'md'",[268,29432,42],{"class":282},[268,29434,29379],{"class":1222},[268,29436,616],{"class":274},[268,29438,7905],{"class":305},[268,29440,42],{"class":282},[268,29442,29384],{"class":1222},[268,29444,7908],{"class":282},[268,29446,302],{"class":274},[268,29448,29449],{"class":282}," {}) { ",[268,29451,29391],{"class":29390},[268,29453,29394],{"class":282},[73,29455,29456],{},"Which signature is the better design, and why?",[23,29458,29460,29466,29472,29478],{"className":29459},[26],[28,29461,29463,29465],{"className":29462},[31],[33,29464],{"disabled":35,"type":36}," The positional version, because positional parameters are always faster at runtime than destructured ones",[28,29467,29469,29471],{"className":29468},[31],[33,29470],{"disabled":35,"type":36}," The positional version, because JavaScript requires optional parameters to appear positionally after required ones, which destructuring cannot express",[28,29473,29475,29477],{"className":29474},[31],[33,29476],{"disabled":35,"type":36}," Neither — with six parameters you should always use an array and access by index",[28,29479,29481,29483],{"className":29480},[31],[33,29482],{"disabled":35,"type":36}," 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",[66,29485,29486,29488,29493],{},[69,29487,71],{},[73,29489,29490,29492],{},[76,29491,78],{}," 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",[73,29494,29495,355,29497,29499,29500,29503,29504,29507],{},[76,29496,84],{},[76,29498,27040],{}," Once a function has more than two or three parameters, especially with several optional ones, positional calls become error-prone (",[39,29501,29502],{},"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 (",[39,29505,29506],{},"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.",[2107,29509,29510],{},"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":264,"searchDepth":286,"depth":286,"links":29512},[29513,29514,29515,29516,29517,29518,29519,29520,29521,29523,29524,29525,29526,29527,29528,29529,29530,29531,29532,29533],{"id":26820,"depth":296,"text":26821},{"id":12736,"depth":296,"text":12737},{"id":27063,"depth":296,"text":27064},{"id":13031,"depth":296,"text":13032},{"id":13180,"depth":296,"text":13181},{"id":13320,"depth":296,"text":13321},{"id":13527,"depth":296,"text":13528},{"id":13728,"depth":296,"text":13729},{"id":27881,"depth":296,"text":29522},"Q9. In const [a, ...b] = arr; and const c = [...arr, 99];, what role does the ... play in each statement, respectively?",{"id":27953,"depth":296,"text":27954},{"id":14223,"depth":296,"text":14224},{"id":28198,"depth":296,"text":28199},{"id":28323,"depth":296,"text":28324},{"id":14773,"depth":296,"text":14774},{"id":18416,"depth":296,"text":18417},{"id":15130,"depth":296,"text":15131},{"id":15310,"depth":296,"text":15311},{"id":18979,"depth":296,"text":18980},{"id":26305,"depth":296,"text":26306},{"id":29342,"depth":296,"text":29343},{},"\u002Fjs\u002F09-destructuring-and-spread",{"title":26810,"description":264},"js\u002F09-destructuring-and-spread","Fj5PF4LLft8vgxhAC9OGx5Tew253WYpxgNT39cXKEts",{"id":29540,"title":29541,"body":29542,"description":264,"extension":2144,"meta":34143,"navigation":35,"path":34144,"seo":34145,"stem":34146,"__hash__":34147},"content\u002Fjs\u002F10-classes-and-prototypes.md","10 — Classes & Prototypes",{"type":8,"value":29543,"toc":34119},[29544,29547,29670,29910,30117,30425,30687,30920,31184,31411,31610,31806,32009,32205,32459,32637,32849,33142,33414,33637,34023,34116],[11,29545,29541],{"id":29546},"_10-classes-prototypes",[15,29548,29549,29556,29621],{},[18,29550,29552,29553,29555],{"id":29551},"q1-which-statement-best-describes-the-relationship-between-javascript-class-syntax-and-prototypes","Q1. Which statement best describes the relationship between JavaScript ",[39,29554,1468],{}," syntax and prototypes?",[23,29557,29559,29583,29594,29605],{"className":29558},[26],[28,29560,29562,355,29564,29567,29568,29571,29572,29575,29576,29579,29580],{"className":29561},[31],[33,29563],{"disabled":35,"type":36},[39,29565,29566],{},"class Foo {}"," is just syntactic sugar — it creates an ordinary function ",[39,29569,29570],{},"Foo"," whose ",[39,29573,29574],{},".prototype"," object holds the instance methods, the same underlying mechanism as manually writing ",[39,29577,29578],{},"function Foo() {}"," and assigning methods onto ",[39,29581,29582],{},"Foo.prototype",[28,29584,29586,355,29588,29590,29591,29593],{"className":29585},[31],[33,29587],{"disabled":35,"type":36},[39,29589,1468],{}," introduces a completely new object model separate from prototypes — classes do not have a ",[39,29592,29574],{}," property at all",[28,29595,29597,355,29599,29601,29602,29604],{"className":29596},[31],[33,29598],{"disabled":35,"type":36},[39,29600,1468],{}," methods are copied onto every instance individually when ",[39,29603,2689],{}," is called, so no prototype chain lookup is involved",[28,29606,29608,355,29610,29612,29613,186,29615,29617,29618,29620],{"className":29607},[31],[33,29609],{"disabled":35,"type":36},[39,29611,1468],{}," syntax only works for built-in types like ",[39,29614,88],{},[39,29616,2672],{},"; user-defined types must still use ",[39,29619,275],{}," constructors",[66,29622,29623,29625,29639],{},[69,29624,71],{},[73,29626,29627,3459,29629,29567,29631,29571,29633,29575,29635,29579,29637],{},[76,29628,78],{},[39,29630,29566],{},[39,29632,29570],{},[39,29634,29574],{},[39,29636,29578],{},[39,29638,29582],{},[73,29640,29641,29643,29644,29646,29647,29650,29651,29653,29654,29656,29657,29660,29661,29663,29664,29666,29667,29669],{},[76,29642,84],{}," Under the hood, a ",[39,29645,1468],{}," declaration still produces a function value (",[39,29648,29649],{},"typeof Foo === \"function\"","), and every method written in the class body is installed onto ",[39,29652,29582],{},", exactly like the pre-ES6 pattern of ",[39,29655,29578],{}," plus ",[39,29658,29659],{},"Foo.prototype.method = ...",". Classes add stricter syntax (mandatory ",[39,29662,2689],{},", real inheritance via ",[39,29665,1502],{},", TDZ, always-strict-mode bodies), but the runtime object model — functions with a ",[39,29668,29574],{}," object shared by instances — is unchanged. B, C, and D all describe a different object model than the one JS actually uses.",[15,29671,29672,29674,29810,29866],{"language":247},[18,29673,12737],{"id":12736},[257,29675,29676],{"language":247},[260,29677,29679],{"className":262,"code":29678,"language":247,"meta":264,"style":264},"class Animal {\n  speak() {\n    return \"...\";\n  }\n}\n\nfunction LegacyAnimal() {}\nLegacyAnimal.prototype.speak = function () {\n  return \"...\";\n};\n\nconsole.log(typeof Animal, typeof Animal.prototype.speak);\nconsole.log(typeof LegacyAnimal, typeof LegacyAnimal.prototype.speak);\n",[39,29680,29681,29690,29697,29706,29710,29714,29718,29727,29747,29755,29759,29763,29787],{"__ignoreMap":264},[268,29682,29683,29685,29688],{"class":270,"line":271},[268,29684,1468],{"class":274},[268,29686,29687],{"class":278}," Animal",[268,29689,9914],{"class":282},[268,29691,29692,29695],{"class":270,"line":286},[268,29693,29694],{"class":278},"  speak",[268,29696,283],{"class":282},[268,29698,29699,29701,29704],{"class":270,"line":296},[268,29700,9871],{"class":274},[268,29702,29703],{"class":289}," \"...\"",[268,29705,293],{"class":282},[268,29707,29708],{"class":270,"line":311},[268,29709,1948],{"class":282},[268,29711,29712],{"class":270,"line":788},[268,29713,314],{"class":282},[268,29715,29716],{"class":270,"line":1951},[268,29717,5033],{"emptyLinePlaceholder":35},[268,29719,29720,29722,29725],{"class":270,"line":8955},[268,29721,275],{"class":274},[268,29723,29724],{"class":278}," LegacyAnimal",[268,29726,3682],{"class":282},[268,29728,29729,29732,29734,29736,29738,29741,29743,29745],{"class":270,"line":8966},[268,29730,29731],{"class":305},"LegacyAnimal",[268,29733,462],{"class":282},[268,29735,12070],{"class":305},[268,29737,462],{"class":282},[268,29739,29740],{"class":278},"speak",[268,29742,616],{"class":274},[268,29744,12080],{"class":274},[268,29746,12922],{"class":282},[268,29748,29749,29751,29753],{"class":270,"line":8974},[268,29750,1240],{"class":274},[268,29752,29703],{"class":289},[268,29754,293],{"class":282},[268,29756,29757],{"class":270,"line":8985},[268,29758,12940],{"class":282},[268,29760,29761],{"class":270,"line":8990},[268,29762,5033],{"emptyLinePlaceholder":35},[268,29764,29765,29767,29769,29771,29773,29776,29778,29780,29782,29784],{"class":270,"line":8997},[268,29766,1353],{"class":282},[268,29768,1356],{"class":278},[268,29770,622],{"class":282},[268,29772,1361],{"class":274},[268,29774,29775],{"class":282}," Animal, ",[268,29777,1361],{"class":274},[268,29779,29687],{"class":305},[268,29781,462],{"class":282},[268,29783,12070],{"class":305},[268,29785,29786],{"class":282},".speak);\n",[268,29788,29789,29791,29793,29795,29797,29800,29802,29804,29806,29808],{"class":270,"line":9002},[268,29790,1353],{"class":282},[268,29792,1356],{"class":278},[268,29794,622],{"class":282},[268,29796,1361],{"class":274},[268,29798,29799],{"class":282}," LegacyAnimal, ",[268,29801,1361],{"class":274},[268,29803,29724],{"class":305},[268,29805,462],{"class":282},[268,29807,12070],{"class":305},[268,29809,29786],{"class":282},[23,29811,29813,29828,29846,29857],{"className":29812},[26],[28,29814,29816,355,29818,1133,29821,29824,29825,29827],{"className":29815},[31],[33,29817],{"disabled":35,"type":36},[39,29819,29820],{},"\"function\" \"undefined\"",[39,29822,29823],{},"\"function\" \"function\""," — only the legacy pattern actually attaches ",[39,29826,29740],{}," onto the prototype",[28,29829,29831,355,29833,1133,29835,10954,29837,29839,29840,29842,29843,29845],{"className":29830},[31],[33,29832],{"disabled":35,"type":36},[39,29834,29823],{},[39,29836,29823],{},[39,29838,1468],{}," declaration produces an ordinary function value whose methods are installed on ",[39,29841,29574],{},", exactly like manually building a constructor function and assigning to ",[39,29844,29574],{}," by hand",[28,29847,29849,355,29851,1133,29854,29856],{"className":29848},[31],[33,29850],{"disabled":35,"type":36},[39,29852,29853],{},"\"object\" \"function\"",[39,29855,29823],{}," — classes are plain objects, not functions",[28,29858,29860,355,29862,1133,29864],{"className":29859},[31],[33,29861],{"disabled":35,"type":36},[39,29863,29823],{},[39,29865,29853],{},[66,29867,29868,29870,29884],{},[69,29869,71],{},[73,29871,29872,1727,29874,1133,29876,10954,29878,29839,29880,29842,29882,29845],{},[76,29873,78],{},[39,29875,29823],{},[39,29877,29823],{},[39,29879,1468],{},[39,29881,29574],{},[39,29883,29574],{},[73,29885,29886,355,29888,29890,29891,29894,29895,137,29897,29899,29900,29903,29904,23941,29907,29909],{},[76,29887,84],{},[76,29889,930],{}," both blocks log identically, which is exactly the point — ",[39,29892,29893],{},"Animal"," is a function just like ",[39,29896,29731],{},[39,29898,29740],{}," lives on ",[39,29901,29902],{},"Animal.prototype"," just like it lives on ",[39,29905,29906],{},"LegacyAnimal.prototype",[39,29908,1468],{}," keyword is a more readable, safer syntax for building this same function-plus-prototype structure; it doesn't create a fundamentally different kind of value. Options C and D invent a distinction (class as \"object\") that doesn't exist in JS.",[15,29911,29912,29914,30023,30074],{"language":247},[18,29913,27064],{"id":27063},[257,29915,29916],{"language":247},[260,29917,29919],{"className":262,"code":29918,"language":247,"meta":264,"style":264},"const p = new Point3D(1, 2, 3);\n\nclass Point3D {\n  constructor(x, y, z) {\n    this.x = x;\n    this.y = y;\n    this.z = z;\n  }\n}\n",[39,29920,29921,29949,29953,29961,29980,29991,30003,30015,30019],{"__ignoreMap":264},[268,29922,29923,29925,29928,29930,29932,29935,29937,29939,29941,29943,29945,29947],{"class":270,"line":271},[268,29924,243],{"class":274},[268,29926,29927],{"class":305}," p",[268,29929,616],{"class":274},[268,29931,11370],{"class":274},[268,29933,29934],{"class":278}," Point3D",[268,29936,622],{"class":282},[268,29938,2255],{"class":305},[268,29940,42],{"class":282},[268,29942,2258],{"class":305},[268,29944,42],{"class":282},[268,29946,3423],{"class":305},[268,29948,628],{"class":282},[268,29950,29951],{"class":270,"line":286},[268,29952,5033],{"emptyLinePlaceholder":35},[268,29954,29955,29957,29959],{"class":270,"line":296},[268,29956,1468],{"class":274},[268,29958,29934],{"class":278},[268,29960,9914],{"class":282},[268,29962,29963,29966,29968,29970,29972,29974,29976,29978],{"class":270,"line":311},[268,29964,29965],{"class":274},"  constructor",[268,29967,622],{"class":282},[268,29969,2403],{"class":1222},[268,29971,42],{"class":282},[268,29973,2909],{"class":1222},[268,29975,42],{"class":282},[268,29977,28015],{"class":1222},[268,29979,1235],{"class":282},[268,29981,29982,29984,29987,29989],{"class":270,"line":788},[268,29983,22057],{"class":305},[268,29985,29986],{"class":282},".x ",[268,29988,302],{"class":274},[268,29990,3547],{"class":282},[268,29992,29993,29995,29998,30000],{"class":270,"line":1951},[268,29994,22057],{"class":305},[268,29996,29997],{"class":282},".y ",[268,29999,302],{"class":274},[268,30001,30002],{"class":282}," y;\n",[268,30004,30005,30007,30010,30012],{"class":270,"line":8955},[268,30006,22057],{"class":305},[268,30008,30009],{"class":282},".z ",[268,30011,302],{"class":274},[268,30013,30014],{"class":282}," z;\n",[268,30016,30017],{"class":270,"line":8966},[268,30018,1948],{"class":282},[268,30020,30021],{"class":270,"line":8974},[268,30022,314],{"class":282},[23,30024,30026,30032,30050,30066],{"className":30025},[26],[28,30027,30029,30031],{"className":30028},[31],[33,30030],{"disabled":35,"type":36}," It works fine — classes, like function declarations, are fully hoisted with their implementation",[28,30033,30035,30037,30038,30040,30041,30043,30044,30047,30048],{"className":30034},[31],[33,30036],{"disabled":35,"type":36}," It logs ",[39,30039,833],{}," when ",[39,30042,73],{}," is later inspected, because ",[39,30045,30046],{},"Point3D"," is hoisted but left uninitialized like a ",[39,30049,1440],{},[28,30051,30053,355,30055,30058,30059,30061,30062,446,30064],{"className":30052},[31],[33,30054],{"disabled":35,"type":36},[39,30056,30057],{},"ReferenceError: Cannot access 'Point3D' before initialization"," — the class binding is hoisted but stays in the temporal dead zone until the ",[39,30060,1468],{}," statement itself is evaluated, just like ",[39,30063,240],{},[39,30065,243],{},[28,30067,30069,355,30071],{"className":30068},[31],[33,30070],{"disabled":35,"type":36},[39,30072,30073],{},"TypeError: Point3D is not a constructor",[66,30075,30076,30078,30090],{},[69,30077,71],{},[73,30079,30080,1004,30082,30058,30084,30061,30086,446,30088],{},[76,30081,78],{},[39,30083,30057],{},[39,30085,1468],{},[39,30087,240],{},[39,30089,243],{},[73,30091,30092,355,30094,30096,30097,30099,30100,30102,30103,30105,30106,446,30108,30110,30111,30113,30114,30116],{},[76,30093,84],{},[76,30095,365],{}," unlike function declarations, ",[39,30098,1468],{}," declarations are not hoisted with their implementation ready to use. The name ",[39,30101,30046],{}," is hoisted to the top of its scope but remains in the temporal dead zone (TDZ) until the ",[39,30104,1468],{}," statement's line actually executes, exactly like ",[39,30107,240],{},[39,30109,243],{},". Referencing it any earlier — even just to call ",[39,30112,2689],{}," on it — throws a ",[39,30115,815],{},". This is a common trap for developers used to function declarations being freely callable before their textual position (see quiz 05).",[15,30118,30119,30121,30307,30359],{"language":247},[18,30120,13032],{"id":13031},[257,30122,30123],{"language":247},[260,30124,30126],{"className":262,"code":30125,"language":247,"meta":264,"style":264},"class Point {\n  constructor(x, y) {\n    this.x = x;\n    this.y = y;\n  }\n  distanceFromOrigin() {\n    return Math.sqrt(this.x ** 2 + this.y ** 2);\n  }\n}\n\nconst p = new Point(3, 4);\nconsole.log(Object.getPrototypeOf(p) === Point.prototype);\nconsole.log(p.hasOwnProperty(\"distanceFromOrigin\"));\nconsole.log(p.hasOwnProperty(\"x\"));\n",[39,30127,30128,30137,30151,30161,30171,30175,30182,30215,30219,30223,30227,30249,30273,30291],{"__ignoreMap":264},[268,30129,30130,30132,30135],{"class":270,"line":271},[268,30131,1468],{"class":274},[268,30133,30134],{"class":278}," Point",[268,30136,9914],{"class":282},[268,30138,30139,30141,30143,30145,30147,30149],{"class":270,"line":286},[268,30140,29965],{"class":274},[268,30142,622],{"class":282},[268,30144,2403],{"class":1222},[268,30146,42],{"class":282},[268,30148,2909],{"class":1222},[268,30150,1235],{"class":282},[268,30152,30153,30155,30157,30159],{"class":270,"line":296},[268,30154,22057],{"class":305},[268,30156,29986],{"class":282},[268,30158,302],{"class":274},[268,30160,3547],{"class":282},[268,30162,30163,30165,30167,30169],{"class":270,"line":311},[268,30164,22057],{"class":305},[268,30166,29997],{"class":282},[268,30168,302],{"class":274},[268,30170,30002],{"class":282},[268,30172,30173],{"class":270,"line":788},[268,30174,1948],{"class":282},[268,30176,30177,30180],{"class":270,"line":1951},[268,30178,30179],{"class":278},"  distanceFromOrigin",[268,30181,283],{"class":282},[268,30183,30184,30186,30189,30192,30194,30196,30198,30200,30202,30204,30207,30209,30211,30213],{"class":270,"line":8955},[268,30185,9871],{"class":274},[268,30187,30188],{"class":282}," Math.",[268,30190,30191],{"class":278},"sqrt",[268,30193,622],{"class":282},[268,30195,950],{"class":305},[268,30197,29986],{"class":282},[268,30199,6231],{"class":274},[268,30201,2214],{"class":305},[268,30203,3350],{"class":274},[268,30205,30206],{"class":305}," this",[268,30208,29997],{"class":282},[268,30210,6231],{"class":274},[268,30212,2214],{"class":305},[268,30214,628],{"class":282},[268,30216,30217],{"class":270,"line":8966},[268,30218,1948],{"class":282},[268,30220,30221],{"class":270,"line":8974},[268,30222,314],{"class":282},[268,30224,30225],{"class":270,"line":8985},[268,30226,5033],{"emptyLinePlaceholder":35},[268,30228,30229,30231,30233,30235,30237,30239,30241,30243,30245,30247],{"class":270,"line":8990},[268,30230,243],{"class":274},[268,30232,29927],{"class":305},[268,30234,616],{"class":274},[268,30236,11370],{"class":274},[268,30238,30134],{"class":278},[268,30240,622],{"class":282},[268,30242,3423],{"class":305},[268,30244,42],{"class":282},[268,30246,15049],{"class":305},[268,30248,628],{"class":282},[268,30250,30251,30253,30255,30257,30260,30263,30265,30267,30269,30271],{"class":270,"line":8997},[268,30252,1353],{"class":282},[268,30254,1356],{"class":278},[268,30256,19627],{"class":282},[268,30258,30259],{"class":278},"getPrototypeOf",[268,30261,30262],{"class":282},"(p) ",[268,30264,3280],{"class":274},[268,30266,30134],{"class":305},[268,30268,462],{"class":282},[268,30270,12070],{"class":305},[268,30272,628],{"class":282},[268,30274,30275,30277,30279,30282,30284,30286,30289],{"class":270,"line":9002},[268,30276,1353],{"class":282},[268,30278,1356],{"class":278},[268,30280,30281],{"class":282},"(p.",[268,30283,20679],{"class":278},[268,30285,622],{"class":282},[268,30287,30288],{"class":289},"\"distanceFromOrigin\"",[268,30290,4818],{"class":282},[268,30292,30293,30295,30297,30299,30301,30303,30305],{"class":270,"line":14676},[268,30294,1353],{"class":282},[268,30296,1356],{"class":278},[268,30298,30281],{"class":282},[268,30300,20679],{"class":278},[268,30302,622],{"class":282},[268,30304,22248],{"class":289},[268,30306,4818],{"class":282},[23,30308,30310,30321,30332,30343],{"className":30309},[26],[28,30311,30313,355,30315,42,30317,42,30319],{"className":30312},[31],[33,30314],{"disabled":35,"type":36},[39,30316,2185],{},[39,30318,2185],{},[39,30320,2185],{},[28,30322,30324,355,30326,42,30328,42,30330],{"className":30323},[31],[33,30325],{"disabled":35,"type":36},[39,30327,2986],{},[39,30329,2986],{},[39,30331,2185],{},[28,30333,30335,355,30337,42,30339,42,30341],{"className":30334},[31],[33,30336],{"disabled":35,"type":36},[39,30338,2185],{},[39,30340,2986],{},[39,30342,2986],{},[28,30344,30346,355,30348,42,30350,42,30352,30354,30355,30358],{"className":30345},[31],[33,30347],{"disabled":35,"type":36},[39,30349,2185],{},[39,30351,2986],{},[39,30353,2185],{}," — methods defined in a class body live once on the shared prototype, while properties assigned via ",[39,30356,30357],{},"this.x ="," inside the constructor become the instance's own properties",[66,30360,30361,30363,30375],{},[69,30362,71],{},[73,30364,30365,6901,30367,42,30369,42,30371,30354,30373,30358],{},[76,30366,78],{},[39,30368,2185],{},[39,30370,2986],{},[39,30372,2185],{},[39,30374,30357],{},[73,30376,30377,355,30379,30382,30383,30385,30386,30389,30390,30393,30394,30396,30397,30400,30401,30403,30404,30406,30407,3990,30409,30411,30412,3277,30414,186,30416,30418,30419,30421,30422,30424],{},[76,30378,84],{},[39,30380,30381],{},"Object.getPrototypeOf(p) === Point.prototype"," confirms that ",[39,30384,73],{},"'s internal ",[39,30387,30388],{},"[[Prototype]]"," link points to ",[39,30391,30392],{},"Point.prototype",", which is where ",[39,30395,2689],{}," wires it up. ",[39,30398,30399],{},"distanceFromOrigin"," was declared as a class method, so it lives once on ",[39,30402,30392],{}," and is ",[104,30405,95],{}," an own property of ",[39,30408,73],{},[39,30410,20679],{}," correctly reports ",[39,30413,2986],{},[39,30415,2403],{},[39,30417,2909],{},", by contrast, are assigned directly onto ",[39,30420,950],{}," inside the constructor, so they genuinely are own properties of every instance, hence ",[39,30423,2185],{},". This is the standard way to verify that instance methods are shared, not duplicated per instance.",[15,30426,30427,30429,30560,30621],{"language":247},[18,30428,13181],{"id":13180},[257,30430,30431],{"language":247},[260,30432,30434],{"className":262,"code":30433,"language":247,"meta":264,"style":264},"class LivingThing {\n  breathe() {\n    return \"breathing\";\n  }\n}\n\nclass Animal extends LivingThing {}\nclass Dog extends Animal {}\n\nconst rex = new Dog();\nconsole.log(rex.breathe());\nconsole.log(Object.getPrototypeOf(Object.getPrototypeOf(rex)) === Animal.prototype);\n",[39,30435,30436,30445,30452,30461,30465,30469,30473,30487,30500,30504,30519,30533],{"__ignoreMap":264},[268,30437,30438,30440,30443],{"class":270,"line":271},[268,30439,1468],{"class":274},[268,30441,30442],{"class":278}," LivingThing",[268,30444,9914],{"class":282},[268,30446,30447,30450],{"class":270,"line":286},[268,30448,30449],{"class":278},"  breathe",[268,30451,283],{"class":282},[268,30453,30454,30456,30459],{"class":270,"line":296},[268,30455,9871],{"class":274},[268,30457,30458],{"class":289}," \"breathing\"",[268,30460,293],{"class":282},[268,30462,30463],{"class":270,"line":311},[268,30464,1948],{"class":282},[268,30466,30467],{"class":270,"line":788},[268,30468,314],{"class":282},[268,30470,30471],{"class":270,"line":1951},[268,30472,5033],{"emptyLinePlaceholder":35},[268,30474,30475,30477,30479,30482,30484],{"class":270,"line":8955},[268,30476,1468],{"class":274},[268,30478,29687],{"class":278},[268,30480,30481],{"class":274}," extends",[268,30483,30442],{"class":278},[268,30485,30486],{"class":282}," {}\n",[268,30488,30489,30491,30494,30496,30498],{"class":270,"line":8966},[268,30490,1468],{"class":274},[268,30492,30493],{"class":278}," Dog",[268,30495,30481],{"class":274},[268,30497,29687],{"class":278},[268,30499,30486],{"class":282},[268,30501,30502],{"class":270,"line":8974},[268,30503,5033],{"emptyLinePlaceholder":35},[268,30505,30506,30508,30511,30513,30515,30517],{"class":270,"line":8985},[268,30507,243],{"class":274},[268,30509,30510],{"class":305}," rex",[268,30512,616],{"class":274},[268,30514,11370],{"class":274},[268,30516,30493],{"class":278},[268,30518,794],{"class":282},[268,30520,30521,30523,30525,30528,30531],{"class":270,"line":8990},[268,30522,1353],{"class":282},[268,30524,1356],{"class":278},[268,30526,30527],{"class":282},"(rex.",[268,30529,30530],{"class":278},"breathe",[268,30532,8174],{"class":282},[268,30534,30535,30537,30539,30541,30543,30545,30547,30550,30552,30554,30556,30558],{"class":270,"line":8997},[268,30536,1353],{"class":282},[268,30538,1356],{"class":278},[268,30540,19627],{"class":282},[268,30542,30259],{"class":278},[268,30544,19627],{"class":282},[268,30546,30259],{"class":278},[268,30548,30549],{"class":282},"(rex)) ",[268,30551,3280],{"class":274},[268,30553,29687],{"class":305},[268,30555,462],{"class":282},[268,30557,12070],{"class":305},[268,30559,628],{"class":282},[23,30561,30563,30589,30603,30612],{"className":30562},[26],[28,30564,30566,355,30568,1133,30571,3990,30573,30575,30576,99,30579,30581,30582,30584,30585,30588],{"className":30565},[31],[33,30567],{"disabled":35,"type":36},[39,30569,30570],{},"\"breathing\"",[39,30572,2185],{},[39,30574,30530],{}," isn't found on ",[39,30577,30578],{},"Dog.prototype",[39,30580,29902],{},", so the engine keeps walking up the ",[39,30583,30388],{}," chain until it reaches ",[39,30586,30587],{},"LivingThing.prototype",", where the method is finally found",[28,30590,30592,355,30594,2833,30597,30599,30600],{"className":30591},[31],[33,30593],{"disabled":35,"type":36},[39,30595,30596],{},"TypeError: rex.breathe is not a function",[39,30598,30530],{}," is defined two inheritance levels above ",[39,30601,30602],{},"Dog",[28,30604,30606,355,30608,1133,30610],{"className":30605},[31],[33,30607],{"disabled":35,"type":36},[39,30609,30570],{},[39,30611,2986],{},[28,30613,30615,355,30617,1133,30619],{"className":30614},[31],[33,30616],{"disabled":35,"type":36},[39,30618,833],{},[39,30620,2185],{},[66,30622,30623,30625,30643],{},[69,30624,71],{},[73,30626,30627,3459,30629,1133,30631,3990,30633,30575,30635,99,30637,30581,30639,30584,30641,30588],{},[76,30628,78],{},[39,30630,30570],{},[39,30632,2185],{},[39,30634,30530],{},[39,30636,30578],{},[39,30638,29902],{},[39,30640,30388],{},[39,30642,30587],{},[73,30644,30645,30647,30648,30651,30652,30655,30656,3299,30658,5992,30660,3299,30662,5992,30664,3299,30666,30668,30669,3277,30671,830,30674,137,30676,830,30679,30681,30682,30684,30685,462],{},[76,30646,84],{}," Property\u002Fmethod lookup in JS is never limited to an object's own prototype — when ",[39,30649,30650],{},"rex.breathe()"," is called, the engine checks ",[39,30653,30654],{},"rex"," itself (no ",[39,30657,30530],{},[39,30659,30578],{},[39,30661,30530],{},[39,30663,29902],{},[39,30665,30530],{},[39,30667,30587],{}," (found), and stops there. This walk continues until a match is found or the chain terminates at ",[39,30670,2650],{},[39,30672,30673],{},"Object.getPrototypeOf(rex)",[39,30675,30578],{},[39,30677,30678],{},"Object.getPrototypeOf(Dog.prototype)",[39,30680,29902],{}," — exactly what ",[39,30683,1502],{}," wires up — so the equality check is ",[39,30686,2185],{},[15,30688,30689,30691,30826,30867],{"language":247},[18,30690,24128],{"id":24127},[257,30692,30693],{"language":247},[260,30694,30696],{"className":262,"code":30695,"language":247,"meta":264,"style":264},"class Vehicle {\n  constructor(make) {\n    this.make = make;\n  }\n}\n\nclass Car extends Vehicle {\n  constructor(make, model) {\n    this.model = model;\n    super(make);\n  }\n}\n\nconst c = new Car(\"Toyota\", \"Corolla\");\n",[39,30697,30698,30707,30718,30730,30734,30738,30742,30755,30770,30782,30790,30794,30798,30802],{"__ignoreMap":264},[268,30699,30700,30702,30705],{"class":270,"line":271},[268,30701,1468],{"class":274},[268,30703,30704],{"class":278}," Vehicle",[268,30706,9914],{"class":282},[268,30708,30709,30711,30713,30716],{"class":270,"line":286},[268,30710,29965],{"class":274},[268,30712,622],{"class":282},[268,30714,30715],{"class":1222},"make",[268,30717,1235],{"class":282},[268,30719,30720,30722,30725,30727],{"class":270,"line":296},[268,30721,22057],{"class":305},[268,30723,30724],{"class":282},".make ",[268,30726,302],{"class":274},[268,30728,30729],{"class":282}," make;\n",[268,30731,30732],{"class":270,"line":311},[268,30733,1948],{"class":282},[268,30735,30736],{"class":270,"line":788},[268,30737,314],{"class":282},[268,30739,30740],{"class":270,"line":1951},[268,30741,5033],{"emptyLinePlaceholder":35},[268,30743,30744,30746,30749,30751,30753],{"class":270,"line":8955},[268,30745,1468],{"class":274},[268,30747,30748],{"class":278}," Car",[268,30750,30481],{"class":274},[268,30752,30704],{"class":278},[268,30754,9914],{"class":282},[268,30756,30757,30759,30761,30763,30765,30768],{"class":270,"line":8966},[268,30758,29965],{"class":274},[268,30760,622],{"class":282},[268,30762,30715],{"class":1222},[268,30764,42],{"class":282},[268,30766,30767],{"class":1222},"model",[268,30769,1235],{"class":282},[268,30771,30772,30774,30777,30779],{"class":270,"line":8974},[268,30773,22057],{"class":305},[268,30775,30776],{"class":282},".model ",[268,30778,302],{"class":274},[268,30780,30781],{"class":282}," model;\n",[268,30783,30784,30787],{"class":270,"line":8985},[268,30785,30786],{"class":305},"    super",[268,30788,30789],{"class":282},"(make);\n",[268,30791,30792],{"class":270,"line":8990},[268,30793,1948],{"class":282},[268,30795,30796],{"class":270,"line":8997},[268,30797,314],{"class":282},[268,30799,30800],{"class":270,"line":9002},[268,30801,5033],{"emptyLinePlaceholder":35},[268,30803,30804,30806,30808,30810,30812,30814,30816,30819,30821,30824],{"class":270,"line":14676},[268,30805,243],{"class":274},[268,30807,16389],{"class":305},[268,30809,616],{"class":274},[268,30811,11370],{"class":274},[268,30813,30748],{"class":278},[268,30815,622],{"class":282},[268,30817,30818],{"class":289},"\"Toyota\"",[268,30820,42],{"class":282},[268,30822,30823],{"class":289},"\"Corolla\"",[268,30825,628],{"class":282},[23,30827,30829,30840,30848,30856],{"className":30828},[26],[28,30830,30832,30834,30835,186,30837,30839],{"className":30831},[31],[33,30833],{"disabled":35,"type":36}," It creates the car normally, with both ",[39,30836,30715],{},[39,30838,30767],{}," set",[28,30841,30843,355,30845],{"className":30842},[31],[33,30844],{"disabled":35,"type":36},[39,30846,30847],{},"ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor",[28,30849,30851,355,30853],{"className":30850},[31],[33,30852],{"disabled":35,"type":36},[39,30854,30855],{},"TypeError: Cannot set property 'model' of undefined",[28,30857,30859,30861,30862,30864,30865],{"className":30858},[31],[33,30860],{"disabled":35,"type":36}," It works, but ",[39,30863,30715],{}," ends up ",[39,30866,833],{},[66,30868,30869,30871,30877],{},[69,30870,71],{},[73,30872,30873,1727,30875],{},[76,30874,78],{},[39,30876,30847],{},[73,30878,30879,355,30881,30883,30884,30886,30887,30890,30891,30894,30895,355,30898,30900,30901,30904,30905,30907,30908,30910,30911,30913,30914,30916,30917,30919],{},[76,30880,84],{},[76,30882,582],{}," in a derived class, ",[39,30885,950],{}," doesn't exist until ",[39,30888,30889],{},"super()"," has run — the parent constructor is what actually allocates and initializes the object. ",[39,30892,30893],{},"Car","'s constructor tries to write ",[39,30896,30897],{},"this.model = model",[104,30899,11314],{}," calling ",[39,30902,30903],{},"super(make)",", so it touches ",[39,30906,950],{}," while it's still uninitialized, and the engine throws immediately. The fix is to call ",[39,30909,30903],{}," first and only then assign ",[39,30912,30897],{},". This rule has no equivalent in base (non-",[39,30915,1502],{},") classes, where ",[39,30918,950],{}," is available from the start of the constructor.",[15,30921,30922,30924,31083,31128],{"language":247},[18,30923,13528],{"id":13527},[257,30925,30926],{"language":247},[260,30927,30929],{"className":262,"code":30928,"language":247,"meta":264,"style":264},"class AnimalBase {\n  constructor(name) {\n    this.name = name;\n  }\n  speak() {\n    return `${this.name} makes a sound`;\n  }\n}\n\nclass Cat extends AnimalBase {\n  speak() {\n    return `${this.name} meows`;\n  }\n}\n\nconst c = new Cat(\"Whiskers\");\nconsole.log(c.name, c.speak());\n",[39,30930,30931,30940,30950,30962,30966,30972,30989,30993,30997,31001,31014,31020,31037,31041,31045,31049,31069],{"__ignoreMap":264},[268,30932,30933,30935,30938],{"class":270,"line":271},[268,30934,1468],{"class":274},[268,30936,30937],{"class":278}," AnimalBase",[268,30939,9914],{"class":282},[268,30941,30942,30944,30946,30948],{"class":270,"line":286},[268,30943,29965],{"class":274},[268,30945,622],{"class":282},[268,30947,14605],{"class":1222},[268,30949,1235],{"class":282},[268,30951,30952,30954,30957,30959],{"class":270,"line":296},[268,30953,22057],{"class":305},[268,30955,30956],{"class":282},".name ",[268,30958,302],{"class":274},[268,30960,30961],{"class":282}," name;\n",[268,30963,30964],{"class":270,"line":311},[268,30965,1948],{"class":282},[268,30967,30968,30970],{"class":270,"line":788},[268,30969,29694],{"class":278},[268,30971,283],{"class":282},[268,30973,30974,30976,30978,30980,30982,30984,30987],{"class":270,"line":1951},[268,30975,9871],{"class":274},[268,30977,14262],{"class":289},[268,30979,950],{"class":305},[268,30981,462],{"class":289},[268,30983,14605],{"class":282},[268,30985,30986],{"class":289},"} makes a sound`",[268,30988,293],{"class":282},[268,30990,30991],{"class":270,"line":8955},[268,30992,1948],{"class":282},[268,30994,30995],{"class":270,"line":8966},[268,30996,314],{"class":282},[268,30998,30999],{"class":270,"line":8974},[268,31000,5033],{"emptyLinePlaceholder":35},[268,31002,31003,31005,31008,31010,31012],{"class":270,"line":8985},[268,31004,1468],{"class":274},[268,31006,31007],{"class":278}," Cat",[268,31009,30481],{"class":274},[268,31011,30937],{"class":278},[268,31013,9914],{"class":282},[268,31015,31016,31018],{"class":270,"line":8990},[268,31017,29694],{"class":278},[268,31019,283],{"class":282},[268,31021,31022,31024,31026,31028,31030,31032,31035],{"class":270,"line":8997},[268,31023,9871],{"class":274},[268,31025,14262],{"class":289},[268,31027,950],{"class":305},[268,31029,462],{"class":289},[268,31031,14605],{"class":282},[268,31033,31034],{"class":289},"} meows`",[268,31036,293],{"class":282},[268,31038,31039],{"class":270,"line":9002},[268,31040,1948],{"class":282},[268,31042,31043],{"class":270,"line":14676},[268,31044,314],{"class":282},[268,31046,31047],{"class":270,"line":14681},[268,31048,5033],{"emptyLinePlaceholder":35},[268,31050,31052,31054,31056,31058,31060,31062,31064,31067],{"class":270,"line":31051},16,[268,31053,243],{"class":274},[268,31055,16389],{"class":305},[268,31057,616],{"class":274},[268,31059,11370],{"class":274},[268,31061,31007],{"class":278},[268,31063,622],{"class":282},[268,31065,31066],{"class":289},"\"Whiskers\"",[268,31068,628],{"class":282},[268,31070,31072,31074,31076,31079,31081],{"class":270,"line":31071},17,[268,31073,1353],{"class":282},[268,31075,1356],{"class":278},[268,31077,31078],{"class":282},"(c.name, c.",[268,31080,29740],{"class":278},[268,31082,8174],{"class":282},[23,31084,31086,31098,31106,31119],{"className":31085},[26],[28,31087,31089,355,31091,31094,31095,31097],{"className":31088},[31],[33,31090],{"disabled":35,"type":36},[39,31092,31093],{},"undefined \"undefined meows\""," — without an explicit constructor, ",[39,31096,14605],{}," never gets assigned",[28,31099,31101,355,31103],{"className":31100},[31],[33,31102],{"disabled":35,"type":36},[39,31104,31105],{},"TypeError: Cannot read properties of undefined",[28,31107,31109,355,31111,31114,31115,31118],{"className":31108},[31],[33,31110],{"disabled":35,"type":36},[39,31112,31113],{},"\"Whiskers\" \"Whiskers meows\""," — omitting the constructor doesn't skip initialization; JS auto-generates ",[39,31116,31117],{},"constructor(...args) { super(...args); }"," for any subclass that doesn't define its own, forwarding every argument straight to the parent constructor",[28,31120,31122,355,31124,31127],{"className":31121},[31],[33,31123],{"disabled":35,"type":36},[39,31125,31126],{},"\"Whiskers\" \"Whiskers makes a sound\""," — subclass method overrides only apply if a constructor is explicitly defined",[66,31129,31130,31132,31140],{},[69,31131,71],{},[73,31133,31134,1004,31136,31114,31138,31118],{},[76,31135,78],{},[39,31137,31113],{},[39,31139,31117],{},[73,31141,31142,355,31144,31147,31148,31150,31151,31154,31155,31158,31159,31162,31163,31165,31166,31169,31170,31172,31173,31176,31177,31179,31180,31183],{},[76,31143,84],{},[39,31145,31146],{},"Cat"," has no explicit ",[39,31149,23189],{},", so the spec supplies a default one that simply forwards all arguments to ",[39,31152,31153],{},"super",". That means ",[39,31156,31157],{},"new Cat(\"Whiskers\")"," still runs ",[39,31160,31161],{},"AnimalBase","'s constructor with ",[39,31164,31066],{},", correctly setting ",[39,31167,31168],{},"this.name",". Method overriding is completely independent of whether a constructor was written — ",[39,31171,29740],{}," resolves to ",[39,31174,31175],{},"Cat.prototype.speak"," via normal prototype lookup regardless, so the answer combines the parent-initialized ",[39,31178,14605],{}," with the overridden ",[39,31181,31182],{},"meows"," behavior.",[15,31185,31186,31188,31300,31362],{"language":247},[18,31187,13729],{"id":13728},[257,31189,31190],{"language":247},[260,31191,31193],{"className":262,"code":31192,"language":247,"meta":264,"style":264},"class Employee {\n  describe() {\n    return \"an employee\";\n  }\n}\n\nclass Manager extends Employee {\n  describe() {\n    return `a manager (${super.describe()})`;\n  }\n}\n\nconsole.log(new Manager().describe());\n",[39,31194,31195,31204,31210,31219,31223,31227,31231,31244,31250,31270,31274,31278,31282],{"__ignoreMap":264},[268,31196,31197,31199,31202],{"class":270,"line":271},[268,31198,1468],{"class":274},[268,31200,31201],{"class":278}," Employee",[268,31203,9914],{"class":282},[268,31205,31206,31208],{"class":270,"line":286},[268,31207,19586],{"class":278},[268,31209,283],{"class":282},[268,31211,31212,31214,31217],{"class":270,"line":296},[268,31213,9871],{"class":274},[268,31215,31216],{"class":289}," \"an employee\"",[268,31218,293],{"class":282},[268,31220,31221],{"class":270,"line":311},[268,31222,1948],{"class":282},[268,31224,31225],{"class":270,"line":788},[268,31226,314],{"class":282},[268,31228,31229],{"class":270,"line":1951},[268,31230,5033],{"emptyLinePlaceholder":35},[268,31232,31233,31235,31238,31240,31242],{"class":270,"line":8955},[268,31234,1468],{"class":274},[268,31236,31237],{"class":278}," Manager",[268,31239,30481],{"class":274},[268,31241,31201],{"class":278},[268,31243,9914],{"class":282},[268,31245,31246,31248],{"class":270,"line":8966},[268,31247,19586],{"class":278},[268,31249,283],{"class":282},[268,31251,31252,31254,31257,31259,31261,31263,31265,31268],{"class":270,"line":8974},[268,31253,9871],{"class":274},[268,31255,31256],{"class":289}," `a manager (${",[268,31258,31153],{"class":305},[268,31260,462],{"class":289},[268,31262,9942],{"class":278},[268,31264,16952],{"class":289},[268,31266,31267],{"class":289},"})`",[268,31269,293],{"class":282},[268,31271,31272],{"class":270,"line":8985},[268,31273,1948],{"class":282},[268,31275,31276],{"class":270,"line":8990},[268,31277,314],{"class":282},[268,31279,31280],{"class":270,"line":8997},[268,31281,5033],{"emptyLinePlaceholder":35},[268,31283,31284,31286,31288,31290,31292,31294,31296,31298],{"class":270,"line":9002},[268,31285,1353],{"class":282},[268,31287,1356],{"class":278},[268,31289,622],{"class":282},[268,31291,2689],{"class":274},[268,31293,31237],{"class":278},[268,31295,19341],{"class":282},[268,31297,9942],{"class":278},[268,31299,8174],{"class":282},[23,31301,31303,31311,31330,31338],{"className":31302},[26],[28,31304,31306,355,31308],{"className":31305},[31],[33,31307],{"disabled":35,"type":36},[39,31309,31310],{},"\"an employee\"",[28,31312,31314,355,31316,3990,31319,31322,31323,31326,31327,31329],{"className":31313},[31],[33,31315],{"disabled":35,"type":36},[39,31317,31318],{},"\"a manager (a manager (an employee))\"",[39,31320,31321],{},"super.describe()"," re-invokes ",[39,31324,31325],{},"Manager","'s own ",[39,31328,9942],{},", causing infinite-looking recursion",[28,31331,31333,355,31335],{"className":31332},[31],[33,31334],{"disabled":35,"type":36},[39,31336,31337],{},"TypeError: super.describe is not a function",[28,31339,31341,355,31343,3990,31346,31348,31349,31351,31352,31355,31356,31358,31359,31361],{"className":31340},[31],[33,31342],{"disabled":35,"type":36},[39,31344,31345],{},"\"a manager (an employee)\"",[39,31347,9942],{}," is overridden in ",[39,31350,31325],{},", shadowing ",[39,31353,31354],{},"Employee","'s version for normal calls, but ",[39,31357,31321],{}," explicitly reaches one level up the prototype chain to invoke ",[39,31360,31354],{},"'s original implementation",[66,31363,31364,31366,31382],{},[69,31365,71],{},[73,31367,31368,6901,31370,3990,31372,31348,31374,31351,31376,31355,31378,31358,31380,31361],{},[76,31369,78],{},[39,31371,31345],{},[39,31373,9942],{},[39,31375,31325],{},[39,31377,31354],{},[39,31379,31321],{},[39,31381,31354],{},[73,31383,31384,31386,31387,31390,31391,31394,31395,31397,31398,31400,31401,8574,31404,31407,31408,31410],{},[76,31385,84],{}," Overriding a method in a subclass shadows the parent's version for ordinary calls (",[39,31388,31389],{},"instance.describe()"," always finds ",[39,31392,31393],{},"Manager.prototype.describe"," first). ",[39,31396,31321],{}," bypasses that shadowing on purpose — it's a special reference that looks up ",[39,31399,9942],{}," starting from ",[39,31402,31403],{},"Employee.prototype",[39,31405,31406],{},"Manager.prototype",", invoking the parent's original implementation without re-entering ",[39,31409,31325],{},"'s override. There's no recursion here at all, ruling out option B.",[15,31412,31413,31415,31517,31561],{"language":247},[18,31414,13927],{"id":13926},[257,31416,31417],{"language":247},[260,31418,31420],{"className":262,"code":31419,"language":247,"meta":264,"style":264},"class MathUtils {\n  static square(n) {\n    return n * n;\n  }\n}\n\nconst m = new MathUtils();\nconsole.log(MathUtils.square(5));\nconsole.log(m.square(5));\n",[39,31421,31422,31431,31445,31455,31459,31463,31467,31482,31500],{"__ignoreMap":264},[268,31423,31424,31426,31429],{"class":270,"line":271},[268,31425,1468],{"class":274},[268,31427,31428],{"class":278}," MathUtils",[268,31430,9914],{"class":282},[268,31432,31433,31436,31439,31441,31443],{"class":270,"line":286},[268,31434,31435],{"class":274},"  static",[268,31437,31438],{"class":278}," square",[268,31440,622],{"class":282},[268,31442,4599],{"class":1222},[268,31444,1235],{"class":282},[268,31446,31447,31449,31451,31453],{"class":270,"line":296},[268,31448,9871],{"class":274},[268,31450,13355],{"class":282},[268,31452,6134],{"class":274},[268,31454,16927],{"class":282},[268,31456,31457],{"class":270,"line":311},[268,31458,1948],{"class":282},[268,31460,31461],{"class":270,"line":788},[268,31462,314],{"class":282},[268,31464,31465],{"class":270,"line":1951},[268,31466,5033],{"emptyLinePlaceholder":35},[268,31468,31469,31471,31474,31476,31478,31480],{"class":270,"line":8955},[268,31470,243],{"class":274},[268,31472,31473],{"class":305}," m",[268,31475,616],{"class":274},[268,31477,11370],{"class":274},[268,31479,31428],{"class":278},[268,31481,794],{"class":282},[268,31483,31484,31486,31488,31491,31494,31496,31498],{"class":270,"line":8966},[268,31485,1353],{"class":282},[268,31487,1356],{"class":278},[268,31489,31490],{"class":282},"(MathUtils.",[268,31492,31493],{"class":278},"square",[268,31495,622],{"class":282},[268,31497,2429],{"class":305},[268,31499,4818],{"class":282},[268,31501,31502,31504,31506,31509,31511,31513,31515],{"class":270,"line":8974},[268,31503,1353],{"class":282},[268,31505,1356],{"class":278},[268,31507,31508],{"class":282},"(m.",[268,31510,31493],{"class":278},[268,31512,622],{"class":282},[268,31514,2429],{"class":305},[268,31516,4818],{"class":282},[23,31518,31520,31535,31544,31552],{"className":31519},[26],[28,31521,31523,355,31525,1133,31528,31531,31532,31534],{"className":31522},[31],[33,31524],{"disabled":35,"type":36},[39,31526,31527],{},"25",[39,31529,31530],{},"TypeError: m.square is not a function"," — static methods are installed directly on the class\u002Fconstructor object itself, never on ",[39,31533,29574],{},", so instances have no access to them at all",[28,31536,31538,355,31540,1133,31542],{"className":31537},[31],[33,31539],{"disabled":35,"type":36},[39,31541,31527],{},[39,31543,31527],{},[28,31545,31547,355,31549,31551],{"className":31546},[31],[33,31548],{"disabled":35,"type":36},[39,31550,827],{}," on the very first line, because a class with only static methods cannot be instantiated",[28,31553,31555,355,31557,1133,31559],{"className":31554},[31],[33,31556],{"disabled":35,"type":36},[39,31558,31527],{},[39,31560,833],{},[66,31562,31563,31565,31575],{},[69,31564,71],{},[73,31566,31567,3459,31569,1133,31571,31531,31573,31534],{},[76,31568,78],{},[39,31570,31527],{},[39,31572,31530],{},[39,31574,29574],{},[73,31576,31577,355,31579,31582,31583,31586,31587,31590,31591,31593,31594,31596,31597,31599,31600,31603,31604,3277,31606,31609],{},[76,31578,84],{},[39,31580,31581],{},"static"," methods and properties belong to the class object (",[39,31584,31585],{},"MathUtils",") itself, not to ",[39,31588,31589],{},"MathUtils.prototype",". Since instance property\u002Fmethod lookup only ever walks the ",[39,31592,30388],{}," chain starting from the instance, and ",[39,31595,31589],{}," is never part of that chain that leads to ",[39,31598,31585],{}," itself, ",[39,31601,31602],{},"m.square"," simply doesn't resolve to anything — calling it throws a ",[39,31605,827],{},[39,31607,31608],{},"MathUtils.square(5)"," works because it's called directly on the class object where the static method actually lives.",[15,31611,31612,31614,31689,31741],{"language":247},[18,31613,17619],{"id":17618},[257,31615,31616],{"language":247},[260,31617,31619],{"className":262,"code":31618,"language":247,"meta":264,"style":264},"class Base {\n  static create() {\n    return \"created via Base.create\";\n  }\n}\n\nclass Derived extends Base {}\n\nconsole.log(Derived.create());\n",[39,31620,31621,31629,31638,31647,31651,31655,31659,31672,31676],{"__ignoreMap":264},[268,31622,31623,31625,31627],{"class":270,"line":271},[268,31624,1468],{"class":274},[268,31626,20590],{"class":278},[268,31628,9914],{"class":282},[268,31630,31631,31633,31636],{"class":270,"line":286},[268,31632,31435],{"class":274},[268,31634,31635],{"class":278}," create",[268,31637,283],{"class":282},[268,31639,31640,31642,31645],{"class":270,"line":296},[268,31641,9871],{"class":274},[268,31643,31644],{"class":289}," \"created via Base.create\"",[268,31646,293],{"class":282},[268,31648,31649],{"class":270,"line":311},[268,31650,1948],{"class":282},[268,31652,31653],{"class":270,"line":788},[268,31654,314],{"class":282},[268,31656,31657],{"class":270,"line":1951},[268,31658,5033],{"emptyLinePlaceholder":35},[268,31660,31661,31663,31666,31668,31670],{"class":270,"line":8955},[268,31662,1468],{"class":274},[268,31664,31665],{"class":278}," Derived",[268,31667,30481],{"class":274},[268,31669,20590],{"class":278},[268,31671,30486],{"class":282},[268,31673,31674],{"class":270,"line":8966},[268,31675,5033],{"emptyLinePlaceholder":35},[268,31677,31678,31680,31682,31685,31687],{"class":270,"line":8974},[268,31679,1353],{"class":282},[268,31681,1356],{"class":278},[268,31683,31684],{"class":282},"(Derived.",[268,31686,20628],{"class":278},[268,31688,8174],{"class":282},[23,31690,31692,31700,31726,31733],{"className":31691},[26],[28,31693,31695,355,31697],{"className":31694},[31],[33,31696],{"disabled":35,"type":36},[39,31698,31699],{},"TypeError: Derived.create is not a function",[28,31701,31703,355,31705,3990,31708,31710,31711,5425,31714,31716,31717,31720,31721,31723,31724],{"className":31702},[31],[33,31704],{"disabled":35,"type":36},[39,31706,31707],{},"\"created via Base.create\"",[39,31709,1502],{}," links not just ",[39,31712,31713],{},"Derived.prototype",[39,31715,20765],{},", but also ",[39,31718,31719],{},"Derived"," itself to ",[39,31722,20597],{},", so static members are inherited by the subclass too, the same way instance methods are inherited via ",[39,31725,29574],{},[28,31727,31729,355,31731],{"className":31728},[31],[33,31730],{"disabled":35,"type":36},[39,31732,833],{},[28,31734,31736,355,31738],{"className":31735},[31],[33,31737],{"disabled":35,"type":36},[39,31739,31740],{},"ReferenceError: create is not defined",[66,31742,31743,31745,31763],{},[69,31744,71],{},[73,31746,31747,1727,31749,3990,31751,31710,31753,5425,31755,31716,31757,31720,31759,31723,31761],{},[76,31748,78],{},[39,31750,31707],{},[39,31752,1502],{},[39,31754,31713],{},[39,31756,20765],{},[39,31758,31719],{},[39,31760,20597],{},[39,31762,29574],{},[73,31764,31765,355,31767,355,31769,31771,31772,9057,31774,7083,31776,31778,31779,355,31782,31326,31784,7083,31786,31788,31789,31792,31793,31795,31796,31798,31799,31801,31802,31805],{},[76,31766,84],{},[76,31768,930],{},[39,31770,1502],{}," sets up two parallel prototype links: ",[39,31773,31713],{},[39,31775,30388],{},[39,31777,20765],{}," (for instance methods), ",[104,31780,31781],{},"and",[39,31783,31719],{},[39,31785,30388],{},[39,31787,20597],{}," (for static members). So looking up ",[39,31790,31791],{},"Derived.create"," walks from ",[39,31794,31719],{}," up to ",[39,31797,20597],{},", finds the static method there, and it runs successfully. This surprises developers who assume ",[39,31800,31581],{}," members are entirely non-inherited — they're excluded from ",[104,31803,31804],{},"instances",", but not from subclasses.",[15,31807,31808,31812,31934,31972],{"language":247},[18,31809,31811],{"id":31810},"q11-what-happens-when-this-runs","Q11. What happens when this runs?",[257,31813,31814],{"language":247},[260,31815,31817],{"className":262,"code":31816,"language":247,"meta":264,"style":264},"class BankAccount {\n  #balance = 0;\n  deposit(amount) {\n    this.#balance += amount;\n  }\n  get balance() {\n    return this.#balance;\n  }\n}\n\nconst acct = new BankAccount();\nacct.deposit(100);\nconsole.log(acct.#balance);\n",[39,31818,31819,31828,31839,31851,31863,31867,31875,31884,31888,31892,31896,31911,31925],{"__ignoreMap":264},[268,31820,31821,31823,31826],{"class":270,"line":271},[268,31822,1468],{"class":274},[268,31824,31825],{"class":278}," BankAccount",[268,31827,9914],{"class":282},[268,31829,31830,31833,31835,31837],{"class":270,"line":286},[268,31831,31832],{"class":1222},"  #balance",[268,31834,616],{"class":274},[268,31836,5728],{"class":305},[268,31838,293],{"class":282},[268,31840,31841,31844,31846,31849],{"class":270,"line":296},[268,31842,31843],{"class":278},"  deposit",[268,31845,622],{"class":282},[268,31847,31848],{"class":1222},"amount",[268,31850,1235],{"class":282},[268,31852,31853,31855,31858,31860],{"class":270,"line":311},[268,31854,22057],{"class":305},[268,31856,31857],{"class":282},".#balance ",[268,31859,14575],{"class":274},[268,31861,31862],{"class":282}," amount;\n",[268,31864,31865],{"class":270,"line":788},[268,31866,1948],{"class":282},[268,31868,31869,31871,31873],{"class":270,"line":1951},[268,31870,22013],{"class":274},[268,31872,22016],{"class":278},[268,31874,283],{"class":282},[268,31876,31877,31879,31881],{"class":270,"line":8955},[268,31878,9871],{"class":274},[268,31880,30206],{"class":305},[268,31882,31883],{"class":282},".#balance;\n",[268,31885,31886],{"class":270,"line":8966},[268,31887,1948],{"class":282},[268,31889,31890],{"class":270,"line":8974},[268,31891,314],{"class":282},[268,31893,31894],{"class":270,"line":8985},[268,31895,5033],{"emptyLinePlaceholder":35},[268,31897,31898,31900,31903,31905,31907,31909],{"class":270,"line":8990},[268,31899,243],{"class":274},[268,31901,31902],{"class":305}," acct",[268,31904,616],{"class":274},[268,31906,11370],{"class":274},[268,31908,31825],{"class":278},[268,31910,794],{"class":282},[268,31912,31913,31916,31919,31921,31923],{"class":270,"line":8997},[268,31914,31915],{"class":282},"acct.",[268,31917,31918],{"class":278},"deposit",[268,31920,622],{"class":282},[268,31922,13912],{"class":305},[268,31924,628],{"class":282},[268,31926,31927,31929,31931],{"class":270,"line":9002},[268,31928,1353],{"class":282},[268,31930,1356],{"class":278},[268,31932,31933],{"class":282},"(acct.#balance);\n",[23,31935,31937,31944,31951,31964],{"className":31936},[26],[28,31938,31940,3578,31942],{"className":31939},[31],[33,31941],{"disabled":35,"type":36},[39,31943,13912],{},[28,31945,31947,3578,31949],{"className":31946},[31],[33,31948],{"disabled":35,"type":36},[39,31950,833],{},[28,31952,31954,6738,31956,31959,31960,31963],{"className":31953},[31],[33,31955],{"disabled":35,"type":36},[39,31957,31958],{},"SyntaxError: Private field '#balance' must be declared in an enclosing class"," at parse time — nothing in the file executes at all, not even the earlier ",[39,31961,31962],{},"acct.deposit(100)"," call, because the whole script fails to parse before any code runs",[28,31965,31967,6738,31969],{"className":31966},[31],[33,31968],{"disabled":35,"type":36},[39,31970,31971],{},"TypeError: acct.#balance is not accessible outside class BankAccount",[66,31973,31974,31976,31984],{},[69,31975,71],{},[73,31977,31978,10358,31980,31959,31982,31963],{},[76,31979,78],{},[39,31981,31958],{},[39,31983,31962],{},[73,31985,31986,355,31988,31990,31991,31993,31994,31997,31998,32001,32002,32005,32006,32008],{},[76,31987,84],{},[76,31989,582],{}," unlike an unenforced ",[39,31992,22031],{}," naming convention, a true private field (",[39,31995,31996],{},"#balance",") is enforced at the language level. The ",[39,31999,32000],{},".#name"," syntax is only legal lexically inside a class body that declares that exact private name — writing ",[39,32003,32004],{},"acct.#balance"," anywhere else isn't just a runtime access violation, it's not valid syntax at all, so the engine rejects the entire script before executing a single line. This is stricter than a runtime ",[39,32007,827],{}," (option D): the failure happens at parse time, not when the line would run.",[15,32010,32011,32013,32099,32157],{"language":247},[18,32012,14382],{"id":14381},[257,32014,32015],{"language":247},[260,32016,32018],{"className":262,"code":32017,"language":247,"meta":264,"style":264},"class Wallet {\n  _cash = 50;\n  #pin = \"1234\";\n}\n\nconst w = new Wallet();\nconsole.log(w._cash);\nconsole.log(w[\"#pin\"]);\n",[39,32019,32020,32029,32041,32053,32057,32061,32076,32085],{"__ignoreMap":264},[268,32021,32022,32024,32027],{"class":270,"line":271},[268,32023,1468],{"class":274},[268,32025,32026],{"class":278}," Wallet",[268,32028,9914],{"class":282},[268,32030,32031,32034,32036,32039],{"class":270,"line":286},[268,32032,32033],{"class":1222},"  _cash",[268,32035,616],{"class":274},[268,32037,32038],{"class":305}," 50",[268,32040,293],{"class":282},[268,32042,32043,32046,32048,32051],{"class":270,"line":296},[268,32044,32045],{"class":1222},"  #pin",[268,32047,616],{"class":274},[268,32049,32050],{"class":289}," \"1234\"",[268,32052,293],{"class":282},[268,32054,32055],{"class":270,"line":311},[268,32056,314],{"class":282},[268,32058,32059],{"class":270,"line":788},[268,32060,5033],{"emptyLinePlaceholder":35},[268,32062,32063,32065,32068,32070,32072,32074],{"class":270,"line":1951},[268,32064,243],{"class":274},[268,32066,32067],{"class":305}," w",[268,32069,616],{"class":274},[268,32071,11370],{"class":274},[268,32073,32026],{"class":278},[268,32075,794],{"class":282},[268,32077,32078,32080,32082],{"class":270,"line":8955},[268,32079,1353],{"class":282},[268,32081,1356],{"class":278},[268,32083,32084],{"class":282},"(w._cash);\n",[268,32086,32087,32089,32091,32094,32097],{"class":270,"line":8966},[268,32088,1353],{"class":282},[268,32090,1356],{"class":278},[268,32092,32093],{"class":282},"(w[",[268,32095,32096],{"class":289},"\"#pin\"",[268,32098,15180],{"class":282},[23,32100,32102,32114,32123,32131],{"className":32101},[26],[28,32103,32105,355,32107,1133,32110,32113],{"className":32104},[31],[33,32106],{"disabled":35,"type":36},[39,32108,32109],{},"50",[39,32111,32112],{},"1234"," — bracket notation is a valid way to reach private fields from outside a class",[28,32115,32117,355,32119,1133,32121],{"className":32116},[31],[33,32118],{"disabled":35,"type":36},[39,32120,833],{},[39,32122,833],{},[28,32124,32126,1271,32128,32130],{"className":32125},[31],[33,32127],{"disabled":35,"type":36},[39,32129,1274],{}," on the second line",[28,32132,32134,355,32136,1133,32138,3990,32140,32143,32144,32147,32148,32151,32152,32154,32155],{"className":32133},[31],[33,32135],{"disabled":35,"type":36},[39,32137,32109],{},[39,32139,833],{},[39,32141,32142],{},"_cash"," is only a naming convention, so it's freely readable from outside; ",[39,32145,32146],{},"#pin"," is a genuinely private field, and ",[39,32149,32150],{},"w[\"#pin\"]"," doesn't reach it at all — it's just an ordinary bracket lookup for a property literally named the four characters ",[39,32153,32096],{},", which was never set, so it returns ",[39,32156,833],{},[66,32158,32159,32161,32179],{},[69,32160,71],{},[73,32162,32163,6901,32165,1133,32167,3990,32169,32143,32171,32147,32173,32151,32175,32154,32177],{},[76,32164,78],{},[39,32166,32109],{},[39,32168,833],{},[39,32170,32142],{},[39,32172,32146],{},[39,32174,32150],{},[39,32176,32096],{},[39,32178,833],{},[73,32180,32181,355,32183,32185,32186,32188,32189,32192,32193,32195,32196,32198,32199,32201,32202,32204],{},[76,32182,84],{},[76,32184,365],{}," the leading underscore in ",[39,32187,32142],{}," communicates \"please don't touch this from outside,\" but the engine does nothing to enforce it — ",[39,32190,32191],{},"w._cash"," reads it just like any other property. ",[39,32194,32146],{}," is different in kind, not just convention: private fields are never accessible via bracket\u002Fcomputed notation at all, even from inside the class. ",[39,32197,32150],{}," doesn't parse as a private-field access — the string ",[39,32200,32096],{}," is just an ordinary property key, and since no property with that literal name was ever set, the lookup quietly returns ",[39,32203,833],{}," instead of exposing the private value or throwing.",[15,32206,32207,32209,32356,32411],{"language":247},[18,32208,14538],{"id":14537},[257,32210,32211],{"language":247},[260,32212,32214],{"className":262,"code":32213,"language":247,"meta":264,"style":264},"class Rectangle {\n  constructor(width, height) {\n    this.width = width;\n    this.height = height;\n  }\n  get area() {\n    return this.width * this.height;\n  }\n}\n\nconst r = new Rectangle(4, 5);\nconsole.log(r.area);\nr.width = 10;\nconsole.log(r.area);\n",[39,32215,32216,32225,32241,32253,32265,32269,32278,32293,32297,32301,32305,32328,32337,32348],{"__ignoreMap":264},[268,32217,32218,32220,32223],{"class":270,"line":271},[268,32219,1468],{"class":274},[268,32221,32222],{"class":278}," Rectangle",[268,32224,9914],{"class":282},[268,32226,32227,32229,32231,32234,32236,32239],{"class":270,"line":286},[268,32228,29965],{"class":274},[268,32230,622],{"class":282},[268,32232,32233],{"class":1222},"width",[268,32235,42],{"class":282},[268,32237,32238],{"class":1222},"height",[268,32240,1235],{"class":282},[268,32242,32243,32245,32248,32250],{"class":270,"line":296},[268,32244,22057],{"class":305},[268,32246,32247],{"class":282},".width ",[268,32249,302],{"class":274},[268,32251,32252],{"class":282}," width;\n",[268,32254,32255,32257,32260,32262],{"class":270,"line":311},[268,32256,22057],{"class":305},[268,32258,32259],{"class":282},".height ",[268,32261,302],{"class":274},[268,32263,32264],{"class":282}," height;\n",[268,32266,32267],{"class":270,"line":788},[268,32268,1948],{"class":282},[268,32270,32271,32273,32276],{"class":270,"line":1951},[268,32272,22013],{"class":274},[268,32274,32275],{"class":278}," area",[268,32277,283],{"class":282},[268,32279,32280,32282,32284,32286,32288,32290],{"class":270,"line":8955},[268,32281,9871],{"class":274},[268,32283,30206],{"class":305},[268,32285,32247],{"class":282},[268,32287,6134],{"class":274},[268,32289,30206],{"class":305},[268,32291,32292],{"class":282},".height;\n",[268,32294,32295],{"class":270,"line":8966},[268,32296,1948],{"class":282},[268,32298,32299],{"class":270,"line":8974},[268,32300,314],{"class":282},[268,32302,32303],{"class":270,"line":8985},[268,32304,5033],{"emptyLinePlaceholder":35},[268,32306,32307,32309,32312,32314,32316,32318,32320,32322,32324,32326],{"class":270,"line":8990},[268,32308,243],{"class":274},[268,32310,32311],{"class":305}," r",[268,32313,616],{"class":274},[268,32315,11370],{"class":274},[268,32317,32222],{"class":278},[268,32319,622],{"class":282},[268,32321,15049],{"class":305},[268,32323,42],{"class":282},[268,32325,2429],{"class":305},[268,32327,628],{"class":282},[268,32329,32330,32332,32334],{"class":270,"line":8997},[268,32331,1353],{"class":282},[268,32333,1356],{"class":278},[268,32335,32336],{"class":282},"(r.area);\n",[268,32338,32339,32342,32344,32346],{"class":270,"line":9002},[268,32340,32341],{"class":282},"r.width ",[268,32343,302],{"class":274},[268,32345,306],{"class":305},[268,32347,293],{"class":282},[268,32349,32350,32352,32354],{"class":270,"line":14676},[268,32351,1353],{"class":282},[268,32353,1356],{"class":278},[268,32355,32336],{"class":282},[23,32357,32359,32380,32392,32401],{"className":32358},[26],[28,32360,32362,355,32364,1133,32366,32368,32369,32371,32372,32375,32376,446,32378],{"className":32361},[31],[33,32363],{"disabled":35,"type":36},[39,32365,6149],{},[39,32367,32109],{}," — a getter runs its body fresh on every access; nothing caches the earlier result, so once ",[39,32370,32233],{}," changes, the next read of ",[39,32373,32374],{},"area"," recomputes from the current ",[39,32377,32233],{},[39,32379,32238],{},[28,32381,32383,355,32385,1133,32387,3990,32389,32391],{"className":32382},[31],[33,32384],{"disabled":35,"type":36},[39,32386,6149],{},[39,32388,6149],{},[39,32390,32374],{}," is computed once at first access and then cached like a regular property",[28,32393,32395,355,32397,1133,32399],{"className":32394},[31],[33,32396],{"disabled":35,"type":36},[39,32398,3040],{},[39,32400,3040],{},[28,32402,32404,355,32406,1133,32408],{"className":32403},[31],[33,32405],{"disabled":35,"type":36},[39,32407,6149],{},[39,32409,32410],{},"TypeError: Cannot set property 'width'",[66,32412,32413,32415,32431],{},[69,32414,71],{},[73,32416,32417,3459,32419,1133,32421,32368,32423,32371,32425,32375,32427,446,32429],{},[76,32418,78],{},[39,32420,6149],{},[39,32422,32109],{},[39,32424,32233],{},[39,32426,32374],{},[39,32428,32233],{},[39,32430,32238],{},[73,32432,32433,812,32435,32438,32439,32442,32443,32446,32447,32450,32451,32454,32455,32458],{},[76,32434,84],{},[39,32436,32437],{},"get"," accessor in a class is a function that runs every single time ",[39,32440,32441],{},"instance.prop"," is read — it's transparent property syntax over a method call, not a stored value. Nothing about ",[39,32444,32445],{},"r.area"," is memoized, so the first read computes ",[39,32448,32449],{},"4 * 5 = 20",", and after ",[39,32452,32453],{},"r.width = 10",", the second read recomputes ",[39,32456,32457],{},"10 * 5 = 50"," from the current field values. Assuming the result gets cached (option B) is a common but incorrect mental model — that's not how getters work unless you explicitly build caching yourself.",[15,32460,32461,32463,32574,32612],{"language":247},[18,32462,25492],{"id":25491},[257,32464,32465],{"language":247},[260,32466,32468],{"className":262,"code":32467,"language":247,"meta":264,"style":264},"class Temperature {\n  #celsius = 0;\n  get fahrenheit() {\n    return (this.#celsius * 9) \u002F 5 + 32;\n  }\n}\n\nconst t = new Temperature();\nt.fahrenheit = 100;\nconsole.log(t.fahrenheit);\n",[39,32469,32470,32479,32490,32499,32527,32531,32535,32539,32554,32565],{"__ignoreMap":264},[268,32471,32472,32474,32477],{"class":270,"line":271},[268,32473,1468],{"class":274},[268,32475,32476],{"class":278}," Temperature",[268,32478,9914],{"class":282},[268,32480,32481,32484,32486,32488],{"class":270,"line":286},[268,32482,32483],{"class":1222},"  #celsius",[268,32485,616],{"class":274},[268,32487,5728],{"class":305},[268,32489,293],{"class":282},[268,32491,32492,32494,32497],{"class":270,"line":296},[268,32493,22013],{"class":274},[268,32495,32496],{"class":278}," fahrenheit",[268,32498,283],{"class":282},[268,32500,32501,32503,32505,32507,32510,32512,32514,32516,32518,32520,32522,32525],{"class":270,"line":311},[268,32502,9871],{"class":274},[268,32504,2182],{"class":282},[268,32506,950],{"class":305},[268,32508,32509],{"class":282},".#celsius ",[268,32511,6134],{"class":274},[268,32513,6477],{"class":305},[268,32515,6131],{"class":282},[268,32517,446],{"class":274},[268,32519,2387],{"class":305},[268,32521,3350],{"class":274},[268,32523,32524],{"class":305}," 32",[268,32526,293],{"class":282},[268,32528,32529],{"class":270,"line":788},[268,32530,1948],{"class":282},[268,32532,32533],{"class":270,"line":1951},[268,32534,314],{"class":282},[268,32536,32537],{"class":270,"line":8955},[268,32538,5033],{"emptyLinePlaceholder":35},[268,32540,32541,32543,32546,32548,32550,32552],{"class":270,"line":8966},[268,32542,243],{"class":274},[268,32544,32545],{"class":305}," t",[268,32547,616],{"class":274},[268,32549,11370],{"class":274},[268,32551,32476],{"class":278},[268,32553,794],{"class":282},[268,32555,32556,32559,32561,32563],{"class":270,"line":8974},[268,32557,32558],{"class":282},"t.fahrenheit ",[268,32560,302],{"class":274},[268,32562,13821],{"class":305},[268,32564,293],{"class":282},[268,32566,32567,32569,32571],{"class":270,"line":8985},[268,32568,1353],{"class":282},[268,32570,1356],{"class":278},[268,32572,32573],{"class":282},"(t.fahrenheit);\n",[23,32575,32577,32586,32598,32605],{"className":32576},[26],[28,32578,32580,3578,32582,32585],{"className":32579},[31],[33,32581],{"disabled":35,"type":36},[39,32583,32584],{},"32"," — the assignment is silently ignored because there's no setter",[28,32587,32589,355,32591,32594,32595,32597],{"className":32588},[31],[33,32590],{"disabled":35,"type":36},[39,32592,32593],{},"TypeError: Cannot set property fahrenheit of #\u003CTemperature> which has only a getter"," — class bodies (including field initializers and methods) always execute in strict mode, even without a ",[39,32596,254],{}," pragma, so assigning to a getter-only property throws rather than failing silently",[28,32599,32601,3578,32603],{"className":32600},[31],[33,32602],{"disabled":35,"type":36},[39,32604,13912],{},[28,32606,32608,3578,32610],{"className":32607},[31],[33,32609],{"disabled":35,"type":36},[39,32611,3040],{},[66,32613,32614,32616,32624],{},[69,32615,71],{},[73,32617,32618,1727,32620,32594,32622,32597],{},[76,32619,78],{},[39,32621,32593],{},[39,32623,254],{},[73,32625,32626,355,32628,32630,32631,32633,32634,32636],{},[76,32627,84],{},[76,32629,582],{}," JS class bodies are implicitly strict mode, no ",[39,32632,254],{}," needed. In strict mode, assigning to a property that only has a getter (no setter defined) throws a ",[39,32635,827],{}," instead of silently doing nothing. This is a meaningful difference from a plain object literal in a non-strict script, where the same kind of assignment can fail silently — classes fail loudly by default, which is generally the safer behavior for catching bugs early.",[15,32638,32639,32643,32758,32807],{"language":247},[18,32640,32642],{"id":32641},"q15-what-does-this-log-in-order","Q15. What does this log, in order?",[257,32644,32645],{"language":247},[260,32646,32648],{"className":262,"code":32647,"language":247,"meta":264,"style":264},"class Counter {\n  count = this.logStart();\n\n  constructor() {\n    console.log(\"constructor body runs, count =\", this.count);\n  }\n\n  logStart() {\n    console.log(\"field initializer runs\");\n    return 0;\n  }\n}\n\nnew Counter();\n",[39,32649,32650,32659,32674,32678,32684,32702,32706,32710,32717,32730,32738,32742,32746,32750],{"__ignoreMap":264},[268,32651,32652,32654,32657],{"class":270,"line":271},[268,32653,1468],{"class":274},[268,32655,32656],{"class":278}," Counter",[268,32658,9914],{"class":282},[268,32660,32661,32663,32665,32667,32669,32672],{"class":270,"line":286},[268,32662,10123],{"class":1222},[268,32664,616],{"class":274},[268,32666,30206],{"class":305},[268,32668,462],{"class":282},[268,32670,32671],{"class":278},"logStart",[268,32673,794],{"class":282},[268,32675,32676],{"class":270,"line":296},[268,32677,5033],{"emptyLinePlaceholder":35},[268,32679,32680,32682],{"class":270,"line":311},[268,32681,29965],{"class":274},[268,32683,283],{"class":282},[268,32685,32686,32688,32690,32692,32695,32697,32699],{"class":270,"line":788},[268,32687,9707],{"class":282},[268,32689,1356],{"class":278},[268,32691,622],{"class":282},[268,32693,32694],{"class":289},"\"constructor body runs, count =\"",[268,32696,42],{"class":282},[268,32698,950],{"class":305},[268,32700,32701],{"class":282},".count);\n",[268,32703,32704],{"class":270,"line":1951},[268,32705,1948],{"class":282},[268,32707,32708],{"class":270,"line":8955},[268,32709,5033],{"emptyLinePlaceholder":35},[268,32711,32712,32715],{"class":270,"line":8966},[268,32713,32714],{"class":278},"  logStart",[268,32716,283],{"class":282},[268,32718,32719,32721,32723,32725,32728],{"class":270,"line":8974},[268,32720,9707],{"class":282},[268,32722,1356],{"class":278},[268,32724,622],{"class":282},[268,32726,32727],{"class":289},"\"field initializer runs\"",[268,32729,628],{"class":282},[268,32731,32732,32734,32736],{"class":270,"line":8985},[268,32733,9871],{"class":274},[268,32735,5728],{"class":305},[268,32737,293],{"class":282},[268,32739,32740],{"class":270,"line":8990},[268,32741,1948],{"class":282},[268,32743,32744],{"class":270,"line":8997},[268,32745,314],{"class":282},[268,32747,32748],{"class":270,"line":9002},[268,32749,5033],{"emptyLinePlaceholder":35},[268,32751,32752,32754,32756],{"class":270,"line":14676},[268,32753,2689],{"class":274},[268,32755,32656],{"class":278},[268,32757,794],{"class":282},[23,32759,32761,32771,32781,32798],{"className":32760},[26],[28,32762,32764,355,32766,1133,32769],{"className":32763},[31],[33,32765],{"disabled":35,"type":36},[39,32767,32768],{},"\"constructor body runs, count = 0\"",[39,32770,32727],{},[28,32772,32774,355,32776,1133,32778],{"className":32773},[31],[33,32775],{"disabled":35,"type":36},[39,32777,32727],{},[39,32779,32780],{},"\"constructor body runs, count = undefined\"",[28,32782,32784,355,32786,1133,32788,32790,32791,32793,32794,32797],{"className":32783},[31],[33,32785],{"disabled":35,"type":36},[39,32787,32727],{},[39,32789,32768],{}," — public class fields are initialized per-instance before the constructor body executes, so ",[39,32792,10191],{},"'s initializer (and the method call inside it) runs first, and by the time the constructor body logs, ",[39,32795,32796],{},"this.count"," is already set",[28,32799,32801,355,32803,32806],{"className":32800},[31],[33,32802],{"disabled":35,"type":36},[39,32804,32805],{},"TypeError: this.logStart is not a function",", because instance methods aren't available yet during field initialization",[66,32808,32809,32811,32823],{},[69,32810,71],{},[73,32812,32813,1004,32815,1133,32817,32790,32819,32793,32821,32797],{},[76,32814,78],{},[39,32816,32727],{},[39,32818,32768],{},[39,32820,10191],{},[39,32822,32796],{},[73,32824,32825,32827,32828,32830,32831,32833,32834,32836,32837,32839,32840,32843,32844,32846,32847,462],{},[76,32826,84],{}," Public instance fields declared with ",[39,32829,302],{}," at the class body level are set up per-instance as part of construction, and for a base (non-",[39,32832,1502],{},") class that happens ",[104,32835,11314],{}," the explicit constructor body runs. So ",[39,32838,10191],{},"'s initializer executes first — calling ",[39,32841,32842],{},"this.logStart()"," (which is already available on the prototype at that point, ruling out option D) and logging ",[39,32845,32727],{}," — and only afterward does the constructor body run and log the now-initialized ",[39,32848,32796],{},[15,32850,32851,32853,32990,33065],{"language":247},[18,32852,15131],{"id":15130},[257,32854,32855],{"language":247},[260,32856,32858],{"className":262,"code":32857,"language":247,"meta":264,"style":264},"class Shape {\n  constructor() {\n    console.log(this.describe());\n  }\n  describe() {\n    return \"a shape\";\n  }\n}\n\nclass Circle extends Shape {\n  radius = 5;\n  describe() {\n    return `a circle with radius ${this.radius}`;\n  }\n}\n\nnew Circle();\n",[39,32859,32860,32869,32875,32891,32895,32901,32910,32914,32918,32922,32935,32946,32952,32970,32974,32978,32982],{"__ignoreMap":264},[268,32861,32862,32864,32867],{"class":270,"line":271},[268,32863,1468],{"class":274},[268,32865,32866],{"class":278}," Shape",[268,32868,9914],{"class":282},[268,32870,32871,32873],{"class":270,"line":286},[268,32872,29965],{"class":274},[268,32874,283],{"class":282},[268,32876,32877,32879,32881,32883,32885,32887,32889],{"class":270,"line":296},[268,32878,9707],{"class":282},[268,32880,1356],{"class":278},[268,32882,622],{"class":282},[268,32884,950],{"class":305},[268,32886,462],{"class":282},[268,32888,9942],{"class":278},[268,32890,8174],{"class":282},[268,32892,32893],{"class":270,"line":311},[268,32894,1948],{"class":282},[268,32896,32897,32899],{"class":270,"line":788},[268,32898,19586],{"class":278},[268,32900,283],{"class":282},[268,32902,32903,32905,32908],{"class":270,"line":1951},[268,32904,9871],{"class":274},[268,32906,32907],{"class":289}," \"a shape\"",[268,32909,293],{"class":282},[268,32911,32912],{"class":270,"line":8955},[268,32913,1948],{"class":282},[268,32915,32916],{"class":270,"line":8966},[268,32917,314],{"class":282},[268,32919,32920],{"class":270,"line":8974},[268,32921,5033],{"emptyLinePlaceholder":35},[268,32923,32924,32926,32929,32931,32933],{"class":270,"line":8985},[268,32925,1468],{"class":274},[268,32927,32928],{"class":278}," Circle",[268,32930,30481],{"class":274},[268,32932,32866],{"class":278},[268,32934,9914],{"class":282},[268,32936,32937,32940,32942,32944],{"class":270,"line":8990},[268,32938,32939],{"class":1222},"  radius",[268,32941,616],{"class":274},[268,32943,2387],{"class":305},[268,32945,293],{"class":282},[268,32947,32948,32950],{"class":270,"line":8997},[268,32949,19586],{"class":278},[268,32951,283],{"class":282},[268,32953,32954,32956,32959,32961,32963,32966,32968],{"class":270,"line":9002},[268,32955,9871],{"class":274},[268,32957,32958],{"class":289}," `a circle with radius ${",[268,32960,950],{"class":305},[268,32962,462],{"class":289},[268,32964,32965],{"class":282},"radius",[268,32967,11603],{"class":289},[268,32969,293],{"class":282},[268,32971,32972],{"class":270,"line":14676},[268,32973,1948],{"class":282},[268,32975,32976],{"class":270,"line":14681},[268,32977,314],{"class":282},[268,32979,32980],{"class":270,"line":31051},[268,32981,5033],{"emptyLinePlaceholder":35},[268,32983,32984,32986,32988],{"class":270,"line":31071},[268,32985,2689],{"class":274},[268,32987,32928],{"class":278},[268,32989,794],{"class":282},[23,32991,32993,33001,33009,33017],{"className":32992},[26],[28,32994,32996,355,32998],{"className":32995},[31],[33,32997],{"disabled":35,"type":36},[39,32999,33000],{},"\"a shape\"",[28,33002,33004,355,33006],{"className":33003},[31],[33,33005],{"disabled":35,"type":36},[39,33007,33008],{},"\"a circle with radius 5\"",[28,33010,33012,355,33014],{"className":33011},[31],[33,33013],{"disabled":35,"type":36},[39,33015,33016],{},"ReferenceError: Cannot access 'radius' before initialization",[28,33018,33020,355,33022,33025,33026,23506,33029,33032,33033,33036,33037,33039,33040,33042,33043,33046,33047,355,33049,33051,33052,33054,33055,33057,33058,33061,33062,33064],{"className":33019},[31],[33,33021],{"disabled":35,"type":36},[39,33023,33024],{},"\"a circle with radius undefined\""," — method dispatch always uses the actual (derived) prototype, so ",[39,33027,33028],{},"this.describe()",[39,33030,33031],{},"Shape","'s constructor already resolves to ",[39,33034,33035],{},"Circle","'s overridden ",[39,33038,9942],{},"; but ",[39,33041,33035],{},"'s own field initializers (including ",[39,33044,33045],{},"radius = 5",") only run ",[104,33048,1747],{},[39,33050,30889],{}," returns, so at the moment ",[39,33053,9942],{}," runs mid-",[39,33056,30889],{}," call, ",[39,33059,33060],{},"this.radius"," isn't set yet and simply reads as ",[39,33063,833],{}," rather than throwing",[66,33066,33067,33069,33099],{},[69,33068,71],{},[73,33070,33071,6901,33073,33025,33075,23506,33077,33032,33079,33036,33081,33039,33083,33042,33085,33046,33087,355,33089,33051,33091,33054,33093,33057,33095,33061,33097,33064],{},[76,33072,78],{},[39,33074,33024],{},[39,33076,33028],{},[39,33078,33031],{},[39,33080,33035],{},[39,33082,9942],{},[39,33084,33035],{},[39,33086,33045],{},[104,33088,1747],{},[39,33090,30889],{},[39,33092,9942],{},[39,33094,30889],{},[39,33096,33060],{},[39,33098,833],{},[73,33100,33101,355,33103,33105,33106,33108,33109,33111,33112,33114,33115,2758,33118,33121,33122,33124,33125,33127,33128,33130,33131,33133,33134,446,33136,33138,33139,33141],{},[76,33102,84],{},[76,33104,365],{}," this combines two rules that interact badly. First, method overriding is resolved dynamically through the prototype chain, so even while ",[39,33107,33031],{},"'s constructor is still running (as part of ",[39,33110,30889],{},"), ",[39,33113,33028],{}," finds ",[39,33116,33117],{},"Circle.prototype.describe",[39,33119,33120],{},"Shape.prototype.describe",". Second, in a derived class, instance field initializers (like ",[39,33123,33045],{},") only run once ",[39,33126,30889],{}," has returned — they haven't executed yet at the point ",[39,33129,9942],{}," is invoked mid-",[39,33132,30889],{},". Reading a not-yet-set instance property doesn't throw (that's only TDZ behavior for ",[39,33135,240],{},[39,33137,243],{}," bindings); it just returns ",[39,33140,833],{},", since the property genuinely doesn't exist yet anywhere in the chain. This ordering gotcha is a real source of bugs when a base constructor calls an overridable method.",[15,33143,33144,33146,33312,33364],{"language":247},[18,33145,15311],{"id":15310},[257,33147,33148],{"language":247},[260,33149,33151],{"className":262,"code":33150,"language":247,"meta":264,"style":264},"class Logger {\n  prefix = \"[LOG]\";\n\n  logRegular(msg) {\n    console.log(this.prefix, msg);\n  }\n\n  logArrow = (msg) => {\n    console.log(this.prefix, msg);\n  };\n}\n\nconst a = new Logger();\nconst b = new Logger();\n\nconsole.log(a.logRegular === b.logRegular);\nconsole.log(a.logArrow === b.logArrow);\n",[39,33152,33153,33162,33174,33178,33190,33203,33207,33211,33228,33240,33244,33248,33252,33266,33280,33284,33298],{"__ignoreMap":264},[268,33154,33155,33157,33160],{"class":270,"line":271},[268,33156,1468],{"class":274},[268,33158,33159],{"class":278}," Logger",[268,33161,9914],{"class":282},[268,33163,33164,33167,33169,33172],{"class":270,"line":286},[268,33165,33166],{"class":1222},"  prefix",[268,33168,616],{"class":274},[268,33170,33171],{"class":289}," \"[LOG]\"",[268,33173,293],{"class":282},[268,33175,33176],{"class":270,"line":296},[268,33177,5033],{"emptyLinePlaceholder":35},[268,33179,33180,33183,33185,33188],{"class":270,"line":311},[268,33181,33182],{"class":278},"  logRegular",[268,33184,622],{"class":282},[268,33186,33187],{"class":1222},"msg",[268,33189,1235],{"class":282},[268,33191,33192,33194,33196,33198,33200],{"class":270,"line":788},[268,33193,9707],{"class":282},[268,33195,1356],{"class":278},[268,33197,622],{"class":282},[268,33199,950],{"class":305},[268,33201,33202],{"class":282},".prefix, msg);\n",[268,33204,33205],{"class":270,"line":1951},[268,33206,1948],{"class":282},[268,33208,33209],{"class":270,"line":8955},[268,33210,5033],{"emptyLinePlaceholder":35},[268,33212,33213,33216,33218,33220,33222,33224,33226],{"class":270,"line":8966},[268,33214,33215],{"class":278},"  logArrow",[268,33217,616],{"class":274},[268,33219,2182],{"class":282},[268,33221,33187],{"class":1222},[268,33223,6131],{"class":282},[268,33225,9414],{"class":274},[268,33227,9914],{"class":282},[268,33229,33230,33232,33234,33236,33238],{"class":270,"line":8974},[268,33231,9707],{"class":282},[268,33233,1356],{"class":278},[268,33235,622],{"class":282},[268,33237,950],{"class":305},[268,33239,33202],{"class":282},[268,33241,33242],{"class":270,"line":8985},[268,33243,15185],{"class":282},[268,33245,33246],{"class":270,"line":8990},[268,33247,314],{"class":282},[268,33249,33250],{"class":270,"line":8997},[268,33251,5033],{"emptyLinePlaceholder":35},[268,33253,33254,33256,33258,33260,33262,33264],{"class":270,"line":9002},[268,33255,243],{"class":274},[268,33257,7203],{"class":305},[268,33259,616],{"class":274},[268,33261,11370],{"class":274},[268,33263,33159],{"class":278},[268,33265,794],{"class":282},[268,33267,33268,33270,33272,33274,33276,33278],{"class":270,"line":14676},[268,33269,243],{"class":274},[268,33271,16372],{"class":305},[268,33273,616],{"class":274},[268,33275,11370],{"class":274},[268,33277,33159],{"class":278},[268,33279,794],{"class":282},[268,33281,33282],{"class":270,"line":14681},[268,33283,5033],{"emptyLinePlaceholder":35},[268,33285,33286,33288,33290,33293,33295],{"class":270,"line":31051},[268,33287,1353],{"class":282},[268,33289,1356],{"class":278},[268,33291,33292],{"class":282},"(a.logRegular ",[268,33294,3280],{"class":274},[268,33296,33297],{"class":282}," b.logRegular);\n",[268,33299,33300,33302,33304,33307,33309],{"class":270,"line":31071},[268,33301,1353],{"class":282},[268,33303,1356],{"class":278},[268,33305,33306],{"class":282},"(a.logArrow ",[268,33308,3280],{"class":274},[268,33310,33311],{"class":282}," b.logArrow);\n",[23,33313,33315,33337,33346,33355],{"className":33314},[26],[28,33316,33318,355,33320,1133,33322,33324,33325,33328,33329,33332,33333,33336],{"className":33317},[31],[33,33319],{"disabled":35,"type":36},[39,33321,2185],{},[39,33323,2986],{}," — a regular method (",[39,33326,33327],{},"logRegular",") is defined once on ",[39,33330,33331],{},"Logger.prototype"," and shared by every instance, so both instances reference the identical function object; an arrow function class field (",[39,33334,33335],{},"logArrow",") is instead created fresh during each constructor run and assigned as an own property on that specific instance, so two instances never share the same function reference",[28,33338,33340,355,33342,1133,33344],{"className":33339},[31],[33,33341],{"disabled":35,"type":36},[39,33343,2986],{},[39,33345,2986],{},[28,33347,33349,355,33351,1133,33353],{"className":33348},[31],[33,33350],{"disabled":35,"type":36},[39,33352,2185],{},[39,33354,2185],{},[28,33356,33358,355,33360,1133,33362],{"className":33357},[31],[33,33359],{"disabled":35,"type":36},[39,33361,2986],{},[39,33363,2185],{},[66,33365,33366,33368,33382],{},[69,33367,71],{},[73,33369,33370,3459,33372,1133,33374,33324,33376,33328,33378,33332,33380,33336],{},[76,33371,78],{},[39,33373,2185],{},[39,33375,2986],{},[39,33377,33327],{},[39,33379,33331],{},[39,33381,33335],{},[73,33383,33384,355,33386,355,33388,33390,33391,33393,33394,830,33396,3277,33398,33400,33401,33404,33405,33408,33409,23506,33411,33413],{},[76,33385,84],{},[76,33387,438],{},[39,33389,33327],{}," is ordinary class-method syntax, so it's installed exactly once on ",[39,33392,33331],{}," — every instance looks it up through the prototype chain and gets back the same function object, hence ",[39,33395,3280],{},[39,33397,2185],{},[39,33399,33335],{}," is a class ",[104,33402,33403],{},"field"," whose value happens to be an arrow function; like any instance field, its initializer runs separately for every ",[39,33406,33407],{},"new Logger()"," call, creating a brand-new closure each time and assigning it as an own property of that instance. That's what makes ",[39,33410,950],{},[39,33412,33335],{}," permanently bound to its own instance — but it comes at a real memory cost (one extra function object per instance) compared to a shared prototype method, which matters for classes instantiated many times.",[15,33415,33416,33418,33502,33561],{"language":247},[18,33417,18980],{"id":18979},[257,33419,33420],{"language":247},[260,33421,33423],{"className":262,"code":33422,"language":247,"meta":264,"style":264},"class Shape {}\n\nconst s = new Shape();\n\nclass NewShape {}\nShape.prototype = NewShape.prototype;\n\nconsole.log(s instanceof Shape);\n",[39,33424,33425,33433,33437,33452,33456,33465,33483,33487],{"__ignoreMap":264},[268,33426,33427,33429,33431],{"class":270,"line":271},[268,33428,1468],{"class":274},[268,33430,32866],{"class":278},[268,33432,30486],{"class":282},[268,33434,33435],{"class":270,"line":286},[268,33436,5033],{"emptyLinePlaceholder":35},[268,33438,33439,33441,33444,33446,33448,33450],{"class":270,"line":296},[268,33440,243],{"class":274},[268,33442,33443],{"class":305}," s",[268,33445,616],{"class":274},[268,33447,11370],{"class":274},[268,33449,32866],{"class":278},[268,33451,794],{"class":282},[268,33453,33454],{"class":270,"line":311},[268,33455,5033],{"emptyLinePlaceholder":35},[268,33457,33458,33460,33463],{"class":270,"line":788},[268,33459,1468],{"class":274},[268,33461,33462],{"class":278}," NewShape",[268,33464,30486],{"class":282},[268,33466,33467,33469,33471,33473,33475,33477,33479,33481],{"class":270,"line":1951},[268,33468,33031],{"class":305},[268,33470,462],{"class":282},[268,33472,12070],{"class":305},[268,33474,616],{"class":274},[268,33476,33462],{"class":305},[268,33478,462],{"class":282},[268,33480,12070],{"class":305},[268,33482,293],{"class":282},[268,33484,33485],{"class":270,"line":8955},[268,33486,5033],{"emptyLinePlaceholder":35},[268,33488,33489,33491,33493,33496,33498,33500],{"class":270,"line":8966},[268,33490,1353],{"class":282},[268,33492,1356],{"class":278},[268,33494,33495],{"class":282},"(s ",[268,33497,3707],{"class":274},[268,33499,32866],{"class":278},[268,33501,628],{"class":282},[23,33503,33505,33518,33546,33554],{"className":33504},[26],[28,33506,33508,355,33510,3990,33512,33514,33515,33517],{"className":33507},[31],[33,33509],{"disabled":35,"type":36},[39,33511,2185],{},[39,33513,25393],{}," was created as an instance of ",[39,33516,33031],{},", so it stays an instance forever",[28,33519,33521,355,33523,3990,33525,33527,33528,33531,33532,33534,33535,9057,33537,33539,33540,33542,33543],{"className":33520},[31],[33,33522],{"disabled":35,"type":36},[39,33524,2986],{},[39,33526,3707],{}," re-reads ",[39,33529,33530],{},"Shape.prototype"," at the moment of the check, not at construction time; since ",[39,33533,33530],{}," now points to a different object than the one actually in ",[39,33536,25393],{},[39,33538,30388],{}," chain, the check fails even though ",[39,33541,25393],{}," was legitimately built by ",[39,33544,33545],{},"new Shape()",[28,33547,33549,355,33551],{"className":33548},[31],[33,33550],{"disabled":35,"type":36},[39,33552,33553],{},"TypeError: Right-hand side of 'instanceof' is not callable",[28,33555,33557,355,33559],{"className":33556},[31],[33,33558],{"disabled":35,"type":36},[39,33560,833],{},[66,33562,33563,33565,33585],{},[69,33564,71],{},[73,33566,33567,1727,33569,3990,33571,33527,33573,33531,33575,33534,33577,9057,33579,33539,33581,33542,33583],{},[76,33568,78],{},[39,33570,2986],{},[39,33572,3707],{},[39,33574,33530],{},[39,33576,33530],{},[39,33578,25393],{},[39,33580,30388],{},[39,33582,25393],{},[39,33584,33545],{},[73,33586,33587,355,33589,355,33591,33594,33595,9057,33598,33600,33601,9057,33603,33605,33606,33608,33609,33611,33612,33614,33615,33617,33618,33621,33622,33624,33625,33627,33628,33630,33631,33633,33634,33636],{},[76,33588,84],{},[76,33590,365],{},[39,33592,33593],{},"x instanceof C"," works by taking ",[39,33596,33597],{},"C.prototype",[104,33599,28182],{}," value and checking whether it appears anywhere in ",[39,33602,2403],{},[39,33604,30388],{}," chain — it does not remember what ",[39,33607,33597],{}," was at construction time. ",[39,33610,25393],{}," was built while ",[39,33613,33530],{}," pointed to its original prototype object, so that original object is permanently baked into ",[39,33616,25393],{},"'s chain. Reassigning ",[39,33619,33620],{},"Shape.prototype = NewShape.prototype"," afterward changes what the ",[104,33623,1468],{}," currently points to, but does nothing to ",[39,33626,25393],{},"'s existing chain, so the two no longer match and ",[39,33629,3707],{}," reports ",[39,33632,2986],{},". Reassigning ",[39,33635,29574],{}," after instances already exist is a real footgun for exactly this reason.",[15,33638,33639,33641,33918,33968],{"language":247},[18,33640,26306],{"id":26305},[257,33642,33643],{"language":247},[260,33644,33646],{"className":262,"code":33645,"language":247,"meta":264,"style":264},"const Serializable = Base => class extends Base {\n  toJSON() {\n    return JSON.stringify(this);\n  }\n};\n\nconst Comparable = Base => class extends Base {\n  equals(other) {\n    return this.toJSON() === other.toJSON();\n  }\n};\n\nclass Point {\n  constructor(x, y) {\n    this.x = x;\n    this.y = y;\n  }\n}\n\nclass ComparablePoint extends Comparable(Serializable(Point)) {}\n\nconst a = new ComparablePoint(1, 2);\nconst b = new ComparablePoint(1, 2);\n\nconsole.log(a.equals(b));\n",[39,33647,33648,33670,33677,33693,33697,33701,33705,33726,33738,33759,33763,33767,33771,33779,33793,33803,33813,33817,33822,33827,33847,33852,33875,33898,33903],{"__ignoreMap":264},[268,33649,33650,33652,33655,33657,33659,33661,33664,33666,33668],{"class":270,"line":271},[268,33651,243],{"class":274},[268,33653,33654],{"class":278}," Serializable",[268,33656,616],{"class":274},[268,33658,20590],{"class":1222},[268,33660,14969],{"class":274},[268,33662,33663],{"class":274}," class",[268,33665,30481],{"class":274},[268,33667,20590],{"class":278},[268,33669,9914],{"class":282},[268,33671,33672,33675],{"class":270,"line":286},[268,33673,33674],{"class":278},"  toJSON",[268,33676,283],{"class":282},[268,33678,33679,33681,33683,33685,33687,33689,33691],{"class":270,"line":296},[268,33680,9871],{"class":274},[268,33682,21715],{"class":305},[268,33684,462],{"class":282},[268,33686,21707],{"class":278},[268,33688,622],{"class":282},[268,33690,950],{"class":305},[268,33692,628],{"class":282},[268,33694,33695],{"class":270,"line":311},[268,33696,1948],{"class":282},[268,33698,33699],{"class":270,"line":788},[268,33700,12940],{"class":282},[268,33702,33703],{"class":270,"line":1951},[268,33704,5033],{"emptyLinePlaceholder":35},[268,33706,33707,33709,33712,33714,33716,33718,33720,33722,33724],{"class":270,"line":8955},[268,33708,243],{"class":274},[268,33710,33711],{"class":278}," Comparable",[268,33713,616],{"class":274},[268,33715,20590],{"class":1222},[268,33717,14969],{"class":274},[268,33719,33663],{"class":274},[268,33721,30481],{"class":274},[268,33723,20590],{"class":278},[268,33725,9914],{"class":282},[268,33727,33728,33731,33733,33736],{"class":270,"line":8966},[268,33729,33730],{"class":278},"  equals",[268,33732,622],{"class":282},[268,33734,33735],{"class":1222},"other",[268,33737,1235],{"class":282},[268,33739,33740,33742,33744,33746,33748,33750,33752,33755,33757],{"class":270,"line":8974},[268,33741,9871],{"class":274},[268,33743,30206],{"class":305},[268,33745,462],{"class":282},[268,33747,22419],{"class":278},[268,33749,16182],{"class":282},[268,33751,3280],{"class":274},[268,33753,33754],{"class":282}," other.",[268,33756,22419],{"class":278},[268,33758,794],{"class":282},[268,33760,33761],{"class":270,"line":8985},[268,33762,1948],{"class":282},[268,33764,33765],{"class":270,"line":8990},[268,33766,12940],{"class":282},[268,33768,33769],{"class":270,"line":8997},[268,33770,5033],{"emptyLinePlaceholder":35},[268,33772,33773,33775,33777],{"class":270,"line":9002},[268,33774,1468],{"class":274},[268,33776,30134],{"class":278},[268,33778,9914],{"class":282},[268,33780,33781,33783,33785,33787,33789,33791],{"class":270,"line":14676},[268,33782,29965],{"class":274},[268,33784,622],{"class":282},[268,33786,2403],{"class":1222},[268,33788,42],{"class":282},[268,33790,2909],{"class":1222},[268,33792,1235],{"class":282},[268,33794,33795,33797,33799,33801],{"class":270,"line":14681},[268,33796,22057],{"class":305},[268,33798,29986],{"class":282},[268,33800,302],{"class":274},[268,33802,3547],{"class":282},[268,33804,33805,33807,33809,33811],{"class":270,"line":31051},[268,33806,22057],{"class":305},[268,33808,29997],{"class":282},[268,33810,302],{"class":274},[268,33812,30002],{"class":282},[268,33814,33815],{"class":270,"line":31071},[268,33816,1948],{"class":282},[268,33818,33820],{"class":270,"line":33819},18,[268,33821,314],{"class":282},[268,33823,33825],{"class":270,"line":33824},19,[268,33826,5033],{"emptyLinePlaceholder":35},[268,33828,33830,33832,33835,33837,33839,33841,33844],{"class":270,"line":33829},20,[268,33831,1468],{"class":274},[268,33833,33834],{"class":278}," ComparablePoint",[268,33836,30481],{"class":274},[268,33838,33711],{"class":278},[268,33840,622],{"class":282},[268,33842,33843],{"class":278},"Serializable",[268,33845,33846],{"class":282},"(Point)) {}\n",[268,33848,33850],{"class":270,"line":33849},21,[268,33851,5033],{"emptyLinePlaceholder":35},[268,33853,33855,33857,33859,33861,33863,33865,33867,33869,33871,33873],{"class":270,"line":33854},22,[268,33856,243],{"class":274},[268,33858,7203],{"class":305},[268,33860,616],{"class":274},[268,33862,11370],{"class":274},[268,33864,33834],{"class":278},[268,33866,622],{"class":282},[268,33868,2255],{"class":305},[268,33870,42],{"class":282},[268,33872,2258],{"class":305},[268,33874,628],{"class":282},[268,33876,33878,33880,33882,33884,33886,33888,33890,33892,33894,33896],{"class":270,"line":33877},23,[268,33879,243],{"class":274},[268,33881,16372],{"class":305},[268,33883,616],{"class":274},[268,33885,11370],{"class":274},[268,33887,33834],{"class":278},[268,33889,622],{"class":282},[268,33891,2255],{"class":305},[268,33893,42],{"class":282},[268,33895,2258],{"class":305},[268,33897,628],{"class":282},[268,33899,33901],{"class":270,"line":33900},24,[268,33902,5033],{"emptyLinePlaceholder":35},[268,33904,33906,33908,33910,33913,33916],{"class":270,"line":33905},25,[268,33907,1353],{"class":282},[268,33909,1356],{"class":278},[268,33911,33912],{"class":282},"(a.",[268,33914,33915],{"class":278},"equals",[268,33917,21722],{"class":282},[23,33919,33921,33929,33945,33960],{"className":33920},[26],[28,33922,33924,355,33926],{"className":33923},[31],[33,33925],{"disabled":35,"type":36},[39,33927,33928],{},"SyntaxError: A class can only extend one expression",[28,33930,33932,355,33934,2833,33936,20968,33938,33940,33941,33944],{"className":33931},[31],[33,33933],{"disabled":35,"type":36},[39,33935,2986],{},[39,33937,22419],{},[39,33939,33843],{}," is shadowed by ",[39,33942,33943],{},"Comparable","'s own method",[28,33946,33948,355,33950,33952,33953,33955,33956,33959],{"className":33947},[31],[33,33949],{"disabled":35,"type":36},[39,33951,2185],{}," — since JS classes support only single inheritance via ",[39,33954,1502],{},", each mixin is written as a function that takes a base class and returns a new subclass extending it; chaining these calls (",[39,33957,33958],{},"Comparable(Serializable(Point))",") layers multiple independent behaviors onto one class, which is how JS works around not having true multiple inheritance",[28,33961,33963,355,33965],{"className":33962},[31],[33,33964],{"disabled":35,"type":36},[39,33966,33967],{},"TypeError: other.toJSON is not a function",[66,33969,33970,33972,33982],{},[69,33971,71],{},[73,33973,33974,1004,33976,33952,33978,33955,33980,33959],{},[76,33975,78],{},[39,33977,2185],{},[39,33979,1502],{},[39,33981,33958],{},[73,33983,33984,355,33986,355,33988,33990,33991,33994,33995,33998,33999,2272,34001,34004,34005,3277,34007,34010,34011,186,34013,34015,34016,34019,34020,34022],{},[76,33985,84],{},[76,33987,930],{},[39,33989,1502],{}," only ever accepts a single expression, but that expression can itself be a function call that returns a class — which is exactly what a mixin function is. ",[39,33992,33993],{},"Serializable(Point)"," returns an anonymous class extending ",[39,33996,33997],{},"Point"," that adds ",[39,34000,22419],{},[39,34002,34003],{},"Comparable(...)"," wraps that again, adding ",[39,34006,33915],{},[39,34008,34009],{},"ComparablePoint"," ends up with both ",[39,34012,22419],{},[39,34014,33915],{}," available through its prototype chain, with no conflict between them, so ",[39,34017,34018],{},"a.equals(b)"," compares their JSON forms and correctly returns ",[39,34021,2185],{},". This composition pattern is JS's standard workaround for the lack of real multiple inheritance.",[15,34024,34025,34046,34083],{},[18,34026,34028,34029,42,34032,137,34035,34038,34039,42,34041,383,34043,34045],{"id":34027},"q20-a-team-building-a-ui-has-modal-tooltip-and-dropdown-components-all-three-need-identical-positioning-logic-but-positioning-isnt-conceptually-a-kind-of-modal-tooltip-or-dropdown-its-an-unrelated-cross-cutting-concern-whats-the-best-practice-way-to-share-this-behavior","Q20. A team building a UI has ",[39,34030,34031],{},"Modal",[39,34033,34034],{},"Tooltip",[39,34036,34037],{},"Dropdown"," components. All three need identical positioning logic, but \"positioning\" isn't conceptually a kind of ",[39,34040,34031],{},[39,34042,34034],{},[39,34044,34037],{}," — it's an unrelated, cross-cutting concern. What's the best-practice way to share this behavior?",[23,34047,34049,34059,34065,34074],{"className":34048},[26],[28,34050,34052,34054,34055,34058],{"className":34051},[31],[33,34053],{"disabled":35,"type":36}," Create one deep base class ",[39,34056,34057],{},"PositionableUIElement"," that all three extend, even though they aren't otherwise conceptually related, so the shared logic lives in exactly one place",[28,34060,34062,34064],{"className":34061},[31],[33,34063],{"disabled":35,"type":36}," Copy-paste the positioning code into each of the three components to avoid any coupling between them",[28,34066,34068,34070,34071,34073],{"className":34067},[31],[33,34069],{"disabled":35,"type":36}," Use multiple inheritance by having each component ",[39,34072,1502],{}," both a base UI class and a separate positioning class at the same time",[28,34075,34077,34079,34080,34082],{"className":34076},[31],[33,34078],{"disabled":35,"type":36}," Extract the positioning logic into a standalone function\u002Fobject (a composed helper or mixin, as in Q19) that each component uses, since ",[39,34081,1502],{}," should model a genuine \"is-a\" relationship — reaching for inheritance purely to share unrelated behavior produces awkward, fragile hierarchies as more cross-cutting concerns pile up",[66,34084,34085,34087,34094],{},[69,34086,71],{},[73,34088,34089,34091,34092,34082],{},[76,34090,78],{}," D — Extract the positioning logic into a standalone function\u002Fobject (a composed helper or mixin, as in Q19) that each component uses, since ",[39,34093,1502],{},[73,34095,34096,355,34098,355,34100,34102,34103,42,34105,137,34107,34109,34110,34112,34113,34115],{},[76,34097,84],{},[76,34099,930],{},[39,34101,1502],{}," should express \"this really is a specialized version of that,\" not just \"I want to reuse some code.\" Forcing ",[39,34104,34031],{},[39,34106,34034],{},[39,34108,34037],{}," under a shared ",[39,34111,34057],{}," base (option A) works today but becomes fragile the moment a fourth unrelated concern (e.g., \"draggable\") needs sharing too — deep, unrelated hierarchies are hard to reason about and hard to change safely. Copy-pasting (option B) duplicates bugs across three places. Option C isn't even possible — JS's ",[39,34114,1502],{}," clause accepts exactly one class expression, though as Q19 showed, that one expression can itself be composed from multiple mixins. Preferring composition (small, focused, combinable units of behavior) over deep inheritance chains is the widely recommended default for sharing behavior that isn't a true \"is-a\" relationship.",[2107,34117,34118],{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}",{"title":264,"searchDepth":286,"depth":286,"links":34120},[34121,34123,34124,34125,34126,34127,34128,34129,34130,34131,34132,34133,34134,34135,34136,34137,34138,34139,34140,34141],{"id":29551,"depth":296,"text":34122},"Q1. Which statement best describes the relationship between JavaScript class syntax and prototypes?",{"id":12736,"depth":296,"text":12737},{"id":27063,"depth":296,"text":27064},{"id":13031,"depth":296,"text":13032},{"id":13180,"depth":296,"text":13181},{"id":24127,"depth":296,"text":24128},{"id":13527,"depth":296,"text":13528},{"id":13728,"depth":296,"text":13729},{"id":13926,"depth":296,"text":13927},{"id":17618,"depth":296,"text":17619},{"id":31810,"depth":296,"text":31811},{"id":14381,"depth":296,"text":14382},{"id":14537,"depth":296,"text":14538},{"id":25491,"depth":296,"text":25492},{"id":32641,"depth":296,"text":32642},{"id":15130,"depth":296,"text":15131},{"id":15310,"depth":296,"text":15311},{"id":18979,"depth":296,"text":18980},{"id":26305,"depth":296,"text":26306},{"id":34027,"depth":296,"text":34142},"Q20. A team building a UI has Modal, Tooltip, and Dropdown components. All three need identical positioning logic, but \"positioning\" isn't conceptually a kind of Modal, Tooltip, or Dropdown — it's an unrelated, cross-cutting concern. What's the best-practice way to share this behavior?",{},"\u002Fjs\u002F10-classes-and-prototypes",{"title":29541,"description":264},"js\u002F10-classes-and-prototypes","wCJbrMlNmKaevEMTyrlZlHx1QwR_W9CFu79psIbMZPo",{"id":34149,"title":34150,"body":34151,"description":264,"extension":2144,"meta":37260,"navigation":35,"path":37261,"seo":37262,"stem":37263,"__hash__":37264},"content\u002Fjs\u002F11-this-keyword.md","11 — The this Keyword",{"type":8,"value":34152,"toc":37235},[34153,34160,34294,34404,34573,34725,34884,35049,35225,35337,35538,35717,35836,36016,36184,36302,36512,36636,36795,36956,37055,37232],[11,34154,34156,34157,34159],{"id":34155},"_11-the-this-keyword","11 — The ",[39,34158,950],{}," Keyword",[15,34161,34162,34164,34237,34264],{"language":247},[18,34163,23361],{"id":23360},[257,34165,34166],{"language":247},[260,34167,34169],{"className":262,"code":34168,"language":247,"meta":264,"style":264},"const user = {\n  name: 'Ava',\n  greet() {\n    return `Hi, I'm ${this.name}`;\n  }\n};\n\nconsole.log(user.greet());\n",[39,34170,34171,34181,34190,34196,34213,34217,34221,34225],{"__ignoreMap":264},[268,34172,34173,34175,34177,34179],{"class":270,"line":271},[268,34174,243],{"class":274},[268,34176,4071],{"class":305},[268,34178,616],{"class":274},[268,34180,9914],{"class":282},[268,34182,34183,34185,34188],{"class":270,"line":286},[268,34184,20028],{"class":282},[268,34186,34187],{"class":289},"'Ava'",[268,34189,1789],{"class":282},[268,34191,34192,34194],{"class":270,"line":296},[268,34193,22220],{"class":278},[268,34195,283],{"class":282},[268,34197,34198,34200,34203,34205,34207,34209,34211],{"class":270,"line":311},[268,34199,9871],{"class":274},[268,34201,34202],{"class":289}," `Hi, I'm ${",[268,34204,950],{"class":305},[268,34206,462],{"class":289},[268,34208,14605],{"class":282},[268,34210,11603],{"class":289},[268,34212,293],{"class":282},[268,34214,34215],{"class":270,"line":788},[268,34216,1948],{"class":282},[268,34218,34219],{"class":270,"line":1951},[268,34220,12940],{"class":282},[268,34222,34223],{"class":270,"line":8955},[268,34224,5033],{"emptyLinePlaceholder":35},[268,34226,34227,34229,34231,34233,34235],{"class":270,"line":8966},[268,34228,1353],{"class":282},[268,34230,1356],{"class":278},[268,34232,8168],{"class":282},[268,34234,12761],{"class":278},[268,34236,8174],{"class":282},[23,34238,34240,34246,34252,34258],{"className":34239},[26],[28,34241,34243,34245],{"className":34242},[31],[33,34244],{"disabled":35,"type":36}," \"Hi, I'm Ava\"",[28,34247,34249,34251],{"className":34248},[31],[33,34250],{"disabled":35,"type":36}," \"Hi, I'm undefined\"",[28,34253,34255,34257],{"className":34254},[31],[33,34256],{"disabled":35,"type":36}," Throws a TypeError",[28,34259,34261,34263],{"className":34260},[31],[33,34262],{"disabled":35,"type":36}," \"Hi, I'm user\"",[66,34265,34266,34268,34273],{},[69,34267,71],{},[73,34269,34270,34272],{},[76,34271,78],{}," A — \"Hi, I'm Ava\"",[73,34274,34275,34277,34278,34281,34282,33111,34285,34287,34288,34290,34291,34293],{},[76,34276,84],{}," This is ",[76,34279,34280],{},"implicit binding",": when a function is called as a property of an object (",[39,34283,34284],{},"user.greet()",[39,34286,950],{}," is bound to the object on the left of the dot at call time, not to where the function was defined. \"Hi, I'm undefined\" would only happen if ",[39,34289,12761],{}," were invoked without a receiver (e.g. destructured first). There's no reason for a TypeError here since ",[39,34292,22787],{}," exists.",[15,34295,34296,34300,34345,34377],{"language":247},[18,34297,34299],{"id":34298},"q2-what-does-this-print-in-an-es-module-strict-mode","Q2. What does this print in an ES module (strict mode)?",[257,34301,34302],{"language":247},[260,34303,34305],{"className":262,"code":34304,"language":247,"meta":264,"style":264},"function whoAmI() {\n  return this;\n}\n\nconsole.log(whoAmI());\n",[39,34306,34307,34316,34324,34328,34332],{"__ignoreMap":264},[268,34308,34309,34311,34314],{"class":270,"line":271},[268,34310,275],{"class":274},[268,34312,34313],{"class":278}," whoAmI",[268,34315,283],{"class":282},[268,34317,34318,34320,34322],{"class":270,"line":286},[268,34319,1240],{"class":274},[268,34321,30206],{"class":305},[268,34323,293],{"class":282},[268,34325,34326],{"class":270,"line":296},[268,34327,314],{"class":282},[268,34329,34330],{"class":270,"line":311},[268,34331,5033],{"emptyLinePlaceholder":35},[268,34333,34334,34336,34338,34340,34343],{"class":270,"line":788},[268,34335,1353],{"class":282},[268,34337,1356],{"class":278},[268,34339,622],{"class":282},[268,34341,34342],{"class":278},"whoAmI",[268,34344,8174],{"class":282},[23,34346,34348,34353,34361,34369],{"className":34347},[26],[28,34349,34351,17135],{"className":34350},[31],[33,34352],{"disabled":35,"type":36},[28,34354,34356,34358,34359,2690],{"className":34355},[31],[33,34357],{"disabled":35,"type":36}," The global object (",[39,34360,994],{},[28,34362,34364,34366,34367],{"className":34363},[31],[33,34365],{"disabled":35,"type":36}," An empty object ",[39,34368,2328],{},[28,34370,34372,4396,34374,34376],{"className":34371},[31],[33,34373],{"disabled":35,"type":36},[39,34375,34342],{}," function itself",[66,34378,34379,34381,34386],{},[69,34380,71],{},[73,34382,34383,34385],{},[76,34384,78],{}," A — undefined",[73,34387,34388,34277,34390,34393,34394,34396,34397,34400,34401,34403],{},[76,34389,84],{},[76,34391,34392],{},"default binding",". When a function is called with no receiver and no explicit binding, ",[39,34395,950],{}," falls back to the global object in sloppy mode, but ES modules (and any code under ",[39,34398,34399],{},"'use strict'",") run in strict mode by default, where the fallback is ",[39,34402,833],{}," instead. The \"global object\" answer is a very common trap left over from sloppy-mode intuition.",[15,34405,34406,34413,34497,34531],{"language":247},[18,34407,23672,34409,34412],{"id":34408},"q3-what-does-call-do-here",[39,34410,34411],{},"call"," do here?",[257,34414,34415],{"language":247},[260,34416,34418],{"className":262,"code":34417,"language":247,"meta":264,"style":264},"function intro() {\n  return `${this.role}: ${this.name}`;\n}\n\nconst emp = { name: 'Sam', role: 'Dev' };\nconsole.log(intro.call(emp));\n",[39,34419,34420,34429,34454,34458,34462,34483],{"__ignoreMap":264},[268,34421,34422,34424,34427],{"class":270,"line":271},[268,34423,275],{"class":274},[268,34425,34426],{"class":278}," intro",[268,34428,283],{"class":282},[268,34430,34431,34433,34435,34437,34439,34441,34444,34446,34448,34450,34452],{"class":270,"line":286},[268,34432,1240],{"class":274},[268,34434,14262],{"class":289},[268,34436,950],{"class":305},[268,34438,462],{"class":289},[268,34440,7753],{"class":282},[268,34442,34443],{"class":289},"}: ${",[268,34445,950],{"class":305},[268,34447,462],{"class":289},[268,34449,14605],{"class":282},[268,34451,11603],{"class":289},[268,34453,293],{"class":282},[268,34455,34456],{"class":270,"line":296},[268,34457,314],{"class":282},[268,34459,34460],{"class":270,"line":311},[268,34461,5033],{"emptyLinePlaceholder":35},[268,34463,34464,34466,34469,34471,34473,34476,34478,34481],{"class":270,"line":788},[268,34465,243],{"class":274},[268,34467,34468],{"class":305}," emp",[268,34470,616],{"class":274},[268,34472,4076],{"class":282},[268,34474,34475],{"class":289},"'Sam'",[268,34477,27781],{"class":282},[268,34479,34480],{"class":289},"'Dev'",[268,34482,2790],{"class":282},[268,34484,34485,34487,34489,34492,34494],{"class":270,"line":1951},[268,34486,1353],{"class":282},[268,34488,1356],{"class":278},[268,34490,34491],{"class":282},"(intro.",[268,34493,34411],{"class":278},[268,34495,34496],{"class":282},"(emp));\n",[23,34498,34500,34506,34512,34525],{"className":34499},[26],[28,34501,34503,34505],{"className":34502},[31],[33,34504],{"disabled":35,"type":36}," \"Dev: Sam\"",[28,34507,34509,34511],{"className":34508},[31],[33,34510],{"disabled":35,"type":36}," \"undefined: undefined\"",[28,34513,34515,34517,34518,34521,34522],{"className":34514},[31],[33,34516],{"disabled":35,"type":36}," Throws a TypeError because ",[39,34519,34520],{},"intro"," isn't a method of ",[39,34523,34524],{},"emp",[28,34526,34528,34530],{"className":34527},[31],[33,34529],{"disabled":35,"type":36}," \"Sam: Dev\"",[66,34532,34533,34535,34540],{},[69,34534,71],{},[73,34536,34537,34539],{},[76,34538,78],{}," A — \"Dev: Sam\"",[73,34541,34542,355,34544,34547,34548,355,34550,34553,34554,34557,34558,34561,34562,34564,34565,2272,34567,34569,34570,34572],{},[76,34543,84],{},[39,34545,34546],{},"Function.prototype.call(thisArg, ...args)"," invokes the function immediately with ",[39,34549,950],{},[76,34551,34552],{},"explicitly"," set to ",[39,34555,34556],{},"thisArg",". This is ",[76,34559,34560],{},"explicit binding"," — it doesn't matter that ",[39,34563,34520],{}," was never attached to ",[39,34566,34524],{},[39,34568,34411],{}," temporarily makes ",[39,34571,34524],{}," the receiver. The \"Sam: Dev\" option swaps the template order, which isn't how the string is built.",[15,34574,34575,34577,34654,34679],{"language":247},[18,34576,13032],{"id":13031},[257,34578,34579],{"language":247},[260,34580,34582],{"className":262,"code":34581,"language":247,"meta":264,"style":264},"function total(a, b) {\n  return this.base + a + b;\n}\n\nconsole.log(total.apply({ base: 10 }, [2, 3]));\n",[39,34583,34584,34601,34618,34622,34626],{"__ignoreMap":264},[268,34585,34586,34588,34591,34593,34595,34597,34599],{"class":270,"line":271},[268,34587,275],{"class":274},[268,34589,34590],{"class":278}," total",[268,34592,622],{"class":282},[268,34594,1223],{"class":1222},[268,34596,42],{"class":282},[268,34598,1232],{"class":1222},[268,34600,1235],{"class":282},[268,34602,34603,34605,34607,34610,34612,34614,34616],{"class":270,"line":286},[268,34604,1240],{"class":274},[268,34606,30206],{"class":305},[268,34608,34609],{"class":282},".base ",[268,34611,1246],{"class":274},[268,34613,1243],{"class":282},[268,34615,1246],{"class":274},[268,34617,1249],{"class":282},[268,34619,34620],{"class":270,"line":296},[268,34621,314],{"class":282},[268,34623,34624],{"class":270,"line":311},[268,34625,5033],{"emptyLinePlaceholder":35},[268,34627,34628,34630,34632,34635,34638,34641,34643,34646,34648,34650,34652],{"class":270,"line":788},[268,34629,1353],{"class":282},[268,34631,1356],{"class":278},[268,34633,34634],{"class":282},"(total.",[268,34636,34637],{"class":278},"apply",[268,34639,34640],{"class":282},"({ base: ",[268,34642,5825],{"class":305},[268,34644,34645],{"class":282}," }, [",[268,34647,2258],{"class":305},[268,34649,42],{"class":282},[268,34651,3423],{"class":305},[268,34653,24210],{"class":282},[23,34655,34657,34663,34668,34674],{"className":34656},[26],[28,34658,34660,34662],{"className":34659},[31],[33,34661],{"disabled":35,"type":36}," 15",[28,34664,34666,3027],{"className":34665},[31],[33,34667],{"disabled":35,"type":36},[28,34669,34671,34673],{"className":34670},[31],[33,34672],{"disabled":35,"type":36}," Throws a TypeError because arrays aren't valid arguments",[28,34675,34677,2387],{"className":34676},[31],[33,34678],{"disabled":35,"type":36},[66,34680,34681,34683,34688],{},[69,34682,71],{},[73,34684,34685,34687],{},[76,34686,78],{}," A — 15",[73,34689,34690,355,34692,34695,34696,34698,34699,34701,34702,186,34704,4973,34706,830,34709,42,34711,830,34713,42,34715,830,34717,6345,34719,3277,34722,34724],{},[76,34691,84],{},[39,34693,34694],{},"apply(thisArg, argsArray)"," behaves exactly like ",[39,34697,34411],{},", except positional arguments are supplied as an array, which ",[39,34700,34637],{}," spreads into ",[39,34703,1223],{},[39,34705,1232],{},[39,34707,34708],{},"this.base",[39,34710,5825],{},[39,34712,1223],{},[39,34714,2258],{},[39,34716,1232],{},[39,34718,3423],{},[39,34720,34721],{},"10 + 2 + 3 = 15",[39,34723,34637],{}," accepting an array-like for arguments is its entire purpose — it doesn't throw.",[15,34726,34727,34731,34817,34846],{"language":247},[18,34728,34730],{"id":34729},"q5-what-is-logged-after-100ms","Q5. What is logged after 100ms?",[257,34732,34733],{"language":247},[260,34734,34736],{"className":262,"code":34735,"language":247,"meta":264,"style":264},"const user = { name: 'Ava', greet() { return `Hi, I'm ${this.name}`; } };\nconst greetLater = user.greet.bind(user);\n\nsetTimeout(() => console.log(greetLater()), 100);\n",[39,34737,34738,34772,34789,34793],{"__ignoreMap":264},[268,34739,34740,34742,34744,34746,34748,34750,34752,34754,34757,34759,34761,34763,34765,34767,34769],{"class":270,"line":271},[268,34741,243],{"class":274},[268,34743,4071],{"class":305},[268,34745,616],{"class":274},[268,34747,4076],{"class":282},[268,34749,34187],{"class":289},[268,34751,42],{"class":282},[268,34753,12761],{"class":278},[268,34755,34756],{"class":282},"() { ",[268,34758,9151],{"class":274},[268,34760,34202],{"class":289},[268,34762,950],{"class":305},[268,34764,462],{"class":289},[268,34766,14605],{"class":282},[268,34768,11603],{"class":289},[268,34770,34771],{"class":282},"; } };\n",[268,34773,34774,34776,34779,34781,34784,34787],{"class":270,"line":286},[268,34775,243],{"class":274},[268,34777,34778],{"class":305}," greetLater",[268,34780,616],{"class":274},[268,34782,34783],{"class":282}," user.greet.",[268,34785,34786],{"class":278},"bind",[268,34788,19797],{"class":282},[268,34790,34791],{"class":270,"line":296},[268,34792,5033],{"emptyLinePlaceholder":35},[268,34794,34795,34797,34799,34801,34803,34805,34807,34810,34813,34815],{"class":270,"line":311},[268,34796,9578],{"class":278},[268,34798,9411],{"class":282},[268,34800,9414],{"class":274},[268,34802,9417],{"class":282},[268,34804,1356],{"class":278},[268,34806,622],{"class":282},[268,34808,34809],{"class":278},"greetLater",[268,34811,34812],{"class":282},"()), ",[268,34814,13912],{"class":305},[268,34816,628],{"class":282},[23,34818,34820,34825,34830,34836],{"className":34819},[26],[28,34821,34823,34245],{"className":34822},[31],[33,34824],{"disabled":35,"type":36},[28,34826,34828,34251],{"className":34827},[31],[33,34829],{"disabled":35,"type":36},[28,34831,34833,34835],{"className":34832},[31],[33,34834],{"disabled":35,"type":36}," The string is logged immediately, not after 100ms",[28,34837,34839,34517,34841,34843,34844],{"className":34838},[31],[33,34840],{"disabled":35,"type":36},[39,34842,34786],{}," already executed ",[39,34845,12761],{},[66,34847,34848,34850,34854],{},[69,34849,71],{},[73,34851,34852,34272],{},[76,34853,78],{},[73,34855,34856,355,34858,34860,34861,34863,34864,34866,34867,34869,34870,34872,34873,446,34875,34877,34878,34880,34881,34883],{},[76,34857,84],{},[39,34859,34786],{}," does ",[76,34862,95],{}," call the function — it returns a new function with ",[39,34865,950],{}," permanently locked to the given value, to be invoked later. That's the trap in option C\u002FD: beginners often confuse ",[39,34868,34786],{}," (defer + fix ",[39,34871,950],{},") with ",[39,34874,34411],{},[39,34876,34637],{}," (invoke now). Since ",[39,34879,34809],{}," carries ",[39,34882,4155],{}," as its bound receiver no matter how or when it's called, it still logs \"Hi, I'm Ava\" once the timer fires.",[15,34885,34886,34888,34972,34995],{"language":247},[18,34887,13321],{"id":13320},[257,34889,34890],{"language":247},[260,34891,34893],{"className":262,"code":34892,"language":247,"meta":264,"style":264},"const counter = {\n  count: 0,\n  increment: () => {\n    this.count++;\n    return this.count;\n  }\n};\n\nconsole.log(counter.increment());\n",[39,34894,34895,34906,34914,34926,34937,34946,34950,34954,34958],{"__ignoreMap":264},[268,34896,34897,34899,34902,34904],{"class":270,"line":271},[268,34898,243],{"class":274},[268,34900,34901],{"class":305}," counter",[268,34903,616],{"class":274},[268,34905,9914],{"class":282},[268,34907,34908,34910,34912],{"class":270,"line":286},[268,34909,22232],{"class":282},[268,34911,3307],{"class":305},[268,34913,1789],{"class":282},[268,34915,34916,34919,34922,34924],{"class":270,"line":296},[268,34917,34918],{"class":278},"  increment",[268,34920,34921],{"class":282},": () ",[268,34923,9414],{"class":274},[268,34925,9914],{"class":282},[268,34927,34928,34930,34933,34935],{"class":270,"line":311},[268,34929,22057],{"class":305},[268,34931,34932],{"class":282},".count",[268,34934,9401],{"class":274},[268,34936,293],{"class":282},[268,34938,34939,34941,34943],{"class":270,"line":788},[268,34940,9871],{"class":274},[268,34942,30206],{"class":305},[268,34944,34945],{"class":282},".count;\n",[268,34947,34948],{"class":270,"line":1951},[268,34949,1948],{"class":282},[268,34951,34952],{"class":270,"line":8955},[268,34953,12940],{"class":282},[268,34955,34956],{"class":270,"line":8966},[268,34957,5033],{"emptyLinePlaceholder":35},[268,34959,34960,34962,34964,34967,34970],{"class":270,"line":8974},[268,34961,1353],{"class":282},[268,34963,1356],{"class":278},[268,34965,34966],{"class":282},"(counter.",[268,34968,34969],{"class":278},"increment",[268,34971,8174],{"class":282},[23,34973,34975,34980,34985,34990],{"className":34974},[26],[28,34976,34978,2199],{"className":34977},[31],[33,34979],{"disabled":35,"type":36},[28,34981,34983,3027],{"className":34982},[31],[33,34984],{"disabled":35,"type":36},[28,34986,34988,17135],{"className":34987},[31],[33,34989],{"disabled":35,"type":36},[28,34991,34993,34257],{"className":34992},[31],[33,34994],{"disabled":35,"type":36},[66,34996,34997,34999,35004],{},[69,34998,71],{},[73,35000,35001,35003],{},[76,35002,78],{}," B — NaN",[73,35005,35006,355,35008,35010,35011,35013,35014,35016,35017,35020,35021,35023,35024,35026,35027,2182,35029,35031,35032,35034,35035,3277,35038,35040,35041,137,35043,5409,35046,35048],{},[76,35007,84],{},[76,35009,930],{}," arrow functions have no ",[39,35012,950],{}," of their own — they capture ",[39,35015,950],{}," lexically from the enclosing scope at the point they're ",[104,35018,35019],{},"defined",", not from the object they're attached to. Here ",[39,35022,34969],{}," is defined at the top level of the module, so its ",[39,35025,950],{}," is the module's ",[39,35028,950],{},[39,35030,833],{}," in an ES module, or ",[39,35033,658],{}," in CommonJS) — either way, not ",[39,35036,35037],{},"counter",[39,35039,32796],{}," is therefore ",[39,35042,833],{},[39,35044,35045],{},"undefined++",[39,35047,3040],{},". Using an arrow function as an object method is a classic beginner mistake for exactly this reason.",[15,35050,35051,35053,35159,35182],{"language":247},[18,35052,13528],{"id":13527},[257,35054,35055],{"language":247},[260,35056,35058],{"className":262,"code":35057,"language":247,"meta":264,"style":264},"class Timer {\n  constructor() {\n    this.seconds = 0;\n  }\n  tick() {\n    this.seconds++;\n    return this.seconds;\n  }\n}\n\nconst t = new Timer();\nconsole.log(t.tick());\n",[39,35059,35060,35069,35075,35088,35092,35099,35110,35119,35123,35127,35131,35145],{"__ignoreMap":264},[268,35061,35062,35064,35067],{"class":270,"line":271},[268,35063,1468],{"class":274},[268,35065,35066],{"class":278}," Timer",[268,35068,9914],{"class":282},[268,35070,35071,35073],{"class":270,"line":286},[268,35072,29965],{"class":274},[268,35074,283],{"class":282},[268,35076,35077,35079,35082,35084,35086],{"class":270,"line":296},[268,35078,22057],{"class":305},[268,35080,35081],{"class":282},".seconds ",[268,35083,302],{"class":274},[268,35085,5728],{"class":305},[268,35087,293],{"class":282},[268,35089,35090],{"class":270,"line":311},[268,35091,1948],{"class":282},[268,35093,35094,35097],{"class":270,"line":788},[268,35095,35096],{"class":278},"  tick",[268,35098,283],{"class":282},[268,35100,35101,35103,35106,35108],{"class":270,"line":1951},[268,35102,22057],{"class":305},[268,35104,35105],{"class":282},".seconds",[268,35107,9401],{"class":274},[268,35109,293],{"class":282},[268,35111,35112,35114,35116],{"class":270,"line":8955},[268,35113,9871],{"class":274},[268,35115,30206],{"class":305},[268,35117,35118],{"class":282},".seconds;\n",[268,35120,35121],{"class":270,"line":8966},[268,35122,1948],{"class":282},[268,35124,35125],{"class":270,"line":8974},[268,35126,314],{"class":282},[268,35128,35129],{"class":270,"line":8985},[268,35130,5033],{"emptyLinePlaceholder":35},[268,35132,35133,35135,35137,35139,35141,35143],{"class":270,"line":8990},[268,35134,243],{"class":274},[268,35136,32545],{"class":305},[268,35138,616],{"class":274},[268,35140,11370],{"class":274},[268,35142,35066],{"class":278},[268,35144,794],{"class":282},[268,35146,35147,35149,35151,35154,35157],{"class":270,"line":8997},[268,35148,1353],{"class":282},[268,35150,1356],{"class":278},[268,35152,35153],{"class":282},"(t.",[268,35155,35156],{"class":278},"tick",[268,35158,8174],{"class":282},[23,35160,35162,35167,35172,35177],{"className":35161},[26],[28,35163,35165,2199],{"className":35164},[31],[33,35166],{"disabled":35,"type":36},[28,35168,35170,5728],{"className":35169},[31],[33,35171],{"disabled":35,"type":36},[28,35173,35175,17135],{"className":35174},[31],[33,35176],{"disabled":35,"type":36},[28,35178,35180,3027],{"className":35179},[31],[33,35181],{"disabled":35,"type":36},[66,35183,35184,35186,35191],{},[69,35185,71],{},[73,35187,35188,35190],{},[76,35189,78],{}," A — 1",[73,35192,35193,355,35195,35198,35199,35201,35202,15108,35205,35208,35209,35212,35213,35216,35217,5425,35219,35221,35222,35224],{},[76,35194,84],{},[39,35196,35197],{},"new Timer()"," creates a fresh object and binds it as ",[39,35200,950],{}," inside the constructor, setting ",[39,35203,35204],{},"this.seconds = 0",[39,35206,35207],{},"t.tick()"," afterward is ordinary implicit binding (",[39,35210,35211],{},"t"," is the receiver), so ",[39,35214,35215],{},"this.seconds++"," increments ",[39,35218,3307],{},[39,35220,2255],{}," and returns it. There's no ambiguity here — the gotchas around ",[39,35223,950],{}," and classes usually appear once a method is detached from its instance (see later questions).",[15,35226,35227,35231,35268,35309],{"language":247},[18,35228,35230],{"id":35229},"q8-what-happens-here","Q8. What happens here?",[257,35232,35233],{"language":247},[260,35234,35236],{"className":262,"code":35235,"language":247,"meta":264,"style":264},"const Foo = () => {};\nconst f = new Foo();\n",[39,35237,35238,35253],{"__ignoreMap":264},[268,35239,35240,35242,35245,35247,35249,35251],{"class":270,"line":271},[268,35241,243],{"class":274},[268,35243,35244],{"class":278}," Foo",[268,35246,616],{"class":274},[268,35248,15158],{"class":282},[268,35250,9414],{"class":274},[268,35252,15812],{"class":282},[268,35254,35255,35257,35260,35262,35264,35266],{"class":270,"line":286},[268,35256,243],{"class":274},[268,35258,35259],{"class":305}," f",[268,35261,616],{"class":274},[268,35263,11370],{"class":274},[268,35265,35244],{"class":278},[268,35267,794],{"class":282},[23,35269,35271,35279,35290,35299],{"className":35270},[26],[28,35272,35274,6738,35276],{"className":35273},[31],[33,35275],{"disabled":35,"type":36},[39,35277,35278],{},"TypeError: Foo is not a constructor",[28,35280,35282,355,35284,35287,35288],{"className":35281},[31],[33,35283],{"disabled":35,"type":36},[39,35285,35286],{},"f"," becomes a new empty object whose prototype is ",[39,35289,29582],{},[28,35291,35293,355,35295,830,35297],{"className":35292},[31],[33,35294],{"disabled":35,"type":36},[39,35296,35286],{},[39,35298,833],{},[28,35300,35302,355,35304,23506,35306,35308],{"className":35301},[31],[33,35303],{"disabled":35,"type":36},[39,35305,950],{},[39,35307,29570],{}," is bound to the new object, same as a regular function",[66,35310,35311,35313,35320],{},[69,35312,71],{},[73,35314,35315,35317,35318],{},[76,35316,78],{}," A — Throws ",[39,35319,35278],{},[73,35321,35322,355,35324,35326,35327,35330,35331,35333,35334,35336],{},[76,35323,84],{},[76,35325,582],{}," arrow functions intentionally lack the internal ",[39,35328,35329],{},"[[Construct]]"," method that regular functions have, so they can never be used with ",[39,35332,2689],{}," — this is part of what makes their lexical ",[39,35335,950],{}," reliable (there's no separate \"new binding\" mode to worry about). This is a deliberate design choice, not an oversight: it prevents arrow functions from ever being accidentally used as constructors.",[15,35338,35339,35343,35455,35484],{"language":247},[18,35340,35342],{"id":35341},"q9-this-module-runs-under-strict-mode-its-an-es-module-what-happens","Q9. This module runs under strict mode (it's an ES module). What happens?",[257,35344,35345],{"language":247},[260,35346,35348],{"className":262,"code":35347,"language":247,"meta":264,"style":264},"const obj = {\n  items: [1, 2, 3],\n  label: 'nums',\n  printAll() {\n    this.items.forEach(function (item) {\n      console.log(this.label, item);\n    });\n  }\n};\n\nobj.printAll();\n",[39,35349,35350,35360,35378,35388,35395,35414,35428,35433,35437,35441,35445],{"__ignoreMap":264},[268,35351,35352,35354,35356,35358],{"class":270,"line":271},[268,35353,243],{"class":274},[268,35355,4651],{"class":305},[268,35357,616],{"class":274},[268,35359,9914],{"class":282},[268,35361,35362,35365,35367,35369,35371,35373,35375],{"class":270,"line":286},[268,35363,35364],{"class":282},"  items: [",[268,35366,2255],{"class":305},[268,35368,42],{"class":282},[268,35370,2258],{"class":305},[268,35372,42],{"class":282},[268,35374,3423],{"class":305},[268,35376,35377],{"class":282},"],\n",[268,35379,35380,35383,35386],{"class":270,"line":296},[268,35381,35382],{"class":282},"  label: ",[268,35384,35385],{"class":289},"'nums'",[268,35387,1789],{"class":282},[268,35389,35390,35393],{"class":270,"line":311},[268,35391,35392],{"class":278},"  printAll",[268,35394,283],{"class":282},[268,35396,35397,35399,35402,35404,35406,35408,35410,35412],{"class":270,"line":788},[268,35398,22057],{"class":305},[268,35400,35401],{"class":282},".items.",[268,35403,12330],{"class":278},[268,35405,622],{"class":282},[268,35407,275],{"class":274},[268,35409,2182],{"class":282},[268,35411,14793],{"class":1222},[268,35413,1235],{"class":282},[268,35415,35416,35419,35421,35423,35425],{"class":270,"line":1951},[268,35417,35418],{"class":282},"      console.",[268,35420,1356],{"class":278},[268,35422,622],{"class":282},[268,35424,950],{"class":305},[268,35426,35427],{"class":282},".label, item);\n",[268,35429,35430],{"class":270,"line":8955},[268,35431,35432],{"class":282},"    });\n",[268,35434,35435],{"class":270,"line":8966},[268,35436,1948],{"class":282},[268,35438,35439],{"class":270,"line":8974},[268,35440,12940],{"class":282},[268,35442,35443],{"class":270,"line":8985},[268,35444,5033],{"emptyLinePlaceholder":35},[268,35446,35447,35450,35453],{"class":270,"line":8990},[268,35448,35449],{"class":282},"obj.",[268,35451,35452],{"class":278},"printAll",[268,35454,794],{"class":282},[23,35456,35458,35464,35472,35478],{"className":35457},[26],[28,35459,35461,35463],{"className":35460},[31],[33,35462],{"disabled":35,"type":36}," Logs \"nums 1\", \"nums 2\", \"nums 3\"",[28,35465,35467,6738,35469],{"className":35466},[31],[33,35468],{"disabled":35,"type":36},[39,35470,35471],{},"TypeError: Cannot read properties of undefined (reading 'label')",[28,35473,35475,35477],{"className":35474},[31],[33,35476],{"disabled":35,"type":36}," Logs \"undefined 1\", \"undefined 2\", \"undefined 3\"",[28,35479,35481,35483],{"className":35480},[31],[33,35482],{"disabled":35,"type":36}," Logs \"nums undefined\" three times",[66,35485,35486,35488,35494],{},[69,35487,71],{},[73,35489,35490,14198,35492],{},[76,35491,78],{},[39,35493,35471],{},[73,35495,35496,355,35498,35500,35501,35503,35504,35506,35507,20968,35509,35511,35512,355,35514,35516,35517,35520,35521,35524,35525,9057,35527,35529,35530,26085,35532,35534,35535,35537],{},[76,35497,84],{},[76,35499,365],{}," the callback passed to ",[39,35502,12330],{}," is a plain function, not a method call — it gets ",[76,35505,34392],{},", not the ",[39,35508,950],{},[39,35510,35452],{},". In strict-mode code (which class bodies and ES modules always are), default binding makes ",[39,35513,950],{},[39,35515,833],{}," rather than falling back to the global object, so ",[39,35518,35519],{},"this.label"," throws immediately on the first iteration. The fix is to either use an arrow function for the callback (",[39,35522,35523],{},"this.items.forEach(item => console.log(this.label, item))",", which lexically inherits ",[39,35526,35452],{},[39,35528,950],{},"), or pass ",[39,35531,950],{},[39,35533,12330],{},"'s optional second ",[39,35536,34556],{}," argument.",[15,35539,35540,35544,35647,35670],{"language":247},[18,35541,35543],{"id":35542},"q10-what-does-this-log-in-nodejs","Q10. What does this log in Node.js?",[257,35545,35546],{"language":247},[260,35547,35549],{"className":262,"code":35548,"language":247,"meta":264,"style":264},"class Countdown {\n  constructor() {\n    this.time = 3;\n  }\n  start() {\n    setTimeout(function () {\n      console.log(this.time);\n    }, 0);\n  }\n}\n\nnew Countdown().start();\n",[39,35550,35551,35560,35566,35579,35583,35590,35601,35614,35623,35627,35631,35635],{"__ignoreMap":264},[268,35552,35553,35555,35558],{"class":270,"line":271},[268,35554,1468],{"class":274},[268,35556,35557],{"class":278}," Countdown",[268,35559,9914],{"class":282},[268,35561,35562,35564],{"class":270,"line":286},[268,35563,29965],{"class":274},[268,35565,283],{"class":282},[268,35567,35568,35570,35573,35575,35577],{"class":270,"line":296},[268,35569,22057],{"class":305},[268,35571,35572],{"class":282},".time ",[268,35574,302],{"class":274},[268,35576,3396],{"class":305},[268,35578,293],{"class":282},[268,35580,35581],{"class":270,"line":311},[268,35582,1948],{"class":282},[268,35584,35585,35588],{"class":270,"line":788},[268,35586,35587],{"class":278},"  start",[268,35589,283],{"class":282},[268,35591,35592,35595,35597,35599],{"class":270,"line":1951},[268,35593,35594],{"class":278},"    setTimeout",[268,35596,622],{"class":282},[268,35598,275],{"class":274},[268,35600,12922],{"class":282},[268,35602,35603,35605,35607,35609,35611],{"class":270,"line":8955},[268,35604,35418],{"class":282},[268,35606,1356],{"class":278},[268,35608,622],{"class":282},[268,35610,950],{"class":305},[268,35612,35613],{"class":282},".time);\n",[268,35615,35616,35619,35621],{"class":270,"line":8966},[268,35617,35618],{"class":282},"    }, ",[268,35620,3307],{"class":305},[268,35622,628],{"class":282},[268,35624,35625],{"class":270,"line":8974},[268,35626,1948],{"class":282},[268,35628,35629],{"class":270,"line":8985},[268,35630,314],{"class":282},[268,35632,35633],{"class":270,"line":8990},[268,35634,5033],{"emptyLinePlaceholder":35},[268,35636,35637,35639,35641,35643,35645],{"class":270,"line":8997},[268,35638,2689],{"class":274},[268,35640,35557],{"class":278},[268,35642,19341],{"class":282},[268,35644,13946],{"class":278},[268,35646,794],{"class":282},[23,35648,35650,35655,35660,35665],{"className":35649},[26],[28,35651,35653,3396],{"className":35652},[31],[33,35654],{"disabled":35,"type":36},[28,35656,35658,17135],{"className":35657},[31],[33,35659],{"disabled":35,"type":36},[28,35661,35663,34257],{"className":35662},[31],[33,35664],{"disabled":35,"type":36},[28,35666,35668,3027],{"className":35667},[31],[33,35669],{"disabled":35,"type":36},[66,35671,35672,35674,35679],{},[69,35673,71],{},[73,35675,35676,35678],{},[76,35677,78],{}," B — undefined",[73,35680,35681,35683,35684,35686,35687,35690,35691,35693,35694,355,35696,35699,35700,35703,35704,35707,35708,35710,35711,35713,35714,462],{},[76,35682,84],{}," The callback given to ",[39,35685,9578],{}," is invoked as a plain function call by the timer internals, not as a method of the ",[39,35688,35689],{},"Countdown"," instance, so ",[39,35692,950],{}," inside it is ",[76,35695,95],{},[39,35697,35698],{},"countdown",". In Node it ends up being the ",[39,35701,35702],{},"Timeout"," object (or the global object in a browser under sloppy mode); either way, ",[39,35705,35706],{},"this.time"," doesn't exist on it, so the property access quietly returns ",[39,35709,833],{}," rather than throwing. The fix is to use an arrow function for the callback so it inherits ",[39,35712,950],{}," lexically from ",[39,35715,35716],{},"start()",[15,35718,35719,35723,35769,35801],{"language":247},[18,35720,35722],{"id":35721},"q11-what-does-this-log-when-the-button-is-clicked","Q11. What does this log when the button is clicked?",[257,35724,35725],{"language":247},[260,35726,35728],{"className":262,"code":35727,"language":247,"meta":264,"style":264},"button.addEventListener('click', () => {\n  console.log(this === button);\n});\n",[39,35729,35730,35750,35765],{"__ignoreMap":264},[268,35731,35732,35735,35738,35740,35743,35746,35748],{"class":270,"line":271},[268,35733,35734],{"class":282},"button.",[268,35736,35737],{"class":278},"addEventListener",[268,35739,622],{"class":282},[268,35741,35742],{"class":289},"'click'",[268,35744,35745],{"class":282},", () ",[268,35747,9414],{"class":274},[268,35749,9914],{"class":282},[268,35751,35752,35754,35756,35758,35760,35762],{"class":270,"line":286},[268,35753,5556],{"class":282},[268,35755,1356],{"class":278},[268,35757,622],{"class":282},[268,35759,950],{"class":305},[268,35761,3043],{"class":274},[268,35763,35764],{"class":282}," button);\n",[268,35766,35767],{"class":270,"line":296},[268,35768,20047],{"class":282},[23,35770,35772,35777,35782,35791],{"className":35771},[26],[28,35773,35775,3200],{"className":35774},[31],[33,35776],{"disabled":35,"type":36},[28,35778,35780,7905],{"className":35779},[31],[33,35781],{"disabled":35,"type":36},[28,35783,35785,35787,35788,35790],{"className":35784},[31],[33,35786],{"disabled":35,"type":36}," Throws a ReferenceError because ",[39,35789,950],{}," is undeclared",[28,35792,35794,35796,35797,35800],{"className":35793},[31],[33,35795],{"disabled":35,"type":36}," It depends on whether the button has an ",[39,35798,35799],{},"onclick"," attribute",[66,35802,35803,35805,35810],{},[69,35804,71],{},[73,35806,35807,35809],{},[76,35808,78],{}," A — false",[73,35811,35812,35814,35815,35817,35818,35820,35821,35824,35825,35827,35828,35830,35831,35833,35834,462],{},[76,35813,84],{}," DOM listeners normally invoke a plain ",[39,35816,275],{}," callback with ",[39,35819,950],{}," set to the element the listener is attached to — that's how ",[39,35822,35823],{},"this === button"," would become ",[39,35826,2185],{}," with a regular ",[39,35829,275],{}," handler. But arrow functions ignore that call-time binding entirely and use the lexical ",[39,35832,950],{}," from the surrounding scope where the arrow was defined (module\u002Fouter scope), which is not the button. Reaching for an arrow function \"for brevity\" in an event handler is a common way to accidentally lose access to the element via ",[39,35835,950],{},[15,35837,35838,35840,35949,35976],{"language":247},[18,35839,14382],{"id":14381},[257,35841,35842],{"language":247},[260,35843,35845],{"className":262,"code":35844,"language":247,"meta":264,"style":264},"function intro() {\n  return `${this.role}: ${this.name}`;\n}\n\nconst emp = { name: 'Sam', role: 'Dev' };\nconst bound = intro.bind(emp);\n\nconsole.log(bound.call({ name: 'Other', role: 'X' }));\n",[39,35846,35847,35855,35879,35883,35887,35905,35922,35926],{"__ignoreMap":264},[268,35848,35849,35851,35853],{"class":270,"line":271},[268,35850,275],{"class":274},[268,35852,34426],{"class":278},[268,35854,283],{"class":282},[268,35856,35857,35859,35861,35863,35865,35867,35869,35871,35873,35875,35877],{"class":270,"line":286},[268,35858,1240],{"class":274},[268,35860,14262],{"class":289},[268,35862,950],{"class":305},[268,35864,462],{"class":289},[268,35866,7753],{"class":282},[268,35868,34443],{"class":289},[268,35870,950],{"class":305},[268,35872,462],{"class":289},[268,35874,14605],{"class":282},[268,35876,11603],{"class":289},[268,35878,293],{"class":282},[268,35880,35881],{"class":270,"line":296},[268,35882,314],{"class":282},[268,35884,35885],{"class":270,"line":311},[268,35886,5033],{"emptyLinePlaceholder":35},[268,35888,35889,35891,35893,35895,35897,35899,35901,35903],{"class":270,"line":788},[268,35890,243],{"class":274},[268,35892,34468],{"class":305},[268,35894,616],{"class":274},[268,35896,4076],{"class":282},[268,35898,34475],{"class":289},[268,35900,27781],{"class":282},[268,35902,34480],{"class":289},[268,35904,2790],{"class":282},[268,35906,35907,35909,35912,35914,35917,35919],{"class":270,"line":1951},[268,35908,243],{"class":274},[268,35910,35911],{"class":305}," bound",[268,35913,616],{"class":274},[268,35915,35916],{"class":282}," intro.",[268,35918,34786],{"class":278},[268,35920,35921],{"class":282},"(emp);\n",[268,35923,35924],{"class":270,"line":8955},[268,35925,5033],{"emptyLinePlaceholder":35},[268,35927,35928,35930,35932,35935,35937,35939,35942,35944,35947],{"class":270,"line":8966},[268,35929,1353],{"class":282},[268,35931,1356],{"class":278},[268,35933,35934],{"class":282},"(bound.",[268,35936,34411],{"class":278},[268,35938,23123],{"class":282},[268,35940,35941],{"class":289},"'Other'",[268,35943,27781],{"class":282},[268,35945,35946],{"class":289},"'X'",[268,35948,27280],{"class":282},[23,35950,35952,35957,35963,35971],{"className":35951},[26],[28,35953,35955,34505],{"className":35954},[31],[33,35956],{"disabled":35,"type":36},[28,35958,35960,35962],{"className":35959},[31],[33,35961],{"disabled":35,"type":36}," \"X: Other\"",[28,35964,35966,34517,35968,35970],{"className":35965},[31],[33,35967],{"disabled":35,"type":36},[39,35969,34411],{}," can't be used on a bound function",[28,35972,35974,34511],{"className":35973},[31],[33,35975],{"disabled":35,"type":36},[66,35977,35978,35980,35984],{},[69,35979,71],{},[73,35981,35982,34539],{},[76,35983,78],{},[73,35985,35986,355,35988,355,35990,35992,35993,35995,35996,42,35998,36000,36001,36003,36004,36006,36007,36010,36011,446,36013,36015],{},[76,35987,84],{},[76,35989,930],{},[39,35991,34786],{}," creates a \"hard-bound\" function whose ",[39,35994,950],{}," cannot be overridden by any later ",[39,35997,34411],{},[39,35999,34637],{},", or even another ",[39,36002,34786],{}," — the original receiver (",[39,36005,34524],{},") always wins. Beginners often assume the ",[104,36008,36009],{},"most recent"," binding call takes precedence, but explicit-binding precedence rules put hard binding above ordinary ",[39,36012,34411],{},[39,36014,34637],{}," on the bound wrapper.",[15,36017,36018,36020,36113,36141],{"language":247},[18,36019,14538],{"id":14537},[257,36021,36022],{"language":247},[260,36023,36025],{"className":262,"code":36024,"language":247,"meta":264,"style":264},"function Person(name) {\n  this.name = name;\n}\n\nconst BoundPerson = Person.bind({ name: 'ignored' });\nconst p = new BoundPerson('Zoe');\n\nconsole.log(p.name);\n",[39,36026,36027,36040,36051,36055,36059,36081,36100,36104],{"__ignoreMap":264},[268,36028,36029,36031,36034,36036,36038],{"class":270,"line":271},[268,36030,275],{"class":274},[268,36032,36033],{"class":278}," Person",[268,36035,622],{"class":282},[268,36037,14605],{"class":1222},[268,36039,1235],{"class":282},[268,36041,36042,36045,36047,36049],{"class":270,"line":286},[268,36043,36044],{"class":305},"  this",[268,36046,30956],{"class":282},[268,36048,302],{"class":274},[268,36050,30961],{"class":282},[268,36052,36053],{"class":270,"line":296},[268,36054,314],{"class":282},[268,36056,36057],{"class":270,"line":311},[268,36058,5033],{"emptyLinePlaceholder":35},[268,36060,36061,36063,36066,36068,36071,36073,36075,36078],{"class":270,"line":788},[268,36062,243],{"class":274},[268,36064,36065],{"class":305}," BoundPerson",[268,36067,616],{"class":274},[268,36069,36070],{"class":282}," Person.",[268,36072,34786],{"class":278},[268,36074,23123],{"class":282},[268,36076,36077],{"class":289},"'ignored'",[268,36079,36080],{"class":282}," });\n",[268,36082,36083,36085,36087,36089,36091,36093,36095,36098],{"class":270,"line":1951},[268,36084,243],{"class":274},[268,36086,29927],{"class":305},[268,36088,616],{"class":274},[268,36090,11370],{"class":274},[268,36092,36065],{"class":278},[268,36094,622],{"class":282},[268,36096,36097],{"class":289},"'Zoe'",[268,36099,628],{"class":282},[268,36101,36102],{"class":270,"line":8955},[268,36103,5033],{"emptyLinePlaceholder":35},[268,36105,36106,36108,36110],{"class":270,"line":8966},[268,36107,1353],{"class":282},[268,36109,1356],{"class":278},[268,36111,36112],{"class":282},"(p.name);\n",[23,36114,36116,36122,36128,36133],{"className":36115},[26],[28,36117,36119,36121],{"className":36118},[31],[33,36120],{"disabled":35,"type":36}," 'ignored'",[28,36123,36125,36127],{"className":36124},[31],[33,36126],{"disabled":35,"type":36}," 'Zoe'",[28,36129,36131,17135],{"className":36130},[31],[33,36132],{"disabled":35,"type":36},[28,36134,36136,36138,36139],{"className":36135},[31],[33,36137],{"disabled":35,"type":36}," Throws a TypeError because a bound function can't be used with ",[39,36140,2689],{},[66,36142,36143,36145,36150],{},[69,36144,71],{},[73,36146,36147,36149],{},[76,36148,78],{}," B — 'Zoe'",[73,36151,36152,355,36154,36156,36157,36159,36160,36163,36164,36166,36167,36169,36170,36173,36174,36176,36177,36180,36181,36183],{},[76,36153,84],{},[76,36155,582],{}," this is the one case where hard binding ",[104,36158,10043],{}," get overridden — the spec explicitly makes ",[76,36161,36162],{},"new binding"," take precedence over a bound ",[39,36165,950],{}," when a bound function is invoked with ",[39,36168,2689],{},". The bound ",[39,36171,36172],{},"{ name: 'ignored' }"," receiver is discarded, and ",[39,36175,73],{}," becomes a freshly constructed object as if ",[39,36178,36179],{},"new Person('Zoe')"," had been called directly. This is easy to get wrong because it contradicts Q12's rule, but ",[39,36182,2689],{}," is the one exception to \"bind always wins.\"",[15,36185,36186,36188,36241,36270],{"language":247},[18,36187,14774],{"id":14773},[257,36189,36190],{"language":247},[260,36191,36193],{"className":262,"code":36192,"language":247,"meta":264,"style":264},"'use strict';\n\nfunction f() {\n  return this;\n}\n\nconsole.log(f());\n",[39,36194,36195,36201,36205,36213,36221,36225,36229],{"__ignoreMap":264},[268,36196,36197,36199],{"class":270,"line":271},[268,36198,34399],{"class":289},[268,36200,293],{"class":282},[268,36202,36203],{"class":270,"line":286},[268,36204,5033],{"emptyLinePlaceholder":35},[268,36206,36207,36209,36211],{"class":270,"line":296},[268,36208,275],{"class":274},[268,36210,35259],{"class":278},[268,36212,283],{"class":282},[268,36214,36215,36217,36219],{"class":270,"line":311},[268,36216,1240],{"class":274},[268,36218,30206],{"class":305},[268,36220,293],{"class":282},[268,36222,36223],{"class":270,"line":788},[268,36224,314],{"class":282},[268,36226,36227],{"class":270,"line":1951},[268,36228,5033],{"emptyLinePlaceholder":35},[268,36230,36231,36233,36235,36237,36239],{"class":270,"line":8955},[268,36232,1353],{"class":282},[268,36234,1356],{"class":278},[268,36236,622],{"class":282},[268,36238,35286],{"class":278},[268,36240,8174],{"class":282},[23,36242,36244,36249,36256,36263],{"className":36243},[26],[28,36245,36247,17135],{"className":36246},[31],[33,36248],{"disabled":35,"type":36},[28,36250,36252,355,36254],{"className":36251},[31],[33,36253],{"disabled":35,"type":36},[39,36255,994],{},[28,36257,36259,355,36261],{"className":36258},[31],[33,36260],{"disabled":35,"type":36},[39,36262,2328],{},[28,36264,36266,355,36268],{"className":36265},[31],[33,36267],{"disabled":35,"type":36},[39,36269,2650],{},[66,36271,36272,36274,36278],{},[69,36273,71],{},[73,36275,36276,34385],{},[76,36277,78],{},[73,36279,36280,355,36282,36284,36285,36287,36288,26085,36290,36292,36293,36295,36296,36298,36299,36301],{},[76,36281,84],{},[76,36283,182],{}," under ",[39,36286,34399],{},", default binding no longer falls back to the global object the way sloppy-mode code does — it leaves ",[39,36289,950],{},[39,36291,833],{},". This matters for portability between script contexts: the same unbound function call in a non-strict ",[39,36294,434],{}," tag would return ",[39,36297,189],{}," in a browser, so relying on ",[39,36300,950],{}," in a top-level function call behaves differently depending on strict mode.",[15,36303,36304,36312,36431,36471],{"language":247},[18,36305,36307,36308,36311],{"id":36306},"q15-why-is-thishandleclick-thishandleclickbindthis-written-inside-this-constructor","Q15. Why is ",[39,36309,36310],{},"this.handleClick = this.handleClick.bind(this)"," written inside this constructor?",[257,36313,36314],{"language":247},[260,36315,36317],{"className":262,"code":36316,"language":247,"meta":264,"style":264},"class Button {\n  constructor() {\n    this.clicks = 0;\n    this.handleClick = this.handleClick.bind(this);\n  }\n  handleClick() {\n    this.clicks++;\n  }\n}\n\nconst b = new Button();\nel.addEventListener('click', b.handleClick);\n",[39,36318,36319,36328,36334,36347,36369,36373,36380,36391,36395,36399,36403,36417],{"__ignoreMap":264},[268,36320,36321,36323,36326],{"class":270,"line":271},[268,36322,1468],{"class":274},[268,36324,36325],{"class":278}," Button",[268,36327,9914],{"class":282},[268,36329,36330,36332],{"class":270,"line":286},[268,36331,29965],{"class":274},[268,36333,283],{"class":282},[268,36335,36336,36338,36341,36343,36345],{"class":270,"line":296},[268,36337,22057],{"class":305},[268,36339,36340],{"class":282},".clicks ",[268,36342,302],{"class":274},[268,36344,5728],{"class":305},[268,36346,293],{"class":282},[268,36348,36349,36351,36354,36356,36358,36361,36363,36365,36367],{"class":270,"line":311},[268,36350,22057],{"class":305},[268,36352,36353],{"class":282},".handleClick ",[268,36355,302],{"class":274},[268,36357,30206],{"class":305},[268,36359,36360],{"class":282},".handleClick.",[268,36362,34786],{"class":278},[268,36364,622],{"class":282},[268,36366,950],{"class":305},[268,36368,628],{"class":282},[268,36370,36371],{"class":270,"line":788},[268,36372,1948],{"class":282},[268,36374,36375,36378],{"class":270,"line":1951},[268,36376,36377],{"class":278},"  handleClick",[268,36379,283],{"class":282},[268,36381,36382,36384,36387,36389],{"class":270,"line":8955},[268,36383,22057],{"class":305},[268,36385,36386],{"class":282},".clicks",[268,36388,9401],{"class":274},[268,36390,293],{"class":282},[268,36392,36393],{"class":270,"line":8966},[268,36394,1948],{"class":282},[268,36396,36397],{"class":270,"line":8974},[268,36398,314],{"class":282},[268,36400,36401],{"class":270,"line":8985},[268,36402,5033],{"emptyLinePlaceholder":35},[268,36404,36405,36407,36409,36411,36413,36415],{"class":270,"line":8990},[268,36406,243],{"class":274},[268,36408,16372],{"class":305},[268,36410,616],{"class":274},[268,36412,11370],{"class":274},[268,36414,36325],{"class":278},[268,36416,794],{"class":282},[268,36418,36419,36422,36424,36426,36428],{"class":270,"line":8997},[268,36420,36421],{"class":282},"el.",[268,36423,35737],{"class":278},[268,36425,622],{"class":282},[268,36427,35742],{"class":289},[268,36429,36430],{"class":282},", b.handleClick);\n",[23,36432,36434,36450,36456,36462],{"className":36433},[26],[28,36435,36437,36439,36440,36443,36444,36446,36447],{"className":36436},[31],[33,36438],{"disabled":35,"type":36}," So ",[39,36441,36442],{},"handleClick"," keeps referring to ",[39,36445,1232],{}," even though the listener calls it as a plain function, not ",[39,36448,36449],{},"b.handleClick()",[28,36451,36453,36455],{"className":36452},[31],[33,36454],{"disabled":35,"type":36}," To improve performance by caching the method lookup",[28,36457,36459,36461],{"className":36458},[31],[33,36460],{"disabled":35,"type":36}," Because class methods can't be passed as callbacks otherwise (a syntax restriction)",[28,36463,36465,36467,36468,36470],{"className":36464},[31],[33,36466],{"disabled":35,"type":36}," To make ",[39,36469,36442],{}," a private field",[66,36472,36473,36475,36486],{},[69,36474,71],{},[73,36476,36477,36479,36480,36443,36482,36446,36484],{},[76,36478,78],{}," A — So ",[39,36481,36442],{},[39,36483,1232],{},[39,36485,36449],{},[73,36487,36488,355,36490,36492,36493,36496,36497,36500,36501,36504,36505,7415,36507,36509,36510,6232],{},[76,36489,84],{},[76,36491,930],{}," once a method is passed by reference (",[39,36494,36495],{},"b.handleClick"," without calling it), it's detached from its instance — the event system will call it as ",[39,36498,36499],{},"handleClick(event)",", a plain invocation with default binding, not ",[39,36502,36503],{},"b.handleClick(event)",". Pre-binding in the constructor guarantees ",[39,36506,950],{},[39,36508,1232],{}," regardless of how the function is later invoked. This is a genuine correctness requirement, not a performance trick, and class syntax has no restriction that would otherwise forbid passing a method as a callback (it would just silently lose its ",[39,36511,950],{},[15,36513,36514,36518,36574,36608],{"language":247},[18,36515,36517],{"id":36516},"q16-what-is-the-trade-off-of-using-an-arrow-class-field-instead-of-a-bound-prototype-method","Q16. What is the trade-off of using an arrow class field instead of a bound prototype method?",[257,36519,36520],{"language":247},[260,36521,36523],{"className":262,"code":36522,"language":247,"meta":264,"style":264},"class Button {\n  clicks = 0;\n  handleClick = () => {\n    this.clicks++;\n  };\n}\n",[39,36524,36525,36533,36544,36556,36566,36570],{"__ignoreMap":264},[268,36526,36527,36529,36531],{"class":270,"line":271},[268,36528,1468],{"class":274},[268,36530,36325],{"class":278},[268,36532,9914],{"class":282},[268,36534,36535,36538,36540,36542],{"class":270,"line":286},[268,36536,36537],{"class":1222},"  clicks",[268,36539,616],{"class":274},[268,36541,5728],{"class":305},[268,36543,293],{"class":282},[268,36545,36546,36548,36550,36552,36554],{"class":270,"line":296},[268,36547,36377],{"class":278},[268,36549,616],{"class":274},[268,36551,15158],{"class":282},[268,36553,9414],{"class":274},[268,36555,9914],{"class":282},[268,36557,36558,36560,36562,36564],{"class":270,"line":311},[268,36559,22057],{"class":305},[268,36561,36386],{"class":282},[268,36563,9401],{"class":274},[268,36565,293],{"class":282},[268,36567,36568],{"class":270,"line":788},[268,36569,15185],{"class":282},[268,36571,36572],{"class":270,"line":1951},[268,36573,314],{"class":282},[23,36575,36577,36585,36593,36602],{"className":36576},[26],[28,36578,36580,355,36582,36584],{"className":36579},[31],[33,36581],{"disabled":35,"type":36},[39,36583,36442],{}," is guaranteed auto-bound to each instance, but it's created fresh per instance (living on the object, not the shared prototype), using more memory than a single prototype method",[28,36586,36588,355,36590,36592],{"className":36587},[31],[33,36589],{"disabled":35,"type":36},[39,36591,36442],{}," behaves identically to a prototype method in every respect, including memory usage",[28,36594,36596,36598,36599],{"className":36595},[31],[33,36597],{"disabled":35,"type":36}," Arrow class fields cannot access other instance fields like ",[39,36600,36601],{},"this.clicks",[28,36603,36605,36607],{"className":36604},[31],[33,36606],{"disabled":35,"type":36}," This syntax is invalid — arrow functions cannot be used as class fields",[66,36609,36610,36612,36618],{},[69,36611,71],{},[73,36613,36614,3459,36616,36584],{},[76,36615,78],{},[39,36617,36442],{},[73,36619,36620,355,36622,36624,36625,36627,36628,36631,36632,36635],{},[76,36621,84],{},[76,36623,438],{}," an arrow class field is initialized per-instance in the constructor step, capturing that instance's ",[39,36626,950],{}," lexically — so it never needs ",[39,36629,36630],{},".bind()"," and is safe to hand off as a callback directly. The cost is that every instance gets its own copy of the function instead of sharing one on ",[39,36633,36634],{},"Button.prototype",", which matters if you're creating thousands of instances. For a handful of instances this is a non-issue and the auto-binding convenience usually wins.",[15,36637,36638,36640,36719,36748],{"language":247},[18,36639,15311],{"id":15310},[257,36641,36642],{"language":247},[260,36643,36645],{"className":262,"code":36644,"language":247,"meta":264,"style":264},"'use strict';\n\nconst user = { name: 'Ava', greet() { return `Hi, I'm ${this.name}`; } };\nconst { greet } = user;\n\nconsole.log(greet());\n",[39,36646,36647,36653,36657,36689,36703,36707],{"__ignoreMap":264},[268,36648,36649,36651],{"class":270,"line":271},[268,36650,34399],{"class":289},[268,36652,293],{"class":282},[268,36654,36655],{"class":270,"line":286},[268,36656,5033],{"emptyLinePlaceholder":35},[268,36658,36659,36661,36663,36665,36667,36669,36671,36673,36675,36677,36679,36681,36683,36685,36687],{"class":270,"line":296},[268,36660,243],{"class":274},[268,36662,4071],{"class":305},[268,36664,616],{"class":274},[268,36666,4076],{"class":282},[268,36668,34187],{"class":289},[268,36670,42],{"class":282},[268,36672,12761],{"class":278},[268,36674,34756],{"class":282},[268,36676,9151],{"class":274},[268,36678,34202],{"class":289},[268,36680,950],{"class":305},[268,36682,462],{"class":289},[268,36684,14605],{"class":282},[268,36686,11603],{"class":289},[268,36688,34771],{"class":282},[268,36690,36691,36693,36695,36697,36699,36701],{"class":270,"line":311},[268,36692,243],{"class":274},[268,36694,20200],{"class":282},[268,36696,12761],{"class":305},[268,36698,7908],{"class":282},[268,36700,302],{"class":274},[268,36702,26989],{"class":282},[268,36704,36705],{"class":270,"line":788},[268,36706,5033],{"emptyLinePlaceholder":35},[268,36708,36709,36711,36713,36715,36717],{"class":270,"line":1951},[268,36710,1353],{"class":282},[268,36712,1356],{"class":278},[268,36714,622],{"class":282},[268,36716,12761],{"class":278},[268,36718,8174],{"class":282},[23,36720,36722,36730,36735,36740],{"className":36721},[26],[28,36723,36725,6738,36727],{"className":36724},[31],[33,36726],{"disabled":35,"type":36},[39,36728,36729],{},"TypeError: Cannot read properties of undefined (reading 'name')",[28,36731,36733,34245],{"className":36732},[31],[33,36734],{"disabled":35,"type":36},[28,36736,36738,34251],{"className":36737},[31],[33,36739],{"disabled":35,"type":36},[28,36741,36743,35787,36745,36747],{"className":36742},[31],[33,36744],{"disabled":35,"type":36},[39,36746,12761],{}," isn't defined",[66,36749,36750,36752,36758],{},[69,36751,71],{},[73,36753,36754,35317,36756],{},[76,36755,78],{},[39,36757,36729],{},[73,36759,36760,36762,36763,36765,36766,36768,36769,36771,36772,36774,36775,36777,36778,830,36780,1179,36782,36784,36785,36787,36788,36791,36792,36794],{},[76,36761,84],{}," Destructuring ",[39,36764,12761],{}," off ",[39,36767,4155],{}," copies the ",[104,36770,275],{},", not its association with ",[39,36773,4155],{}," — calling the standalone ",[39,36776,12870],{}," afterward is a plain invocation with default binding, and in strict mode that means ",[39,36779,950],{},[39,36781,833],{},[39,36783,31168],{}," throws. The best-practice fix is to either call it as ",[39,36786,34284],{},", bind it explicitly (",[39,36789,36790],{},"const greet = user.greet.bind(user)","), or avoid destructuring methods that depend on ",[39,36793,950],{}," at all — prefer plain functions with explicit parameters when a value needs to travel independently of its object.",[15,36796,36797,36801,36896,36926],{"language":247},[18,36798,36800],{"id":36799},"q18-which-style-is-generally-the-more-testable-reusable-choice-for-a-value-transformation-function","Q18. Which style is generally the more testable, reusable choice for a value-transformation function?",[257,36802,36803],{"language":247},[260,36804,36806],{"className":262,"code":36805,"language":247,"meta":264,"style":264},"\u002F\u002F Option A\nfunction applyDiscount() {\n  return this.price * (1 - this.rate);\n}\n\n\u002F\u002F Option B\nfunction applyDiscount(price, rate) {\n  return price * (1 - rate);\n}\n",[39,36807,36808,36813,36822,36844,36848,36852,36857,36874,36892],{"__ignoreMap":264},[268,36809,36810],{"class":270,"line":271},[268,36811,36812],{"class":29390},"\u002F\u002F Option A\n",[268,36814,36815,36817,36820],{"class":270,"line":286},[268,36816,275],{"class":274},[268,36818,36819],{"class":278}," applyDiscount",[268,36821,283],{"class":282},[268,36823,36824,36826,36828,36831,36833,36835,36837,36839,36841],{"class":270,"line":296},[268,36825,1240],{"class":274},[268,36827,30206],{"class":305},[268,36829,36830],{"class":282},".price ",[268,36832,6134],{"class":274},[268,36834,2182],{"class":282},[268,36836,2255],{"class":305},[268,36838,6286],{"class":274},[268,36840,30206],{"class":305},[268,36842,36843],{"class":282},".rate);\n",[268,36845,36846],{"class":270,"line":311},[268,36847,314],{"class":282},[268,36849,36850],{"class":270,"line":788},[268,36851,5033],{"emptyLinePlaceholder":35},[268,36853,36854],{"class":270,"line":1951},[268,36855,36856],{"class":29390},"\u002F\u002F Option B\n",[268,36858,36859,36861,36863,36865,36867,36869,36872],{"class":270,"line":8955},[268,36860,275],{"class":274},[268,36862,36819],{"class":278},[268,36864,622],{"class":282},[268,36866,17225],{"class":1222},[268,36868,42],{"class":282},[268,36870,36871],{"class":1222},"rate",[268,36873,1235],{"class":282},[268,36875,36876,36878,36881,36883,36885,36887,36889],{"class":270,"line":8966},[268,36877,1240],{"class":274},[268,36879,36880],{"class":282}," price ",[268,36882,6134],{"class":274},[268,36884,2182],{"class":282},[268,36886,2255],{"class":305},[268,36888,6286],{"class":274},[268,36890,36891],{"class":282}," rate);\n",[268,36893,36894],{"class":270,"line":8974},[268,36895,314],{"class":282},[23,36897,36899,36905,36914,36920],{"className":36898},[26],[28,36900,36902,36904],{"className":36901},[31],[33,36903],{"disabled":35,"type":36}," Option B — explicit parameters, no dependency on how the function is called",[28,36906,36908,36910,36911,36913],{"className":36907},[31],[33,36909],{"disabled":35,"type":36}," Option A — relying on ",[39,36912,950],{}," is always more idiomatic in JavaScript",[28,36915,36917,36919],{"className":36916},[31],[33,36918],{"disabled":35,"type":36}," They are equivalent in every practical sense",[28,36921,36923,36925],{"className":36922},[31],[33,36924],{"disabled":35,"type":36}," Option A, but only if it's converted to an arrow function",[66,36927,36928,36930,36935],{},[69,36929,71],{},[73,36931,36932,36934],{},[76,36933,78],{}," A — Option B — explicit parameters, no dependency on how the function is called",[73,36936,36937,355,36939,36941,36942,36944,36945,446,36947,36949,36950,36952,36953,36955],{},[76,36938,84],{},[76,36940,930],{}," functions that read ",[39,36943,950],{}," are coupled to their call-site — they only work correctly when invoked as a method (or explicitly bound), which makes them fragile when passed around, destructured, or unit-tested in isolation (you'd have to fake a receiver via ",[39,36946,34411],{},[39,36948,34637],{}," just to test them). Preferring explicit parameters over implicit ",[39,36951,950],{}," is a widely recommended practice for utility\u002Fpure functions; ",[39,36954,950],{}," binding is best reserved for genuine object methods that need to read multiple pieces of instance state.",[15,36957,36958,36965,36989,37020],{"language":247},[18,36959,36961,36962,36964],{"id":36960},"q19-what-does-this-refer-to-at-the-top-level-of-an-es-module-file","Q19. What does ",[39,36963,950],{}," refer to at the top level of an ES module file?",[257,36966,36967],{"language":247},[260,36968,36970],{"className":262,"code":36969,"language":247,"meta":264,"style":264},"\u002F\u002F inside a .mjs file or a \u003Cscript type=\"module\">\nconsole.log(this);\n",[39,36971,36972,36977],{"__ignoreMap":264},[268,36973,36974],{"class":270,"line":271},[268,36975,36976],{"class":29390},"\u002F\u002F inside a .mjs file or a \u003Cscript type=\"module\">\n",[268,36978,36979,36981,36983,36985,36987],{"class":270,"line":286},[268,36980,1353],{"class":282},[268,36982,1356],{"class":278},[268,36984,622],{"class":282},[268,36986,950],{"class":305},[268,36988,628],{"class":282},[23,36990,36992,36997,37006,37013],{"className":36991},[26],[28,36993,36995,17135],{"className":36994},[31],[33,36996],{"disabled":35,"type":36},[28,36998,37000,37002,37003,37005],{"className":36999},[31],[33,37001],{"disabled":35,"type":36}," The module's own ",[39,37004,638],{}," object, like in CommonJS",[28,37007,37009,355,37011],{"className":37008},[31],[33,37010],{"disabled":35,"type":36},[39,37012,994],{},[28,37014,37016,355,37018],{"className":37015},[31],[33,37017],{"disabled":35,"type":36},[39,37019,2650],{},[66,37021,37022,37024,37028],{},[69,37023,71],{},[73,37025,37026,34385],{},[76,37027,78],{},[73,37029,37030,355,37032,37034,37035,37037,37038,37040,37041,830,37043,37045,37046,37049,37050,830,37052,37054],{},[76,37031,84],{},[76,37033,182],{}," ES modules are always strict and have no top-level ",[39,37036,950],{}," binding to any object — it's ",[39,37039,833],{}," by spec, unlike CommonJS modules, where top-level ",[39,37042,950],{},[39,37044,658],{},". Code migrating from CommonJS to ESM that relied on top-level ",[39,37047,37048],{},"this.foo = ..."," for exports will silently break (",[39,37051,950],{},[39,37053,833],{},", so property access on it throws) rather than continuing to \"work\" some other way.",[15,37056,37057,37059,37146,37180],{"language":247},[18,37058,19301],{"id":19300},[257,37060,37061],{"language":247},[260,37062,37064],{"className":262,"code":37063,"language":247,"meta":264,"style":264},"const nums = [1, 2, 3];\nconst scaled = nums.map(function (x) {\n  return this.multiplier * x;\n}, { multiplier: 10 });\n\nconsole.log(scaled);\n",[39,37065,37066,37088,37111,37124,37133,37137],{"__ignoreMap":264},[268,37067,37068,37070,37072,37074,37076,37078,37080,37082,37084,37086],{"class":270,"line":271},[268,37069,243],{"class":274},[268,37071,12090],{"class":305},[268,37073,616],{"class":274},[268,37075,8710],{"class":282},[268,37077,2255],{"class":305},[268,37079,42],{"class":282},[268,37081,2258],{"class":305},[268,37083,42],{"class":282},[268,37085,3423],{"class":305},[268,37087,8737],{"class":282},[268,37089,37090,37092,37095,37097,37099,37101,37103,37105,37107,37109],{"class":270,"line":286},[268,37091,243],{"class":274},[268,37093,37094],{"class":305}," scaled",[268,37096,616],{"class":274},[268,37098,15341],{"class":282},[268,37100,23950],{"class":278},[268,37102,622],{"class":282},[268,37104,275],{"class":274},[268,37106,2182],{"class":282},[268,37108,2403],{"class":1222},[268,37110,1235],{"class":282},[268,37112,37113,37115,37117,37120,37122],{"class":270,"line":296},[268,37114,1240],{"class":274},[268,37116,30206],{"class":305},[268,37118,37119],{"class":282},".multiplier ",[268,37121,6134],{"class":274},[268,37123,3547],{"class":282},[268,37125,37126,37129,37131],{"class":270,"line":311},[268,37127,37128],{"class":282},"}, { multiplier: ",[268,37130,5825],{"class":305},[268,37132,36080],{"class":282},[268,37134,37135],{"class":270,"line":788},[268,37136,5033],{"emptyLinePlaceholder":35},[268,37138,37139,37141,37143],{"class":270,"line":1951},[268,37140,1353],{"class":282},[268,37142,1356],{"class":278},[268,37144,37145],{"class":282},"(scaled);\n",[23,37147,37149,37157,37165,37173],{"className":37148},[26],[28,37150,37152,355,37154],{"className":37151},[31],[33,37153],{"disabled":35,"type":36},[268,37155,37156],{},"10, 20, 30",[28,37158,37160,34517,37162,37164],{"className":37159},[31],[33,37161],{"disabled":35,"type":36},[39,37163,23950],{},"'s callback can't be passed a receiver",[28,37166,37168,355,37170],{"className":37167},[31],[33,37169],{"disabled":35,"type":36},[268,37171,37172],{},"NaN, NaN, NaN",[28,37174,37176,355,37178],{"className":37175},[31],[33,37177],{"disabled":35,"type":36},[268,37179,23888],{},[66,37181,37182,37184,37190],{},[69,37183,71],{},[73,37185,37186,3459,37188],{},[76,37187,78],{},[268,37189,37156],{},[73,37191,37192,355,37194,37196,37197,42,37199,42,37201,42,37203,42,37206,42,37209,37212,37213,37215,37216,37218,37219,830,37222,37224,37225,37228,37229,37231],{},[76,37193,84],{},[76,37195,930],{}," many array iteration methods (",[39,37198,23950],{},[39,37200,14962],{},[39,37202,12330],{},[39,37204,37205],{},"some",[39,37207,37208],{},"every",[39,37210,37211],{},"find",") accept an optional second argument that becomes ",[39,37214,950],{}," inside the callback — it's a lesser-known alternative to ",[39,37217,36630],{}," or an arrow function for supplying a receiver. Here ",[39,37220,37221],{},"this.multiplier",[39,37223,5825],{}," for every call, so each element is scaled: ",[39,37226,37227],{},"[1*10, 2*10, 3*10]",". It's underused compared to arrow functions\u002Fclosures, but recognizing it avoids \"wait, how does ",[39,37230,950],{}," work here\" confusion when it appears in existing code.",[2107,37233,37234],{},"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 .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}",{"title":264,"searchDepth":286,"depth":286,"links":37236},[37237,37238,37239,37241,37242,37243,37244,37245,37246,37247,37248,37249,37250,37251,37252,37254,37255,37256,37257,37259],{"id":23360,"depth":296,"text":23361},{"id":34298,"depth":296,"text":34299},{"id":34408,"depth":296,"text":37240},"Q3. What does call do here?",{"id":13031,"depth":296,"text":13032},{"id":34729,"depth":296,"text":34730},{"id":13320,"depth":296,"text":13321},{"id":13527,"depth":296,"text":13528},{"id":35229,"depth":296,"text":35230},{"id":35341,"depth":296,"text":35342},{"id":35542,"depth":296,"text":35543},{"id":35721,"depth":296,"text":35722},{"id":14381,"depth":296,"text":14382},{"id":14537,"depth":296,"text":14538},{"id":14773,"depth":296,"text":14774},{"id":36306,"depth":296,"text":37253},"Q15. Why is this.handleClick = this.handleClick.bind(this) written inside this constructor?",{"id":36516,"depth":296,"text":36517},{"id":15310,"depth":296,"text":15311},{"id":36799,"depth":296,"text":36800},{"id":36960,"depth":296,"text":37258},"Q19. What does this refer to at the top level of an ES module file?",{"id":19300,"depth":296,"text":19301},{},"\u002Fjs\u002F11-this-keyword",{"title":34150,"description":264},"js\u002F11-this-keyword","nJp5igyZ0J5H0qcdrZnThdGK3i-zTIH4XvKKC3Z85Uc",{"id":37266,"title":37267,"body":37268,"description":264,"extension":2144,"meta":40906,"navigation":35,"path":40907,"seo":40908,"stem":40909,"__hash__":40910},"content\u002Fjs\u002F12-closures-and-lexical-scope.md","12 — Closures & Lexical Scope",{"type":8,"value":37269,"toc":40881},[37270,37273,37443,37571,37692,37813,38081,38265,38440,38645,38827,38968,39116,39262,39459,39667,39850,40014,40240,40511,40723,40878],[11,37271,37267],{"id":37272},"_12-closures-lexical-scope",[15,37274,37275,37277,37377,37404],{"language":247},[18,37276,26821],{"id":26820},[257,37278,37279],{"language":247},[260,37280,37282],{"className":262,"code":37281,"language":247,"meta":264,"style":264},"function makeCounter() {\n  let count = 0;\n  return function increment() {\n    count++;\n    return count;\n  };\n}\n\nconst counter = makeCounter();\nconsole.log(counter(), counter(), counter());\n",[39,37283,37284,37293,37305,37316,37325,37332,37336,37340,37344,37356],{"__ignoreMap":264},[268,37285,37286,37288,37291],{"class":270,"line":271},[268,37287,275],{"class":274},[268,37289,37290],{"class":278}," makeCounter",[268,37292,283],{"class":282},[268,37294,37295,37297,37299,37301,37303],{"class":270,"line":286},[268,37296,2206],{"class":274},[268,37298,10091],{"class":282},[268,37300,302],{"class":274},[268,37302,5728],{"class":305},[268,37304,293],{"class":282},[268,37306,37307,37309,37311,37314],{"class":270,"line":296},[268,37308,1240],{"class":274},[268,37310,12080],{"class":274},[268,37312,37313],{"class":278}," increment",[268,37315,283],{"class":282},[268,37317,37318,37321,37323],{"class":270,"line":311},[268,37319,37320],{"class":282},"    count",[268,37322,9401],{"class":274},[268,37324,293],{"class":282},[268,37326,37327,37329],{"class":270,"line":788},[268,37328,9871],{"class":274},[268,37330,37331],{"class":282}," count;\n",[268,37333,37334],{"class":270,"line":1951},[268,37335,15185],{"class":282},[268,37337,37338],{"class":270,"line":8955},[268,37339,314],{"class":282},[268,37341,37342],{"class":270,"line":8966},[268,37343,5033],{"emptyLinePlaceholder":35},[268,37345,37346,37348,37350,37352,37354],{"class":270,"line":8974},[268,37347,243],{"class":274},[268,37349,34901],{"class":305},[268,37351,616],{"class":274},[268,37353,37290],{"class":278},[268,37355,794],{"class":282},[268,37357,37358,37360,37362,37364,37366,37369,37371,37373,37375],{"class":270,"line":8985},[268,37359,1353],{"class":282},[268,37361,1356],{"class":278},[268,37363,622],{"class":282},[268,37365,35037],{"class":278},[268,37367,37368],{"class":282},"(), ",[268,37370,35037],{"class":278},[268,37372,37368],{"class":282},[268,37374,35037],{"class":278},[268,37376,8174],{"class":282},[23,37378,37380,37386,37392,37398],{"className":37379},[26],[28,37381,37383,37385],{"className":37382},[31],[33,37384],{"disabled":35,"type":36}," 1 2 3",[28,37387,37389,37391],{"className":37388},[31],[33,37390],{"disabled":35,"type":36}," 1 1 1",[28,37393,37395,37397],{"className":37394},[31],[33,37396],{"disabled":35,"type":36}," undefined undefined undefined",[28,37399,37401,37403],{"className":37400},[31],[33,37402],{"disabled":35,"type":36}," NaN NaN NaN",[66,37405,37406,37408,37413],{},[69,37407,71],{},[73,37409,37410,37412],{},[76,37411,78],{}," A — 1 2 3",[73,37414,37415,355,37417,37419,37420,7728,37423,37425,37426,37429,37430,37432,37433,37435,37436,37438,37439,37442],{},[76,37416,84],{},[39,37418,34969],{}," forms a ",[76,37421,37422],{},"closure",[39,37424,10191],{}," — it keeps a live reference to that variable binding even after ",[39,37427,37428],{},"makeCounter"," has returned. Each call mutates the same ",[39,37431,10191],{},", so it increments across calls rather than resetting. \"1 1 1\" is the trap a beginner falls into by assuming ",[39,37434,10191],{}," re-initializes to ",[39,37437,3307],{}," on every call, as if it were a local variable reset each time — but it's only initialized once, when ",[39,37440,37441],{},"makeCounter()"," runs.",[15,37444,37445,37447,37520,37546],{"language":247},[18,37446,12737],{"id":12736},[257,37448,37449],{"language":247},[260,37450,37452],{"className":262,"code":37451,"language":247,"meta":264,"style":264},"function outer() {\n  const secret = 42;\n  return () => secret;\n}\n\nconst getSecret = outer();\nconsole.log(getSecret());\n",[39,37453,37454,37462,37475,37486,37490,37494,37507],{"__ignoreMap":264},[268,37455,37456,37458,37460],{"class":270,"line":271},[268,37457,275],{"class":274},[268,37459,9700],{"class":278},[268,37461,283],{"class":282},[268,37463,37464,37466,37469,37471,37473],{"class":270,"line":286},[268,37465,12441],{"class":274},[268,37467,37468],{"class":305}," secret",[268,37470,616],{"class":274},[268,37472,779],{"class":305},[268,37474,293],{"class":282},[268,37476,37477,37479,37481,37483],{"class":270,"line":296},[268,37478,1240],{"class":274},[268,37480,15158],{"class":282},[268,37482,9414],{"class":274},[268,37484,37485],{"class":282}," secret;\n",[268,37487,37488],{"class":270,"line":311},[268,37489,314],{"class":282},[268,37491,37492],{"class":270,"line":788},[268,37493,5033],{"emptyLinePlaceholder":35},[268,37495,37496,37498,37501,37503,37505],{"class":270,"line":1951},[268,37497,243],{"class":274},[268,37499,37500],{"class":305}," getSecret",[268,37502,616],{"class":274},[268,37504,9700],{"class":278},[268,37506,794],{"class":282},[268,37508,37509,37511,37513,37515,37518],{"class":270,"line":8955},[268,37510,1353],{"class":282},[268,37512,1356],{"class":278},[268,37514,622],{"class":282},[268,37516,37517],{"class":278},"getSecret",[268,37519,8174],{"class":282},[23,37521,37523,37528,37533,37541],{"className":37522},[26],[28,37524,37526,779],{"className":37525},[31],[33,37527],{"disabled":35,"type":36},[28,37529,37531,17135],{"className":37530},[31],[33,37532],{"disabled":35,"type":36},[28,37534,37536,35787,37538,37540],{"className":37535},[31],[33,37537],{"disabled":35,"type":36},[39,37539,9628],{}," has already returned",[28,37542,37544,4794],{"className":37543},[31],[33,37545],{"disabled":35,"type":36},[66,37547,37548,37550,37555],{},[69,37549,71],{},[73,37551,37552,37554],{},[76,37553,78],{}," A — 42",[73,37556,37557,37559,37560,37563,37564,37567,37568,37570],{},[76,37558,84],{}," Even though ",[39,37561,37562],{},"outer()"," has finished executing, the arrow function returned from it keeps ",[39,37565,37566],{},"secret"," alive via closure — the variable isn't garbage collected while a reachable function still references it. This is exactly what makes closures useful for private state: ",[39,37569,37566],{}," is inaccessible from outside except through the returned function.",[15,37572,37573,37575,37630,37657],{"language":247},[18,37574,12877],{"id":12876},[257,37576,37577],{"language":247},[260,37578,37580],{"className":262,"code":37579,"language":247,"meta":264,"style":264},"for (var i = 0; i \u003C 3; i++) {\n  setTimeout(() => console.log(i), 0);\n}\n",[39,37581,37582,37608,37626],{"__ignoreMap":264},[268,37583,37584,37586,37588,37590,37592,37594,37596,37598,37600,37602,37604,37606],{"class":270,"line":271},[268,37585,6926],{"class":274},[268,37587,2182],{"class":282},[268,37589,1440],{"class":274},[268,37591,9384],{"class":282},[268,37593,302],{"class":274},[268,37595,5728],{"class":305},[268,37597,9391],{"class":282},[268,37599,1076],{"class":274},[268,37601,3396],{"class":305},[268,37603,9398],{"class":282},[268,37605,9401],{"class":274},[268,37607,1235],{"class":282},[268,37609,37610,37612,37614,37616,37618,37620,37622,37624],{"class":270,"line":286},[268,37611,9408],{"class":278},[268,37613,9411],{"class":282},[268,37615,9414],{"class":274},[268,37617,9417],{"class":282},[268,37619,1356],{"class":278},[268,37621,9422],{"class":282},[268,37623,3307],{"class":305},[268,37625,628],{"class":282},[268,37627,37628],{"class":270,"line":296},[268,37629,314],{"class":282},[23,37631,37633,37639,37645,37651],{"className":37632},[26],[28,37634,37636,37638],{"className":37635},[31],[33,37637],{"disabled":35,"type":36}," 3 3 3",[28,37640,37642,37644],{"className":37641},[31],[33,37643],{"disabled":35,"type":36}," 0 1 2",[28,37646,37648,37650],{"className":37647},[31],[33,37649],{"disabled":35,"type":36}," 0 1 2 3",[28,37652,37654,37656],{"className":37653},[31],[33,37655],{"disabled":35,"type":36}," 2 2 2",[66,37658,37659,37661,37666],{},[69,37660,71],{},[73,37662,37663,37665],{},[76,37664,78],{}," A — 3 3 3",[73,37667,37668,355,37670,37672,37673,355,37675,37677,37678,37680,37681,9582,37683,37685,37686,37688,37689,37691],{},[76,37669,84],{},[39,37671,1440],{}," is function\u002Fglobal-scoped, not block-scoped, so there is only ",[76,37674,9572],{},[39,37676,9509],{}," binding shared by the whole loop and every callback closure. By the time any ",[39,37679,9578],{}," callback actually runs (after the synchronous loop has finished), ",[39,37682,9509],{},[39,37684,3423],{},", and all three callbacks read that same final value. \"0 1 2\" is what people expect from intuition — it's the correct answer only once ",[39,37687,1440],{}," is swapped for ",[39,37690,240],{}," (see next question).",[15,37693,37694,37696,37751,37775],{"language":247},[18,37695,13032],{"id":13031},[257,37697,37698],{"language":247},[260,37699,37701],{"className":262,"code":37700,"language":247,"meta":264,"style":264},"for (let i = 0; i \u003C 3; i++) {\n  setTimeout(() => console.log(i), 0);\n}\n",[39,37702,37703,37729,37747],{"__ignoreMap":264},[268,37704,37705,37707,37709,37711,37713,37715,37717,37719,37721,37723,37725,37727],{"class":270,"line":271},[268,37706,6926],{"class":274},[268,37708,2182],{"class":282},[268,37710,240],{"class":274},[268,37712,9384],{"class":282},[268,37714,302],{"class":274},[268,37716,5728],{"class":305},[268,37718,9391],{"class":282},[268,37720,1076],{"class":274},[268,37722,3396],{"class":305},[268,37724,9398],{"class":282},[268,37726,9401],{"class":274},[268,37728,1235],{"class":282},[268,37730,37731,37733,37735,37737,37739,37741,37743,37745],{"class":270,"line":286},[268,37732,9408],{"class":278},[268,37734,9411],{"class":282},[268,37736,9414],{"class":274},[268,37738,9417],{"class":282},[268,37740,1356],{"class":278},[268,37742,9422],{"class":282},[268,37744,3307],{"class":305},[268,37746,628],{"class":282},[268,37748,37749],{"class":270,"line":296},[268,37750,314],{"class":282},[23,37752,37754,37759,37764,37770],{"className":37753},[26],[28,37755,37757,37644],{"className":37756},[31],[33,37758],{"disabled":35,"type":36},[28,37760,37762,37638],{"className":37761},[31],[33,37763],{"disabled":35,"type":36},[28,37765,37767,37769],{"className":37766},[31],[33,37768],{"disabled":35,"type":36}," 0 0 0",[28,37771,37773,37385],{"className":37772},[31],[33,37774],{"disabled":35,"type":36},[66,37776,37777,37779,37784],{},[69,37778,71],{},[73,37780,37781,37783],{},[76,37782,78],{}," A — 0 1 2",[73,37785,37786,4396,37788,37791,37792,37796,37797,37799,37800,37802,37803,42,37805,42,37807,37809,37810,37812],{},[76,37787,84],{},[39,37789,37790],{},"for (let ...)"," form is special-cased by the spec: it creates a ",[76,37793,9593,37794,9596],{},[39,37795,9509],{},", copying the previous iteration's value into the new binding before running the loop body. Each ",[39,37798,9578],{}," callback closes over its own iteration's ",[39,37801,9509],{},", so they log ",[39,37804,3307],{},[39,37806,2255],{},[39,37808,2258],{}," in order — this is the standard fix for the classic ",[39,37811,1440],{}," loop bug in Q3.",[15,37814,37815,37819,38018,38041],{"language":247},[18,37816,37818],{"id":37817},"q5-what-is-logged","Q5. What is logged?",[257,37820,37821],{"language":247},[260,37822,37824],{"className":262,"code":37823,"language":247,"meta":264,"style":264},"function memoize(fn) {\n  const cache = new Map();\n  return function (n) {\n    if (cache.has(n)) return cache.get(n);\n    const result = fn(n);\n    cache.set(n, result);\n    return result;\n  };\n}\n\nlet calls = 0;\nconst square = memoize(n => { calls++; return n * n; });\n\nsquare(4);\nsquare(4);\nsquare(5);\nconsole.log(calls);\n",[39,37825,37826,37840,37854,37866,37889,37903,37914,37920,37924,37928,37932,37944,37976,37980,37990,38000,38010],{"__ignoreMap":264},[268,37827,37828,37830,37833,37835,37838],{"class":270,"line":271},[268,37829,275],{"class":274},[268,37831,37832],{"class":278}," memoize",[268,37834,622],{"class":282},[268,37836,37837],{"class":1222},"fn",[268,37839,1235],{"class":282},[268,37841,37842,37844,37846,37848,37850,37852],{"class":270,"line":286},[268,37843,12441],{"class":274},[268,37845,15807],{"class":305},[268,37847,616],{"class":274},[268,37849,11370],{"class":274},[268,37851,11373],{"class":278},[268,37853,794],{"class":282},[268,37855,37856,37858,37860,37862,37864],{"class":270,"line":296},[268,37857,1240],{"class":274},[268,37859,12080],{"class":274},[268,37861,2182],{"class":282},[268,37863,4599],{"class":1222},[268,37865,1235],{"class":282},[268,37867,37868,37870,37873,37876,37879,37881,37884,37886],{"class":270,"line":311},[268,37869,9686],{"class":274},[268,37871,37872],{"class":282}," (cache.",[268,37874,37875],{"class":278},"has",[268,37877,37878],{"class":282},"(n)) ",[268,37880,9151],{"class":274},[268,37882,37883],{"class":282}," cache.",[268,37885,32437],{"class":278},[268,37887,37888],{"class":282},"(n);\n",[268,37890,37891,37894,37896,37898,37901],{"class":270,"line":788},[268,37892,37893],{"class":274},"    const",[268,37895,5583],{"class":305},[268,37897,616],{"class":274},[268,37899,37900],{"class":278}," fn",[268,37902,37888],{"class":282},[268,37904,37905,37908,37911],{"class":270,"line":1951},[268,37906,37907],{"class":282},"    cache.",[268,37909,37910],{"class":278},"set",[268,37912,37913],{"class":282},"(n, result);\n",[268,37915,37916,37918],{"class":270,"line":8955},[268,37917,9871],{"class":274},[268,37919,10895],{"class":282},[268,37921,37922],{"class":270,"line":8966},[268,37923,15185],{"class":282},[268,37925,37926],{"class":270,"line":8974},[268,37927,314],{"class":282},[268,37929,37930],{"class":270,"line":8985},[268,37931,5033],{"emptyLinePlaceholder":35},[268,37933,37934,37936,37938,37940,37942],{"class":270,"line":8990},[268,37935,240],{"class":274},[268,37937,14552],{"class":282},[268,37939,302],{"class":274},[268,37941,5728],{"class":305},[268,37943,293],{"class":282},[268,37945,37946,37948,37950,37952,37954,37956,37958,37960,37963,37965,37967,37969,37971,37973],{"class":270,"line":8997},[268,37947,243],{"class":274},[268,37949,31438],{"class":305},[268,37951,616],{"class":274},[268,37953,37832],{"class":278},[268,37955,622],{"class":282},[268,37957,4599],{"class":1222},[268,37959,14969],{"class":274},[268,37961,37962],{"class":282}," { calls",[268,37964,9401],{"class":274},[268,37966,2272],{"class":282},[268,37968,9151],{"class":274},[268,37970,13355],{"class":282},[268,37972,6134],{"class":274},[268,37974,37975],{"class":282}," n; });\n",[268,37977,37978],{"class":270,"line":9002},[268,37979,5033],{"emptyLinePlaceholder":35},[268,37981,37982,37984,37986,37988],{"class":270,"line":14676},[268,37983,31493],{"class":278},[268,37985,622],{"class":282},[268,37987,15049],{"class":305},[268,37989,628],{"class":282},[268,37991,37992,37994,37996,37998],{"class":270,"line":14681},[268,37993,31493],{"class":278},[268,37995,622],{"class":282},[268,37997,15049],{"class":305},[268,37999,628],{"class":282},[268,38001,38002,38004,38006,38008],{"class":270,"line":31051},[268,38003,31493],{"class":278},[268,38005,622],{"class":282},[268,38007,2429],{"class":305},[268,38009,628],{"class":282},[268,38011,38012,38014,38016],{"class":270,"line":31071},[268,38013,1353],{"class":282},[268,38015,1356],{"class":278},[268,38017,14688],{"class":282},[23,38019,38021,38026,38031,38036],{"className":38020},[26],[28,38022,38024,2214],{"className":38023},[31],[33,38025],{"disabled":35,"type":36},[28,38027,38029,3396],{"className":38028},[31],[33,38030],{"disabled":35,"type":36},[28,38032,38034,2199],{"className":38033},[31],[33,38035],{"disabled":35,"type":36},[28,38037,38039,5728],{"className":38038},[31],[33,38040],{"disabled":35,"type":36},[66,38042,38043,38045,38050],{},[69,38044,71],{},[73,38046,38047,38049],{},[76,38048,78],{}," A — 2",[73,38051,38052,38054,38055,38057,38058,38061,38062,38064,38065,358,38067,38070,38071,38074,38075,38077,38078,38080],{},[76,38053,84],{}," The memoized wrapper closes over ",[39,38056,15925],{}," so it persists across calls. The first ",[39,38059,38060],{},"square(4)"," is a miss (computes, increments ",[39,38063,14764],{}," to 1, caches it), the second ",[39,38066,38060],{},[76,38068,38069],{},"hit"," and returns the cached value without calling the original function, and ",[39,38072,38073],{},"square(5)"," is a new miss (increments ",[39,38076,14764],{}," to 2). Expecting ",[39,38079,3423],{}," assumes memoization isn't working — that's the whole point of the closure-backed cache.",[15,38082,38083,38085,38196,38220],{"language":247},[18,38084,13321],{"id":13320},[257,38086,38087],{"language":247},[260,38088,38090],{"className":262,"code":38089,"language":247,"meta":264,"style":264},"function createBankAccount(balance) {\n  return {\n    deposit(amount) { balance += amount; return balance; },\n    getBalance() { return balance; }\n  };\n}\n\nconst acc = createBankAccount(100);\nacc.deposit(50);\nconsole.log(acc.balance);\n",[39,38091,38092,38105,38111,38133,38145,38149,38153,38157,38174,38187],{"__ignoreMap":264},[268,38093,38094,38096,38099,38101,38103],{"class":270,"line":271},[268,38095,275],{"class":274},[268,38097,38098],{"class":278}," createBankAccount",[268,38100,622],{"class":282},[268,38102,22170],{"class":1222},[268,38104,1235],{"class":282},[268,38106,38107,38109],{"class":270,"line":286},[268,38108,1240],{"class":274},[268,38110,9914],{"class":282},[268,38112,38113,38116,38118,38120,38123,38125,38128,38130],{"class":270,"line":296},[268,38114,38115],{"class":278},"    deposit",[268,38117,622],{"class":282},[268,38119,31848],{"class":1222},[268,38121,38122],{"class":282},") { balance ",[268,38124,14575],{"class":274},[268,38126,38127],{"class":282}," amount; ",[268,38129,9151],{"class":274},[268,38131,38132],{"class":282}," balance; },\n",[268,38134,38135,38138,38140,38142],{"class":270,"line":311},[268,38136,38137],{"class":278},"    getBalance",[268,38139,34756],{"class":282},[268,38141,9151],{"class":274},[268,38143,38144],{"class":282}," balance; }\n",[268,38146,38147],{"class":270,"line":788},[268,38148,15185],{"class":282},[268,38150,38151],{"class":270,"line":1951},[268,38152,314],{"class":282},[268,38154,38155],{"class":270,"line":8955},[268,38156,5033],{"emptyLinePlaceholder":35},[268,38158,38159,38161,38164,38166,38168,38170,38172],{"class":270,"line":8966},[268,38160,243],{"class":274},[268,38162,38163],{"class":305}," acc",[268,38165,616],{"class":274},[268,38167,38098],{"class":278},[268,38169,622],{"class":282},[268,38171,13912],{"class":305},[268,38173,628],{"class":282},[268,38175,38176,38179,38181,38183,38185],{"class":270,"line":8974},[268,38177,38178],{"class":282},"acc.",[268,38180,31918],{"class":278},[268,38182,622],{"class":282},[268,38184,32109],{"class":305},[268,38186,628],{"class":282},[268,38188,38189,38191,38193],{"class":270,"line":8985},[268,38190,1353],{"class":282},[268,38192,1356],{"class":278},[268,38194,38195],{"class":282},"(acc.balance);\n",[23,38197,38199,38204,38210,38215],{"className":38198},[26],[28,38200,38202,17135],{"className":38201},[31],[33,38203],{"disabled":35,"type":36},[28,38205,38207,38209],{"className":38206},[31],[33,38208],{"disabled":35,"type":36}," 150",[28,38211,38213,13821],{"className":38212},[31],[33,38214],{"disabled":35,"type":36},[28,38216,38218,34257],{"className":38217},[31],[33,38219],{"disabled":35,"type":36},[66,38221,38222,38224,38228],{},[69,38223,71],{},[73,38225,38226,34385],{},[76,38227,78],{},[73,38229,38230,355,38232,38234,38235,38238,38239,186,38241,38244,38245,38248,38249,6033,38251,38253,38254,38256,38257,38260,38261,38264],{},[76,38231,84],{},[39,38233,22170],{}," is never assigned as a property of the returned object — it only exists as a variable in ",[39,38236,38237],{},"createBankAccount","'s scope, accessible to ",[39,38240,31918],{},[39,38242,38243],{},"getBalance"," through closure. ",[39,38246,38247],{},"acc.balance"," looks for an own property named ",[39,38250,22170],{},[39,38252,24160],{},", which doesn't exist, so it's ",[39,38255,833],{},". This is precisely the ",[76,38258,38259],{},"private state pattern",": the real value (now ",[39,38262,38263],{},"150"," internally) is only reachable through the exposed methods, never by direct property access.",[15,38266,38267,38269,38375,38399],{"language":247},[18,38268,13528],{"id":13527},[257,38270,38271],{"language":247},[260,38272,38274],{"className":262,"code":38273,"language":247,"meta":264,"style":264},"function makeCounter() {\n  let c = 0;\n  return () => ++c;\n}\n\nconst a = makeCounter();\nconst b = makeCounter();\n\na();\na();\nconsole.log(a(), b());\n",[39,38275,38276,38284,38297,38311,38315,38319,38331,38343,38347,38353,38359],{"__ignoreMap":264},[268,38277,38278,38280,38282],{"class":270,"line":271},[268,38279,275],{"class":274},[268,38281,37290],{"class":278},[268,38283,283],{"class":282},[268,38285,38286,38288,38291,38293,38295],{"class":270,"line":286},[268,38287,2206],{"class":274},[268,38289,38290],{"class":282}," c ",[268,38292,302],{"class":274},[268,38294,5728],{"class":305},[268,38296,293],{"class":282},[268,38298,38299,38301,38303,38305,38308],{"class":270,"line":296},[268,38300,1240],{"class":274},[268,38302,15158],{"class":282},[268,38304,9414],{"class":274},[268,38306,38307],{"class":274}," ++",[268,38309,38310],{"class":282},"c;\n",[268,38312,38313],{"class":270,"line":311},[268,38314,314],{"class":282},[268,38316,38317],{"class":270,"line":788},[268,38318,5033],{"emptyLinePlaceholder":35},[268,38320,38321,38323,38325,38327,38329],{"class":270,"line":1951},[268,38322,243],{"class":274},[268,38324,7203],{"class":305},[268,38326,616],{"class":274},[268,38328,37290],{"class":278},[268,38330,794],{"class":282},[268,38332,38333,38335,38337,38339,38341],{"class":270,"line":8955},[268,38334,243],{"class":274},[268,38336,16372],{"class":305},[268,38338,616],{"class":274},[268,38340,37290],{"class":278},[268,38342,794],{"class":282},[268,38344,38345],{"class":270,"line":8966},[268,38346,5033],{"emptyLinePlaceholder":35},[268,38348,38349,38351],{"class":270,"line":8974},[268,38350,1223],{"class":278},[268,38352,794],{"class":282},[268,38354,38355,38357],{"class":270,"line":8985},[268,38356,1223],{"class":278},[268,38358,794],{"class":282},[268,38360,38361,38363,38365,38367,38369,38371,38373],{"class":270,"line":8990},[268,38362,1353],{"class":282},[268,38364,1356],{"class":278},[268,38366,622],{"class":282},[268,38368,1223],{"class":278},[268,38370,37368],{"class":282},[268,38372,1232],{"class":278},[268,38374,8174],{"class":282},[23,38376,38378,38384,38389,38394],{"className":38377},[26],[28,38379,38381,38383],{"className":38380},[31],[33,38382],{"disabled":35,"type":36}," 3 1",[28,38385,38387,28149],{"className":38386},[31],[33,38388],{"disabled":35,"type":36},[28,38390,38392,28817],{"className":38391},[31],[33,38393],{"disabled":35,"type":36},[28,38395,38397,28143],{"className":38396},[31],[33,38398],{"disabled":35,"type":36},[66,38400,38401,38403,38408],{},[69,38402,71],{},[73,38404,38405,38407],{},[76,38406,78],{}," A — 3 1",[73,38409,38410,38412,38413,38415,38416,355,38419,38421,38422,186,38424,38426,38427,38429,38430,38432,38433,2272,38435,38437,38438,462],{},[76,38411,84],{}," Each call to ",[39,38414,37441],{}," creates a ",[76,38417,38418],{},"brand-new, independent",[39,38420,16484],{}," binding — ",[39,38423,1223],{},[39,38425,1232],{}," do not share state even though they came from the same factory function. ",[39,38428,1223],{}," has been invoked three times total by the time it's logged (two discarded calls, then a third inside the ",[39,38431,5627],{},"), reaching ",[39,38434,3423],{},[39,38436,1232],{}," is invoked for the first time inside the same line, giving ",[39,38439,2255],{},[15,38441,38442,38444,38573,38607],{"language":247},[18,38443,13729],{"id":13728},[257,38445,38446],{"language":247},[260,38447,38449],{"className":262,"code":38448,"language":247,"meta":264,"style":264},"function createLogger(config) {\n  return function log(msg) {\n    console.log(`[${config.level}] ${msg}`);\n  };\n}\n\nconst config = { level: 'info' };\nconst logger = createLogger(config);\nconfig.level = 'error';\n\nlogger('test');\n",[39,38450,38451,38464,38478,38504,38508,38512,38516,38532,38545,38557,38561],{"__ignoreMap":264},[268,38452,38453,38455,38458,38460,38462],{"class":270,"line":271},[268,38454,275],{"class":274},[268,38456,38457],{"class":278}," createLogger",[268,38459,622],{"class":282},[268,38461,8109],{"class":1222},[268,38463,1235],{"class":282},[268,38465,38466,38468,38470,38472,38474,38476],{"class":270,"line":286},[268,38467,1240],{"class":274},[268,38469,12080],{"class":274},[268,38471,16942],{"class":278},[268,38473,622],{"class":282},[268,38475,33187],{"class":1222},[268,38477,1235],{"class":282},[268,38479,38480,38482,38484,38486,38488,38490,38492,38495,38498,38500,38502],{"class":270,"line":296},[268,38481,9707],{"class":282},[268,38483,1356],{"class":278},[268,38485,622],{"class":282},[268,38487,18824],{"class":289},[268,38489,8109],{"class":282},[268,38491,462],{"class":289},[268,38493,38494],{"class":282},"level",[268,38496,38497],{"class":289},"}] ${",[268,38499,33187],{"class":282},[268,38501,11603],{"class":289},[268,38503,628],{"class":282},[268,38505,38506],{"class":270,"line":311},[268,38507,15185],{"class":282},[268,38509,38510],{"class":270,"line":788},[268,38511,314],{"class":282},[268,38513,38514],{"class":270,"line":1951},[268,38515,5033],{"emptyLinePlaceholder":35},[268,38517,38518,38520,38522,38524,38527,38530],{"class":270,"line":8955},[268,38519,243],{"class":274},[268,38521,8029],{"class":305},[268,38523,616],{"class":274},[268,38525,38526],{"class":282}," { level: ",[268,38528,38529],{"class":289},"'info'",[268,38531,2790],{"class":282},[268,38533,38534,38536,38539,38541,38543],{"class":270,"line":8966},[268,38535,243],{"class":274},[268,38537,38538],{"class":305}," logger",[268,38540,616],{"class":274},[268,38542,38457],{"class":278},[268,38544,7381],{"class":282},[268,38546,38547,38550,38552,38555],{"class":270,"line":8974},[268,38548,38549],{"class":282},"config.level ",[268,38551,302],{"class":274},[268,38553,38554],{"class":289}," 'error'",[268,38556,293],{"class":282},[268,38558,38559],{"class":270,"line":8985},[268,38560,5033],{"emptyLinePlaceholder":35},[268,38562,38563,38566,38568,38571],{"class":270,"line":8990},[268,38564,38565],{"class":278},"logger",[268,38567,622],{"class":282},[268,38569,38570],{"class":289},"'test'",[268,38572,628],{"class":282},[23,38574,38576,38584,38592,38600],{"className":38575},[26],[28,38577,38579,22539,38581,38583],{"className":38578},[31],[33,38580],{"disabled":35,"type":36},[268,38582,18282],{}," test\"",[28,38585,38587,22539,38589,38583],{"className":38586},[31],[33,38588],{"disabled":35,"type":36},[268,38590,38591],{},"info",[28,38593,38595,34517,38597,38599],{"className":38594},[31],[33,38596],{"disabled":35,"type":36},[39,38598,8109],{}," was reassigned",[28,38601,38603,22539,38605,38583],{"className":38602},[31],[33,38604],{"disabled":35,"type":36},[268,38606,833],{},[66,38608,38609,38611,38618],{},[69,38610,71],{},[73,38612,38613,38615,38616,38583],{},[76,38614,78],{}," A — \"",[268,38617,18282],{},[73,38619,38620,355,38622,38624,38625,38628,38629,21185,38632,38635,38636,38638,38639,38641,38642,38644],{},[76,38621,84],{},[76,38623,365],{}," a closure captures the ",[104,38626,38627],{},"variable binding",", not a snapshot of its value at creation time — and for an object, that binding holds a reference. Mutating ",[39,38630,38631],{},"config.level",[39,38633,38634],{},"createLogger"," runs is visible to ",[39,38637,1356],{}," the next time it reads ",[39,38640,38631],{},", because both ",[39,38643,8109],{}," (outer) and the closure's captured reference point to the same object. This surprises people who expect closures to \"freeze\" values the way default arguments do.",[15,38646,38647,38655,38744,38796],{"language":247},[18,38648,38650,38651,38654],{"id":38649},"q9-given-modern-js-engines-like-v8-what-typically-happens-to-bigarray-here","Q9. Given modern JS engines (like V8), what typically happens to ",[39,38652,38653],{},"bigArray"," here?",[257,38656,38657],{"language":247},[260,38658,38660],{"className":262,"code":38659,"language":247,"meta":264,"style":264},"function heavyClosure() {\n  const bigArray = new Array(1_000_000).fill('x');\n  return function tiny() {\n    return 'hi';\n  };\n}\n\nconst fn = heavyClosure();\n",[39,38661,38662,38671,38700,38711,38720,38724,38728,38732],{"__ignoreMap":264},[268,38663,38664,38666,38669],{"class":270,"line":271},[268,38665,275],{"class":274},[268,38667,38668],{"class":278}," heavyClosure",[268,38670,283],{"class":282},[268,38672,38673,38675,38678,38680,38682,38684,38686,38689,38691,38694,38696,38698],{"class":270,"line":286},[268,38674,12441],{"class":274},[268,38676,38677],{"class":305}," bigArray",[268,38679,616],{"class":274},[268,38681,11370],{"class":274},[268,38683,24460],{"class":278},[268,38685,622],{"class":282},[268,38687,38688],{"class":305},"1_000_000",[268,38690,6232],{"class":282},[268,38692,38693],{"class":278},"fill",[268,38695,622],{"class":282},[268,38697,28650],{"class":289},[268,38699,628],{"class":282},[268,38701,38702,38704,38706,38709],{"class":270,"line":296},[268,38703,1240],{"class":274},[268,38705,12080],{"class":274},[268,38707,38708],{"class":278}," tiny",[268,38710,283],{"class":282},[268,38712,38713,38715,38718],{"class":270,"line":311},[268,38714,9871],{"class":274},[268,38716,38717],{"class":289}," 'hi'",[268,38719,293],{"class":282},[268,38721,38722],{"class":270,"line":788},[268,38723,15185],{"class":282},[268,38725,38726],{"class":270,"line":1951},[268,38727,314],{"class":282},[268,38729,38730],{"class":270,"line":8955},[268,38731,5033],{"emptyLinePlaceholder":35},[268,38733,38734,38736,38738,38740,38742],{"class":270,"line":8966},[268,38735,243],{"class":274},[268,38737,37900],{"class":305},[268,38739,616],{"class":274},[268,38741,38668],{"class":278},[268,38743,794],{"class":282},[23,38745,38747,38759,38773,38784],{"className":38746},[26],[28,38748,38750,355,38752,38754,38755,38758],{"className":38749},[31],[33,38751],{"disabled":35,"type":36},[39,38753,38653],{}," is eligible for garbage collection because ",[39,38756,38757],{},"tiny"," never references it — modern engines only keep alive the specific bindings an escaping closure actually uses",[28,38760,38762,355,38764,38766,38767,38769,38770,38772],{"className":38761},[31],[33,38763],{"disabled":35,"type":36},[39,38765,38653],{}," is retained in memory forever as long as ",[39,38768,37837],{}," exists, regardless of whether ",[39,38771,38757],{}," uses it",[28,38774,38776,355,38778,38780,38781,38783],{"className":38775},[31],[33,38777],{"disabled":35,"type":36},[39,38779,38653],{}," gets copied into ",[39,38782,38757],{},"'s closure, doubling memory usage",[28,38785,38787,355,38789,38792,38793,38795],{"className":38786},[31],[33,38788],{"disabled":35,"type":36},[39,38790,38791],{},"heavyClosure"," throws an error because ",[39,38794,38653],{}," is unused",[66,38797,38798,38800,38808],{},[69,38799,71],{},[73,38801,38802,3459,38804,38754,38806,38758],{},[76,38803,78],{},[39,38805,38653],{},[39,38807,38757],{},[73,38809,38810,355,38812,38814,38815,38817,38818,38820,38821,38823,38824,38826],{},[76,38811,84],{},[76,38813,438],{}," it's a common myth that a surviving closure keeps the ",[104,38816,20753],{}," enclosing scope alive. Modern engines perform static analysis and only retain the variables an inner function actually touches; since ",[39,38819,38757],{}," never reads ",[39,38822,38653],{},", V8 can typically collect it once ",[39,38825,38791],{}," returns. That said, this is an engine optimization, not a spec guarantee — the safe, portable practice is still to avoid holding unnecessary large references in scope alongside a closure you intend to keep around, since older or simpler engines may retain the whole variable environment.",[15,38828,38829,38831,38904,38927],{"language":247},[18,38830,17619],{"id":17618},[257,38832,38833],{"language":247},[260,38834,38836],{"className":262,"code":38835,"language":247,"meta":264,"style":264},"for (var i = 0; i \u003C 3; i++) {\n  (function (j) {\n    setTimeout(() => console.log(j), 0);\n  })(i);\n}\n",[39,38837,38838,38864,38877,38895,38900],{"__ignoreMap":264},[268,38839,38840,38842,38844,38846,38848,38850,38852,38854,38856,38858,38860,38862],{"class":270,"line":271},[268,38841,6926],{"class":274},[268,38843,2182],{"class":282},[268,38845,1440],{"class":274},[268,38847,9384],{"class":282},[268,38849,302],{"class":274},[268,38851,5728],{"class":305},[268,38853,9391],{"class":282},[268,38855,1076],{"class":274},[268,38857,3396],{"class":305},[268,38859,9398],{"class":282},[268,38861,9401],{"class":274},[268,38863,1235],{"class":282},[268,38865,38866,38869,38871,38873,38875],{"class":270,"line":286},[268,38867,38868],{"class":282},"  (",[268,38870,275],{"class":274},[268,38872,2182],{"class":282},[268,38874,9520],{"class":1222},[268,38876,1235],{"class":282},[268,38878,38879,38881,38883,38885,38887,38889,38891,38893],{"class":270,"line":296},[268,38880,35594],{"class":278},[268,38882,9411],{"class":282},[268,38884,9414],{"class":274},[268,38886,9417],{"class":282},[268,38888,1356],{"class":278},[268,38890,9474],{"class":282},[268,38892,3307],{"class":305},[268,38894,628],{"class":282},[268,38896,38897],{"class":270,"line":311},[268,38898,38899],{"class":282},"  })(i);\n",[268,38901,38902],{"class":270,"line":788},[268,38903,314],{"class":282},[23,38905,38907,38912,38917,38922],{"className":38906},[26],[28,38908,38910,37644],{"className":38909},[31],[33,38911],{"disabled":35,"type":36},[28,38913,38915,37638],{"className":38914},[31],[33,38916],{"disabled":35,"type":36},[28,38918,38920,37397],{"className":38919},[31],[33,38921],{"disabled":35,"type":36},[28,38923,38925,37769],{"className":38924},[31],[33,38926],{"disabled":35,"type":36},[66,38928,38929,38931,38935],{},[69,38930,71],{},[73,38932,38933,37783],{},[76,38934,78],{},[73,38936,38937,38939,38940,38942,38943,38945,38946,38949,38950,38952,38953,38955,38956,38958,38959,38961,38962,38964,38965,38967],{},[76,38938,84],{}," This is the classic pre-",[39,38941,240],{}," fix for the ",[39,38944,1440],{}," loop bug: the ",[76,38947,38948],{},"IIFE"," (immediately invoked function expression) creates a new function scope on every iteration, and ",[39,38951,9509],{},"'s current value is passed in as the argument ",[39,38954,9520],{},". Each ",[39,38957,9578],{}," callback then closes over its own private ",[39,38960,9520],{},", not the shared loop ",[39,38963,9509],{},", reproducing the same effect ",[39,38966,240],{}," gives you automatically.",[15,38969,38970,38972,39056,39089],{"language":247},[18,38971,14224],{"id":14223},[257,38973,38974],{"language":247},[260,38975,38977],{"className":262,"code":38976,"language":247,"meta":264,"style":264},"const fns = [];\nfor (let i = 0; i \u003C 3; i++) {\n  fns.push(() => i);\n}\nconsole.log(fns.map(fn => fn()));\n",[39,38978,38979,38990,39016,39030,39034],{"__ignoreMap":264},[268,38980,38981,38983,38986,38988],{"class":270,"line":271},[268,38982,243],{"class":274},[268,38984,38985],{"class":305}," fns",[268,38987,616],{"class":274},[268,38989,12449],{"class":282},[268,38991,38992,38994,38996,38998,39000,39002,39004,39006,39008,39010,39012,39014],{"class":270,"line":286},[268,38993,6926],{"class":274},[268,38995,2182],{"class":282},[268,38997,240],{"class":274},[268,38999,9384],{"class":282},[268,39001,302],{"class":274},[268,39003,5728],{"class":305},[268,39005,9391],{"class":282},[268,39007,1076],{"class":274},[268,39009,3396],{"class":305},[268,39011,9398],{"class":282},[268,39013,9401],{"class":274},[268,39015,1235],{"class":282},[268,39017,39018,39021,39023,39025,39027],{"class":270,"line":296},[268,39019,39020],{"class":282},"  fns.",[268,39022,12499],{"class":278},[268,39024,9411],{"class":282},[268,39026,9414],{"class":274},[268,39028,39029],{"class":282}," i);\n",[268,39031,39032],{"class":270,"line":311},[268,39033,314],{"class":282},[268,39035,39036,39038,39040,39043,39045,39047,39049,39051,39053],{"class":270,"line":788},[268,39037,1353],{"class":282},[268,39039,1356],{"class":278},[268,39041,39042],{"class":282},"(fns.",[268,39044,23950],{"class":278},[268,39046,622],{"class":282},[268,39048,37837],{"class":1222},[268,39050,14969],{"class":274},[268,39052,37900],{"class":278},[268,39054,39055],{"class":282},"()));\n",[23,39057,39059,39066,39073,39081],{"className":39058},[26],[28,39060,39062,355,39064],{"className":39061},[31],[33,39063],{"disabled":35,"type":36},[268,39065,9494],{},[28,39067,39069,355,39071],{"className":39068},[31],[33,39070],{"disabled":35,"type":36},[268,39072,9505],{},[28,39074,39076,355,39078],{"className":39075},[31],[33,39077],{"disabled":35,"type":36},[268,39079,39080],{},"2, 2, 2",[28,39082,39084,355,39086],{"className":39083},[31],[33,39085],{"disabled":35,"type":36},[268,39087,39088],{},"undefined, undefined, undefined",[66,39090,39091,39093,39099],{},[69,39092,71],{},[73,39094,39095,3459,39097],{},[76,39096,78],{},[268,39098,9494],{},[73,39100,39101,39103,39104,39106,39107,39109,39110,39112,39113,39115],{},[76,39102,84],{}," This confirms the per-iteration binding of ",[39,39105,240],{}," has nothing to do with timing or asynchrony — even called synchronously (no ",[39,39108,9578],{}," involved), each pushed arrow function closes over its own iteration's ",[39,39111,9509],{},". It's a common misconception that ",[39,39114,240],{},"'s loop fix is specifically an \"async trick\"; it's really about scoping, and this example proves that by removing the timer entirely.",[15,39117,39118,39125,39194,39223],{"language":247},[18,39119,11036,39121,39124],{"id":39120},"q12-what-happens-when-show-is-called",[39,39122,39123],{},"show()"," is called?",[257,39126,39127],{"language":247},[260,39128,39130],{"className":262,"code":39129,"language":247,"meta":264,"style":264},"let value = 'outer';\n\nfunction show() {\n  console.log(value);\n  let value = 'inner';\n}\n\nshow();\n",[39,39131,39132,39145,39149,39158,39166,39179,39183,39187],{"__ignoreMap":264},[268,39133,39134,39136,39138,39140,39143],{"class":270,"line":271},[268,39135,240],{"class":274},[268,39137,4789],{"class":282},[268,39139,302],{"class":274},[268,39141,39142],{"class":289}," 'outer'",[268,39144,293],{"class":282},[268,39146,39147],{"class":270,"line":286},[268,39148,5033],{"emptyLinePlaceholder":35},[268,39150,39151,39153,39156],{"class":270,"line":296},[268,39152,275],{"class":274},[268,39154,39155],{"class":278}," show",[268,39157,283],{"class":282},[268,39159,39160,39162,39164],{"class":270,"line":311},[268,39161,5556],{"class":282},[268,39163,1356],{"class":278},[268,39165,29257],{"class":282},[268,39167,39168,39170,39172,39174,39177],{"class":270,"line":788},[268,39169,2206],{"class":274},[268,39171,4789],{"class":282},[268,39173,302],{"class":274},[268,39175,39176],{"class":289}," 'inner'",[268,39178,293],{"class":282},[268,39180,39181],{"class":270,"line":1951},[268,39182,314],{"class":282},[268,39184,39185],{"class":270,"line":8955},[268,39186,5033],{"emptyLinePlaceholder":35},[268,39188,39189,39192],{"class":270,"line":8966},[268,39190,39191],{"class":278},"show",[268,39193,794],{"class":282},[23,39195,39197,39205,39211,39217],{"className":39196},[26],[28,39198,39200,6738,39202],{"className":39199},[31],[33,39201],{"disabled":35,"type":36},[39,39203,39204],{},"ReferenceError: Cannot access 'value' before initialization",[28,39206,39208,39210],{"className":39207},[31],[33,39209],{"disabled":35,"type":36}," Logs \"outer\"",[28,39212,39214,39216],{"className":39213},[31],[33,39215],{"disabled":35,"type":36}," Logs \"inner\"",[28,39218,39220,39222],{"className":39219},[31],[33,39221],{"disabled":35,"type":36}," Logs undefined",[66,39224,39225,39227,39233],{},[69,39226,71],{},[73,39228,39229,35317,39231],{},[76,39230,78],{},[39,39232,39204],{},[73,39234,39235,355,39237,39239,39240,39243,39244,39246,39247,39250,39251,39253,39254,39257,39258,39261],{},[76,39236,84],{},[76,39238,365],{}," the inner ",[39,39241,39242],{},"let value"," declaration is hoisted to the top of ",[39,39245,39191],{},"'s function scope (though not initialized), so it ",[76,39248,39249],{},"shadows"," the outer ",[39,39252,4780],{}," for the entire function body — including the ",[39,39255,39256],{},"console.log(value)"," line that appears before the declaration. That reference falls into the ",[76,39259,39260],{},"temporal dead zone"," and throws, rather than falling back to the outer variable the way people expect closures\u002Fscoping to \"skip over\" an inner declaration that hasn't run yet.",[15,39263,39264,39266,39383,39407],{"language":247},[18,39265,14538],{"id":14537},[257,39267,39268],{"language":247},[260,39269,39271],{"className":262,"code":39270,"language":247,"meta":264,"style":264},"function createValidator(min) {\n  return function validate(value) {\n    return value >= min;\n  };\n}\n\nlet minValue = 10;\nconst validate = createValidator(minValue);\nminValue = 100;\n\nconsole.log(validate(50));\n",[39,39272,39273,39287,39302,39313,39317,39321,39325,39338,39351,39362,39366],{"__ignoreMap":264},[268,39274,39275,39277,39280,39282,39285],{"class":270,"line":271},[268,39276,275],{"class":274},[268,39278,39279],{"class":278}," createValidator",[268,39281,622],{"class":282},[268,39283,39284],{"class":1222},"min",[268,39286,1235],{"class":282},[268,39288,39289,39291,39293,39296,39298,39300],{"class":270,"line":286},[268,39290,1240],{"class":274},[268,39292,12080],{"class":274},[268,39294,39295],{"class":278}," validate",[268,39297,622],{"class":282},[268,39299,4780],{"class":1222},[268,39301,1235],{"class":282},[268,39303,39304,39306,39308,39310],{"class":270,"line":296},[268,39305,9871],{"class":274},[268,39307,4789],{"class":282},[268,39309,6779],{"class":274},[268,39311,39312],{"class":282}," min;\n",[268,39314,39315],{"class":270,"line":311},[268,39316,15185],{"class":282},[268,39318,39319],{"class":270,"line":788},[268,39320,314],{"class":282},[268,39322,39323],{"class":270,"line":1951},[268,39324,5033],{"emptyLinePlaceholder":35},[268,39326,39327,39329,39332,39334,39336],{"class":270,"line":8955},[268,39328,240],{"class":274},[268,39330,39331],{"class":282}," minValue ",[268,39333,302],{"class":274},[268,39335,306],{"class":305},[268,39337,293],{"class":282},[268,39339,39340,39342,39344,39346,39348],{"class":270,"line":8966},[268,39341,243],{"class":274},[268,39343,39295],{"class":305},[268,39345,616],{"class":274},[268,39347,39279],{"class":278},[268,39349,39350],{"class":282},"(minValue);\n",[268,39352,39353,39356,39358,39360],{"class":270,"line":8974},[268,39354,39355],{"class":282},"minValue ",[268,39357,302],{"class":274},[268,39359,13821],{"class":305},[268,39361,293],{"class":282},[268,39363,39364],{"class":270,"line":8985},[268,39365,5033],{"emptyLinePlaceholder":35},[268,39367,39368,39370,39372,39374,39377,39379,39381],{"class":270,"line":8990},[268,39369,1353],{"class":282},[268,39371,1356],{"class":278},[268,39373,622],{"class":282},[268,39375,39376],{"class":278},"validate",[268,39378,622],{"class":282},[268,39380,32109],{"class":305},[268,39382,4818],{"class":282},[23,39384,39386,39391,39396,39402],{"className":39385},[26],[28,39387,39389,7905],{"className":39388},[31],[33,39390],{"disabled":35,"type":36},[28,39392,39394,3200],{"className":39393},[31],[33,39395],{"disabled":35,"type":36},[28,39397,39399,39401],{"className":39398},[31],[33,39400],{"disabled":35,"type":36}," Throws a ReferenceError",[28,39403,39405,17135],{"className":39404},[31],[33,39406],{"disabled":35,"type":36},[66,39408,39409,39411,39416],{},[69,39410,71],{},[73,39412,39413,39415],{},[76,39414,78],{}," A — true",[73,39417,39418,355,39420,39422,39423,39425,39426,39429,39430,3990,39433,39436,39437,39439,39440,39442,39443,39446,39447,39449,39450,137,39453,830,39456,39458],{},[76,39419,84],{},[76,39421,365],{}," unlike Q8's object example, ",[39,39424,39284],{}," here is a ",[76,39427,39428],{},"parameter",", and primitives are passed ",[76,39431,39432],{},"by value",[39,39434,39435],{},"createValidator(minValue)"," copies the number ",[39,39438,5825],{}," into the parameter ",[39,39441,39284],{}," at call time. Reassigning the outer ",[39,39444,39445],{},"minValue"," variable afterward has no effect on that already-copied parameter, so ",[39,39448,39376],{},"'s closure still sees ",[39,39451,39452],{},"min = 10",[39,39454,39455],{},"50 >= 10",[39,39457,2185],{},". This is the mirror image of Q8: closures capture bindings by reference, but a primitive value copied into a parameter is disconnected from the variable it came from.",[15,39460,39461,39463,39594,39626],{"language":247},[18,39462,14774],{"id":14773},[257,39464,39465],{"language":247},[260,39466,39468],{"className":262,"code":39467,"language":247,"meta":264,"style":264},"function createButtons(labels) {\n  return labels.map(label => () => console.log(`Clicked ${label}`));\n}\n\nconst labels = ['A', 'B'];\nconst handlers = createButtons(labels);\nlabels.push('C');\n\nhandlers.forEach(fn => fn());\n",[39,39469,39470,39484,39518,39522,39526,39545,39559,39573,39577],{"__ignoreMap":264},[268,39471,39472,39474,39477,39479,39482],{"class":270,"line":271},[268,39473,275],{"class":274},[268,39475,39476],{"class":278}," createButtons",[268,39478,622],{"class":282},[268,39480,39481],{"class":1222},"labels",[268,39483,1235],{"class":282},[268,39485,39486,39488,39491,39493,39495,39497,39499,39501,39503,39505,39507,39509,39512,39514,39516],{"class":270,"line":286},[268,39487,1240],{"class":274},[268,39489,39490],{"class":282}," labels.",[268,39492,23950],{"class":278},[268,39494,622],{"class":282},[268,39496,14401],{"class":1222},[268,39498,14969],{"class":274},[268,39500,15158],{"class":282},[268,39502,9414],{"class":274},[268,39504,9417],{"class":282},[268,39506,1356],{"class":278},[268,39508,622],{"class":282},[268,39510,39511],{"class":289},"`Clicked ${",[268,39513,14401],{"class":282},[268,39515,11603],{"class":289},[268,39517,4818],{"class":282},[268,39519,39520],{"class":270,"line":296},[268,39521,314],{"class":282},[268,39523,39524],{"class":270,"line":311},[268,39525,5033],{"emptyLinePlaceholder":35},[268,39527,39528,39530,39533,39535,39537,39539,39541,39543],{"class":270,"line":788},[268,39529,243],{"class":274},[268,39531,39532],{"class":305}," labels",[268,39534,616],{"class":274},[268,39536,8710],{"class":282},[268,39538,17902],{"class":289},[268,39540,42],{"class":282},[268,39542,26647],{"class":289},[268,39544,8737],{"class":282},[268,39546,39547,39549,39552,39554,39556],{"class":270,"line":1951},[268,39548,243],{"class":274},[268,39550,39551],{"class":305}," handlers",[268,39553,616],{"class":274},[268,39555,39476],{"class":278},[268,39557,39558],{"class":282},"(labels);\n",[268,39560,39561,39564,39566,39568,39571],{"class":270,"line":8955},[268,39562,39563],{"class":282},"labels.",[268,39565,12499],{"class":278},[268,39567,622],{"class":282},[268,39569,39570],{"class":289},"'C'",[268,39572,628],{"class":282},[268,39574,39575],{"class":270,"line":8966},[268,39576,5033],{"emptyLinePlaceholder":35},[268,39578,39579,39582,39584,39586,39588,39590,39592],{"class":270,"line":8974},[268,39580,39581],{"class":282},"handlers.",[268,39583,12330],{"class":278},[268,39585,622],{"class":282},[268,39587,37837],{"class":1222},[268,39589,14969],{"class":274},[268,39591,37900],{"class":278},[268,39593,8174],{"class":282},[23,39595,39597,39603,39609,39615],{"className":39596},[26],[28,39598,39600,39602],{"className":39599},[31],[33,39601],{"disabled":35,"type":36}," \"Clicked A\" then \"Clicked B\" (2 lines total)",[28,39604,39606,39608],{"className":39605},[31],[33,39607],{"disabled":35,"type":36}," \"Clicked A\", \"Clicked B\", \"Clicked C\" (3 lines total)",[28,39610,39612,39614],{"className":39611},[31],[33,39613],{"disabled":35,"type":36}," \"Clicked C\" three times",[28,39616,39618,34517,39620,39622,39623],{"className":39617},[31],[33,39619],{"disabled":35,"type":36},[39,39621,39481],{}," was mutated after ",[39,39624,39625],{},".map",[66,39627,39628,39630,39635],{},[69,39629,71],{},[73,39631,39632,39634],{},[76,39633,78],{}," A — \"Clicked A\" then \"Clicked B\" (2 lines total)",[73,39636,39637,355,39639,39641,39642,39645,39646,39649,39650,39652,39653,355,39655,39657,39658,39660,39661,39663,39664,39666],{},[76,39638,84],{},[39,39640,39625],{}," runs synchronously and finishes building ",[39,39643,39644],{},"handlers"," (with exactly 2 functions) before ",[39,39647,39648],{},"labels.push('C')"," ever executes — pushing to ",[39,39651,39481],{}," afterward doesn't retroactively add a third handler. Additionally, each arrow function closes over its own ",[39,39654,14401],{},[76,39656,39428],{},", a primitive string copied per iteration by ",[39,39659,39625],{},", not a shared reference into the ",[39,39662,39481],{}," array — so even mutating ",[39,39665,39481],{}," further wouldn't change what the existing handlers log.",[15,39668,39669,39673,39778,39811],{"language":247},[18,39670,39672],{"id":39671},"q15-which-approach-actually-prevents-external-code-from-directly-overwriting-the-account-balance","Q15. Which approach actually prevents external code from directly overwriting the account balance?",[257,39674,39675],{"language":247},[260,39676,39678],{"className":262,"code":39677,"language":247,"meta":264,"style":264},"\u002F\u002F Option A\nclass BankAccount {\n  constructor(balance) { this.balance = balance; }\n}\n\n\u002F\u002F Option B\nfunction createAccount(balance) {\n  return {\n    deposit(amount) { balance += amount; return balance; },\n    getBalance() { return balance; }\n  };\n}\n",[39,39679,39680,39684,39692,39711,39715,39719,39723,39736,39742,39760,39770,39774],{"__ignoreMap":264},[268,39681,39682],{"class":270,"line":271},[268,39683,36812],{"class":29390},[268,39685,39686,39688,39690],{"class":270,"line":286},[268,39687,1468],{"class":274},[268,39689,31825],{"class":278},[268,39691,9914],{"class":282},[268,39693,39694,39696,39698,39700,39702,39704,39707,39709],{"class":270,"line":296},[268,39695,29965],{"class":274},[268,39697,622],{"class":282},[268,39699,22170],{"class":1222},[268,39701,29387],{"class":282},[268,39703,950],{"class":305},[268,39705,39706],{"class":282},".balance ",[268,39708,302],{"class":274},[268,39710,38144],{"class":282},[268,39712,39713],{"class":270,"line":311},[268,39714,314],{"class":282},[268,39716,39717],{"class":270,"line":788},[268,39718,5033],{"emptyLinePlaceholder":35},[268,39720,39721],{"class":270,"line":1951},[268,39722,36856],{"class":29390},[268,39724,39725,39727,39730,39732,39734],{"class":270,"line":8955},[268,39726,275],{"class":274},[268,39728,39729],{"class":278}," createAccount",[268,39731,622],{"class":282},[268,39733,22170],{"class":1222},[268,39735,1235],{"class":282},[268,39737,39738,39740],{"class":270,"line":8966},[268,39739,1240],{"class":274},[268,39741,9914],{"class":282},[268,39743,39744,39746,39748,39750,39752,39754,39756,39758],{"class":270,"line":8974},[268,39745,38115],{"class":278},[268,39747,622],{"class":282},[268,39749,31848],{"class":1222},[268,39751,38122],{"class":282},[268,39753,14575],{"class":274},[268,39755,38127],{"class":282},[268,39757,9151],{"class":274},[268,39759,38132],{"class":282},[268,39761,39762,39764,39766,39768],{"class":270,"line":8985},[268,39763,38137],{"class":278},[268,39765,34756],{"class":282},[268,39767,9151],{"class":274},[268,39769,38144],{"class":282},[268,39771,39772],{"class":270,"line":8990},[268,39773,15185],{"class":282},[268,39775,39776],{"class":270,"line":8997},[268,39777,314],{"class":282},[23,39779,39781,39790,39796,39805],{"className":39780},[26],[28,39782,39784,39786,39787,39789],{"className":39783},[31],[33,39785],{"disabled":35,"type":36}," Option B — ",[39,39788,22170],{}," lives only in closure scope, so there's no property to overwrite from outside",[28,39791,39793,39795],{"className":39792},[31],[33,39794],{"disabled":35,"type":36}," Option A — classes always enforce encapsulation",[28,39797,39799,39801,39802],{"className":39798},[31],[33,39800],{"disabled":35,"type":36}," Both are equally safe against ",[39,39803,39804],{},"account.balance = 999999",[28,39806,39808,39810],{"className":39807},[31],[33,39809],{"disabled":35,"type":36}," Neither prevents it; JavaScript has no way to hide state",[66,39812,39813,39815,39822],{},[69,39814,71],{},[73,39816,39817,39819,39820,39789],{},[76,39818,78],{}," A — Option B — ",[39,39821,22170],{},[73,39823,39824,355,39826,39828,39829,39832,39833,39835,39836,39838,39839,39842,39843,39845,39846,39849],{},[76,39825,84],{},[76,39827,930],{}," in Option A, ",[39,39830,39831],{},"this.balance"," is a plain public property — anyone holding the instance can do ",[39,39834,39804],{}," directly, no method required. In Option B, ",[39,39837,22170],{}," never becomes a property of the returned object; it only exists as a variable the closures can reach, so there is no ",[39,39840,39841],{},"account.balance"," to assign to at all. (A class using a true private field, ",[39,39844,31996],{},", would achieve the same guarantee — the key distinction is private-by-closure or ",[39,39847,39848],{},"#field"," versus a plain public property, not \"class vs. factory function\" per se.)",[15,39851,39852,39856,39919,39969],{"language":247},[18,39853,39855],{"id":39854},"q16-this-click-handler-is-attached-to-a-large-widget-that-later-gets-removed-from-the-dom-whats-the-best-practice-to-prevent-a-memory-leak","Q16. This click handler is attached to a large widget that later gets removed from the DOM. What's the best practice to prevent a memory leak?",[257,39857,39858],{"language":247},[260,39859,39861],{"className":262,"code":39860,"language":247,"meta":264,"style":264},"function setupWidget(el, largeCachedData) {\n  el.addEventListener('click', function handler() {\n    console.log(largeCachedData.summary);\n  });\n}\n",[39,39862,39863,39881,39901,39910,39915],{"__ignoreMap":264},[268,39864,39865,39867,39870,39872,39874,39876,39879],{"class":270,"line":271},[268,39866,275],{"class":274},[268,39868,39869],{"class":278}," setupWidget",[268,39871,622],{"class":282},[268,39873,25687],{"class":1222},[268,39875,42],{"class":282},[268,39877,39878],{"class":1222},"largeCachedData",[268,39880,1235],{"class":282},[268,39882,39883,39886,39888,39890,39892,39894,39896,39899],{"class":270,"line":286},[268,39884,39885],{"class":282},"  el.",[268,39887,35737],{"class":278},[268,39889,622],{"class":282},[268,39891,35742],{"class":289},[268,39893,42],{"class":282},[268,39895,275],{"class":274},[268,39897,39898],{"class":278}," handler",[268,39900,283],{"class":282},[268,39902,39903,39905,39907],{"class":270,"line":296},[268,39904,9707],{"class":282},[268,39906,1356],{"class":278},[268,39908,39909],{"class":282},"(largeCachedData.summary);\n",[268,39911,39912],{"class":270,"line":311},[268,39913,39914],{"class":282},"  });\n",[268,39916,39917],{"class":270,"line":788},[268,39918,314],{"class":282},[23,39920,39922,39945,39954,39960],{"className":39921},[26],[28,39923,39925,39927,39928,39931,39932,446,39935,39938,39939,39941,39942,39944],{"className":39924},[31],[33,39926],{"disabled":35,"type":36}," Call ",[39,39929,39930],{},"el.removeEventListener('click', handler)"," (or use an ",[39,39933,39934],{},"AbortController",[39,39936,39937],{},"signal",") before discarding ",[39,39940,25687],{},", so the closure holding ",[39,39943,39878],{}," can be released",[28,39946,39948,39950,39951,39953],{"className":39947},[31],[33,39949],{"disabled":35,"type":36}," Nothing needs to change — removing ",[39,39952,25687],{}," from the DOM automatically releases its listeners and closures",[28,39955,39957,39959],{"className":39956},[31],[33,39958],{"disabled":35,"type":36}," Replace the named function with an arrow function to avoid the leak",[28,39961,39963,39965,39966,39968],{"className":39962},[31],[33,39964],{"disabled":35,"type":36}," Avoid closures entirely by making ",[39,39967,39878],{}," a global variable",[66,39970,39971,39973,39988],{},[69,39972,71],{},[73,39974,39975,39977,39978,39931,39980,446,39982,39938,39984,39941,39986,39944],{},[76,39976,78],{}," A — Call ",[39,39979,39930],{},[39,39981,39934],{},[39,39983,39937],{},[39,39985,25687],{},[39,39987,39878],{},[73,39989,39990,355,39992,39994,39995,39998,39999,40001,40002,40004,40005,9057,40007,40009,40010,40013],{},[76,39991,84],{},[76,39993,365],{}," as long as the listener reference exists, the ",[39,39996,39997],{},"handler"," closure keeps ",[39,40000,39878],{}," alive — and if something else (a framework, a detached-node cache, a reference cycle) keeps the element itself alive too, simply removing ",[39,40003,25687],{}," from the DOM tree doesn't guarantee garbage collection. Explicitly removing the listener (or attaching it with an ",[39,40006,39934],{},[39,40008,39937],{}," and calling ",[39,40011,40012],{},"abort()",") breaks the reference chain so both the element and the closed-over data can be collected. Swapping to an arrow function changes nothing about what's captured.",[15,40015,40016,40020,40175,40210],{"language":247},[18,40017,40019],{"id":40018},"q17-whats-the-pitfall-in-this-memoization-helper","Q17. What's the pitfall in this memoization helper?",[257,40021,40022],{"language":247},[260,40023,40025],{"className":262,"code":40024,"language":247,"meta":264,"style":264},"function memoize(fn) {\n  const cache = {};\n  return function (obj) {\n    const key = JSON.stringify(obj);\n    if (key in cache) return cache[key];\n    return (cache[key] = fn(obj));\n  };\n}\n\nconst process = memoize(data => data.a + data.b);\nprocess({ a: 1, b: 2 });\nprocess({ b: 2, a: 1 });\n",[39,40026,40027,40039,40049,40061,40078,40095,40108,40112,40116,40120,40144,40159],{"__ignoreMap":264},[268,40028,40029,40031,40033,40035,40037],{"class":270,"line":271},[268,40030,275],{"class":274},[268,40032,37832],{"class":278},[268,40034,622],{"class":282},[268,40036,37837],{"class":1222},[268,40038,1235],{"class":282},[268,40040,40041,40043,40045,40047],{"class":270,"line":286},[268,40042,12441],{"class":274},[268,40044,15807],{"class":305},[268,40046,616],{"class":274},[268,40048,15812],{"class":282},[268,40050,40051,40053,40055,40057,40059],{"class":270,"line":296},[268,40052,1240],{"class":274},[268,40054,12080],{"class":274},[268,40056,2182],{"class":282},[268,40058,22990],{"class":1222},[268,40060,1235],{"class":282},[268,40062,40063,40065,40067,40069,40071,40073,40075],{"class":270,"line":311},[268,40064,37893],{"class":274},[268,40066,12117],{"class":305},[268,40068,616],{"class":274},[268,40070,21715],{"class":305},[268,40072,462],{"class":282},[268,40074,21707],{"class":278},[268,40076,40077],{"class":282},"(obj);\n",[268,40079,40080,40082,40085,40087,40090,40092],{"class":270,"line":788},[268,40081,9686],{"class":274},[268,40083,40084],{"class":282}," (key ",[268,40086,20749],{"class":274},[268,40088,40089],{"class":282}," cache) ",[268,40091,9151],{"class":274},[268,40093,40094],{"class":282}," cache[key];\n",[268,40096,40097,40099,40102,40104,40106],{"class":270,"line":1951},[268,40098,9871],{"class":274},[268,40100,40101],{"class":282}," (cache[key] ",[268,40103,302],{"class":274},[268,40105,37900],{"class":278},[268,40107,21900],{"class":282},[268,40109,40110],{"class":270,"line":8955},[268,40111,15185],{"class":282},[268,40113,40114],{"class":270,"line":8966},[268,40115,314],{"class":282},[268,40117,40118],{"class":270,"line":8974},[268,40119,5033],{"emptyLinePlaceholder":35},[268,40121,40122,40124,40126,40128,40130,40132,40134,40136,40139,40141],{"class":270,"line":8985},[268,40123,243],{"class":274},[268,40125,10851],{"class":305},[268,40127,616],{"class":274},[268,40129,37832],{"class":278},[268,40131,622],{"class":282},[268,40133,21188],{"class":1222},[268,40135,14969],{"class":274},[268,40137,40138],{"class":282}," data.a ",[268,40140,1246],{"class":274},[268,40142,40143],{"class":282}," data.b);\n",[268,40145,40146,40148,40151,40153,40155,40157],{"class":270,"line":8990},[268,40147,140],{"class":278},[268,40149,40150],{"class":282},"({ a: ",[268,40152,2255],{"class":305},[268,40154,10279],{"class":282},[268,40156,2258],{"class":305},[268,40158,36080],{"class":282},[268,40160,40161,40163,40166,40168,40171,40173],{"class":270,"line":8997},[268,40162,140],{"class":278},[268,40164,40165],{"class":282},"({ b: ",[268,40167,2258],{"class":305},[268,40169,40170],{"class":282},", a: ",[268,40172,2255],{"class":305},[268,40174,36080],{"class":282},[23,40176,40178,40186,40192,40200],{"className":40177},[26],[28,40179,40181,355,40183,40185],{"className":40180},[31],[33,40182],{"disabled":35,"type":36},[39,40184,20555],{}," is key-order-sensitive, so these logically-equal objects produce different cache keys (an unwanted cache miss), and the cache also grows unbounded with no eviction",[28,40187,40189,40191],{"className":40188},[31],[33,40190],{"disabled":35,"type":36}," This code throws a TypeError on the second call because the key already exists",[28,40193,40195,355,40197,40199],{"className":40194},[31],[33,40196],{"disabled":35,"type":36},[39,40198,20555],{}," automatically sorts object keys, so this memoization works correctly and efficiently",[28,40201,40203,40205,40206,40209],{"className":40202},[31],[33,40204],{"disabled":35,"type":36}," The cache is shared across all calls to ",[39,40207,40208],{},"memoize",", causing collisions between unrelated functions",[66,40211,40212,40214,40220],{},[69,40213,71],{},[73,40215,40216,3459,40218,40185],{},[76,40217,78],{},[39,40219,20555],{},[73,40221,40222,355,40224,355,40226,186,40229,40232,40233,40235,40236,40239],{},[76,40223,84],{},[76,40225,930],{},[39,40227,40228],{},"JSON.stringify({a:1,b:2})",[39,40230,40231],{},"JSON.stringify({b:2,a:1})"," produce different strings even though the objects are equivalent, so the second call recomputes instead of hitting the cache — a subtle correctness\u002Fperf bug, not a crash. Separately, nothing ever removes entries from ",[39,40234,15925],{},", so a memoized function called with many distinct inputs grows the closure's cache indefinitely. Better practice: normalize keys (e.g. sort object keys before stringifying, or use a stable hash) and cap growth with an LRU eviction strategy or a ",[39,40237,40238],{},"WeakMap"," when keying by object identity is acceptable.",[15,40241,40242,40244,40452,40479],{"language":247},[18,40243,18980],{"id":18979},[257,40245,40246],{"language":247},[260,40247,40249],{"className":262,"code":40248,"language":247,"meta":264,"style":264},"const curry = fn => (...args) =>\n  args.length >= fn.length\n    ? fn(...args)\n    : (...more) => curry(fn)(...args, ...more);\n\nconst add3 = (a, b, c) => a + b + c;\nconst curried = curry(add3);\n\nconsole.log(curried(1)(2)(3), curried(1, 2)(3), curried(1, 2, 3));\n",[39,40250,40251,40276,40292,40306,40337,40341,40376,40390,40394],{"__ignoreMap":264},[268,40252,40253,40255,40258,40260,40262,40264,40266,40268,40271,40273],{"class":270,"line":271},[268,40254,243],{"class":274},[268,40256,40257],{"class":278}," curry",[268,40259,616],{"class":274},[268,40261,37900],{"class":1222},[268,40263,14969],{"class":274},[268,40265,2182],{"class":282},[268,40267,15329],{"class":274},[268,40269,40270],{"class":1222},"args",[268,40272,6131],{"class":282},[268,40274,40275],{"class":274},"=>\n",[268,40277,40278,40281,40283,40286,40289],{"class":270,"line":286},[268,40279,40280],{"class":282},"  args.",[268,40282,3567],{"class":305},[268,40284,40285],{"class":274}," >=",[268,40287,40288],{"class":282}," fn.",[268,40290,40291],{"class":305},"length\n",[268,40293,40294,40297,40299,40301,40303],{"class":270,"line":296},[268,40295,40296],{"class":274},"    ?",[268,40298,37900],{"class":278},[268,40300,622],{"class":282},[268,40302,15329],{"class":274},[268,40304,40305],{"class":282},"args)\n",[268,40307,40308,40311,40313,40315,40318,40320,40322,40324,40327,40329,40332,40334],{"class":270,"line":311},[268,40309,40310],{"class":274},"    :",[268,40312,2182],{"class":282},[268,40314,15329],{"class":274},[268,40316,40317],{"class":1222},"more",[268,40319,6131],{"class":282},[268,40321,9414],{"class":274},[268,40323,40257],{"class":278},[268,40325,40326],{"class":282},"(fn)(",[268,40328,15329],{"class":274},[268,40330,40331],{"class":282},"args, ",[268,40333,15329],{"class":274},[268,40335,40336],{"class":282},"more);\n",[268,40338,40339],{"class":270,"line":788},[268,40340,5033],{"emptyLinePlaceholder":35},[268,40342,40343,40345,40348,40350,40352,40354,40356,40358,40360,40362,40364,40366,40368,40370,40372,40374],{"class":270,"line":1951},[268,40344,243],{"class":274},[268,40346,40347],{"class":278}," add3",[268,40349,616],{"class":274},[268,40351,2182],{"class":282},[268,40353,1223],{"class":1222},[268,40355,42],{"class":282},[268,40357,1232],{"class":1222},[268,40359,42],{"class":282},[268,40361,16484],{"class":1222},[268,40363,6131],{"class":282},[268,40365,9414],{"class":274},[268,40367,1243],{"class":282},[268,40369,1246],{"class":274},[268,40371,2209],{"class":282},[268,40373,1246],{"class":274},[268,40375,28498],{"class":282},[268,40377,40378,40380,40383,40385,40387],{"class":270,"line":8955},[268,40379,243],{"class":274},[268,40381,40382],{"class":305}," curried",[268,40384,616],{"class":274},[268,40386,40257],{"class":278},[268,40388,40389],{"class":282},"(add3);\n",[268,40391,40392],{"class":270,"line":8966},[268,40393,5033],{"emptyLinePlaceholder":35},[268,40395,40396,40398,40400,40402,40405,40407,40409,40412,40414,40416,40418,40420,40422,40424,40426,40428,40430,40432,40434,40436,40438,40440,40442,40444,40446,40448,40450],{"class":270,"line":8974},[268,40397,1353],{"class":282},[268,40399,1356],{"class":278},[268,40401,622],{"class":282},[268,40403,40404],{"class":278},"curried",[268,40406,622],{"class":282},[268,40408,2255],{"class":305},[268,40410,40411],{"class":282},")(",[268,40413,2258],{"class":305},[268,40415,40411],{"class":282},[268,40417,3423],{"class":305},[268,40419,33111],{"class":282},[268,40421,40404],{"class":278},[268,40423,622],{"class":282},[268,40425,2255],{"class":305},[268,40427,42],{"class":282},[268,40429,2258],{"class":305},[268,40431,40411],{"class":282},[268,40433,3423],{"class":305},[268,40435,33111],{"class":282},[268,40437,40404],{"class":278},[268,40439,622],{"class":282},[268,40441,2255],{"class":305},[268,40443,42],{"class":282},[268,40445,2258],{"class":305},[268,40447,42],{"class":282},[268,40449,3423],{"class":305},[268,40451,4818],{"class":282},[23,40453,40455,40461,40467,40473],{"className":40454},[26],[28,40456,40458,40460],{"className":40457},[31],[33,40459],{"disabled":35,"type":36}," 6 6 6",[28,40462,40464,40466],{"className":40463},[31],[33,40465],{"disabled":35,"type":36}," Throws a TypeError because functions can't be called with zero, then more, arguments",[28,40468,40470,40472],{"className":40469},[31],[33,40471],{"disabled":35,"type":36}," NaN NaN 6",[28,40474,40476,40478],{"className":40475},[31],[33,40477],{"disabled":35,"type":36}," 6 NaN NaN",[66,40480,40481,40483,40488],{},[69,40482,71],{},[73,40484,40485,40487],{},[76,40486,78],{}," A — 6 6 6",[73,40489,40490,355,40492,40494,40495,40497,40498,40501,40502,5512,40505,40507,40508,40510],{},[76,40491,84],{},[76,40493,930],{}," each partial call returns a new closure that remembers (",[39,40496,40270],{},") the arguments accumulated so far, comparing their count against ",[39,40499,40500],{},"fn.length"," (the declared arity of ",[39,40503,40504],{},"add3",[39,40506,3423],{},"). Once enough arguments have accumulated across however many calls it took, the closure invokes the original function. All three calling styles — one at a time, in pairs, or all at once — reach the same total of three arguments and the same result, ",[39,40509,13663],{},". This accumulate-via-closure technique is the standard way to implement generic currying in JS.",[15,40512,40513,40517,40666,40696],{"language":247},[18,40514,40516],{"id":40515},"q19-for-a-list-of-10000-rows-that-re-renders-frequently-which-is-the-more-scalable-click-handling-strategy","Q19. For a list of 10,000 rows that re-renders frequently, which is the more scalable click-handling strategy?",[257,40518,40519],{"language":247},[260,40520,40522],{"className":262,"code":40521,"language":247,"meta":264,"style":264},"\u002F\u002F Approach A — one closure + one listener per row\nitems.forEach(item => {\n  const li = document.createElement('li');\n  li.addEventListener('click', () => selectItem(item.id));\n  list.appendChild(li);\n});\n\n\u002F\u002F Approach B — a single listener on the parent\nlist.addEventListener('click', e => {\n  const li = e.target.closest('li');\n  if (li) selectItem(li.dataset.id);\n});\n",[39,40523,40524,40529,40544,40564,40585,40596,40600,40604,40609,40629,40649,40662],{"__ignoreMap":264},[268,40525,40526],{"class":270,"line":271},[268,40527,40528],{"class":29390},"\u002F\u002F Approach A — one closure + one listener per row\n",[268,40530,40531,40534,40536,40538,40540,40542],{"class":270,"line":286},[268,40532,40533],{"class":282},"items.",[268,40535,12330],{"class":278},[268,40537,622],{"class":282},[268,40539,14793],{"class":1222},[268,40541,14969],{"class":274},[268,40543,9914],{"class":282},[268,40545,40546,40548,40551,40553,40555,40558,40560,40562],{"class":270,"line":296},[268,40547,12441],{"class":274},[268,40549,40550],{"class":305}," li",[268,40552,616],{"class":274},[268,40554,25659],{"class":282},[268,40556,40557],{"class":278},"createElement",[268,40559,622],{"class":282},[268,40561,25667],{"class":289},[268,40563,628],{"class":282},[268,40565,40566,40569,40571,40573,40575,40577,40579,40582],{"class":270,"line":311},[268,40567,40568],{"class":282},"  li.",[268,40570,35737],{"class":278},[268,40572,622],{"class":282},[268,40574,35742],{"class":289},[268,40576,35745],{"class":282},[268,40578,9414],{"class":274},[268,40580,40581],{"class":278}," selectItem",[268,40583,40584],{"class":282},"(item.id));\n",[268,40586,40587,40590,40593],{"class":270,"line":788},[268,40588,40589],{"class":282},"  list.",[268,40591,40592],{"class":278},"appendChild",[268,40594,40595],{"class":282},"(li);\n",[268,40597,40598],{"class":270,"line":1951},[268,40599,20047],{"class":282},[268,40601,40602],{"class":270,"line":8955},[268,40603,5033],{"emptyLinePlaceholder":35},[268,40605,40606],{"class":270,"line":8966},[268,40607,40608],{"class":29390},"\u002F\u002F Approach B — a single listener on the parent\n",[268,40610,40611,40614,40616,40618,40620,40622,40625,40627],{"class":270,"line":8974},[268,40612,40613],{"class":282},"list.",[268,40615,35737],{"class":278},[268,40617,622],{"class":282},[268,40619,35742],{"class":289},[268,40621,42],{"class":282},[268,40623,40624],{"class":1222},"e",[268,40626,14969],{"class":274},[268,40628,9914],{"class":282},[268,40630,40631,40633,40635,40637,40640,40643,40645,40647],{"class":270,"line":8985},[268,40632,12441],{"class":274},[268,40634,40550],{"class":305},[268,40636,616],{"class":274},[268,40638,40639],{"class":282}," e.target.",[268,40641,40642],{"class":278},"closest",[268,40644,622],{"class":282},[268,40646,25667],{"class":289},[268,40648,628],{"class":282},[268,40650,40651,40653,40656,40659],{"class":270,"line":8990},[268,40652,9863],{"class":274},[268,40654,40655],{"class":282}," (li) ",[268,40657,40658],{"class":278},"selectItem",[268,40660,40661],{"class":282},"(li.dataset.id);\n",[268,40663,40664],{"class":270,"line":8997},[268,40665,20047],{"class":282},[23,40667,40669,40675,40681,40687],{"className":40668},[26],[28,40670,40672,40674],{"className":40671},[31],[33,40673],{"disabled":35,"type":36}," Approach B — event delegation avoids allocating one closure and one listener per row, which matters a lot at scale",[28,40676,40678,40680],{"className":40677},[31],[33,40679],{"disabled":35,"type":36}," Approach A — more closures means more granular control and better performance",[28,40682,40684,40686],{"className":40683},[31],[33,40685],{"disabled":35,"type":36}," They perform identically; closures have no measurable cost",[28,40688,40690,40692,40693,40695],{"className":40689},[31],[33,40691],{"disabled":35,"type":36}," Approach A, but only if each closure is wrapped in ",[39,40694,36630],{}," instead of an arrow function",[66,40697,40698,40700,40705],{},[69,40699,71],{},[73,40701,40702,40704],{},[76,40703,78],{}," A — Approach B — event delegation avoids allocating one closure and one listener per row, which matters a lot at scale",[73,40706,40707,355,40709,40711,40712,446,40715,40718,40719,40722],{},[76,40708,84],{},[76,40710,438],{}," Approach A allocates 10,000 separate closures and registers 10,000 separate listeners, all of which need to be torn down and recreated on every re-render — real memory and GC pressure at that scale. Approach B attaches a single listener once, using event bubbling and ",[39,40713,40714],{},"closest()",[39,40716,40717],{},"dataset"," to figure out which row was clicked, so re-rendering the list doesn't require touching listeners at all. This is the standard ",[76,40720,40721],{},"event delegation"," pattern for large or frequently-changing lists.",[15,40724,40725,40733,40820,40852],{"language":247},[18,40726,40728,40729,40732],{"id":40727},"q20-why-must-timeoutid-be-declared-in-the-outer-function-here-rather-than-inside-the-returned-function","Q20. Why must ",[39,40730,40731],{},"timeoutId"," be declared in the outer function here, rather than inside the returned function?",[257,40734,40735],{"language":247},[260,40736,40738],{"className":262,"code":40737,"language":247,"meta":264,"style":264},"function debounce(fn, delay) {\n  let timeoutId;\n  return function (...args) {\n    clearTimeout(timeoutId);\n    timeoutId = setTimeout(() => fn.apply(this, args), delay);\n  };\n}\n",[39,40739,40740,40758,40765,40779,40787,40812,40816],{"__ignoreMap":264},[268,40741,40742,40744,40747,40749,40751,40753,40756],{"class":270,"line":271},[268,40743,275],{"class":274},[268,40745,40746],{"class":278}," debounce",[268,40748,622],{"class":282},[268,40750,37837],{"class":1222},[268,40752,42],{"class":282},[268,40754,40755],{"class":1222},"delay",[268,40757,1235],{"class":282},[268,40759,40760,40762],{"class":270,"line":286},[268,40761,2206],{"class":274},[268,40763,40764],{"class":282}," timeoutId;\n",[268,40766,40767,40769,40771,40773,40775,40777],{"class":270,"line":296},[268,40768,1240],{"class":274},[268,40770,12080],{"class":274},[268,40772,2182],{"class":282},[268,40774,15329],{"class":274},[268,40776,40270],{"class":1222},[268,40778,1235],{"class":282},[268,40780,40781,40784],{"class":270,"line":311},[268,40782,40783],{"class":278},"    clearTimeout",[268,40785,40786],{"class":282},"(timeoutId);\n",[268,40788,40789,40792,40794,40797,40799,40801,40803,40805,40807,40809],{"class":270,"line":788},[268,40790,40791],{"class":282},"    timeoutId ",[268,40793,302],{"class":274},[268,40795,40796],{"class":278}," setTimeout",[268,40798,9411],{"class":282},[268,40800,9414],{"class":274},[268,40802,40288],{"class":282},[268,40804,34637],{"class":278},[268,40806,622],{"class":282},[268,40808,950],{"class":305},[268,40810,40811],{"class":282},", args), delay);\n",[268,40813,40814],{"class":270,"line":1951},[268,40815,15185],{"class":282},[268,40817,40818],{"class":270,"line":8955},[268,40819,314],{"class":282},[23,40821,40823,40829,40835,40844],{"className":40822},[26],[28,40824,40826,40828],{"className":40825},[31],[33,40827],{"disabled":35,"type":36}," So its value persists across multiple calls to the debounced function, letting each new call cancel the previous pending timer",[28,40830,40832,40834],{"className":40831},[31],[33,40833],{"disabled":35,"type":36}," It's purely stylistic — declaring it inside the returned function would behave identically",[28,40836,40838,40840,40841,40843],{"className":40837},[31],[33,40839],{"disabled":35,"type":36}," To avoid a naming collision with the ",[39,40842,40755],{}," parameter",[28,40845,40847,12848,40849,40851],{"className":40846},[31],[33,40848],{"disabled":35,"type":36},[39,40850,240],{}," inside the returned function would throw a redeclaration error on the second call",[66,40853,40854,40856,40861],{},[69,40855,71],{},[73,40857,40858,40860],{},[76,40859,78],{}," A — So its value persists across multiple calls to the debounced function, letting each new call cancel the previous pending timer",[73,40862,40863,355,40865,40867,40868,40870,40871,40873,40874,40877],{},[76,40864,84],{},[76,40866,930],{}," debouncing fundamentally needs state (the id of the currently-pending timer) that outlives any single invocation and is shared across every call to the returned function — exactly what a variable in the enclosing closure scope provides. If ",[39,40869,40731],{}," were declared inside the returned function instead, it would be reinitialized to ",[39,40872,833],{}," on every call, ",[39,40875,40876],{},"clearTimeout(undefined)"," would be a no-op, and the previous timer would never actually get cancelled — defeating the entire point of debouncing.",[2107,40879,40880],{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}",{"title":264,"searchDepth":286,"depth":286,"links":40882},[40883,40884,40885,40886,40887,40888,40889,40890,40891,40893,40894,40895,40897,40898,40899,40900,40901,40902,40903,40904],{"id":26820,"depth":296,"text":26821},{"id":12736,"depth":296,"text":12737},{"id":12876,"depth":296,"text":12877},{"id":13031,"depth":296,"text":13032},{"id":37817,"depth":296,"text":37818},{"id":13320,"depth":296,"text":13321},{"id":13527,"depth":296,"text":13528},{"id":13728,"depth":296,"text":13729},{"id":38649,"depth":296,"text":40892},"Q9. Given modern JS engines (like V8), what typically happens to bigArray here?",{"id":17618,"depth":296,"text":17619},{"id":14223,"depth":296,"text":14224},{"id":39120,"depth":296,"text":40896},"Q12. What happens when show() is called?",{"id":14537,"depth":296,"text":14538},{"id":14773,"depth":296,"text":14774},{"id":39671,"depth":296,"text":39672},{"id":39854,"depth":296,"text":39855},{"id":40018,"depth":296,"text":40019},{"id":18979,"depth":296,"text":18980},{"id":40515,"depth":296,"text":40516},{"id":40727,"depth":296,"text":40905},"Q20. Why must timeoutId be declared in the outer function here, rather than inside the returned function?",{},"\u002Fjs\u002F12-closures-and-lexical-scope",{"title":37267,"description":264},"js\u002F12-closures-and-lexical-scope","9uP5qEx9nJT-_4J4zpRcN92MjbqYmYaGjAVnbbo_W6A",{"id":40912,"title":40913,"body":40914,"description":264,"extension":2144,"meta":44164,"navigation":35,"path":44165,"seo":44166,"stem":44167,"__hash__":44168},"content\u002Fjs\u002F13-higher-order-functions.md","13 — Higher-Order Functions",{"type":8,"value":40915,"toc":44140},[40916,40919,41090,41246,41359,41482,41612,41846,41969,42104,42200,42288,42499,42625,42776,43056,43219,43397,43558,43790,43987,44137],[11,40917,40913],{"id":40918},"_13-higher-order-functions",[15,40920,40921,40923,41014,41049],{"language":247},[18,40922,26821],{"id":26820},[257,40924,40925],{"language":247},[260,40926,40928],{"className":262,"code":40927,"language":247,"meta":264,"style":264},"function applyDiscount(prices, discountFn) {\n  return prices.map(discountFn);\n}\n\nconst withTax = applyDiscount([100, 200], p => p * 1.1);\nconsole.log(withTax);\n",[39,40929,40930,40948,40960,40964,40968,41005],{"__ignoreMap":264},[268,40931,40932,40934,40936,40938,40941,40943,40946],{"class":270,"line":271},[268,40933,275],{"class":274},[268,40935,36819],{"class":278},[268,40937,622],{"class":282},[268,40939,40940],{"class":1222},"prices",[268,40942,42],{"class":282},[268,40944,40945],{"class":1222},"discountFn",[268,40947,1235],{"class":282},[268,40949,40950,40952,40955,40957],{"class":270,"line":286},[268,40951,1240],{"class":274},[268,40953,40954],{"class":282}," prices.",[268,40956,23950],{"class":278},[268,40958,40959],{"class":282},"(discountFn);\n",[268,40961,40962],{"class":270,"line":296},[268,40963,314],{"class":282},[268,40965,40966],{"class":270,"line":311},[268,40967,5033],{"emptyLinePlaceholder":35},[268,40969,40970,40972,40975,40977,40979,40981,40983,40985,40988,40991,40993,40995,40998,41000,41003],{"class":270,"line":788},[268,40971,243],{"class":274},[268,40973,40974],{"class":305}," withTax",[268,40976,616],{"class":274},[268,40978,36819],{"class":278},[268,40980,17519],{"class":282},[268,40982,13912],{"class":305},[268,40984,42],{"class":282},[268,40986,40987],{"class":305},"200",[268,40989,40990],{"class":282},"], ",[268,40992,73],{"class":1222},[268,40994,14969],{"class":274},[268,40996,40997],{"class":282}," p ",[268,40999,6134],{"class":274},[268,41001,41002],{"class":305}," 1.1",[268,41004,628],{"class":282},[268,41006,41007,41009,41011],{"class":270,"line":1951},[268,41008,1353],{"class":282},[268,41010,1356],{"class":278},[268,41012,41013],{"class":282},"(withTax);\n",[23,41015,41017,41025,41033,41041],{"className":41016},[26],[28,41018,41020,355,41022],{"className":41019},[31],[33,41021],{"disabled":35,"type":36},[268,41023,41024],{},"110.00000000000001, 220.00000000000002",[28,41026,41028,355,41030],{"className":41027},[31],[33,41029],{"disabled":35,"type":36},[268,41031,41032],{},"110, 220",[28,41034,41036,34517,41038,41040],{"className":41035},[31],[33,41037],{"disabled":35,"type":36},[39,41039,40945],{}," isn't a built-in method",[28,41042,41044,355,41046],{"className":41043},[31],[33,41045],{"disabled":35,"type":36},[268,41047,41048],{},"100, 200",[66,41050,41051,41053,41059],{},[69,41052,71],{},[73,41054,41055,3459,41057],{},[76,41056,78],{},[268,41058,41024],{},[73,41060,41061,355,41063,358,41066,41069,41070,41072,41073,186,41076,41079,41080,446,41083,41086,41087,41089],{},[76,41062,84],{},[39,41064,41065],{},"applyDiscount",[76,41067,41068],{},"higher-order function"," — it accepts another function as an argument and delegates the transformation to it via ",[39,41071,23950],{},". The math itself hits a classic floating-point trap: ",[39,41074,41075],{},"100 * 1.1",[39,41077,41078],{},"200 * 1.1"," can't be represented exactly in IEEE-754 double precision, so the results carry tiny rounding error instead of the clean ",[39,41081,41082],{},"110",[39,41084,41085],{},"220"," you'd expect. ",[76,41088,365],{}," this is why money math is usually done in integer cents or with a decimal library, not floating-point multiplication.",[15,41091,41092,41094,41184,41212],{"language":247},[18,41093,12737],{"id":12736},[257,41095,41096],{"language":247},[260,41097,41099],{"className":262,"code":41098,"language":247,"meta":264,"style":264},"function multiplyBy(factor) {\n  return function (n) {\n    return n * factor;\n  };\n}\n\nconst double = multiplyBy(2);\nconsole.log(double(5));\n",[39,41100,41101,41115,41127,41138,41142,41146,41150,41167],{"__ignoreMap":264},[268,41102,41103,41105,41108,41110,41113],{"class":270,"line":271},[268,41104,275],{"class":274},[268,41106,41107],{"class":278}," multiplyBy",[268,41109,622],{"class":282},[268,41111,41112],{"class":1222},"factor",[268,41114,1235],{"class":282},[268,41116,41117,41119,41121,41123,41125],{"class":270,"line":286},[268,41118,1240],{"class":274},[268,41120,12080],{"class":274},[268,41122,2182],{"class":282},[268,41124,4599],{"class":1222},[268,41126,1235],{"class":282},[268,41128,41129,41131,41133,41135],{"class":270,"line":296},[268,41130,9871],{"class":274},[268,41132,13355],{"class":282},[268,41134,6134],{"class":274},[268,41136,41137],{"class":282}," factor;\n",[268,41139,41140],{"class":270,"line":311},[268,41141,15185],{"class":282},[268,41143,41144],{"class":270,"line":788},[268,41145,314],{"class":282},[268,41147,41148],{"class":270,"line":1951},[268,41149,5033],{"emptyLinePlaceholder":35},[268,41151,41152,41154,41157,41159,41161,41163,41165],{"class":270,"line":8955},[268,41153,243],{"class":274},[268,41155,41156],{"class":305}," double",[268,41158,616],{"class":274},[268,41160,41107],{"class":278},[268,41162,622],{"class":282},[268,41164,2258],{"class":305},[268,41166,628],{"class":282},[268,41168,41169,41171,41173,41175,41178,41180,41182],{"class":270,"line":8966},[268,41170,1353],{"class":282},[268,41172,1356],{"class":278},[268,41174,622],{"class":282},[268,41176,41177],{"class":278},"double",[268,41179,622],{"class":282},[268,41181,2429],{"class":305},[268,41183,4818],{"class":282},[23,41185,41187,41192,41201,41206],{"className":41186},[26],[28,41188,41190,306],{"className":41189},[31],[33,41191],{"disabled":35,"type":36},[28,41193,41195,34517,41197,41200],{"className":41194},[31],[33,41196],{"disabled":35,"type":36},[39,41198,41199],{},"multiplyBy"," doesn't return a callable value",[28,41202,41204,3027],{"className":41203},[31],[33,41205],{"disabled":35,"type":36},[28,41207,41209,41211],{"className":41208},[31],[33,41210],{"disabled":35,"type":36}," 7 (5 + 2)",[66,41213,41214,41216,41221],{},[69,41215,71],{},[73,41217,41218,41220],{},[76,41219,78],{}," A — 10",[73,41222,41223,355,41225,41227,41228,3277,41230,41232,41233,41235,41236,41238,41239,6204,41242,41245],{},[76,41224,84],{},[39,41226,41199],{}," is a factory: it returns a new function that closes over ",[39,41229,41112],{},[39,41231,41177],{}," is that returned function with ",[39,41234,41112],{}," fixed at ",[39,41237,2258],{},", so calling ",[39,41240,41241],{},"double(5)",[39,41243,41244],{},"5 * 2 = 10",". This \"function returning a function\" shape is the foundation both of closures and of currying, covered later in this quiz.",[15,41247,41248,41250,41302,41332],{"language":247},[18,41249,12877],{"id":12876},[257,41251,41252],{"language":247},[260,41253,41255],{"className":262,"code":41254,"language":247,"meta":264,"style":264},"const names = ['ana', 'bob'];\nconsole.log(names.map(n => n.toUpperCase()));\n",[39,41256,41257,41278],{"__ignoreMap":264},[268,41258,41259,41261,41264,41266,41268,41271,41273,41276],{"class":270,"line":271},[268,41260,243],{"class":274},[268,41262,41263],{"class":305}," names",[268,41265,616],{"class":274},[268,41267,8710],{"class":282},[268,41269,41270],{"class":289},"'ana'",[268,41272,42],{"class":282},[268,41274,41275],{"class":289},"'bob'",[268,41277,8737],{"class":282},[268,41279,41280,41282,41284,41287,41289,41291,41293,41295,41298,41300],{"class":270,"line":286},[268,41281,1353],{"class":282},[268,41283,1356],{"class":278},[268,41285,41286],{"class":282},"(names.",[268,41288,23950],{"class":278},[268,41290,622],{"class":282},[268,41292,4599],{"class":1222},[268,41294,14969],{"class":274},[268,41296,41297],{"class":282}," n.",[268,41299,16179],{"class":278},[268,41301,39055],{"class":282},[23,41303,41305,41313,41321,41327],{"className":41304},[26],[28,41306,41308,355,41310],{"className":41307},[31],[33,41309],{"disabled":35,"type":36},[268,41311,41312],{},"'ANA', 'BOB'",[28,41314,41316,355,41318],{"className":41315},[31],[33,41317],{"disabled":35,"type":36},[268,41319,41320],{},"'ana', 'bob'",[28,41322,41324,41326],{"className":41323},[31],[33,41325],{"disabled":35,"type":36}," 'ANA,BOB'",[28,41328,41330,34257],{"className":41329},[31],[33,41331],{"disabled":35,"type":36},[66,41333,41334,41336,41342],{},[69,41335,71],{},[73,41337,41338,3459,41340],{},[76,41339,78],{},[268,41341,41312],{},[73,41343,41344,355,41346,38415,41348,41351,41352,41355,41356,41358],{},[76,41345,84],{},[39,41347,23950],{},[76,41349,41350],{},"new array"," by applying the callback to every element and collecting the return values — it never mutates ",[39,41353,41354],{},"names",". Each string's ",[39,41357,16073],{}," produces a new uppercase string, and those are collected in order into the result array.",[15,41360,41361,41363,41425,41455],{"language":247},[18,41362,13032],{"id":13031},[257,41364,41365],{"language":247},[260,41366,41368],{"className":262,"code":41367,"language":247,"meta":264,"style":264},"const nums = [1, 2, 3, 4, 5];\nconsole.log(nums.filter(n => n > 3));\n",[39,41369,41370,41400],{"__ignoreMap":264},[268,41371,41372,41374,41376,41378,41380,41382,41384,41386,41388,41390,41392,41394,41396,41398],{"class":270,"line":271},[268,41373,243],{"class":274},[268,41375,12090],{"class":305},[268,41377,616],{"class":274},[268,41379,8710],{"class":282},[268,41381,2255],{"class":305},[268,41383,42],{"class":282},[268,41385,2258],{"class":305},[268,41387,42],{"class":282},[268,41389,3423],{"class":305},[268,41391,42],{"class":282},[268,41393,15049],{"class":305},[268,41395,42],{"class":282},[268,41397,2429],{"class":305},[268,41399,8737],{"class":282},[268,41401,41402,41404,41406,41409,41411,41413,41415,41417,41419,41421,41423],{"class":270,"line":286},[268,41403,1353],{"class":282},[268,41405,1356],{"class":278},[268,41407,41408],{"class":282},"(nums.",[268,41410,14962],{"class":278},[268,41412,622],{"class":282},[268,41414,4599],{"class":1222},[268,41416,14969],{"class":274},[268,41418,13355],{"class":282},[268,41420,6435],{"class":274},[268,41422,3396],{"class":305},[268,41424,4818],{"class":282},[23,41426,41428,41435,41442,41447],{"className":41427},[26],[28,41429,41431,355,41433],{"className":41430},[31],[33,41432],{"disabled":35,"type":36},[268,41434,24862],{},[28,41436,41438,355,41440],{"className":41437},[31],[33,41439],{"disabled":35,"type":36},[268,41441,23888],{},[28,41443,41445,7905],{"className":41444},[31],[33,41446],{"disabled":35,"type":36},[28,41448,41450,355,41452],{"className":41449},[31],[33,41451],{"disabled":35,"type":36},[268,41453,41454],{},"false, false, false, true, true",[66,41456,41457,41459,41465],{},[69,41458,71],{},[73,41460,41461,3459,41463],{},[76,41462,78],{},[268,41464,24862],{},[73,41466,41467,355,41469,41471,41472,41474,41475,186,41478,41481],{},[76,41468,84],{},[39,41470,14962],{}," keeps only the elements for which the predicate returns a truthy value, returning a new array of just those elements — not the boolean results themselves (that would be ",[39,41473,23950],{},"'s job). ",[39,41476,41477],{},"4 > 3",[39,41479,41480],{},"5 > 3"," are the only true cases.",[15,41483,41484,41486,41553,41580],{"language":247},[18,41485,13181],{"id":13180},[257,41487,41488],{"language":247},[260,41489,41491],{"className":262,"code":41490,"language":247,"meta":264,"style":264},"const cart = [{ price: 10 }, { price: 20 }, { price: 5 }];\nconsole.log(cart.reduce((sum, item) => sum + item.price, 0));\n",[39,41492,41493,41518],{"__ignoreMap":264},[268,41494,41495,41497,41500,41502,41505,41507,41510,41512,41514,41516],{"class":270,"line":271},[268,41496,243],{"class":274},[268,41498,41499],{"class":305}," cart",[268,41501,616],{"class":274},[268,41503,41504],{"class":282}," [{ price: ",[268,41506,5825],{"class":305},[268,41508,41509],{"class":282}," }, { price: ",[268,41511,6149],{"class":305},[268,41513,41509],{"class":282},[268,41515,2429],{"class":305},[268,41517,26654],{"class":282},[268,41519,41520,41522,41524,41527,41529,41531,41533,41535,41537,41539,41541,41544,41546,41549,41551],{"class":270,"line":286},[268,41521,1353],{"class":282},[268,41523,1356],{"class":278},[268,41525,41526],{"class":282},"(cart.",[268,41528,14980],{"class":278},[268,41530,6122],{"class":282},[268,41532,28535],{"class":1222},[268,41534,42],{"class":282},[268,41536,14793],{"class":1222},[268,41538,6131],{"class":282},[268,41540,9414],{"class":274},[268,41542,41543],{"class":282}," sum ",[268,41545,1246],{"class":274},[268,41547,41548],{"class":282}," item.price, ",[268,41550,3307],{"class":305},[268,41552,4818],{"class":282},[23,41554,41556,41562,41567,41572],{"className":41555},[26],[28,41557,41559,41561],{"className":41558},[31],[33,41560],{"disabled":35,"type":36}," 35",[28,41563,41565,5728],{"className":41564},[31],[33,41566],{"disabled":35,"type":36},[28,41568,41570,3027],{"className":41569},[31],[33,41571],{"disabled":35,"type":36},[28,41573,41575,355,41577],{"className":41574},[31],[33,41576],{"disabled":35,"type":36},[268,41578,41579],{},"10, 20, 5",[66,41581,41582,41584,41589],{},[69,41583,71],{},[73,41585,41586,41588],{},[76,41587,78],{}," A — 35",[73,41590,41591,355,41593,41595,41596,41598,41599,41601,41602,42,41605,42,41608,41611],{},[76,41592,84],{},[39,41594,14980],{}," folds the array down to a single value by repeatedly applying the callback, carrying an accumulator (",[39,41597,28535],{},", starting at the initial value ",[39,41600,3307],{},") forward. ",[39,41603,41604],{},"0 + 10 = 10",[39,41606,41607],{},"10 + 20 = 30",[39,41609,41610],{},"30 + 5 = 35"," — the final accumulator is what's returned.",[15,41613,41614,41616,41772,41806],{"language":247},[18,41615,13321],{"id":13320},[257,41617,41618],{"language":247},[260,41619,41621],{"className":262,"code":41620,"language":247,"meta":264,"style":264},"const orders = [\n  { amount: 100, status: 'paid' },\n  { amount: 50, status: 'pending' },\n  { amount: 200, status: 'paid' }\n];\n\nconst total = orders\n  .filter(o => o.status === 'paid')\n  .map(o => o.amount)\n  .reduce((a, b) => a + b, 0);\n\nconsole.log(total);\n",[39,41622,41623,41634,41649,41662,41674,41678,41682,41693,41717,41732,41760,41764],{"__ignoreMap":264},[268,41624,41625,41627,41630,41632],{"class":270,"line":271},[268,41626,243],{"class":274},[268,41628,41629],{"class":305}," orders",[268,41631,616],{"class":274},[268,41633,16546],{"class":282},[268,41635,41636,41639,41641,41644,41647],{"class":270,"line":286},[268,41637,41638],{"class":282},"  { amount: ",[268,41640,13912],{"class":305},[268,41642,41643],{"class":282},", status: ",[268,41645,41646],{"class":289},"'paid'",[268,41648,20042],{"class":282},[268,41650,41651,41653,41655,41657,41660],{"class":270,"line":296},[268,41652,41638],{"class":282},[268,41654,32109],{"class":305},[268,41656,41643],{"class":282},[268,41658,41659],{"class":289},"'pending'",[268,41661,20042],{"class":282},[268,41663,41664,41666,41668,41670,41672],{"class":270,"line":311},[268,41665,41638],{"class":282},[268,41667,40987],{"class":305},[268,41669,41643],{"class":282},[268,41671,41646],{"class":289},[268,41673,29394],{"class":282},[268,41675,41676],{"class":270,"line":788},[268,41677,8737],{"class":282},[268,41679,41680],{"class":270,"line":1951},[268,41681,5033],{"emptyLinePlaceholder":35},[268,41683,41684,41686,41688,41690],{"class":270,"line":8955},[268,41685,243],{"class":274},[268,41687,34590],{"class":305},[268,41689,616],{"class":274},[268,41691,41692],{"class":282}," orders\n",[268,41694,41695,41698,41700,41702,41705,41707,41710,41712,41715],{"class":270,"line":8966},[268,41696,41697],{"class":282},"  .",[268,41699,14962],{"class":278},[268,41701,622],{"class":282},[268,41703,41704],{"class":1222},"o",[268,41706,14969],{"class":274},[268,41708,41709],{"class":282}," o.status ",[268,41711,3280],{"class":274},[268,41713,41714],{"class":289}," 'paid'",[268,41716,20702],{"class":282},[268,41718,41719,41721,41723,41725,41727,41729],{"class":270,"line":8974},[268,41720,41697],{"class":282},[268,41722,23950],{"class":278},[268,41724,622],{"class":282},[268,41726,41704],{"class":1222},[268,41728,14969],{"class":274},[268,41730,41731],{"class":282}," o.amount)\n",[268,41733,41734,41736,41738,41740,41742,41744,41746,41748,41750,41752,41754,41756,41758],{"class":270,"line":8985},[268,41735,41697],{"class":282},[268,41737,14980],{"class":278},[268,41739,6122],{"class":282},[268,41741,1223],{"class":1222},[268,41743,42],{"class":282},[268,41745,1232],{"class":1222},[268,41747,6131],{"class":282},[268,41749,9414],{"class":274},[268,41751,1243],{"class":282},[268,41753,1246],{"class":274},[268,41755,14999],{"class":282},[268,41757,3307],{"class":305},[268,41759,628],{"class":282},[268,41761,41762],{"class":270,"line":8990},[268,41763,5033],{"emptyLinePlaceholder":35},[268,41765,41766,41768,41770],{"class":270,"line":8997},[268,41767,1353],{"class":282},[268,41769,1356],{"class":278},[268,41771,21502],{"class":282},[23,41773,41775,41781,41787,41792],{"className":41774},[26],[28,41776,41778,41780],{"className":41777},[31],[33,41779],{"disabled":35,"type":36}," 300",[28,41782,41784,41786],{"className":41783},[31],[33,41785],{"disabled":35,"type":36}," 350",[28,41788,41790,22087],{"className":41789},[31],[33,41791],{"disabled":35,"type":36},[28,41793,41795,41797,41798,42,41800,137,41802,41805],{"className":41794},[31],[33,41796],{"disabled":35,"type":36}," Throws a TypeError because you can't chain ",[39,41799,15111],{},[39,41801,39625],{},[39,41803,41804],{},".reduce"," together",[66,41807,41808,41810,41815],{},[69,41809,71],{},[73,41811,41812,41814],{},[76,41813,78],{}," A — 300",[73,41816,41817,41819,41820,41823,41824,41826,41827,41829,41830,186,41832,33111,41834,41836,41837,137,41839,41841,41842,41845],{},[76,41818,84],{}," This is a standard ",[76,41821,41822],{},"map\u002Ffilter\u002Freduce composition"," pipeline: ",[39,41825,14962],{}," keeps only the two ",[39,41828,41646],{}," orders (",[39,41831,13912],{},[39,41833,40987],{},[39,41835,23950],{}," projects each down to just its ",[39,41838,31848],{},[39,41840,14980],{}," sums those amounts to ",[39,41843,41844],{},"300",". Each method returns a new array (or value), which is exactly what makes chaining them together work.",[15,41847,41848,41850,41900,41929],{"language":247},[18,41849,13528],{"id":13527},[257,41851,41852],{"language":247},[260,41853,41855],{"className":262,"code":41854,"language":247,"meta":264,"style":264},"const add = a => b => a + b;\nconsole.log(add(3)(4));\n",[39,41856,41857,41879],{"__ignoreMap":264},[268,41858,41859,41861,41863,41865,41867,41869,41871,41873,41875,41877],{"class":270,"line":271},[268,41860,243],{"class":274},[268,41862,1217],{"class":278},[268,41864,616],{"class":274},[268,41866,7203],{"class":1222},[268,41868,14969],{"class":274},[268,41870,16372],{"class":1222},[268,41872,14969],{"class":274},[268,41874,1243],{"class":282},[268,41876,1246],{"class":274},[268,41878,1249],{"class":282},[268,41880,41881,41883,41885,41887,41890,41892,41894,41896,41898],{"class":270,"line":286},[268,41882,1353],{"class":282},[268,41884,1356],{"class":278},[268,41886,622],{"class":282},[268,41888,41889],{"class":278},"add",[268,41891,622],{"class":282},[268,41893,3423],{"class":305},[268,41895,40411],{"class":282},[268,41897,15049],{"class":305},[268,41899,4818],{"class":282},[23,41901,41903,41909,41918,41924],{"className":41902},[26],[28,41904,41906,41908],{"className":41905},[31],[33,41907],{"disabled":35,"type":36}," 7",[28,41910,41912,34517,41914,41917],{"className":41911},[31],[33,41913],{"disabled":35,"type":36},[39,41915,41916],{},"add(3)"," isn't callable",[28,41919,41921,41923],{"className":41920},[31],[33,41922],{"disabled":35,"type":36}," \"34\" (string concatenation)",[28,41925,41927,17135],{"className":41926},[31],[33,41928],{"disabled":35,"type":36},[66,41930,41931,41933,41938],{},[69,41932,71],{},[73,41934,41935,41937],{},[76,41936,78],{}," A — 7",[73,41939,41940,41942,41943,1783,41946,41948,41949,41952,41953,41235,41955,41957,41958,6204,41960,41963,41964,186,41966,41968],{},[76,41941,84],{}," This is basic ",[76,41944,41945],{},"currying",[39,41947,41916],{}," returns a new arrow function ",[39,41950,41951],{},"b => 3 + b"," (with ",[39,41954,1223],{},[39,41956,3423],{}," via closure), and calling that with ",[39,41959,15049],{},[39,41961,41962],{},"3 + 4 = 7",". Both ",[39,41965,1223],{},[39,41967,1232],{}," are numbers, so there's no string coercion involved.",[15,41970,41971,41975,42009,42040],{"language":247},[18,41972,41974],{"id":41973},"q8-what-does-this-famously-log","Q8. What does this famously log?",[257,41976,41977],{"language":247},[260,41978,41980],{"className":262,"code":41979,"language":247,"meta":264,"style":264},"console.log(['1', '2', '3'].map(parseInt));\n",[39,41981,41982],{"__ignoreMap":264},[268,41983,41984,41986,41988,41990,41992,41994,41996,41998,42001,42004,42006],{"class":270,"line":271},[268,41985,1353],{"class":282},[268,41987,1356],{"class":278},[268,41989,17519],{"class":282},[268,41991,17916],{"class":289},[268,41993,42],{"class":282},[268,41995,17912],{"class":289},[268,41997,42],{"class":282},[268,41999,42000],{"class":289},"'3'",[268,42002,42003],{"class":282},"].",[268,42005,23950],{"class":278},[268,42007,42008],{"class":282},"(parseInt));\n",[23,42010,42012,42020,42027,42035],{"className":42011},[26],[28,42013,42015,355,42017],{"className":42014},[31],[33,42016],{"disabled":35,"type":36},[268,42018,42019],{},"1, NaN, NaN",[28,42021,42023,355,42025],{"className":42022},[31],[33,42024],{"disabled":35,"type":36},[268,42026,23888],{},[28,42028,42030,355,42032],{"className":42029},[31],[33,42031],{"disabled":35,"type":36},[268,42033,42034],{},"1, 2, NaN",[28,42036,42038,34257],{"className":42037},[31],[33,42039],{"disabled":35,"type":36},[66,42041,42042,42044,42050],{},[69,42043,71],{},[73,42045,42046,3459,42048],{},[76,42047,78],{},[268,42049,42019],{},[73,42051,42052,355,42054,42056,42057,42059,42060,42063,42064,42067,42068,42071,42072,42075,42076,42078,42079,33111,42081,42075,42084,42086,42087,24403,42089,42092,42093,6345,42095,42097,42098,99,42101,462],{},[76,42053,84],{},[76,42055,365],{}," this is one of JavaScript's most famous \"wat\" moments. ",[39,42058,23950],{}," invokes its callback with ",[76,42061,42062],{},"three"," arguments — ",[39,42065,42066],{},"(element, index, array)"," — and ",[39,42069,42070],{},"parseInt(string, radix)"," treats that second argument as a radix. So it actually runs ",[39,42073,42074],{},"parseInt('1', 0, [...])"," (radix ",[39,42077,3307],{}," means \"auto-detect,\" which defaults to base 10, giving ",[39,42080,2255],{},[39,42082,42083],{},"parseInt('2', 1, [...])",[39,42085,2255],{}," is invalid, giving ",[39,42088,3040],{},[39,42090,42091],{},"parseInt('3', 2, [...])"," (base 2 can't contain the digit ",[39,42094,42000],{},[39,42096,3040],{},"). The fix is ",[39,42099,42100],{},"['1','2','3'].map(s => parseInt(s, 10))",[39,42102,42103],{},".map(Number)",[15,42105,42106,42110,42147,42178],{"language":247},[18,42107,42109],{"id":42108},"q9-what-happens-here","Q9. What happens here?",[257,42111,42112],{"language":247},[260,42113,42115],{"className":262,"code":42114,"language":247,"meta":264,"style":264},"console.log([].reduce((a, b) => a + b));\n",[39,42116,42117],{"__ignoreMap":264},[268,42118,42119,42121,42123,42126,42128,42130,42132,42134,42136,42138,42140,42142,42144],{"class":270,"line":271},[268,42120,1353],{"class":282},[268,42122,1356],{"class":278},[268,42124,42125],{"class":282},"([].",[268,42127,14980],{"class":278},[268,42129,6122],{"class":282},[268,42131,1223],{"class":1222},[268,42133,42],{"class":282},[268,42135,1232],{"class":1222},[268,42137,6131],{"class":282},[268,42139,9414],{"class":274},[268,42141,1243],{"class":282},[268,42143,1246],{"class":274},[268,42145,42146],{"class":282}," b));\n",[23,42148,42150,42157,42164,42171],{"className":42149},[26],[28,42151,42153,6738,42155],{"className":42152},[31],[33,42154],{"disabled":35,"type":36},[39,42156,24280],{},[28,42158,42160,3578,42162],{"className":42159},[31],[33,42161],{"disabled":35,"type":36},[39,42163,3307],{},[28,42165,42167,3578,42169],{"className":42166},[31],[33,42168],{"disabled":35,"type":36},[39,42170,833],{},[28,42172,42174,3578,42176],{"className":42173},[31],[33,42175],{"disabled":35,"type":36},[39,42177,3040],{},[66,42179,42180,42182,42188],{},[69,42181,71],{},[73,42183,42184,35317,42186],{},[76,42185,78],{},[39,42187,24280],{},[73,42189,42190,24264,42192,42194,42195,99,42197,42199],{},[76,42191,84],{},[39,42193,14980],{}," tries to use the array's first element as the starting accumulator — but an empty array has no first element, and there's nothing meaningful to return, so it throws instead of silently producing ",[39,42196,3307],{},[39,42198,833],{},". The fix (and the general best practice — see Q10) is to always supply an explicit initial value.",[15,42201,42202,42204,42243,42267],{"language":247},[18,42203,17619],{"id":17618},[257,42205,42206],{"language":247},[260,42207,42209],{"className":262,"code":42208,"language":247,"meta":264,"style":264},"console.log([].reduce((a, b) => a + b, 100));\n",[39,42210,42211],{"__ignoreMap":264},[268,42212,42213,42215,42217,42219,42221,42223,42225,42227,42229,42231,42233,42235,42237,42239,42241],{"class":270,"line":271},[268,42214,1353],{"class":282},[268,42216,1356],{"class":278},[268,42218,42125],{"class":282},[268,42220,14980],{"class":278},[268,42222,6122],{"class":282},[268,42224,1223],{"class":1222},[268,42226,42],{"class":282},[268,42228,1232],{"class":1222},[268,42230,6131],{"class":282},[268,42232,9414],{"class":274},[268,42234,1243],{"class":282},[268,42236,1246],{"class":274},[268,42238,14999],{"class":282},[268,42240,13912],{"class":305},[268,42242,4818],{"class":282},[23,42244,42246,42251,42257,42262],{"className":42245},[26],[28,42247,42249,13821],{"className":42248},[31],[33,42250],{"disabled":35,"type":36},[28,42252,42254,42256],{"className":42253},[31],[33,42255],{"disabled":35,"type":36}," Throws a TypeError, same as with no initial value",[28,42258,42260,3027],{"className":42259},[31],[33,42261],{"disabled":35,"type":36},[28,42263,42265,17135],{"className":42264},[31],[33,42266],{"disabled":35,"type":36},[66,42268,42269,42271,42276],{},[69,42270,71],{},[73,42272,42273,42275],{},[76,42274,78],{}," A — 100",[73,42277,42278,42280,42281,42283,42284,42287],{},[76,42279,84],{}," With an initial value supplied, ",[39,42282,14980],{}," on an empty array simply returns that initial value ",[76,42285,42286],{},"without ever invoking the callback"," — there are no elements to combine it with. This is the safe, predictable behavior that Q9's version lacks, and it's why always passing an initial value is the recommended default.",[15,42289,42290,42292,42423,42450],{"language":247},[18,42291,14224],{"id":14223},[257,42293,42294],{"language":247},[260,42295,42297],{"className":262,"code":42296,"language":247,"meta":264,"style":264},"function findFirstEven(arr) {\n  let result;\n  arr.forEach(n => {\n    if (n % 2 === 0) {\n      result = n;\n      return;\n    }\n  });\n  return result;\n}\n\nconsole.log(findFirstEven([1, 3, 5, 4, 6, 8]));\n",[39,42298,42299,42312,42318,42333,42349,42358,42364,42368,42372,42378,42382,42386],{"__ignoreMap":264},[268,42300,42301,42303,42306,42308,42310],{"class":270,"line":271},[268,42302,275],{"class":274},[268,42304,42305],{"class":278}," findFirstEven",[268,42307,622],{"class":282},[268,42309,25909],{"class":1222},[268,42311,1235],{"class":282},[268,42313,42314,42316],{"class":270,"line":286},[268,42315,2206],{"class":274},[268,42317,10895],{"class":282},[268,42319,42320,42323,42325,42327,42329,42331],{"class":270,"line":296},[268,42321,42322],{"class":282},"  arr.",[268,42324,12330],{"class":278},[268,42326,622],{"class":282},[268,42328,4599],{"class":1222},[268,42330,14969],{"class":274},[268,42332,9914],{"class":282},[268,42334,42335,42337,42339,42341,42343,42345,42347],{"class":270,"line":311},[268,42336,9686],{"class":274},[268,42338,13562],{"class":282},[268,42340,26178],{"class":274},[268,42342,2214],{"class":305},[268,42344,3043],{"class":274},[268,42346,5728],{"class":305},[268,42348,1235],{"class":282},[268,42350,42351,42354,42356],{"class":270,"line":788},[268,42352,42353],{"class":282},"      result ",[268,42355,302],{"class":274},[268,42357,16927],{"class":282},[268,42359,42360,42362],{"class":270,"line":1951},[268,42361,10451],{"class":274},[268,42363,293],{"class":282},[268,42365,42366],{"class":270,"line":8955},[268,42367,11972],{"class":282},[268,42369,42370],{"class":270,"line":8966},[268,42371,39914],{"class":282},[268,42373,42374,42376],{"class":270,"line":8974},[268,42375,1240],{"class":274},[268,42377,10895],{"class":282},[268,42379,42380],{"class":270,"line":8985},[268,42381,314],{"class":282},[268,42383,42384],{"class":270,"line":8990},[268,42385,5033],{"emptyLinePlaceholder":35},[268,42387,42388,42390,42392,42394,42397,42399,42401,42403,42405,42407,42409,42411,42413,42415,42417,42419,42421],{"class":270,"line":8997},[268,42389,1353],{"class":282},[268,42391,1356],{"class":278},[268,42393,622],{"class":282},[268,42395,42396],{"class":278},"findFirstEven",[268,42398,17519],{"class":282},[268,42400,2255],{"class":305},[268,42402,42],{"class":282},[268,42404,3423],{"class":305},[268,42406,42],{"class":282},[268,42408,2429],{"class":305},[268,42410,42],{"class":282},[268,42412,15049],{"class":305},[268,42414,42],{"class":282},[268,42416,13663],{"class":305},[268,42418,42],{"class":282},[268,42420,10664],{"class":305},[268,42422,24210],{"class":282},[23,42424,42426,42432,42437,42442],{"className":42425},[26],[28,42427,42429,42431],{"className":42428},[31],[33,42430],{"disabled":35,"type":36}," 8",[28,42433,42435,6111],{"className":42434},[31],[33,42436],{"disabled":35,"type":36},[28,42438,42440,17135],{"className":42439},[31],[33,42441],{"disabled":35,"type":36},[28,42443,42445,355,42447],{"className":42444},[31],[33,42446],{"disabled":35,"type":36},[268,42448,42449],{},"4, 6, 8",[66,42451,42452,42454,42459],{},[69,42453,71],{},[73,42455,42456,42458],{},[76,42457,78],{}," A — 8",[73,42460,42461,355,42463,21599,42465,42467,42468,42470,42471,42473,42474,42476,42477,42479,42480,3493,42482,3493,42484,42486,42487,42489,42490,42493,42494,42496,42497,462],{},[76,42462,84],{},[76,42464,365],{},[39,42466,9151],{}," inside the ",[39,42469,12330],{}," callback only exits that single invocation of the callback — it does ",[76,42472,95],{}," break out of the loop, because ",[39,42475,12330],{}," provides no mechanism for early termination at all. So the callback keeps running for every element, and ",[39,42478,5631],{}," gets overwritten each time an even number is found (",[39,42481,15049],{},[39,42483,13663],{},[39,42485,10664],{},"), ending on the ",[104,42488,6891],{}," even number rather than the first. The correct fix for \"stop at the first match\" is ",[39,42491,42492],{},"arr.find(n => n % 2 === 0)",", or a ",[39,42495,9163],{}," loop with a real ",[39,42498,8880],{},[15,42500,42501,42503,42550,42586],{"language":247},[18,42502,14382],{"id":14381},[257,42504,42505],{"language":247},[260,42506,42508],{"className":262,"code":42507,"language":247,"meta":264,"style":264},"const scores = [10, 1, 2, 21];\nconsole.log(scores.sort());\n",[39,42509,42510,42537],{"__ignoreMap":264},[268,42511,42512,42514,42516,42518,42520,42522,42524,42526,42528,42530,42532,42535],{"class":270,"line":271},[268,42513,243],{"class":274},[268,42515,23689],{"class":305},[268,42517,616],{"class":274},[268,42519,8710],{"class":282},[268,42521,5825],{"class":305},[268,42523,42],{"class":282},[268,42525,2255],{"class":305},[268,42527,42],{"class":282},[268,42529,2258],{"class":305},[268,42531,42],{"class":282},[268,42533,42534],{"class":305},"21",[268,42536,8737],{"class":282},[268,42538,42539,42541,42543,42546,42548],{"class":270,"line":286},[268,42540,1353],{"class":282},[268,42542,1356],{"class":278},[268,42544,42545],{"class":282},"(scores.",[268,42547,19029],{"class":278},[268,42549,8174],{"class":282},[23,42551,42553,42561,42569,42577],{"className":42552},[26],[28,42554,42556,355,42558],{"className":42555},[31],[33,42557],{"disabled":35,"type":36},[268,42559,42560],{},"1, 10, 2, 21",[28,42562,42564,355,42566],{"className":42563},[31],[33,42565],{"disabled":35,"type":36},[268,42567,42568],{},"1, 2, 10, 21",[28,42570,42572,355,42574],{"className":42571},[31],[33,42573],{"disabled":35,"type":36},[268,42575,42576],{},"21, 10, 2, 1",[28,42578,42580,355,42582,42585],{"className":42579},[31],[33,42581],{"disabled":35,"type":36},[268,42583,42584],{},"10, 1, 2, 21"," (unchanged)",[66,42587,42588,42590,42596],{},[69,42589,71],{},[73,42591,42592,3459,42594],{},[76,42593,78],{},[268,42595,42560],{},[73,42597,42598,355,42600,355,42602,42605,42606,42608,42609,42612,42613,183,42615,42618,42619,42622,42623,462],{},[76,42599,84],{},[76,42601,365],{},[39,42603,42604],{},"Array.prototype.sort()"," with no comparator converts every element to a ",[76,42607,2626],{}," and compares them lexicographically (by UTF-16 code unit), not numerically. ",[39,42610,42611],{},"'10'"," sorts before ",[39,42614,17912],{},[39,42616,42617],{},"'1' \u003C '2'"," as characters, even though ",[39,42620,42621],{},"10 > 2"," numerically. The fix is always to pass an explicit comparator for numbers: ",[39,42624,23793],{},[15,42626,42627,42638,42670,42724],{"language":247},[18,42628,42630,42631,42633,42634,42637],{"id":42629},"q13-why-does-mapnumber-behave-correctly-while-mapparseint-q8-does-not","Q13. Why does ",[39,42632,42103],{}," behave correctly while ",[39,42635,42636],{},".map(parseInt)"," (Q8) does not?",[257,42639,42640],{"language":247},[260,42641,42643],{"className":262,"code":42642,"language":247,"meta":264,"style":264},"console.log(['1', '2', '3'].map(Number));\n",[39,42644,42645],{"__ignoreMap":264},[268,42646,42647,42649,42651,42653,42655,42657,42659,42661,42663,42665,42667],{"class":270,"line":271},[268,42648,1353],{"class":282},[268,42650,1356],{"class":278},[268,42652,17519],{"class":282},[268,42654,17916],{"class":289},[268,42656,42],{"class":282},[268,42658,17912],{"class":289},[268,42660,42],{"class":282},[268,42662,42000],{"class":289},[268,42664,42003],{"class":282},[268,42666,23950],{"class":278},[268,42668,42669],{"class":282},"(Number));\n",[23,42671,42673,42691,42702,42716],{"className":42672},[26],[28,42674,42676,355,42678,42681,42682,446,42685,42687,42688,42690],{"className":42675},[31],[33,42677],{"disabled":35,"type":36},[39,42679,42680],{},"Number(value)"," only ever looks at its first argument, so the extra ",[39,42683,42684],{},"index",[39,42686,29039],{}," arguments ",[39,42689,23950],{}," passes are harmless",[28,42692,42694,355,42696,42698,42699,42701],{"className":42693},[31],[33,42695],{"disabled":35,"type":36},[39,42697,23950],{}," special-cases ",[39,42700,2682],{}," and only passes it one argument",[28,42703,42705,355,42707,186,42709,42712,42713],{"className":42704},[31],[33,42706],{"disabled":35,"type":36},[39,42708,2682],{},[39,42710,42711],{},"parseInt"," behave identically, so this also produces ",[39,42714,42715],{},"[1, NaN, NaN]",[28,42717,42719,355,42721,42723],{"className":42718},[31],[33,42720],{"disabled":35,"type":36},[39,42722,2682],{}," mutates the original array, so this is actually a different kind of bug",[66,42725,42726,42728,42740],{},[69,42727,71],{},[73,42729,42730,3459,42732,42681,42734,446,42736,42687,42738,42690],{},[76,42731,78],{},[39,42733,42680],{},[39,42735,42684],{},[39,42737,29039],{},[39,42739,23950],{},[73,42741,42742,355,42744,355,42746,42748,42749,42752,42753,42756,42757,42760,42761,42764,42765,3277,42767,42769,42770,42772,42773,42775],{},[76,42743,84],{},[76,42745,930],{},[39,42747,23950],{}," always calls its callback as ",[39,42750,42751],{},"callback(element, index, array)"," regardless of which function you pass — the difference is entirely in how the callback ",[104,42754,42755],{},"reacts"," to those extra arguments. ",[39,42758,42759],{},"Number(v)"," ignores anything beyond the first parameter, so ",[39,42762,42763],{},"[1,2,3].map(Number)"," is safe and gives ",[39,42766,23940],{},[39,42768,42070],{},", uniquely among common conversion functions, ",[104,42771,10043],{}," use its second parameter, which is what turns ",[39,42774,23950],{},"'s index argument into an accidental radix in Q8.",[15,42777,42778,42782,42967,42997],{"language":247},[18,42779,42781],{"id":42780},"q14-what-happens-here","Q14. What happens here?",[257,42783,42784],{"language":247},[260,42785,42787],{"className":262,"code":42786,"language":247,"meta":264,"style":264},"function curry(fn) {\n  return function curried(...args) {\n    if (args.length >= fn.length) return fn(...args);\n    return (...more) => curried(...args, ...more);\n  };\n}\n\nfunction greet(greeting, name = 'friend') {\n  return `${greeting}, ${name}!`;\n}\n\nconst curriedGreet = curry(greet);\nconsole.log(curriedGreet('Hi')('Sam'));\n",[39,42788,42789,42801,42817,42845,42871,42875,42879,42883,42905,42923,42927,42931,42945],{"__ignoreMap":264},[268,42790,42791,42793,42795,42797,42799],{"class":270,"line":271},[268,42792,275],{"class":274},[268,42794,40257],{"class":278},[268,42796,622],{"class":282},[268,42798,37837],{"class":1222},[268,42800,1235],{"class":282},[268,42802,42803,42805,42807,42809,42811,42813,42815],{"class":270,"line":286},[268,42804,1240],{"class":274},[268,42806,12080],{"class":274},[268,42808,40382],{"class":278},[268,42810,622],{"class":282},[268,42812,15329],{"class":274},[268,42814,40270],{"class":1222},[268,42816,1235],{"class":282},[268,42818,42819,42821,42824,42826,42828,42830,42832,42834,42836,42838,42840,42842],{"class":270,"line":296},[268,42820,9686],{"class":274},[268,42822,42823],{"class":282}," (args.",[268,42825,3567],{"class":305},[268,42827,40285],{"class":274},[268,42829,40288],{"class":282},[268,42831,3567],{"class":305},[268,42833,6131],{"class":282},[268,42835,9151],{"class":274},[268,42837,37900],{"class":278},[268,42839,622],{"class":282},[268,42841,15329],{"class":274},[268,42843,42844],{"class":282},"args);\n",[268,42846,42847,42849,42851,42853,42855,42857,42859,42861,42863,42865,42867,42869],{"class":270,"line":311},[268,42848,9871],{"class":274},[268,42850,2182],{"class":282},[268,42852,15329],{"class":274},[268,42854,40317],{"class":1222},[268,42856,6131],{"class":282},[268,42858,9414],{"class":274},[268,42860,40382],{"class":278},[268,42862,622],{"class":282},[268,42864,15329],{"class":274},[268,42866,40331],{"class":282},[268,42868,15329],{"class":274},[268,42870,40336],{"class":282},[268,42872,42873],{"class":270,"line":788},[268,42874,15185],{"class":282},[268,42876,42877],{"class":270,"line":1951},[268,42878,314],{"class":282},[268,42880,42881],{"class":270,"line":8955},[268,42882,5033],{"emptyLinePlaceholder":35},[268,42884,42885,42887,42889,42891,42894,42896,42898,42900,42903],{"class":270,"line":8966},[268,42886,275],{"class":274},[268,42888,3679],{"class":278},[268,42890,622],{"class":282},[268,42892,42893],{"class":1222},"greeting",[268,42895,42],{"class":282},[268,42897,14605],{"class":1222},[268,42899,616],{"class":274},[268,42901,42902],{"class":289}," 'friend'",[268,42904,1235],{"class":282},[268,42906,42907,42909,42911,42913,42916,42918,42921],{"class":270,"line":8974},[268,42908,1240],{"class":274},[268,42910,14262],{"class":289},[268,42912,42893],{"class":282},[268,42914,42915],{"class":289},"}, ${",[268,42917,14605],{"class":282},[268,42919,42920],{"class":289},"}!`",[268,42922,293],{"class":282},[268,42924,42925],{"class":270,"line":8985},[268,42926,314],{"class":282},[268,42928,42929],{"class":270,"line":8990},[268,42930,5033],{"emptyLinePlaceholder":35},[268,42932,42933,42935,42938,42940,42942],{"class":270,"line":8997},[268,42934,243],{"class":274},[268,42936,42937],{"class":305}," curriedGreet",[268,42939,616],{"class":274},[268,42941,40257],{"class":278},[268,42943,42944],{"class":282},"(greet);\n",[268,42946,42947,42949,42951,42953,42956,42958,42961,42963,42965],{"class":270,"line":9002},[268,42948,1353],{"class":282},[268,42950,1356],{"class":278},[268,42952,622],{"class":282},[268,42954,42955],{"class":278},"curriedGreet",[268,42957,622],{"class":282},[268,42959,42960],{"class":289},"'Hi'",[268,42962,40411],{"class":282},[268,42964,34475],{"class":289},[268,42966,4818],{"class":282},[23,42968,42970,42979,42985,42991],{"className":42969},[26],[28,42971,42973,34517,42975,42978],{"className":42972},[31],[33,42974],{"disabled":35,"type":36},[39,42976,42977],{},"curriedGreet('Hi')"," returns a string, and strings aren't callable",[28,42980,42982,42984],{"className":42981},[31],[33,42983],{"disabled":35,"type":36}," \"Hi, Sam!\"",[28,42986,42988,42990],{"className":42987},[31],[33,42989],{"disabled":35,"type":36}," \"Hi, friend!\"",[28,42992,42994,42996],{"className":42993},[31],[33,42995],{"disabled":35,"type":36}," \"Hi, undefined!\"",[66,42998,42999,43001,43008],{},[69,43000,71],{},[73,43002,43003,43005,43006,42978],{},[76,43004,78],{}," A — Throws a TypeError because ",[39,43007,42977],{},[73,43009,43010,355,43012,355,43014,43016,43017,43019,43020,830,43023,2758,43025,20766,43027,43029,43030,43033,43034,43037,43038,43040,43041,43044,43045,43048,43049,43052,43053,43055],{},[76,43011,84],{},[76,43013,365],{},[39,43015,15622],{}," only counts parameters ",[76,43018,11314],{}," the first one with a default value (or a rest parameter) — so ",[39,43021,43022],{},"greet.length",[39,43024,2255],{},[39,43026,2258],{},[39,43028,12761],{}," accepts two arguments. ",[39,43031,43032],{},"curry","'s arity check (",[39,43035,43036],{},"args.length >= fn.length",") is satisfied the moment ",[39,43039,42977],{}," is called with just one argument, so it immediately invokes ",[39,43042,43043],{},"greet('Hi')",", producing the string ",[39,43046,43047],{},"\"Hi, friend!\""," — not another curried function. Calling that string with ",[39,43050,43051],{},"('Sam')"," then throws, because a string isn't a function. This is why generic ",[39,43054,40500],{},"-based curry helpers are fragile against default and rest parameters.",[15,43057,43058,43062,43155,43190],{"language":247},[18,43059,43061],{"id":43060},"q15-which-style-is-generally-preferred-and-why","Q15. Which style is generally preferred, and why?",[257,43063,43064],{"language":247},[260,43065,43067],{"className":262,"code":43066,"language":247,"meta":264,"style":264},"\u002F\u002F Style A\nlet result = [];\nitems.forEach(item => {\n  if (item.active) result.push(transform(item));\n});\n\n\u002F\u002F Style B\nconst result2 = items.filter(item => item.active).map(transform);\n",[39,43068,43069,43074,43084,43098,43115,43119,43123,43128],{"__ignoreMap":264},[268,43070,43071],{"class":270,"line":271},[268,43072,43073],{"class":29390},"\u002F\u002F Style A\n",[268,43075,43076,43078,43080,43082],{"class":270,"line":286},[268,43077,240],{"class":274},[268,43079,10881],{"class":282},[268,43081,302],{"class":274},[268,43083,12449],{"class":282},[268,43085,43086,43088,43090,43092,43094,43096],{"class":270,"line":296},[268,43087,40533],{"class":282},[268,43089,12330],{"class":278},[268,43091,622],{"class":282},[268,43093,14793],{"class":1222},[268,43095,14969],{"class":274},[268,43097,9914],{"class":282},[268,43099,43100,43102,43105,43107,43109,43112],{"class":270,"line":311},[268,43101,9863],{"class":274},[268,43103,43104],{"class":282}," (item.active) result.",[268,43106,12499],{"class":278},[268,43108,622],{"class":282},[268,43110,43111],{"class":278},"transform",[268,43113,43114],{"class":282},"(item));\n",[268,43116,43117],{"class":270,"line":788},[268,43118,20047],{"class":282},[268,43120,43121],{"class":270,"line":1951},[268,43122,5033],{"emptyLinePlaceholder":35},[268,43124,43125],{"class":270,"line":8955},[268,43126,43127],{"class":29390},"\u002F\u002F Style B\n",[268,43129,43130,43132,43135,43137,43139,43141,43143,43145,43147,43150,43152],{"class":270,"line":8966},[268,43131,243],{"class":274},[268,43133,43134],{"class":305}," result2",[268,43136,616],{"class":274},[268,43138,11762],{"class":282},[268,43140,14962],{"class":278},[268,43142,622],{"class":282},[268,43144,14793],{"class":1222},[268,43146,14969],{"class":274},[268,43148,43149],{"class":282}," item.active).",[268,43151,23950],{"class":278},[268,43153,43154],{"class":282},"(transform);\n",[23,43156,43158,43164,43173,43179],{"className":43157},[26],[28,43159,43161,43163],{"className":43160},[31],[33,43162],{"disabled":35,"type":36}," Style B — it's declarative, avoids relying on an external mutable accumulator, and makes the transformation's intent explicit",[28,43165,43167,43169,43170,43172],{"className":43166},[31],[33,43168],{"disabled":35,"type":36}," Style A — ",[39,43171,12330],{}," is always meaningfully faster, so it should be preferred",[28,43174,43176,43178],{"className":43175},[31],[33,43177],{"disabled":35,"type":36}," They're equally idiomatic; there's no practical difference in real codebases",[28,43180,43182,43184,43185,43187,43188],{"className":43181},[31],[33,43183],{"disabled":35,"type":36}," Style B is invalid — you can't chain ",[39,43186,15111],{}," directly into ",[39,43189,39625],{},[66,43191,43192,43194,43199],{},[69,43193,71],{},[73,43195,43196,43198],{},[76,43197,78],{}," A — Style B — it's declarative, avoids relying on an external mutable accumulator, and makes the transformation's intent explicit",[73,43200,43201,355,43203,43205,43206,43209,43210,43212,43213,43215,43216,43218],{},[76,43202,84],{},[76,43204,930],{}," Style A depends on an externally-declared ",[39,43207,43208],{},"let result = []"," that the callback mutates as a side effect — easy to accidentally push twice, forget to initialize, or shadow in a refactor. Style B expresses the same operation as a pipeline of pure transformations with no external mutable state to get wrong. (For very large arrays where the double pass — one for ",[39,43211,14962],{},", one for ",[39,43214,23950],{}," — actually matters, a single ",[39,43217,14980],{}," can combine both into one pass, but for typical sizes, readability wins and the filter\u002Fmap chain is the standard idiom.)",[15,43220,43221,43225,43307,43355],{"language":247},[18,43222,43224],{"id":43223},"q16-whats-the-problem-with-this-code","Q16. What's the problem with this code?",[257,43226,43227],{"language":247},[260,43228,43230],{"className":262,"code":43229,"language":247,"meta":264,"style":264},"const total = orders\n  .map(o => {\n    o.processed = true;\n    return o.amount;\n  })\n  .reduce((a, b) => a + b, 0);\n",[39,43231,43232,43242,43256,43267,43274,43279],{"__ignoreMap":264},[268,43233,43234,43236,43238,43240],{"class":270,"line":271},[268,43235,243],{"class":274},[268,43237,34590],{"class":305},[268,43239,616],{"class":274},[268,43241,41692],{"class":282},[268,43243,43244,43246,43248,43250,43252,43254],{"class":270,"line":286},[268,43245,41697],{"class":282},[268,43247,23950],{"class":278},[268,43249,622],{"class":282},[268,43251,41704],{"class":1222},[268,43253,14969],{"class":274},[268,43255,9914],{"class":282},[268,43257,43258,43261,43263,43265],{"class":270,"line":296},[268,43259,43260],{"class":282},"    o.processed ",[268,43262,302],{"class":274},[268,43264,7905],{"class":305},[268,43266,293],{"class":282},[268,43268,43269,43271],{"class":270,"line":311},[268,43270,9871],{"class":274},[268,43272,43273],{"class":282}," o.amount;\n",[268,43275,43276],{"class":270,"line":788},[268,43277,43278],{"class":282},"  })\n",[268,43280,43281,43283,43285,43287,43289,43291,43293,43295,43297,43299,43301,43303,43305],{"class":270,"line":1951},[268,43282,41697],{"class":282},[268,43284,14980],{"class":278},[268,43286,6122],{"class":282},[268,43288,1223],{"class":1222},[268,43290,42],{"class":282},[268,43292,1232],{"class":1222},[268,43294,6131],{"class":282},[268,43296,9414],{"class":274},[268,43298,1243],{"class":282},[268,43300,1246],{"class":274},[268,43302,14999],{"class":282},[268,43304,3307],{"class":305},[268,43306,628],{"class":282},[23,43308,43310,43325,43334,43346],{"className":43309},[26],[28,43311,43313,4396,43315,43317,43318,43321,43322,43324],{"className":43312},[31],[33,43314],{"disabled":35,"type":36},[39,43316,23950],{}," callback has a hidden side effect — mutating the original ",[39,43319,43320],{},"orders"," objects — when ",[39,43323,23950],{}," is expected to just transform and return values",[28,43326,43328,43330,43331,43333],{"className":43327},[31],[33,43329],{"disabled":35,"type":36}," This throws a TypeError because ",[39,43332,23950],{}," callbacks can't have a function body with multiple statements",[28,43335,43337,355,43339,43341,43342,43345],{"className":43336},[31],[33,43338],{"disabled":35,"type":36},[39,43340,23950],{}," automatically deep-clones each element, so ",[39,43343,43344],{},"o.processed = true"," has no effect on the original array",[28,43347,43349,43351,43352,43354],{"className":43348},[31],[33,43350],{"disabled":35,"type":36}," There's no problem; mutating inside ",[39,43353,23950],{}," is the standard way to flag processed items",[66,43356,43357,43359,43370],{},[69,43358,71],{},[73,43360,43361,43363,43364,43317,43366,43321,43368,43324],{},[76,43362,78],{}," A — The ",[39,43365,23950],{},[39,43367,43320],{},[39,43369,23950],{},[73,43371,43372,355,43374,355,43376,43378,43379,43382,43383,43385,43386,43388,43389,446,43391,43393,43394,43396],{},[76,43373,84],{},[76,43375,930],{},[39,43377,23950],{},"'s contract is \"produce a new value per element,\" not \"do something to the element.\" Mutating ",[39,43380,43381],{},"o.processed"," here is easy to miss when reading the code (you have to read past the ",[39,43384,9151],{}," to notice it), and it silently changes the original ",[39,43387,43320],{}," array\u002Fobjects, which can cause bugs if that same array is read elsewhere, memoized, or the pipeline is accidentally run twice. Best practice is to keep ",[39,43390,23950],{},[39,43392,14962],{}," callbacks pure and do side-effecting work in a separate, clearly-named step (e.g. a ",[39,43395,12330],{}," or explicit loop).",[15,43398,43399,43403,43485,43526],{"language":247},[18,43400,43402],{"id":43401},"q17-which-is-the-better-choice-for-finding-a-single-matching-user-in-a-large-array-and-why","Q17. Which is the better choice for finding a single matching user in a large array, and why?",[257,43404,43405],{"language":247},[260,43406,43408],{"className":262,"code":43407,"language":247,"meta":264,"style":264},"\u002F\u002F Option A\nconst admin = users.filter(u => u.role === 'admin')[0];\n\n\u002F\u002F Option B\nconst admin2 = users.find(u => u.role === 'admin');\n",[39,43409,43410,43414,43450,43454,43458],{"__ignoreMap":264},[268,43411,43412],{"class":270,"line":271},[268,43413,36812],{"class":29390},[268,43415,43416,43418,43421,43423,43426,43428,43430,43433,43435,43438,43440,43443,43446,43448],{"class":270,"line":286},[268,43417,243],{"class":274},[268,43419,43420],{"class":305}," admin",[268,43422,616],{"class":274},[268,43424,43425],{"class":282}," users.",[268,43427,14962],{"class":278},[268,43429,622],{"class":282},[268,43431,43432],{"class":1222},"u",[268,43434,14969],{"class":274},[268,43436,43437],{"class":282}," u.role ",[268,43439,3280],{"class":274},[268,43441,43442],{"class":289}," 'admin'",[268,43444,43445],{"class":282},")[",[268,43447,3307],{"class":305},[268,43449,8737],{"class":282},[268,43451,43452],{"class":270,"line":296},[268,43453,5033],{"emptyLinePlaceholder":35},[268,43455,43456],{"class":270,"line":311},[268,43457,36856],{"class":29390},[268,43459,43460,43462,43465,43467,43469,43471,43473,43475,43477,43479,43481,43483],{"class":270,"line":788},[268,43461,243],{"class":274},[268,43463,43464],{"class":305}," admin2",[268,43466,616],{"class":274},[268,43468,43425],{"class":282},[268,43470,37211],{"class":278},[268,43472,622],{"class":282},[268,43474,43432],{"class":1222},[268,43476,14969],{"class":274},[268,43478,43437],{"class":282},[268,43480,3280],{"class":274},[268,43482,43442],{"class":289},[268,43484,628],{"class":282},[23,43486,43488,43501,43510,43516],{"className":43487},[26],[28,43489,43491,39786,43493,43495,43496,43498,43499],{"className":43490},[31],[33,43492],{"disabled":35,"type":36},[39,43494,37211],{}," stops as soon as it finds a match, while ",[39,43497,14962],{}," always scans the whole array and allocates an array just to discard everything but index ",[39,43500,3307],{},[28,43502,43504,43506,43507,43509],{"className":43503},[31],[33,43505],{"disabled":35,"type":36}," Option A — ",[39,43508,14962],{}," is guaranteed to be optimized by the engine for single-element access",[28,43511,43513,43515],{"className":43512},[31],[33,43514],{"disabled":35,"type":36}," They perform identically since both are O(n) in the worst case",[28,43517,43519,43521,43522,43525],{"className":43518},[31],[33,43520],{"disabled":35,"type":36}," Option B, but only because ",[39,43523,43524],{},"filter(...)​[0]"," is a syntax error",[66,43527,43528,43530,43540],{},[69,43529,71],{},[73,43531,43532,39819,43534,43495,43536,43498,43538],{},[76,43533,78],{},[39,43535,37211],{},[39,43537,14962],{},[39,43539,3307],{},[73,43541,43542,355,43544,355,43546,43548,43549,43551,43552,43554,43555,43557],{},[76,43543,84],{},[76,43545,438],{},[39,43547,37211],{}," short-circuits and returns the first matching element immediately, while ",[39,43550,14962],{}," always iterates the entire array (even after finding a match) and builds a brand-new array — wasted work and a wasted allocation when all you wanted was one item. Both are technically O(n) worst case (no match found), but ",[39,43553,37211],{},"'s best\u002Faverage case is much better, and it never allocates. Prefer ",[39,43556,37211],{}," whenever you only need one result.",[15,43559,43560,43562,43713,43743],{"language":247},[18,43561,18980],{"id":18979},[257,43563,43564],{"language":247},[260,43565,43567],{"className":262,"code":43566,"language":247,"meta":264,"style":264},"const pipe = (...fns) => x => fns.reduce((acc, fn) => fn(acc), x);\n\nconst process = pipe(\n  s => s.trim(),\n  s => s.toLowerCase(),\n  s => s.replace(\u002F\\s+\u002Fg, '-')\n);\n\nconsole.log(process('  Hello World  '));\n",[39,43568,43569,43615,43619,43631,43645,43658,43688,43692,43696],{"__ignoreMap":264},[268,43570,43571,43573,43576,43578,43580,43582,43585,43587,43589,43591,43593,43596,43598,43600,43602,43604,43606,43608,43610,43612],{"class":270,"line":271},[268,43572,243],{"class":274},[268,43574,43575],{"class":278}," pipe",[268,43577,616],{"class":274},[268,43579,2182],{"class":282},[268,43581,15329],{"class":274},[268,43583,43584],{"class":1222},"fns",[268,43586,6131],{"class":282},[268,43588,9414],{"class":274},[268,43590,9206],{"class":1222},[268,43592,14969],{"class":274},[268,43594,43595],{"class":282}," fns.",[268,43597,14980],{"class":278},[268,43599,6122],{"class":282},[268,43601,24160],{"class":1222},[268,43603,42],{"class":282},[268,43605,37837],{"class":1222},[268,43607,6131],{"class":282},[268,43609,9414],{"class":274},[268,43611,37900],{"class":278},[268,43613,43614],{"class":282},"(acc), x);\n",[268,43616,43617],{"class":270,"line":286},[268,43618,5033],{"emptyLinePlaceholder":35},[268,43620,43621,43623,43625,43627,43629],{"class":270,"line":296},[268,43622,243],{"class":274},[268,43624,10851],{"class":305},[268,43626,616],{"class":274},[268,43628,43575],{"class":278},[268,43630,17096],{"class":282},[268,43632,43633,43636,43638,43640,43642],{"class":270,"line":311},[268,43634,43635],{"class":1222},"  s",[268,43637,14969],{"class":274},[268,43639,25398],{"class":282},[268,43641,18832],{"class":278},[268,43643,43644],{"class":282},"(),\n",[268,43646,43647,43649,43651,43653,43656],{"class":270,"line":788},[268,43648,43635],{"class":1222},[268,43650,14969],{"class":274},[268,43652,25398],{"class":282},[268,43654,43655],{"class":278},"toLowerCase",[268,43657,43644],{"class":282},[268,43659,43660,43662,43664,43666,43668,43670,43672,43675,43677,43679,43681,43683,43686],{"class":270,"line":1951},[268,43661,43635],{"class":1222},[268,43663,14969],{"class":274},[268,43665,25398],{"class":282},[268,43667,18250],{"class":278},[268,43669,622],{"class":282},[268,43671,446],{"class":289},[268,43673,43674],{"class":305},"\\s",[268,43676,1246],{"class":274},[268,43678,446],{"class":289},[268,43680,18287],{"class":274},[268,43682,42],{"class":282},[268,43684,43685],{"class":289},"'-'",[268,43687,20702],{"class":282},[268,43689,43690],{"class":270,"line":8955},[268,43691,628],{"class":282},[268,43693,43694],{"class":270,"line":8966},[268,43695,5033],{"emptyLinePlaceholder":35},[268,43697,43698,43700,43702,43704,43706,43708,43711],{"class":270,"line":8974},[268,43699,1353],{"class":282},[268,43701,1356],{"class":278},[268,43703,622],{"class":282},[268,43705,140],{"class":278},[268,43707,622],{"class":282},[268,43709,43710],{"class":289},"'  Hello World  '",[268,43712,4818],{"class":282},[23,43714,43716,43722,43728,43734],{"className":43715},[26],[28,43717,43719,43721],{"className":43718},[31],[33,43720],{"disabled":35,"type":36}," 'hello-world'",[28,43723,43725,43727],{"className":43724},[31],[33,43726],{"disabled":35,"type":36}," 'Hello-World'",[28,43729,43731,43733],{"className":43730},[31],[33,43732],{"disabled":35,"type":36}," '-hello-world-'",[28,43735,43737,34517,43739,43742],{"className":43736},[31],[33,43738],{"disabled":35,"type":36},[39,43740,43741],{},"pipe"," can't accept a variable number of functions",[66,43744,43745,43747,43752],{},[69,43746,71],{},[73,43748,43749,43751],{},[76,43750,78],{}," A — 'hello-world'",[73,43753,43754,355,43756,355,43758,43760,43761,43763,43764,43766,43767,43769,43770,43772,43773,43776,43777,43779,43780,43783,43784,43786,43787,6232],{},[76,43755,84],{},[76,43757,930],{},[39,43759,43741],{}," is a standard function-composition utility built with ",[39,43762,14980],{},": it threads the initial value ",[39,43765,2403],{}," through each function in ",[39,43768,43584],{},", left to right, using each result as the input to the next. ",[39,43771,43710],{}," gets trimmed to ",[39,43774,43775],{},"'Hello World'",", lowercased to ",[39,43778,25367],{},", then has its whitespace replaced with a dash, giving ",[39,43781,43782],{},"'hello-world'",". This ",[39,43785,14980],{},"-over-functions pattern is a common, idiomatic way to build reusable pipelines instead of nesting calls manually (",[39,43788,43789],{},"f(g(h(x)))",[15,43791,43792,43799,43911,43951],{"language":247},[18,43793,43795,43796,43798],{"id":43794},"q19-whats-the-best-practice-benefit-of-writing-createlogger-this-way","Q19. What's the best-practice benefit of writing ",[39,43797,38634],{}," this way?",[257,43800,43801],{"language":247},[260,43802,43804],{"className":262,"code":43803,"language":247,"meta":264,"style":264},"const createLogger = level => message => console.log(`[${level}] ${message}`);\n\nconst logError = createLogger('ERROR');\nconst logInfo = createLogger('INFO');\n\nlogError('Disk full');\nlogInfo('Server started');\n",[39,43805,43806,43843,43847,43865,43883,43887,43899],{"__ignoreMap":264},[268,43807,43808,43810,43812,43814,43817,43819,43822,43824,43826,43828,43830,43832,43834,43836,43839,43841],{"class":270,"line":271},[268,43809,243],{"class":274},[268,43811,38457],{"class":278},[268,43813,616],{"class":274},[268,43815,43816],{"class":1222}," level",[268,43818,14969],{"class":274},[268,43820,43821],{"class":1222}," message",[268,43823,14969],{"class":274},[268,43825,9417],{"class":282},[268,43827,1356],{"class":278},[268,43829,622],{"class":282},[268,43831,18824],{"class":289},[268,43833,38494],{"class":282},[268,43835,38497],{"class":289},[268,43837,43838],{"class":282},"message",[268,43840,11603],{"class":289},[268,43842,628],{"class":282},[268,43844,43845],{"class":270,"line":286},[268,43846,5033],{"emptyLinePlaceholder":35},[268,43848,43849,43851,43854,43856,43858,43860,43863],{"class":270,"line":296},[268,43850,243],{"class":274},[268,43852,43853],{"class":305}," logError",[268,43855,616],{"class":274},[268,43857,38457],{"class":278},[268,43859,622],{"class":282},[268,43861,43862],{"class":289},"'ERROR'",[268,43864,628],{"class":282},[268,43866,43867,43869,43872,43874,43876,43878,43881],{"class":270,"line":311},[268,43868,243],{"class":274},[268,43870,43871],{"class":305}," logInfo",[268,43873,616],{"class":274},[268,43875,38457],{"class":278},[268,43877,622],{"class":282},[268,43879,43880],{"class":289},"'INFO'",[268,43882,628],{"class":282},[268,43884,43885],{"class":270,"line":788},[268,43886,5033],{"emptyLinePlaceholder":35},[268,43888,43889,43892,43894,43897],{"class":270,"line":1951},[268,43890,43891],{"class":278},"logError",[268,43893,622],{"class":282},[268,43895,43896],{"class":289},"'Disk full'",[268,43898,628],{"class":282},[268,43900,43901,43904,43906,43909],{"class":270,"line":8955},[268,43902,43903],{"class":278},"logInfo",[268,43905,622],{"class":282},[268,43907,43908],{"class":289},"'Server started'",[268,43910,628],{"class":282},[23,43912,43914,43923,43936,43942],{"className":43913},[26],[28,43915,43917,43919,43920,43922],{"className":43916},[31],[33,43918],{"disabled":35,"type":36}," It lets you \"lock in\" the ",[39,43921,38494],{}," argument once via partial application, producing specialized, reusable functions instead of repeating the level at every call site",[28,43924,43926,43928,43929,43931,43932,43935],{"className":43925},[31],[33,43927],{"disabled":35,"type":36}," It's purely stylistic — passing ",[39,43930,38494],{}," as a normal second argument to a single ",[39,43933,43934],{},"log(level, message)"," function would be identical in every way",[28,43937,43939,43941],{"className":43938},[31],[33,43940],{"disabled":35,"type":36}," Currying here makes the logger run faster than a two-argument function would",[28,43943,43945,43947,43948,43950],{"className":43944},[31],[33,43946],{"disabled":35,"type":36}," It's required — ",[39,43949,5627],{}," cannot be called with a template literal directly",[66,43952,43953,43955,43962],{},[69,43954,71],{},[73,43956,43957,43959,43960,43922],{},[76,43958,78],{}," A — It lets you \"lock in\" the ",[39,43961,38494],{},[73,43963,43964,355,43966,43968,43969,43971,43972,43974,43975,43977,43978,446,43980,43982,43983,43986],{},[76,43965,84],{},[76,43967,930],{}," this is a textbook, practical use of currying: ",[39,43970,38494],{}," is a configuration-like argument that's known up front and reused many times, while ",[39,43973,43838],{}," varies per call. Currying ",[39,43976,38634],{}," lets you produce ",[39,43979,43891],{},[39,43981,43903],{}," once and then call them like ordinary single-argument functions everywhere else, instead of writing ",[39,43984,43985],{},"log('ERROR', ...)"," at every call site and risking a copy-pasted wrong level string.",[15,43988,43989,43993,44088,44119],{"language":247},[18,43990,43992],{"id":43991},"q20-is-deep-currying-like-this-a-good-practice-when-all-five-arguments-are-always-supplied-together-at-one-call-site","Q20. Is deep currying like this a good practice when all five arguments are always supplied together at one call site?",[257,43994,43995],{"language":247},[260,43996,43998],{"className":262,"code":43997,"language":247,"meta":264,"style":264},"const add5 = curry(a => b => c => d => e => a + b + c + d + e);\nconsole.log(add5(1)(2)(3)(4)(5));\n",[39,43999,44000,44055],{"__ignoreMap":264},[268,44001,44002,44004,44007,44009,44011,44013,44015,44017,44019,44021,44023,44025,44028,44030,44033,44035,44037,44039,44041,44043,44045,44047,44050,44052],{"class":270,"line":271},[268,44003,243],{"class":274},[268,44005,44006],{"class":305}," add5",[268,44008,616],{"class":274},[268,44010,40257],{"class":278},[268,44012,622],{"class":282},[268,44014,1223],{"class":1222},[268,44016,14969],{"class":274},[268,44018,16372],{"class":1222},[268,44020,14969],{"class":274},[268,44022,16389],{"class":1222},[268,44024,14969],{"class":274},[268,44026,44027],{"class":1222}," d",[268,44029,14969],{"class":274},[268,44031,44032],{"class":1222}," e",[268,44034,14969],{"class":274},[268,44036,1243],{"class":282},[268,44038,1246],{"class":274},[268,44040,2209],{"class":282},[268,44042,1246],{"class":274},[268,44044,38290],{"class":282},[268,44046,1246],{"class":274},[268,44048,44049],{"class":282}," d ",[268,44051,1246],{"class":274},[268,44053,44054],{"class":282}," e);\n",[268,44056,44057,44059,44061,44063,44066,44068,44070,44072,44074,44076,44078,44080,44082,44084,44086],{"class":270,"line":286},[268,44058,1353],{"class":282},[268,44060,1356],{"class":278},[268,44062,622],{"class":282},[268,44064,44065],{"class":278},"add5",[268,44067,622],{"class":282},[268,44069,2255],{"class":305},[268,44071,40411],{"class":282},[268,44073,2258],{"class":305},[268,44075,40411],{"class":282},[268,44077,3423],{"class":305},[268,44079,40411],{"class":282},[268,44081,15049],{"class":305},[268,44083,40411],{"class":282},[268,44085,2429],{"class":305},[268,44087,4818],{"class":282},[23,44089,44091,44101,44107,44113],{"className":44090},[26],[28,44092,44094,44096,44097,44100],{"className":44093},[31],[33,44095],{"disabled":35,"type":36}," No — currying pays off when arguments arrive separately over time (partial application); when they always arrive together, a plain ",[39,44098,44099],{},"(a, b, c, d, e) => ..."," function is clearer and easier to debug",[28,44102,44104,44106],{"className":44103},[31],[33,44105],{"disabled":35,"type":36}," Yes — currying should always be preferred for functional purity, regardless of call pattern",[28,44108,44110,44112],{"className":44109},[31],[33,44111],{"disabled":35,"type":36}," No — curried functions are fundamentally incapable of accepting more than one argument per call",[28,44114,44116,44118],{"className":44115},[31],[33,44117],{"disabled":35,"type":36}," Yes — curried chains are always faster than an equivalent multi-parameter function",[66,44120,44121,44123,44130],{},[69,44122,71],{},[73,44124,44125,44127,44128,44100],{},[76,44126,78],{}," A — No — currying pays off when arguments arrive separately over time (partial application); when they always arrive together, a plain ",[39,44129,44099],{},[73,44131,44132,355,44134,44136],{},[76,44133,84],{},[76,44135,930],{}," currying's real value (as in Q19) is enabling partial application — supplying some arguments now and the rest later, at a different place in the code. When every argument is always known and passed at the same call site, chaining five single-argument calls adds indirection, produces longer\u002Fharder-to-read stack traces, and gives no practical benefit over a single multi-parameter function. Good judgment means reaching for currying where it solves a real problem (config-then-use, building specialized functions), not applying it uniformly everywhere as a stylistic default.",[2107,44138,44139],{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}",{"title":264,"searchDepth":286,"depth":286,"links":44141},[44142,44143,44144,44145,44146,44147,44148,44149,44150,44151,44152,44153,44154,44156,44157,44158,44159,44160,44161,44163],{"id":26820,"depth":296,"text":26821},{"id":12736,"depth":296,"text":12737},{"id":12876,"depth":296,"text":12877},{"id":13031,"depth":296,"text":13032},{"id":13180,"depth":296,"text":13181},{"id":13320,"depth":296,"text":13321},{"id":13527,"depth":296,"text":13528},{"id":41973,"depth":296,"text":41974},{"id":42108,"depth":296,"text":42109},{"id":17618,"depth":296,"text":17619},{"id":14223,"depth":296,"text":14224},{"id":14381,"depth":296,"text":14382},{"id":42629,"depth":296,"text":44155},"Q13. Why does .map(Number) behave correctly while .map(parseInt) (Q8) does not?",{"id":42780,"depth":296,"text":42781},{"id":43060,"depth":296,"text":43061},{"id":43223,"depth":296,"text":43224},{"id":43401,"depth":296,"text":43402},{"id":18979,"depth":296,"text":18980},{"id":43794,"depth":296,"text":44162},"Q19. What's the best-practice benefit of writing createLogger this way?",{"id":43991,"depth":296,"text":43992},{},"\u002Fjs\u002F13-higher-order-functions",{"title":40913,"description":264},"js\u002F13-higher-order-functions","ywq6JmMeDkXpj8wM20L2m4-no6iAH5iOyRbU6Cz-CVo",{"id":44170,"title":44171,"body":44172,"description":264,"extension":2144,"meta":47286,"navigation":35,"path":47287,"seo":47288,"stem":47289,"__hash__":47290},"content\u002Fjs\u002F14-modules.md","14 — Modules",{"type":8,"value":44173,"toc":47254},[44174,44177,44271,44337,44466,44644,44832,44946,45185,45430,45505,45611,45777,45855,46057,46156,46369,46506,46727,46981,47074,47251],[11,44175,44171],{"id":44176},"_14-modules",[15,44178,44179,44183,44235],{"language":247},[18,44180,44182],{"id":44181},"q1-which-pair-correctly-matches-each-module-system-to-its-exportimport-syntax","Q1. Which pair correctly matches each module system to its export\u002Fimport syntax?",[23,44184,44186,44197,44212,44225],{"className":44185},[26],[28,44187,44189,44191,44192,446,44194,44196],{"className":44188},[31],[33,44190],{"disabled":35,"type":36}," Both use ",[39,44193,655],{},[39,44195,658],{},", but ESM adds static analysis on top",[28,44198,44200,44202,44203,446,44205,44207,44208,446,44210],{"className":44199},[31],[33,44201],{"disabled":35,"type":36}," ESM uses ",[39,44204,662],{},[39,44206,665],{},"; CommonJS uses ",[39,44209,655],{},[39,44211,658],{},[28,44213,44215,44202,44217,446,44219,44207,44221,446,44223],{"className":44214},[31],[33,44216],{"disabled":35,"type":36},[39,44218,655],{},[39,44220,658],{},[39,44222,662],{},[39,44224,665],{},[28,44226,44228,44191,44230,446,44232,44234],{"className":44227},[31],[33,44229],{"disabled":35,"type":36},[39,44231,662],{},[39,44233,665],{},", but CommonJS resolves them synchronously",[66,44236,44237,44239,44252],{},[69,44238,71],{},[73,44240,44241,44243,44244,446,44246,44207,44248,446,44250],{},[76,44242,78],{}," B — ESM uses ",[39,44245,662],{},[39,44247,665],{},[39,44249,655],{},[39,44251,658],{},[73,44253,44254,44256,44257,446,44259,44261,44262,44264,44265,44267,44268,44270],{},[76,44255,84],{}," ECMAScript Modules (ESM) are the standardized, browser-and-Node-native system built around the ",[39,44258,662],{},[39,44260,665],{}," keywords. CommonJS is Node's original module system, built around the ",[39,44263,714],{}," function and the ",[39,44266,658],{}," object. They are not interchangeable syntaxes for the same mechanism — ESM is statically analyzable at compile time, while CommonJS resolves ",[39,44269,655],{}," calls dynamically at runtime, which is the root of most interop friction between the two.",[15,44272,44273,44277,44307],{"language":247},[18,44274,44276],{"id":44275},"q2-what-is-the-fundamental-difference-between-how-esm-and-commonjs-resolve-imports","Q2. What is the fundamental difference between how ESM and CommonJS resolve imports?",[23,44278,44280,44286,44292,44301],{"className":44279},[26],[28,44281,44283,44285],{"className":44282},[31],[33,44284],{"disabled":35,"type":36}," CommonJS imports are resolved statically at compile time; ESM imports are resolved dynamically at runtime",[28,44287,44289,44291],{"className":44288},[31],[33,44290],{"disabled":35,"type":36}," Both are resolved at compile time, but ESM caches the result and CommonJS doesn't",[28,44293,44295,44297,44298,44300],{"className":44294},[31],[33,44296],{"disabled":35,"type":36}," ESM imports are resolved statically at compile time; CommonJS ",[39,44299,655],{}," calls are resolved dynamically at runtime",[28,44302,44304,44306],{"className":44303},[31],[33,44305],{"disabled":35,"type":36}," There is no meaningful difference — both are just syntax sugar over the same loader",[66,44308,44309,44311,44318],{},[69,44310,71],{},[73,44312,44313,44315,44316,44300],{},[76,44314,78],{}," C — ESM imports are resolved statically at compile time; CommonJS ",[39,44317,655],{},[73,44319,44320,44322,44323,446,44325,44327,44328,44330,44331,44333,44334,44336],{},[76,44321,84],{}," ESM ",[39,44324,662],{},[39,44326,665],{}," declarations must appear at the top level of a module with a literal specifier, so a tool can determine the entire dependency graph before running any code — this is what enables tree-shaking and hoisting. CommonJS ",[39,44329,714],{}," is just a function call, so it can appear inside ",[39,44332,2179],{}," blocks, loops, or be built from a dynamic string, meaning the dependency graph can only be known by actually executing the code. ",[76,44335,930],{}," this is the core reason ESM is described as \"static\" and CommonJS as \"dynamic.\"",[15,44338,44339,44343,44398,44434],{"language":247},[18,44340,44342],{"id":44341},"q3-a-module-has-this-export-statement-which-import-correctly-consumes-both-exports","Q3. A module has this export statement. Which import correctly consumes both exports?",[257,44344,44346],{"language":247,"filename":44345},"math.js",[260,44347,44349],{"className":262,"code":44348,"language":247,"meta":264,"style":264},"export const PI = 3.14159;\nexport default function square(n) {\n  return n * n;\n}\n",[39,44350,44351,44367,44384,44394],{"__ignoreMap":264},[268,44352,44353,44355,44358,44360,44362,44365],{"class":270,"line":271},[268,44354,665],{"class":274},[268,44356,44357],{"class":274}," const",[268,44359,3964],{"class":305},[268,44361,616],{"class":274},[268,44363,44364],{"class":305}," 3.14159",[268,44366,293],{"class":282},[268,44368,44369,44371,44374,44376,44378,44380,44382],{"class":270,"line":286},[268,44370,665],{"class":274},[268,44372,44373],{"class":274}," default",[268,44375,12080],{"class":274},[268,44377,31438],{"class":278},[268,44379,622],{"class":282},[268,44381,4599],{"class":1222},[268,44383,1235],{"class":282},[268,44385,44386,44388,44390,44392],{"class":270,"line":296},[268,44387,1240],{"class":274},[268,44389,13355],{"class":282},[268,44391,6134],{"class":274},[268,44393,16927],{"class":282},[268,44395,44396],{"class":270,"line":311},[268,44397,314],{"class":282},[23,44399,44401,44409,44417,44426],{"className":44400},[26],[28,44402,44404,355,44406],{"className":44403},[31],[33,44405],{"disabled":35,"type":36},[39,44407,44408],{},"import square, { PI } from '.\u002Fmath.js';",[28,44410,44412,355,44414],{"className":44411},[31],[33,44413],{"disabled":35,"type":36},[39,44415,44416],{},"import { square, PI } from '.\u002Fmath.js';",[28,44418,44420,355,44422,44425],{"className":44419},[31],[33,44421],{"disabled":35,"type":36},[39,44423,44424],{},"import { default as square, PI } from '.\u002Fmath.js';"," only — the shorthand form is invalid",[28,44427,44429,355,44431],{"className":44428},[31],[33,44430],{"disabled":35,"type":36},[39,44432,44433],{},"import PI, { square } from '.\u002Fmath.js';",[66,44435,44436,44438,44444],{},[69,44437,71],{},[73,44439,44440,3459,44442],{},[76,44441,78],{},[39,44443,44408],{},[73,44445,44446,44448,44449,44451,44452,44454,44455,44457,44458,44461,44462,44465],{},[76,44447,84],{}," A module can have any number of named exports (",[39,44450,3978],{}," here) plus at most one default export (the ",[39,44453,31493],{}," function). The default import binding comes first with no braces, followed by a comma and the named imports in braces. Option B incorrectly treats ",[39,44456,31493],{}," as a named export. Option D swaps the positions. Option C is unnecessarily verbose — ",[39,44459,44460],{},"import square, { PI }"," is valid shorthand for exactly that ",[39,44463,44464],{},"default as square"," form.",[15,44467,44468,44479,44523,44571,44603],{"language":247},[18,44469,44471,44472,44475,44476,19524],{"id":44470},"q4-counterjs-exports-a-mutable-binding-what-does-mainjs-log","Q4. ",[39,44473,44474],{},"counter.js"," exports a mutable binding. What does ",[39,44477,44478],{},"main.js",[257,44480,44481],{"language":247,"filename":44474},[260,44482,44484],{"className":262,"code":44483,"language":247,"meta":264,"style":264},"export let count = 0;\nexport function increment() {\n  count++;\n}\n",[39,44485,44486,44501,44511,44519],{"__ignoreMap":264},[268,44487,44488,44490,44493,44495,44497,44499],{"class":270,"line":271},[268,44489,665],{"class":274},[268,44491,44492],{"class":274}," let",[268,44494,10091],{"class":282},[268,44496,302],{"class":274},[268,44498,5728],{"class":305},[268,44500,293],{"class":282},[268,44502,44503,44505,44507,44509],{"class":270,"line":286},[268,44504,665],{"class":274},[268,44506,12080],{"class":274},[268,44508,37313],{"class":278},[268,44510,283],{"class":282},[268,44512,44513,44515,44517],{"class":270,"line":296},[268,44514,10123],{"class":282},[268,44516,9401],{"class":274},[268,44518,293],{"class":282},[268,44520,44521],{"class":270,"line":311},[268,44522,314],{"class":282},[257,44524,44525],{"language":247,"filename":44478},[260,44526,44528],{"className":262,"code":44527,"language":247,"meta":264,"style":264},"import { count, increment } from '.\u002Fcounter.js';\n\nconsole.log(count);\nincrement();\nconsole.log(count);\n",[39,44529,44530,44545,44549,44557,44563],{"__ignoreMap":264},[268,44531,44532,44534,44537,44540,44543],{"class":270,"line":271},[268,44533,662],{"class":274},[268,44535,44536],{"class":282}," { count, increment } ",[268,44538,44539],{"class":274},"from",[268,44541,44542],{"class":289}," '.\u002Fcounter.js'",[268,44544,293],{"class":282},[268,44546,44547],{"class":270,"line":286},[268,44548,5033],{"emptyLinePlaceholder":35},[268,44550,44551,44553,44555],{"class":270,"line":296},[268,44552,1353],{"class":282},[268,44554,1356],{"class":278},[268,44556,10157],{"class":282},[268,44558,44559,44561],{"class":270,"line":311},[268,44560,34969],{"class":278},[268,44562,794],{"class":282},[268,44564,44565,44567,44569],{"class":270,"line":788},[268,44566,1353],{"class":282},[268,44568,1356],{"class":278},[268,44570,10157],{"class":282},[23,44572,44574,44580,44586,44597],{"className":44573},[26],[28,44575,44577,44579],{"className":44576},[31],[33,44578],{"disabled":35,"type":36}," 0 then 0",[28,44581,44583,44585],{"className":44582},[31],[33,44584],{"disabled":35,"type":36}," 1 then 1",[28,44587,44589,44591,44592,183,44594,44596],{"className":44588},[31],[33,44590],{"disabled":35,"type":36}," Throws a TypeError on the second ",[39,44593,5627],{},[39,44595,10191],{}," was reassigned externally",[28,44598,44600,44602],{"className":44599},[31],[33,44601],{"disabled":35,"type":36}," 0 then 1",[66,44604,44605,44607,44612],{},[69,44606,71],{},[73,44608,44609,44611],{},[76,44610,78],{}," D — 0 then 1",[73,44613,44614,44616,44617,44620,44621,2018,44623,44625,44626,31326,44628,44630,44631,44634,44635,44637,44638,44640,44641,44643],{},[76,44615,84],{}," ESM named imports are ",[76,44618,44619],{},"live bindings",", not copied values — ",[39,44622,10191],{},[39,44624,44478],{}," is a read-only view directly onto ",[39,44627,44474],{},[39,44629,10191],{}," variable. When ",[39,44632,44633],{},"increment()"," reassigns ",[39,44636,10191],{}," inside the module that owns it, every importer observing that binding sees the new value immediately, without re-importing anything. ",[76,44639,365],{}," this is a major behavioral difference from CommonJS, where ",[39,44642,655],{}," copies the value (or reference) present at the moment of the require call, so a later reassignment in the source module would NOT be visible to something that already required it.",[15,44645,44646,44652,44697,44755,44779],{"language":247},[18,44647,44649,44650,19524],{"id":44648},"q5-the-equivalent-scenario-using-commonjs-what-does-mainjs-log","Q5. The equivalent scenario using CommonJS. What does ",[39,44651,44478],{},[257,44653,44654],{"language":247,"filename":44474},[260,44655,44657],{"className":262,"code":44656,"language":247,"meta":264,"style":264},"let count = 0;\nfunction increment() { count++; }\nmodule.exports = { count, increment };\n",[39,44658,44659,44671,44684],{"__ignoreMap":264},[268,44660,44661,44663,44665,44667,44669],{"class":270,"line":271},[268,44662,240],{"class":274},[268,44664,10091],{"class":282},[268,44666,302],{"class":274},[268,44668,5728],{"class":305},[268,44670,293],{"class":282},[268,44672,44673,44675,44677,44680,44682],{"class":270,"line":286},[268,44674,275],{"class":274},[268,44676,37313],{"class":278},[268,44678,44679],{"class":282},"() { count",[268,44681,9401],{"class":274},[268,44683,25000],{"class":282},[268,44685,44686,44688,44690,44692,44694],{"class":270,"line":296},[268,44687,633],{"class":305},[268,44689,462],{"class":282},[268,44691,638],{"class":305},[268,44693,616],{"class":274},[268,44695,44696],{"class":282}," { count, increment };\n",[257,44698,44699],{"language":247,"filename":44478},[260,44700,44702],{"className":262,"code":44701,"language":247,"meta":264,"style":264},"const { count, increment } = require('.\u002Fcounter.js');\n\nconsole.log(count);\nincrement();\nconsole.log(count);\n",[39,44703,44704,44729,44733,44741,44747],{"__ignoreMap":264},[268,44705,44706,44708,44710,44712,44714,44716,44718,44720,44722,44724,44727],{"class":270,"line":271},[268,44707,243],{"class":274},[268,44709,20200],{"class":282},[268,44711,10191],{"class":305},[268,44713,42],{"class":282},[268,44715,34969],{"class":305},[268,44717,7908],{"class":282},[268,44719,302],{"class":274},[268,44721,619],{"class":278},[268,44723,622],{"class":282},[268,44725,44726],{"class":289},"'.\u002Fcounter.js'",[268,44728,628],{"class":282},[268,44730,44731],{"class":270,"line":286},[268,44732,5033],{"emptyLinePlaceholder":35},[268,44734,44735,44737,44739],{"class":270,"line":296},[268,44736,1353],{"class":282},[268,44738,1356],{"class":278},[268,44740,10157],{"class":282},[268,44742,44743,44745],{"class":270,"line":311},[268,44744,34969],{"class":278},[268,44746,794],{"class":282},[268,44748,44749,44751,44753],{"class":270,"line":788},[268,44750,1353],{"class":282},[268,44752,1356],{"class":278},[268,44754,10157],{"class":282},[23,44756,44758,44763,44768,44773],{"className":44757},[26],[28,44759,44761,44602],{"className":44760},[31],[33,44762],{"disabled":35,"type":36},[28,44764,44766,44579],{"className":44765},[31],[33,44767],{"disabled":35,"type":36},[28,44769,44771,44585],{"className":44770},[31],[33,44772],{"disabled":35,"type":36},[28,44774,44776,44778],{"className":44775},[31],[33,44777],{"disabled":35,"type":36}," undefined then undefined",[66,44780,44781,44783,44788],{},[69,44782,71],{},[73,44784,44785,44787],{},[76,44786,78],{}," B — 0 then 0",[73,44789,44790,355,44792,36768,44795,44798,44799,2182,44801,44803,44804,44806,44807,44809,44810,44812,44813,44815,44816,30385,44818,44820,44821,44823,44824,4948,44826,44828,44829,44831],{},[76,44791,84],{},[39,44793,44794],{},"module.exports = { count, increment }",[104,44796,44797],{},"current primitive value"," of ",[39,44800,10191],{},[39,44802,3307],{},") into a new property on the exports object at the moment ",[39,44805,658],{}," is assigned. ",[39,44808,44478],{},"'s destructured ",[39,44811,10191],{}," is just a local ",[39,44814,243],{}," holding that snapshot — it has no ongoing connection to ",[39,44817,44474],{},[39,44819,10191],{}," variable. Calling ",[39,44822,44633],{}," mutates the module-internal ",[39,44825,10191],{},[39,44827,44478],{},"'s copy never updates. ",[76,44830,365],{}," this exact gap — CommonJS copies values, ESM shares live bindings — is why porting CommonJS \"mutable exported counter\" patterns to ESM (or vice versa) silently changes behavior.",[15,44833,44834,44838,44885,44919],{"language":247},[18,44835,44837],{"id":44836},"q6-what-happens-when-this-code-runs","Q6. What happens when this code runs?",[257,44839,44840],{"language":247},[260,44841,44843],{"className":262,"code":44842,"language":247,"meta":264,"style":264},"import { PI } from '.\u002Fconstants.js';\n\nPI = 3;\nconsole.log(PI);\n",[39,44844,44845,44859,44863,44873],{"__ignoreMap":264},[268,44846,44847,44849,44852,44854,44857],{"class":270,"line":271},[268,44848,662],{"class":274},[268,44850,44851],{"class":282}," { PI } ",[268,44853,44539],{"class":274},[268,44855,44856],{"class":289}," '.\u002Fconstants.js'",[268,44858,293],{"class":282},[268,44860,44861],{"class":270,"line":286},[268,44862,5033],{"emptyLinePlaceholder":35},[268,44864,44865,44867,44869,44871],{"class":270,"line":296},[268,44866,3978],{"class":305},[268,44868,616],{"class":274},[268,44870,3396],{"class":305},[268,44872,293],{"class":282},[268,44874,44875,44877,44879,44881,44883],{"class":270,"line":311},[268,44876,1353],{"class":282},[268,44878,1356],{"class":278},[268,44880,622],{"class":282},[268,44882,3978],{"class":305},[268,44884,628],{"class":282},[23,44886,44888,44894,44900,44909],{"className":44887},[26],[28,44889,44891,44893],{"className":44890},[31],[33,44892],{"disabled":35,"type":36}," SyntaxError \u002F TypeError — named imports are read-only bindings and cannot be reassigned",[28,44895,44897,44899],{"className":44896},[31],[33,44898],{"disabled":35,"type":36}," Logs 3 — the local binding is reassigned but the export is untouched",[28,44901,44903,44905,44906,44908],{"className":44902},[31],[33,44904],{"disabled":35,"type":36}," Logs 3 — and the exporting module's ",[39,44907,3978],{}," is also updated to 3, since imports are live",[28,44910,44912,3578,44914,183,44916,44918],{"className":44911},[31],[33,44913],{"disabled":35,"type":36},[39,44915,833],{},[39,44917,3978],{}," was never actually imported",[66,44920,44921,44923,44928],{},[69,44922,71],{},[73,44924,44925,44927],{},[76,44926,78],{}," A — SyntaxError \u002F TypeError — named imports are read-only bindings and cannot be reassigned",[73,44929,44930,44932,44933,44935,44936,44939,44940,44942,44943,44945],{},[76,44931,84],{}," ESM named imports are read-only views onto the exporting module's binding — \"live\" means updates flow ",[104,44934,44539],{}," the exporter ",[104,44937,44938],{},"to"," every importer, never the reverse. Attempting to assign to an imported binding directly is rejected (a ",[39,44941,4135],{},"-style failure, enforced at the binding level regardless of how the exporter declared it). If you need to change shared state from the importing side, the exporting module must expose a function (like ",[39,44944,44633],{}," in Q4) that performs the mutation internally.",[15,44947,44948,44959,45010,45061,45076,45113],{"language":247},[18,44949,44951,44952,186,44954,44956,44957,19524],{"id":44950},"q7-ajs-and-bjs-import-each-other-using-esm-what-does-running-mainjs-log","Q7. ",[39,44953,1132],{},[39,44955,1136],{}," import each other. Using ESM, what does running ",[39,44958,44478],{},[257,44960,44961],{"language":247,"filename":1132},[260,44962,44964],{"className":262,"code":44963,"language":247,"meta":264,"style":264},"import { bValue } from '.\u002Fb.js';\nexport const aValue = 'A';\nconsole.log('a.js sees bValue:', bValue);\n",[39,44965,44966,44980,44996],{"__ignoreMap":264},[268,44967,44968,44970,44973,44975,44978],{"class":270,"line":271},[268,44969,662],{"class":274},[268,44971,44972],{"class":282}," { bValue } ",[268,44974,44539],{"class":274},[268,44976,44977],{"class":289}," '.\u002Fb.js'",[268,44979,293],{"class":282},[268,44981,44982,44984,44986,44989,44991,44994],{"class":270,"line":286},[268,44983,665],{"class":274},[268,44985,44357],{"class":274},[268,44987,44988],{"class":305}," aValue",[268,44990,616],{"class":274},[268,44992,44993],{"class":289}," 'A'",[268,44995,293],{"class":282},[268,44997,44998,45000,45002,45004,45007],{"class":270,"line":296},[268,44999,1353],{"class":282},[268,45001,1356],{"class":278},[268,45003,622],{"class":282},[268,45005,45006],{"class":289},"'a.js sees bValue:'",[268,45008,45009],{"class":282},", bValue);\n",[257,45011,45012],{"language":247,"filename":1136},[260,45013,45015],{"className":262,"code":45014,"language":247,"meta":264,"style":264},"import { aValue } from '.\u002Fa.js';\nexport const bValue = 'B';\nconsole.log('b.js sees aValue:', aValue);\n",[39,45016,45017,45031,45047],{"__ignoreMap":264},[268,45018,45019,45021,45024,45026,45029],{"class":270,"line":271},[268,45020,662],{"class":274},[268,45022,45023],{"class":282}," { aValue } ",[268,45025,44539],{"class":274},[268,45027,45028],{"class":289}," '.\u002Fa.js'",[268,45030,293],{"class":282},[268,45032,45033,45035,45037,45040,45042,45045],{"class":270,"line":286},[268,45034,665],{"class":274},[268,45036,44357],{"class":274},[268,45038,45039],{"class":305}," bValue",[268,45041,616],{"class":274},[268,45043,45044],{"class":289}," 'B'",[268,45046,293],{"class":282},[268,45048,45049,45051,45053,45055,45058],{"class":270,"line":296},[268,45050,1353],{"class":282},[268,45052,1356],{"class":278},[268,45054,622],{"class":282},[268,45056,45057],{"class":289},"'b.js sees aValue:'",[268,45059,45060],{"class":282},", aValue);\n",[257,45062,45063],{"language":247,"filename":44478},[260,45064,45066],{"className":262,"code":45065,"language":247,"meta":264,"style":264},"import '.\u002Fa.js';\n",[39,45067,45068],{"__ignoreMap":264},[268,45069,45070,45072,45074],{"class":270,"line":271},[268,45071,662],{"class":274},[268,45073,45028],{"class":289},[268,45075,293],{"class":282},[23,45077,45079,45090,45096,45102],{"className":45078},[26],[28,45080,45082,355,45084,1133,45087],{"className":45081},[31],[33,45083],{"disabled":35,"type":36},[39,45085,45086],{},"a.js sees bValue: undefined",[39,45088,45089],{},"b.js sees aValue: A",[28,45091,45093,45095],{"className":45092},[31],[33,45094],{"disabled":35,"type":36}," Throws a ReferenceError immediately due to the circular dependency",[28,45097,45099,45101],{"className":45098},[31],[33,45100],{"disabled":35,"type":36}," Both log their values correctly because ESM resolves circular imports out of order",[28,45103,45105,355,45107,1133,45110],{"className":45104},[31],[33,45106],{"disabled":35,"type":36},[39,45108,45109],{},"b.js sees aValue: undefined",[39,45111,45112],{},"a.js sees bValue: B",[66,45114,45115,45117,45125],{},[69,45116,71],{},[73,45118,45119,6901,45121,1133,45123],{},[76,45120,78],{},[39,45122,45109],{},[39,45124,45112],{},[73,45126,45127,355,45129,45131,45132,45134,45135,45137,45138,44798,45140,45142,45143,45145,45146,3277,45148,45150,45151,20968,45154,45156,45157,9057,45159,45162,45163,45165,45166,45168,45169,45171,45172,45175,45176,45178,45179,3277,45182,45184],{},[76,45128,84],{},[39,45130,44478],{}," imports ",[39,45133,1132],{}," first, so ",[39,45136,1132],{}," starts executing and immediately hits its ",[39,45139,662],{},[39,45141,1136],{},", suspending ",[39,45144,1132],{}," to run ",[39,45147,1136],{},[39,45149,1136],{}," then imports ",[39,45152,45153],{},"aValue",[39,45155,1132],{}," — but ",[39,45158,1132],{},[39,45160,45161],{},"export const aValue = 'A'"," line hasn't executed yet (it's after the import), so the ",[104,45164,4175],{}," exists (hoisted) but is still in its temporal dead zone \u002F unset state, read as ",[39,45167,833],{}," at this point. ",[39,45170,1136],{}," finishes, setting ",[39,45173,45174],{},"bValue = 'B'",", and control returns to ",[39,45177,1132],{},", which now sees the fully-set ",[39,45180,45181],{},"bValue",[76,45183,365],{}," ESM's live-binding model means circular imports don't throw outright, but the order in which each side finishes initializing determines which values are visible when — the fix is usually to reference the circularly-imported binding lazily (inside a function) rather than at module top level.",[15,45186,45187,45191,45244,45297,45359],{"language":247},[18,45188,45190],{"id":45189},"q8-the-same-circular-scenario-but-using-commonjs-whats-the-key-difference-in-outcome-versus-the-esm-version","Q8. The same circular scenario, but using CommonJS. What's the key difference in outcome versus the ESM version?",[257,45192,45193],{"language":247,"filename":1132},[260,45194,45196],{"className":262,"code":45195,"language":247,"meta":264,"style":264},"const { bValue } = require('.\u002Fb.js');\nexports.aValue = 'A';\nconsole.log('a.js sees bValue:', bValue);\n",[39,45197,45198,45219,45232],{"__ignoreMap":264},[268,45199,45200,45202,45204,45206,45208,45210,45212,45214,45217],{"class":270,"line":271},[268,45201,243],{"class":274},[268,45203,20200],{"class":282},[268,45205,45181],{"class":305},[268,45207,7908],{"class":282},[268,45209,302],{"class":274},[268,45211,619],{"class":278},[268,45213,622],{"class":282},[268,45215,45216],{"class":289},"'.\u002Fb.js'",[268,45218,628],{"class":282},[268,45220,45221,45223,45226,45228,45230],{"class":270,"line":286},[268,45222,638],{"class":305},[268,45224,45225],{"class":282},".aValue ",[268,45227,302],{"class":274},[268,45229,44993],{"class":289},[268,45231,293],{"class":282},[268,45233,45234,45236,45238,45240,45242],{"class":270,"line":296},[268,45235,1353],{"class":282},[268,45237,1356],{"class":278},[268,45239,622],{"class":282},[268,45241,45006],{"class":289},[268,45243,45009],{"class":282},[257,45245,45246],{"language":247,"filename":1136},[260,45247,45249],{"className":262,"code":45248,"language":247,"meta":264,"style":264},"const { aValue } = require('.\u002Fa.js');\nexports.bValue = 'B';\nconsole.log('b.js sees aValue:', aValue);\n",[39,45250,45251,45272,45285],{"__ignoreMap":264},[268,45252,45253,45255,45257,45259,45261,45263,45265,45267,45270],{"class":270,"line":271},[268,45254,243],{"class":274},[268,45256,20200],{"class":282},[268,45258,45153],{"class":305},[268,45260,7908],{"class":282},[268,45262,302],{"class":274},[268,45264,619],{"class":278},[268,45266,622],{"class":282},[268,45268,45269],{"class":289},"'.\u002Fa.js'",[268,45271,628],{"class":282},[268,45273,45274,45276,45279,45281,45283],{"class":270,"line":286},[268,45275,638],{"class":305},[268,45277,45278],{"class":282},".bValue ",[268,45280,302],{"class":274},[268,45282,45044],{"class":289},[268,45284,293],{"class":282},[268,45286,45287,45289,45291,45293,45295],{"class":270,"line":296},[268,45288,1353],{"class":282},[268,45290,1356],{"class":278},[268,45292,622],{"class":282},[268,45294,45057],{"class":289},[268,45296,45060],{"class":282},[23,45298,45300,45312,45325,45346],{"className":45299},[26],[28,45301,45303,355,45305,23506,45307,830,45309,45311],{"className":45302},[31],[33,45304],{"disabled":35,"type":36},[39,45306,45153],{},[39,45308,1136],{},[39,45310,17902],{}," because CommonJS eagerly resolves the whole dependency graph before running any module",[28,45313,45315,45317,45318,45321,45322,45324],{"className":45314},[31],[33,45316],{"disabled":35,"type":36}," CommonJS throws a ",[39,45319,45320],{},"RequireError"," on any circular ",[39,45323,655],{},", unlike ESM",[28,45326,45328,355,45330,23506,45332,830,45334,45336,45337,45339,45340,45342,45343,45345],{"className":45327},[31],[33,45329],{"disabled":35,"type":36},[39,45331,45153],{},[39,45333,1136],{},[39,45335,833],{}," because CommonJS destructures a snapshot of ",[39,45338,1132],{},"'s (still-incomplete) ",[39,45341,638],{}," object at require-time, and no later update to ",[39,45344,1132],{},"'s exports is ever reflected",[28,45347,45349,45351,45352,2018,45354,45356,45357],{"className":45348},[31],[33,45350],{"disabled":35,"type":36}," The behavior is identical to ESM — both produce ",[39,45353,833],{},[39,45355,1136],{}," and the correct value in ",[39,45358,1132],{},[66,45360,45361,45363,45379],{},[69,45362,71],{},[73,45364,45365,1004,45367,23506,45369,830,45371,45336,45373,45339,45375,45342,45377,45345],{},[76,45366,78],{},[39,45368,45153],{},[39,45370,1136],{},[39,45372,833],{},[39,45374,1132],{},[39,45376,638],{},[39,45378,1132],{},[73,45380,45381,45383,45384,14552,45386,45389,45390,9057,45392,45394,45395,45397,45398,45401,45402,45405,45406,45409,45410,45412,45413,7415,45415,45417,45418,45420,45421,3277,45424,45426,45427,45429],{},[76,45382,84],{}," When ",[39,45385,1136],{},[39,45387,45388],{},"require('.\u002Fa.js')",", Node returns whatever ",[39,45391,1132],{},[39,45393,658],{}," object currently contains — but ",[39,45396,1132],{}," is mid-execution (it's paused at its own ",[39,45399,45400],{},"require('.\u002Fb.js')"," call, before reaching ",[39,45403,45404],{},"exports.aValue = 'A'","), so the returned object is incomplete\u002Fempty at that point. Because ",[39,45407,45408],{},"const { aValue } = require(...)"," destructures once and copies that value out immediately, ",[39,45411,1136],{},"'s local ",[39,45414,45153],{},[39,45416,833],{}," forever, even after ",[39,45419,1132],{}," later finishes and sets ",[39,45422,45423],{},"exports.aValue",[76,45425,365],{}," this is functionally similar in symptom to the ESM case (Q7) but for a different mechanical reason — CommonJS copies a snapshot of an incomplete object, while ESM shares a live binding that is simply unset at read time; the practical fix in CommonJS is to ",[39,45428,655],{}," inside a function body (deferring the read) rather than destructuring at the top.",[15,45431,45432,45436,45470],{"language":247},[18,45433,45435],{"id":45434},"q9-which-statement-about-renaming-a-default-export-at-its-export-site-is-correct","Q9. Which statement about renaming a default export at its export site is correct?",[23,45437,45439,45449,45458,45464],{"className":45438},[26],[28,45440,45442,45444,45445,45448],{"className":45441},[31],[33,45443],{"disabled":35,"type":36}," A default export has no name to rename at the export site — you write ",[39,45446,45447],{},"export default \u003Cvalue>",", and the importer chooses any local name it wants",[28,45450,45452,45454,45455],{"className":45451},[31],[33,45453],{"disabled":35,"type":36}," A default export can be renamed at the export site using ",[39,45456,45457],{},"export default as myName",[28,45459,45461,45463],{"className":45460},[31],[33,45462],{"disabled":35,"type":36}," A default export must share its name with the file name",[28,45465,45467,45469],{"className":45466},[31],[33,45468],{"disabled":35,"type":36}," A default export can be renamed only if it's a named export first, then re-exported as default",[66,45471,45472,45474,45481],{},[69,45473,71],{},[73,45475,45476,45478,45479,45448],{},[76,45477,78],{}," A — A default export has no name to rename at the export site — you write ",[39,45480,45447],{},[73,45482,45483,355,45485,45488,45489,45491,45492,42,45495,137,45498,45501,45502,462],{},[76,45484,84],{},[39,45486,45487],{},"export default"," binds to the reserved identifier ",[39,45490,9046],{}," internally; there's nothing to \"rename\" on the export side because there was never a chosen name to begin with — you're exporting a value, not a named binding. This is exactly why the importer has total freedom: ",[39,45493,45494],{},"import Foo from '.\u002Fx.js'",[39,45496,45497],{},"import Bar from '.\u002Fx.js'",[39,45499,45500],{},"import whatever123 from '.\u002Fx.js'"," are all equally valid regardless of what the exporting file called the value internally. Contrast with named exports, which do have a fixed export-side name unless explicitly aliased with ",[39,45503,45504],{},"export { x as y }",[15,45506,45507,45511,45533,45554,45587],{"language":247},[18,45508,45510],{"id":45509},"q10-two-files-import-the-same-default-exported-function-under-different-local-names-is-this-a-problem","Q10. Two files import the same default-exported function under different local names. Is this a problem?",[257,45512,45514],{"language":247,"filename":45513},"fileA.js",[260,45515,45517],{"className":262,"code":45516,"language":247,"meta":264,"style":264},"import formatDate from '.\u002FdateUtils.js';\n",[39,45518,45519],{"__ignoreMap":264},[268,45520,45521,45523,45526,45528,45531],{"class":270,"line":271},[268,45522,662],{"class":274},[268,45524,45525],{"class":282}," formatDate ",[268,45527,44539],{"class":274},[268,45529,45530],{"class":289}," '.\u002FdateUtils.js'",[268,45532,293],{"class":282},[257,45534,45536],{"language":247,"filename":45535},"fileB.js",[260,45537,45539],{"className":262,"code":45538,"language":247,"meta":264,"style":264},"import fmtDate from '.\u002FdateUtils.js';\n",[39,45540,45541],{"__ignoreMap":264},[268,45542,45543,45545,45548,45550,45552],{"class":270,"line":271},[268,45544,662],{"class":274},[268,45546,45547],{"class":282}," fmtDate ",[268,45549,44539],{"class":274},[268,45551,45530],{"class":289},[268,45553,293],{"class":282},[23,45555,45557,45563,45569,45578],{"className":45556},[26],[28,45558,45560,45562],{"className":45559},[31],[33,45561],{"disabled":35,"type":36}," Yes — a default export must be imported under the same name everywhere or the module cache breaks",[28,45564,45566,45568],{"className":45565},[31],[33,45567],{"disabled":35,"type":36}," No — default import names are purely local aliases and can legally differ across importing files",[28,45570,45572,45574,45575],{"className":45571},[31],[33,45573],{"disabled":35,"type":36}," No, but it silently creates two separate instances of ",[39,45576,45577],{},"dateUtils.js",[28,45579,45581,45583,45584],{"className":45580},[31],[33,45582],{"disabled":35,"type":36}," Yes — this throws a ",[39,45585,45586],{},"SyntaxError: mismatched default import name",[66,45588,45589,45591,45596],{},[69,45590,71],{},[73,45592,45593,45595],{},[76,45594,78],{}," B — No — default import names are purely local aliases and can legally differ across importing files",[73,45597,45598,45600,45601,186,45604,45607,45608,45610],{},[76,45599,84],{}," Since a default export carries no name of its own (see Q9), every importer is free to bind it to whatever local identifier is convenient — ",[39,45602,45603],{},"formatDate",[39,45605,45606],{},"fmtDate"," both refer to the exact same underlying function object. ",[76,45609,930],{}," while this is legal, letting the local name drift across a codebase makes the export harder to grep for and reason about — many teams adopt a convention (e.g., always import a default as the exact export's canonical name) purely for readability, not because the language requires it.",[15,45612,45613,45619,45649,45684,45734],{"language":247},[18,45614,45616,45617,1685],{"id":45615},"q11-a-commonjs-module-is-imported-from-an-esm-file-in-nodejs-what-typically-happens-to-moduleexports","Q11. A CommonJS module is imported from an ESM file in Node.js. What typically happens to ",[39,45618,658],{},[257,45620,45622],{"language":247,"filename":45621},"legacy.cjs",[260,45623,45625],{"className":262,"code":45624,"language":247,"meta":264,"style":264},"module.exports = { greet: () => 'hi' };\n",[39,45626,45627],{"__ignoreMap":264},[268,45628,45629,45631,45633,45635,45637,45639,45641,45643,45645,45647],{"class":270,"line":271},[268,45630,633],{"class":305},[268,45632,462],{"class":282},[268,45634,638],{"class":305},[268,45636,616],{"class":274},[268,45638,20200],{"class":282},[268,45640,12761],{"class":278},[268,45642,34921],{"class":282},[268,45644,9414],{"class":274},[268,45646,38717],{"class":289},[268,45648,2790],{"class":282},[257,45650,45652],{"language":247,"filename":45651},"main.mjs",[260,45653,45655],{"className":262,"code":45654,"language":247,"meta":264,"style":264},"import legacy from '.\u002Flegacy.cjs';\nconsole.log(legacy.greet());\n",[39,45656,45657,45671],{"__ignoreMap":264},[268,45658,45659,45661,45664,45666,45669],{"class":270,"line":271},[268,45660,662],{"class":274},[268,45662,45663],{"class":282}," legacy ",[268,45665,44539],{"class":274},[268,45667,45668],{"class":289}," '.\u002Flegacy.cjs'",[268,45670,293],{"class":282},[268,45672,45673,45675,45677,45680,45682],{"class":270,"line":286},[268,45674,1353],{"class":282},[268,45676,1356],{"class":278},[268,45678,45679],{"class":282},"(legacy.",[268,45681,12761],{"class":278},[268,45683,8174],{"class":282},[23,45685,45687,45699,45711,45722],{"className":45686},[26],[28,45688,45690,355,45692,45694,45695,45698],{"className":45689},[31],[33,45691],{"disabled":35,"type":36},[39,45693,45621],{},"'s properties automatically become named exports, so ",[39,45696,45697],{},"import { greet } from '.\u002Flegacy.cjs'"," is the only correct form",[28,45700,45702,45704,45705,45707,45708,45710],{"className":45701},[31],[33,45703],{"disabled":35,"type":36}," Node refuses to import ",[39,45706,729],{}," files from ",[39,45709,726],{}," files under any circumstances",[28,45712,45714,355,45716,830,45719,45721],{"className":45713},[31],[33,45715],{"disabled":35,"type":36},[39,45717,45718],{},"legacy",[39,45720,833],{}," because CommonJS modules have no exports Node can see from ESM",[28,45723,45725,355,45727,45729,45730,45733],{"className":45724},[31],[33,45726],{"disabled":35,"type":36},[39,45728,658],{}," becomes the default export as a whole, so ",[39,45731,45732],{},"legacy.greet()"," works via the default import",[66,45735,45736,45738,45746],{},[69,45737,71],{},[73,45739,45740,6901,45742,45729,45744,45733],{},[76,45741,78],{},[39,45743,658],{},[39,45745,45732],{},[73,45747,45748,45750,45751,45753,45754,45756,45757,45759,45760,45763,45764,45767,45768,45770,45771,45773,45774,45776],{},[76,45749,84],{}," Node's interop layer wraps a CommonJS module's entire ",[39,45752,658],{}," object as the ESM default export when it's imported from an ",[39,45755,726],{}," file (or an ESM-mode ",[39,45758,1815],{}," file). So ",[39,45761,45762],{},"import legacy from '.\u002Flegacy.cjs'"," gives you the whole ",[39,45765,45766],{},"{ greet }"," object, and ",[39,45769,45732],{}," works as shown. Named-export interop (",[39,45772,45697],{},") is sometimes synthesized too, via static analysis of the CommonJS source by Node\u002Fbundlers, but this is heuristic and not guaranteed — it's a well-known source of \"why does this named import say undefined\" bugs. ",[76,45775,182],{}," relying on named-import interop for CommonJS packages is fragile across Node versions and bundlers; importing the default and destructuring afterward is the safer, more portable pattern.",[15,45778,45779,45783,45818],{"language":247},[18,45780,45782],{"id":45781},"q12-why-can-bundlers-reliably-tree-shake-esm-code-but-not-commonjs-code","Q12. Why can bundlers reliably tree-shake ESM code but not CommonJS code?",[23,45784,45786,45792,45798,45812],{"className":45785},[26],[28,45787,45789,45791],{"className":45788},[31],[33,45790],{"disabled":35,"type":36}," CommonJS doesn't support tree-shaking because Node.js disables minification",[28,45793,45795,45797],{"className":45794},[31],[33,45796],{"disabled":35,"type":36}," ESM modules are always smaller in file size before bundling even begins",[28,45799,45801,45803,45804,446,45806,45808,45809,45811],{"className":45800},[31],[33,45802],{"disabled":35,"type":36}," ESM's ",[39,45805,662],{},[39,45807,665],{}," are static, top-level-only declarations a bundler can analyze without running any code, whereas ",[39,45810,714],{}," is a plain function call that can be conditional or dynamically constructed, forcing the bundler to assume any export might be used",[28,45813,45815,45817],{"className":45814},[31],[33,45816],{"disabled":35,"type":36}," Tree-shaking is a runtime, not build-time, distinction — it applies equally to both once code is executing",[66,45819,45820,45822,45833],{},[69,45821,71],{},[73,45823,45824,45826,45827,446,45829,45808,45831,45811],{},[76,45825,78],{}," C — ESM's ",[39,45828,662],{},[39,45830,665],{},[39,45832,714],{},[73,45834,45835,45837,45838,45841,45842,45844,45845,45848,45849,45851,45852,45854],{},[76,45836,84],{}," Tree-shaking means removing exports that are never imported anywhere. To do that safely, a bundler needs to prove, without executing the program, exactly which exports each file uses — ESM's syntactic restrictions (imports\u002Fexports must be literal, top-level statements) make that provable at build time. ",[39,45839,45840],{},"require('.\u002Fmod')"," inside an ",[39,45843,2179],{}," block, inside a loop, or built from ",[39,45846,45847],{},"require(someVariable)"," cannot be resolved without actually running the code, so a bundler must conservatively keep everything ",[39,45850,658],{}," might contain. ",[76,45853,438],{}," this is the primary real-world reason teams migrate legacy CommonJS libraries to ESM — smaller bundles, not stylistic preference.",[15,45856,45857,45880,45905,45938,45966,46019],{"language":247},[18,45858,45860,45861,45864,45865,186,45868,3277,45871,45873,45874,45876,45877,45879],{"id":45859},"q13-statejs-is-imported-by-both-pageajs-and-pagebjs-pageajs-mutates-the-shared-state-then-pagebjs-reads-it-what-does-pagebjs-see","Q13. ",[39,45862,45863],{},"state.js"," is imported by both ",[39,45866,45867],{},"pageA.js",[39,45869,45870],{},"pageB.js",[39,45872,45867],{}," mutates the shared state, then ",[39,45875,45870],{}," reads it. What does ",[39,45878,45870],{}," see?",[257,45881,45882],{"language":247,"filename":45863},[260,45883,45885],{"className":262,"code":45884,"language":247,"meta":264,"style":264},"export const store = { user: null };\n",[39,45886,45887],{"__ignoreMap":264},[268,45888,45889,45891,45893,45896,45898,45901,45903],{"class":270,"line":271},[268,45890,665],{"class":274},[268,45892,44357],{"class":274},[268,45894,45895],{"class":305}," store",[268,45897,616],{"class":274},[268,45899,45900],{"class":282}," { user: ",[268,45902,2650],{"class":305},[268,45904,2790],{"class":282},[257,45906,45907],{"language":247,"filename":45867},[260,45908,45910],{"className":262,"code":45909,"language":247,"meta":264,"style":264},"import { store } from '.\u002Fstate.js';\nstore.user = 'ashvini';\n",[39,45911,45912,45926],{"__ignoreMap":264},[268,45913,45914,45916,45919,45921,45924],{"class":270,"line":271},[268,45915,662],{"class":274},[268,45917,45918],{"class":282}," { store } ",[268,45920,44539],{"class":274},[268,45922,45923],{"class":289}," '.\u002Fstate.js'",[268,45925,293],{"class":282},[268,45927,45928,45931,45933,45936],{"class":270,"line":286},[268,45929,45930],{"class":282},"store.user ",[268,45932,302],{"class":274},[268,45934,45935],{"class":289}," 'ashvini'",[268,45937,293],{"class":282},[257,45939,45940],{"language":247,"filename":45870},[260,45941,45943],{"className":262,"code":45942,"language":247,"meta":264,"style":264},"import { store } from '.\u002Fstate.js';\nconsole.log(store.user);\n",[39,45944,45945,45957],{"__ignoreMap":264},[268,45946,45947,45949,45951,45953,45955],{"class":270,"line":271},[268,45948,662],{"class":274},[268,45950,45918],{"class":282},[268,45952,44539],{"class":274},[268,45954,45923],{"class":289},[268,45956,293],{"class":282},[268,45958,45959,45961,45963],{"class":270,"line":286},[268,45960,1353],{"class":282},[268,45962,1356],{"class":278},[268,45964,45965],{"class":282},"(store.user);\n",[23,45967,45969,45982,45994,46007],{"className":45968},[26],[28,45970,45972,355,45974,45977,45978,45981],{"className":45971},[31],[33,45973],{"disabled":35,"type":36},[39,45975,45976],{},"'ashvini'"," — modules are singletons, so both files share the exact same ",[39,45979,45980],{},"store"," object instance",[28,45983,45985,355,45987,45989,45990,45993],{"className":45984},[31],[33,45986],{"disabled":35,"type":36},[39,45988,2650],{}," — each importing file gets its own fresh copy of ",[39,45991,45992],{},"store.js","'s exports",[28,45995,45997,355,45999,3990,46001,46003,46004,46006],{"className":45996},[31],[33,45998],{"disabled":35,"type":36},[39,46000,833],{},[39,46002,45980],{}," isn't re-exported by ",[39,46005,45870],{}," so it can't see the mutation",[28,46008,46010,46012,46013,46015,46016,46018],{"className":46009},[31],[33,46011],{"disabled":35,"type":36}," It depends on import order, and is ",[39,46014,2650],{}," if ",[39,46017,45870],{}," runs first regardless of later mutation",[66,46020,46021,46023,46031],{},[69,46022,71],{},[73,46024,46025,3459,46027,45977,46029,45981],{},[76,46026,78],{},[39,46028,45976],{},[39,46030,45980],{},[73,46032,46033,46035,46036,46038,46039,46041,46042,46044,46045,46047,46048,46050,46051,46053,46054,46056],{},[76,46034,84],{}," A module is only ever evaluated once per module graph, no matter how many files import it — every importer receives references to the ",[104,46037,22779],{}," exported bindings\u002Fobjects, not independent copies. ",[39,46040,45980],{}," is a single object living in ",[39,46043,45863],{},"'s module scope; ",[39,46046,45867],{}," mutates its ",[39,46049,4155],{}," property, and since ",[39,46052,45870],{}," holds a reference to that identical object, it observes the change. ",[76,46055,365],{}," this singleton behavior is exactly what makes modules a common (if implicit) place to stash shared app state, but it's also a classic source of test-pollution bugs — module state persists across test files unless explicitly reset, because the module isn't re-evaluated between imports.",[15,46058,46059,46069,46113],{"language":247},[18,46060,46062,46063,46065,46066,1685],{"id":46061},"q14-what-is-the-key-behavioral-difference-between-static-import-and-dynamic-import","Q14. What is the key behavioral difference between static ",[39,46064,662],{}," and dynamic ",[39,46067,46068],{},"import()",[23,46070,46072,46084,46095,46104],{"className":46071},[26],[28,46073,46075,46077,46078,46080,46081,46083],{"className":46074},[31],[33,46076],{"disabled":35,"type":36}," Static ",[39,46079,662],{}," returns a promise; dynamic ",[39,46082,46068],{}," is synchronous and hoisted",[28,46085,46087,46077,46089,46091,46092,46094],{"className":46086},[31],[33,46088],{"disabled":35,"type":36},[39,46090,662],{}," is hoisted and its target module is fully evaluated before the rest of the file runs; dynamic ",[39,46093,46068],{}," is a function call, evaluated in place, that returns a promise resolving to the module namespace object",[28,46096,46098,46100,46101,46103],{"className":46097},[31],[33,46099],{"disabled":35,"type":36}," They behave identically — ",[39,46102,46068],{}," is just alternate syntax with no timing difference",[28,46105,46107,46109,46110,46112],{"className":46106},[31],[33,46108],{"disabled":35,"type":36}," Dynamic ",[39,46111,46068],{}," can only be used inside Node.js, never in browsers",[66,46114,46115,46117,46126],{},[69,46116,71],{},[73,46118,46119,46121,46122,46091,46124,46094],{},[76,46120,78],{}," B — Static ",[39,46123,662],{},[39,46125,46068],{},[73,46127,46128,46077,46130,46132,46133,46136,46137,46139,46140,46142,46143,46146,46147,99,46150,46152,46153,46155],{},[76,46129,84],{},[39,46131,662],{}," declarations are processed at parse time regardless of where they're textually written in the file — the imported module's code runs to completion before any of the importing module's own top-level code executes (see Q15). Dynamic ",[39,46134,46135],{},"import('.\u002Fmod.js')",", by contrast, is an ordinary expression that can appear anywhere a value is expected (inside an ",[39,46138,2179],{},", a click handler, a loop) and returns a promise, since fetching\u002Fcompiling the module may happen asynchronously. This is the mechanism behind code-splitting and lazy-loading — a chunk is only fetched when the ",[39,46141,46068],{}," call actually runs. ",[76,46144,46145],{},"Note:"," consuming that returned promise (",[39,46148,46149],{},".then()",[39,46151,12304],{},") is covered in depth once Promises and async\u002Fawait are introduced later in this track — for now, just recognize that dynamic ",[39,46154,46068],{}," always hands you a promise, never the module directly.",[15,46157,46158,46162,46203,46261,46316],{"language":247},[18,46159,46161],{"id":46160},"q15-what-does-this-log-and-in-what-order","Q15. What does this log, and in what order?",[257,46163,46165],{"language":247,"filename":46164},"logger.js",[260,46166,46168],{"className":262,"code":46167,"language":247,"meta":264,"style":264},"console.log('logger.js running');\nexport function log(msg) { console.log(msg); }\n",[39,46169,46170,46183],{"__ignoreMap":264},[268,46171,46172,46174,46176,46178,46181],{"class":270,"line":271},[268,46173,1353],{"class":282},[268,46175,1356],{"class":278},[268,46177,622],{"class":282},[268,46179,46180],{"class":289},"'logger.js running'",[268,46182,628],{"class":282},[268,46184,46185,46187,46189,46191,46193,46195,46198,46200],{"class":270,"line":286},[268,46186,665],{"class":274},[268,46188,12080],{"class":274},[268,46190,16942],{"class":278},[268,46192,622],{"class":282},[268,46194,33187],{"class":1222},[268,46196,46197],{"class":282},") { console.",[268,46199,1356],{"class":278},[268,46201,46202],{"class":282},"(msg); }\n",[257,46204,46205],{"language":247,"filename":44478},[260,46206,46208],{"className":262,"code":46207,"language":247,"meta":264,"style":264},"console.log('main.js: before import line');\nimport { log } from '.\u002Flogger.js';\nconsole.log('main.js: after import line');\nlog('hello');\n",[39,46209,46210,46223,46237,46250],{"__ignoreMap":264},[268,46211,46212,46214,46216,46218,46221],{"class":270,"line":271},[268,46213,1353],{"class":282},[268,46215,1356],{"class":278},[268,46217,622],{"class":282},[268,46219,46220],{"class":289},"'main.js: before import line'",[268,46222,628],{"class":282},[268,46224,46225,46227,46230,46232,46235],{"class":270,"line":286},[268,46226,662],{"class":274},[268,46228,46229],{"class":282}," { log } ",[268,46231,44539],{"class":274},[268,46233,46234],{"class":289}," '.\u002Flogger.js'",[268,46236,293],{"class":282},[268,46238,46239,46241,46243,46245,46248],{"class":270,"line":296},[268,46240,1353],{"class":282},[268,46242,1356],{"class":278},[268,46244,622],{"class":282},[268,46246,46247],{"class":289},"'main.js: after import line'",[268,46249,628],{"class":282},[268,46251,46252,46254,46256,46259],{"class":270,"line":311},[268,46253,1356],{"class":278},[268,46255,622],{"class":282},[268,46257,46258],{"class":289},"'hello'",[268,46260,628],{"class":282},[23,46262,46264,46281,46294,46303],{"className":46263},[26],[28,46265,46267,355,46269,42,46272,42,46275,42,46278],{"className":46266},[31],[33,46268],{"disabled":35,"type":36},[39,46270,46271],{},"main.js: before import line",[39,46273,46274],{},"logger.js running",[39,46276,46277],{},"main.js: after import line",[39,46279,46280],{},"hello",[28,46282,46284,355,46286,42,46288,42,46290,42,46292],{"className":46283},[31],[33,46285],{"disabled":35,"type":36},[39,46287,46271],{},[39,46289,46277],{},[39,46291,46274],{},[39,46293,46280],{},[28,46295,46297,46299,46300,46302],{"className":46296},[31],[33,46298],{"disabled":35,"type":36}," This throws a SyntaxError because the ",[39,46301,662],{}," statement appears after other code",[28,46304,46306,355,46308,42,46310,42,46312,42,46314],{"className":46305},[31],[33,46307],{"disabled":35,"type":36},[39,46309,46274],{},[39,46311,46271],{},[39,46313,46277],{},[39,46315,46280],{},[66,46317,46318,46320,46332],{},[69,46319,71],{},[73,46321,46322,6901,46324,42,46326,42,46328,42,46330],{},[76,46323,78],{},[39,46325,46274],{},[39,46327,46271],{},[39,46329,46277],{},[39,46331,46280],{},[73,46333,46334,355,46336,46338,46339,46341,46342,46345,46346,21599,46349,46351,46352,46354,46355,46357,46358,46360,46361,46363,46364,46366,46367,462],{},[76,46335,84],{},[39,46337,662],{}," declarations are hoisted to the top of the module and always execute before any of the module's own top-level code, regardless of where the ",[39,46340,662],{}," line is textually positioned in the source. So even though ",[39,46343,46344],{},"console.log('main.js: before import line')"," appears ",[104,46347,46348],{},"above",[39,46350,662],{}," statement in the file, ",[39,46353,46164],{}," still finishes running first, because hoisting moves the import's effect to the very top of ",[39,46356,44478],{},"'s execution. ",[76,46359,365],{}," this surprises developers coming from CommonJS, where ",[39,46362,714],{}," genuinely executes at its exact position in the file — writing code above a ",[39,46365,714],{}," call really does run first there, unlike with ESM ",[39,46368,662],{},[15,46370,46371,46387,46421,46456],{"language":247},[18,46372,46374,46375,20968,46377,46379,46380,46383,46384,46386],{"id":46373},"q16-which-correctly-re-exports-add-from-mathjs-through-indexjs-without-indexjs-needing-a-separate-local-binding","Q16. Which correctly re-exports ",[39,46376,41889],{},[39,46378,44345],{}," through ",[39,46381,46382],{},"index.js",", without ",[39,46385,46382],{}," needing a separate local binding?",[257,46388,46389],{"language":247,"filename":44345},[260,46390,46392],{"className":262,"code":46391,"language":247,"meta":264,"style":264},"export function add(a, b) { return a + b; }\n",[39,46393,46394],{"__ignoreMap":264},[268,46395,46396,46398,46400,46402,46404,46406,46408,46410,46412,46414,46416,46418],{"class":270,"line":271},[268,46397,665],{"class":274},[268,46399,12080],{"class":274},[268,46401,1217],{"class":278},[268,46403,622],{"class":282},[268,46405,1223],{"class":1222},[268,46407,42],{"class":282},[268,46409,1232],{"class":1222},[268,46411,29387],{"class":282},[268,46413,9151],{"class":274},[268,46415,1243],{"class":282},[268,46417,1246],{"class":274},[268,46419,46420],{"class":282}," b; }\n",[23,46422,46424,46432,46440,46448],{"className":46423},[26],[28,46425,46427,355,46429],{"className":46426},[31],[33,46428],{"disabled":35,"type":36},[39,46430,46431],{},"import { add } from '.\u002Fmath.js'; export add;",[28,46433,46435,355,46437],{"className":46434},[31],[33,46436],{"disabled":35,"type":36},[39,46438,46439],{},"export add from '.\u002Fmath.js';",[28,46441,46443,355,46445],{"className":46442},[31],[33,46444],{"disabled":35,"type":36},[39,46446,46447],{},"export { add } from '.\u002Fmath.js';",[28,46449,46451,355,46453],{"className":46450},[31],[33,46452],{"disabled":35,"type":36},[39,46454,46455],{},"import add from '.\u002Fmath.js'; export default add;",[66,46457,46458,46460,46466],{},[69,46459,71],{},[73,46461,46462,1004,46464],{},[76,46463,78],{},[39,46465,46447],{},[73,46467,46468,4396,46470,46473,46474,9057,46476,46478,46479,26085,46481,46483,46484,46486,46487,46489,46490,46493,46494,46497,46498,46500,46501,9057,46503,46505],{},[76,46469,84],{},[39,46471,46472],{},"export { name } from '.\u002Fsource.js'"," syntax is a dedicated re-export form: it forwards ",[39,46475,44345],{},[39,46477,41889],{}," export through ",[39,46480,46382],{},[39,46482,46382],{},"'s own named export, without ever creating a local ",[39,46485,41889],{}," binding inside ",[39,46488,46382],{}," that you'd have to import first. Option A is invalid syntax (",[39,46491,46492],{},"export add;"," isn't a real form). Option B is also invalid — ",[39,46495,46496],{},"export ... from"," requires braces around named bindings. Option D would work but changes ",[39,46499,41889],{}," into ",[39,46502,46382],{},[104,46504,9046],{}," export rather than preserving it as a named export, which isn't equivalent unless that was the goal.",[15,46507,46508,46512,46552,46574,46620,46675],{"language":247},[18,46509,46511],{"id":46510},"q17-what-is-logged-and-why-is-this-preferred-over-importing-then-re-exporting-manually-when-no-transformation-is-needed","Q17. What is logged, and why is this preferred over importing then re-exporting manually when no transformation is needed?",[257,46513,46515],{"language":247,"filename":46514},"shapes.js",[260,46516,46518],{"className":262,"code":46517,"language":247,"meta":264,"style":264},"export function circleArea(r) { return Math.PI * r * r; }\n",[39,46519,46520],{"__ignoreMap":264},[268,46521,46522,46524,46526,46529,46531,46534,46536,46538,46540,46542,46544,46547,46549],{"class":270,"line":271},[268,46523,665],{"class":274},[268,46525,12080],{"class":274},[268,46527,46528],{"class":278}," circleArea",[268,46530,622],{"class":282},[268,46532,46533],{"class":1222},"r",[268,46535,29387],{"class":282},[268,46537,9151],{"class":274},[268,46539,30188],{"class":282},[268,46541,3978],{"class":305},[268,46543,6108],{"class":274},[268,46545,46546],{"class":282}," r ",[268,46548,6134],{"class":274},[268,46550,46551],{"class":282}," r; }\n",[257,46553,46555],{"language":247,"filename":46554},"geometry.js",[260,46556,46558],{"className":262,"code":46557,"language":247,"meta":264,"style":264},"export { circleArea } from '.\u002Fshapes.js';\n",[39,46559,46560],{"__ignoreMap":264},[268,46561,46562,46564,46567,46569,46572],{"class":270,"line":271},[268,46563,665],{"class":274},[268,46565,46566],{"class":282}," { circleArea } ",[268,46568,44539],{"class":274},[268,46570,46571],{"class":289}," '.\u002Fshapes.js'",[268,46573,293],{"class":282},[257,46575,46576],{"language":247,"filename":44478},[260,46577,46579],{"className":262,"code":46578,"language":247,"meta":264,"style":264},"import { circleArea } from '.\u002Fgeometry.js';\nconsole.log(circleArea(2).toFixed(2));\n",[39,46580,46581,46594],{"__ignoreMap":264},[268,46582,46583,46585,46587,46589,46592],{"class":270,"line":271},[268,46584,662],{"class":274},[268,46586,46566],{"class":282},[268,46588,44539],{"class":274},[268,46590,46591],{"class":289}," '.\u002Fgeometry.js'",[268,46593,293],{"class":282},[268,46595,46596,46598,46600,46602,46605,46607,46609,46611,46614,46616,46618],{"class":270,"line":286},[268,46597,1353],{"class":282},[268,46599,1356],{"class":278},[268,46601,622],{"class":282},[268,46603,46604],{"class":278},"circleArea",[268,46606,622],{"class":282},[268,46608,2258],{"class":305},[268,46610,6232],{"class":282},[268,46612,46613],{"class":278},"toFixed",[268,46615,622],{"class":282},[268,46617,2258],{"class":305},[268,46619,4818],{"class":282},[23,46621,46623,46641,46649,46660],{"className":46622},[26],[28,46624,46626,355,46628,3990,46631,46633,46634,46636,46637,46640],{"className":46625},[31],[33,46627],{"disabled":35,"type":36},[39,46629,46630],{},"12.57",[39,46632,46554],{}," forwards the export without ever binding ",[39,46635,46604],{}," into its own local scope, unlike ",[39,46638,46639],{},"import { x } from ...; export { x };"," which does create a local binding",[28,46642,46644,355,46646,46648],{"className":46643},[31],[33,46645],{"disabled":35,"type":36},[39,46647,46630],{}," — but this is functionally worse than importing-then-exporting because it defeats tree-shaking",[28,46650,46652,355,46654,46656,46657],{"className":46651},[31],[33,46653],{"disabled":35,"type":36},[39,46655,3040],{}," — re-exported functions lose their closure over ",[39,46658,46659],{},"Math.PI",[28,46661,46663,46665,46666,46668,46669,1179,46671,46674],{"className":46662},[31],[33,46664],{"disabled":35,"type":36}," Throws — ",[39,46667,46604],{}," was never locally declared inside ",[39,46670,46554],{},[39,46672,46673],{},"export { circleArea }"," has nothing to reference",[66,46676,46677,46679,46691],{},[69,46678,71],{},[73,46680,46681,3459,46683,3990,46685,46633,46687,46636,46689,46640],{},[76,46682,78],{},[39,46684,46630],{},[39,46686,46554],{},[39,46688,46604],{},[39,46690,46639],{},[73,46692,46693,355,46695,46698,46699,46701,46702,46704,46705,46707,46708,830,46711,137,46714,46717,46718,3277,46721,46723,46724,46726],{},[76,46694,84],{},[39,46696,46697],{},"export { circleArea } from '.\u002Fshapes.js'"," is purely a forwarding declaration at the module-linking level — ",[39,46700,46554],{}," never actually creates a local ",[39,46703,46604],{}," variable, it just tells consumers \"ask ",[39,46706,46514],{}," for this.\" The computation is unaffected: ",[39,46709,46710],{},"circleArea(2)",[39,46712,46713],{},"Math.PI * 4 ≈ 12.566...",[39,46715,46716],{},".toFixed(2)"," rounds that to ",[39,46719,46720],{},"'12.57'",[76,46722,930],{}," this direct re-export form is preferred in \"barrel\" files (",[39,46725,46382],{}," aggregating a package's public API) specifically because it avoids an unnecessary local binding and stays just as tree-shakeable as a direct import, unlike patterns that route the value through an intermediate local variable.",[15,46728,46729,46736,46819,46880,46925],{"language":247},[18,46730,46732,46733,19524],{"id":46731},"q18-what-does-objectkeysutils-log","Q18. What does ",[39,46734,46735],{},"Object.keys(utils)",[257,46737,46739],{"language":247,"filename":46738},"utils.js",[260,46740,46742],{"className":262,"code":46741,"language":247,"meta":264,"style":264},"export function trim(s) { return s.trim(); }\nexport function upper(s) { return s.toUpperCase(); }\nexport default function normalize(s) { return trim(s).toLowerCase(); }\n",[39,46743,46744,46768,46791],{"__ignoreMap":264},[268,46745,46746,46748,46750,46753,46755,46757,46759,46761,46763,46765],{"class":270,"line":271},[268,46747,665],{"class":274},[268,46749,12080],{"class":274},[268,46751,46752],{"class":278}," trim",[268,46754,622],{"class":282},[268,46756,25393],{"class":1222},[268,46758,29387],{"class":282},[268,46760,9151],{"class":274},[268,46762,25398],{"class":282},[268,46764,18832],{"class":278},[268,46766,46767],{"class":282},"(); }\n",[268,46769,46770,46772,46774,46777,46779,46781,46783,46785,46787,46789],{"class":270,"line":286},[268,46771,665],{"class":274},[268,46773,12080],{"class":274},[268,46775,46776],{"class":278}," upper",[268,46778,622],{"class":282},[268,46780,25393],{"class":1222},[268,46782,29387],{"class":282},[268,46784,9151],{"class":274},[268,46786,25398],{"class":282},[268,46788,16179],{"class":278},[268,46790,46767],{"class":282},[268,46792,46793,46795,46797,46799,46802,46804,46806,46808,46810,46812,46815,46817],{"class":270,"line":296},[268,46794,665],{"class":274},[268,46796,44373],{"class":274},[268,46798,12080],{"class":274},[268,46800,46801],{"class":278}," normalize",[268,46803,622],{"class":282},[268,46805,25393],{"class":1222},[268,46807,29387],{"class":282},[268,46809,9151],{"class":274},[268,46811,46752],{"class":278},[268,46813,46814],{"class":282},"(s).",[268,46816,43655],{"class":278},[268,46818,46767],{"class":282},[257,46820,46821],{"language":247,"filename":44478},[260,46822,46824],{"className":262,"code":46823,"language":247,"meta":264,"style":264},"import * as utils from '.\u002Futils.js';\nconsole.log(Object.keys(utils).sort());\nconsole.log(utils.trim('  hi  '));\n",[39,46825,46826,46845,46862],{"__ignoreMap":264},[268,46827,46828,46830,46832,46835,46838,46840,46843],{"class":270,"line":271},[268,46829,662],{"class":274},[268,46831,6108],{"class":305},[268,46833,46834],{"class":274}," as",[268,46836,46837],{"class":282}," utils ",[268,46839,44539],{"class":274},[268,46841,46842],{"class":289}," '.\u002Futils.js'",[268,46844,293],{"class":282},[268,46846,46847,46849,46851,46853,46855,46858,46860],{"class":270,"line":286},[268,46848,1353],{"class":282},[268,46850,1356],{"class":278},[268,46852,19627],{"class":282},[268,46854,9261],{"class":278},[268,46856,46857],{"class":282},"(utils).",[268,46859,19029],{"class":278},[268,46861,8174],{"class":282},[268,46863,46864,46866,46868,46871,46873,46875,46878],{"class":270,"line":296},[268,46865,1353],{"class":282},[268,46867,1356],{"class":278},[268,46869,46870],{"class":282},"(utils.",[268,46872,18832],{"class":278},[268,46874,622],{"class":282},[268,46876,46877],{"class":289},"'  hi  '",[268,46879,4818],{"class":282},[23,46881,46883,46894,46906,46916],{"className":46882},[26],[28,46884,46886,355,46888,1133,46891],{"className":46885},[31],[33,46887],{"disabled":35,"type":36},[39,46889,46890],{},"['trim', 'upper']",[39,46892,46893],{},"'hi'",[28,46895,46897,355,46899,46902,46903,41917],{"className":46896},[31],[33,46898],{"disabled":35,"type":36},[39,46900,46901],{},"['default', 'trim', 'upper']"," then throws because ",[39,46904,46905],{},"utils.trim",[28,46907,46909,355,46911,1133,46914],{"className":46908},[31],[33,46910],{"disabled":35,"type":36},[39,46912,46913],{},"['normalize', 'trim', 'upper']",[39,46915,46893],{},[28,46917,46919,355,46921,1133,46923],{"className":46918},[31],[33,46920],{"disabled":35,"type":36},[39,46922,46901],{},[39,46924,46893],{},[66,46926,46927,46929,46937],{},[69,46928,71],{},[73,46930,46931,6901,46933,1133,46935],{},[76,46932,78],{},[39,46934,46901],{},[39,46936,46893],{},[73,46938,46939,355,46941,38415,46944,46947,46948,42,46950,46953,46954,46957,46958,46961,46962,11464,46965,46967,46968,46971,46972,46974,46975,2758,46978,462],{},[76,46940,84],{},[39,46942,46943],{},"import * as utils",[76,46945,46946],{},"namespace object"," exposing every export of the module as a property — every named export (",[39,46949,18832],{},[39,46951,46952],{},"upper",") under its own name, and the default export under the special key ",[39,46955,46956],{},"'default'"," (not ",[39,46959,46960],{},"'normalize'",", since the function's local name doesn't become the property key). So ",[39,46963,46964],{},"Object.keys(utils).sort()",[39,46966,46901],{},". Named exports remain directly callable as properties, so ",[39,46969,46970],{},"utils.trim('  hi  ')"," runs normally and returns ",[39,46973,46893],{},". Accessing the default function itself would require ",[39,46976,46977],{},"utils.default(...)",[39,46979,46980],{},"utils.normalize(...)",[15,46982,46983,47002,47038],{"language":247},[18,46984,46986,46987,46990,46991,42,46994,46997,46998,47001],{"id":46985},"q19-a-teams-codebase-has-some-files-doing-import-as-api-from-apijs-and-using-apifetchuser-apipostorder-etc-while-other-files-do-import-fetchuser-from-apijs-for-the-exact-same-module-whats-the-best-practice-concern-here","Q19. A team's codebase has some files doing ",[39,46988,46989],{},"import * as api from '.\u002Fapi.js'"," and using ",[39,46992,46993],{},"api.fetchUser()",[39,46995,46996],{},"api.postOrder()",", etc., while other files do ",[39,46999,47000],{},"import { fetchUser } from '.\u002Fapi.js'"," for the exact same module. What's the best-practice concern here?",[23,47003,47005,47017,47023,47029],{"className":47004},[26],[28,47006,47008,47010,47011,186,47013,47016],{"className":47007},[31],[33,47009],{"disabled":35,"type":36}," There is no real concern — ",[39,47012,46993],{},[39,47014,47015],{},"fetchUser()"," are guaranteed to always behave identically with zero trade-offs",[28,47018,47020,47022],{"className":47019},[31],[33,47021],{"disabled":35,"type":36}," Mixing namespace-style and named-import access for the same module hurts predictability and tooling — pick one convention (usually named imports, since they tree-shake better and are easier to grep) and apply it consistently",[28,47024,47026,47028],{"className":47025},[31],[33,47027],{"disabled":35,"type":36}," Namespace imports are strictly forbidden by the ECMAScript spec when named imports exist elsewhere in the codebase",[28,47030,47032,47034,47035],{"className":47031},[31],[33,47033],{"disabled":35,"type":36}," The two forms cause the module to be evaluated twice, doubling any side effects in ",[39,47036,47037],{},"api.js",[66,47039,47040,47042,47047],{},[69,47041,71],{},[73,47043,47044,47046],{},[76,47045,78],{}," B — Mixing namespace-style and named-import access for the same module hurts predictability and tooling — pick one convention (usually named imports, since they tree-shake better and are easier to grep) and apply it consistently",[73,47048,47049,47051,47052,47055,47056,47059,47060,47063,47064,47066,47067,47069,47070,47073],{},[76,47050,84],{}," Both forms are legal and reference the same underlying live bindings (module singletons — see Q13), so there's no correctness bug per se. The issue is consistency: namespace imports (",[39,47053,47054],{},"import * as api",") pull in a reference to every export even if only one is used, which can undermine tree-shaking analysis in some bundlers, and make \"who uses ",[39,47057,47058],{},"fetchUser","\" harder to grep for since call sites read as ",[39,47061,47062],{},"api.fetchUser"," in some files and ",[39,47065,47058],{}," in others. ",[76,47068,930],{}," picking named imports as the default convention (reserving ",[39,47071,47072],{},"import * as ns"," for cases like re-exporting an entire module, or genuinely needing dozens of its exports) keeps call sites uniform and analysis-friendly across a codebase.",[15,47075,47076,47083,47157,47209],{"language":247},[18,47077,47079,47080,47082],{"id":47078},"q20-a-large-commonjs-utility-library-is-required-conditionally-based-on-an-environment-check-then-the-app-is-bundled-for-production-whats-the-most-accurate-best-practice-takeaway","Q20. A large CommonJS utility library is ",[39,47081,655],{},"d conditionally based on an environment check, then the app is bundled for production. What's the most accurate best-practice takeaway?",[257,47084,47085],{"language":247},[260,47086,47088],{"className":262,"code":47087,"language":247,"meta":264,"style":264},"let logger;\nif (process.env.NODE_ENV === 'production') {\n  logger = require('.\u002FprodLogger.js');\n} else {\n  logger = require('.\u002FdevLogger.js');\n}\n",[39,47089,47090,47097,47114,47130,47138,47153],{"__ignoreMap":264},[268,47091,47092,47094],{"class":270,"line":271},[268,47093,240],{"class":274},[268,47095,47096],{"class":282}," logger;\n",[268,47098,47099,47101,47104,47107,47109,47112],{"class":270,"line":286},[268,47100,2179],{"class":274},[268,47102,47103],{"class":282}," (process.env.",[268,47105,47106],{"class":305},"NODE_ENV",[268,47108,3043],{"class":274},[268,47110,47111],{"class":289}," 'production'",[268,47113,1235],{"class":282},[268,47115,47116,47119,47121,47123,47125,47128],{"class":270,"line":296},[268,47117,47118],{"class":282},"  logger ",[268,47120,302],{"class":274},[268,47122,619],{"class":278},[268,47124,622],{"class":282},[268,47126,47127],{"class":289},"'.\u002FprodLogger.js'",[268,47129,628],{"class":282},[268,47131,47132,47134,47136],{"class":270,"line":311},[268,47133,11235],{"class":282},[268,47135,9884],{"class":274},[268,47137,9914],{"class":282},[268,47139,47140,47142,47144,47146,47148,47151],{"class":270,"line":788},[268,47141,47118],{"class":282},[268,47143,302],{"class":274},[268,47145,619],{"class":278},[268,47147,622],{"class":282},[268,47149,47150],{"class":289},"'.\u002FdevLogger.js'",[268,47152,628],{"class":282},[268,47154,47155],{"class":270,"line":1951},[268,47156,314],{"class":282},[23,47158,47160,47170,47181,47197],{"className":47159},[26],[28,47161,47163,47165,47166,47169],{"className":47162},[31],[33,47164],{"disabled":35,"type":36}," Bundlers always evaluate ",[39,47167,47168],{},"process.env.NODE_ENV"," at build time regardless of module system, so this pattern is equally tree-shakeable in both CommonJS and ESM",[28,47171,47173,47175,47176,47178,47179,11115],{"className":47172},[31],[33,47174],{"disabled":35,"type":36}," This pattern is impossible to express in CommonJS at all — ",[39,47177,655],{}," cannot appear inside an ",[39,47180,2179],{},[28,47182,47184,47186,47187,186,47190,47193,47194,47196],{"className":47183},[31],[33,47185],{"disabled":35,"type":36}," The bundler can't statically prove which branch runs, so it typically must include both ",[39,47188,47189],{},"prodLogger.js",[39,47191,47192],{},"devLogger.js"," in the final bundle — an ESM equivalent using dynamic ",[39,47195,46068],{}," inside the conditional, or a build-time env substitution, avoids shipping the unused branch",[28,47198,47200,47202,47203,47205,47206,47208],{"className":47199},[31],[33,47201],{"disabled":35,"type":36}," Switching this to ESM ",[39,47204,662],{}," syntax directly inside the ",[39,47207,2179],{}," block would fix the bundle-size issue",[66,47210,47211,47213,47224],{},[69,47212,71],{},[73,47214,47215,47217,47218,186,47220,47193,47222,47196],{},[76,47216,78],{}," C — The bundler can't statically prove which branch runs, so it typically must include both ",[39,47219,47189],{},[39,47221,47192],{},[39,47223,46068],{},[73,47225,47226,12848,47228,47230,47231,47233,47234,47236,47237,186,47239,47241,47242,47244,47245,47247,47248,47250],{},[76,47227,84],{},[39,47229,714],{}," is an ordinary function call, a bundler generally cannot prove at build time which branch of the ",[39,47232,2179],{}," will execute (even though ",[39,47235,47106],{}," checks are common enough that some bundlers special-case and inline them via string replacement, that's a heuristic, not a language guarantee) — so worst case, both ",[39,47238,47189],{},[39,47240,47192],{}," end up bundled, bloating output. Static ESM ",[39,47243,662],{}," is explicitly disallowed inside a block like this (it must be a top-level declaration — option D is a syntax error, not a fix), so the correct ESM-world fix is dynamic ",[39,47246,46068],{},", which is a real expression usable inside conditionals and only fetches the branch actually reached at runtime. ",[76,47249,438],{}," this is a concrete, production-relevant instance of the static-vs-dynamic distinction from Q2 and Q12 — it's not just theoretical, it directly affects shipped bundle size.",[2107,47252,47253],{},"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 pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}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}",{"title":264,"searchDepth":286,"depth":286,"links":47255},[47256,47257,47258,47259,47261,47263,47264,47266,47267,47268,47269,47271,47272,47274,47276,47277,47279,47280,47282,47284],{"id":44181,"depth":296,"text":44182},{"id":44275,"depth":296,"text":44276},{"id":44341,"depth":296,"text":44342},{"id":44470,"depth":296,"text":47260},"Q4. counter.js exports a mutable binding. What does main.js log?",{"id":44648,"depth":296,"text":47262},"Q5. The equivalent scenario using CommonJS. What does main.js log?",{"id":44836,"depth":296,"text":44837},{"id":44950,"depth":296,"text":47265},"Q7. a.js and b.js import each other. Using ESM, what does running main.js log?",{"id":45189,"depth":296,"text":45190},{"id":45434,"depth":296,"text":45435},{"id":45509,"depth":296,"text":45510},{"id":45615,"depth":296,"text":47270},"Q11. A CommonJS module is imported from an ESM file in Node.js. What typically happens to module.exports?",{"id":45781,"depth":296,"text":45782},{"id":45859,"depth":296,"text":47273},"Q13. state.js is imported by both pageA.js and pageB.js. pageA.js mutates the shared state, then pageB.js reads it. What does pageB.js see?",{"id":46061,"depth":296,"text":47275},"Q14. What is the key behavioral difference between static import and dynamic import()?",{"id":46160,"depth":296,"text":46161},{"id":46373,"depth":296,"text":47278},"Q16. Which correctly re-exports add from math.js through index.js, without index.js needing a separate local binding?",{"id":46510,"depth":296,"text":46511},{"id":46731,"depth":296,"text":47281},"Q18. What does Object.keys(utils) log?",{"id":46985,"depth":296,"text":47283},"Q19. A team's codebase has some files doing import * as api from '.\u002Fapi.js' and using api.fetchUser(), api.postOrder(), etc., while other files do import { fetchUser } from '.\u002Fapi.js' for the exact same module. What's the best-practice concern here?",{"id":47078,"depth":296,"text":47285},"Q20. A large CommonJS utility library is required conditionally based on an environment check, then the app is bundled for production. What's the most accurate best-practice takeaway?",{},"\u002Fjs\u002F14-modules",{"title":44171,"description":264},"js\u002F14-modules","VXJgfzsxPej--WgdCHo0c2PeROfhYcaDVSr6kadoM60",{"id":47292,"title":47293,"body":47294,"description":264,"extension":2144,"meta":50734,"navigation":35,"path":50735,"seo":50736,"stem":50737,"__hash__":50738},"content\u002Fjs\u002F15-callbacks-and-the-event-loop.md","15 — Callbacks & the Event Loop",{"type":8,"value":47295,"toc":50704},[47296,47299,47358,47443,47602,47816,48035,48232,48382,48580,48674,48850,49056,49238,49411,49644,49809,49878,50066,50302,50408,50701],[11,47297,47293],{"id":47298},"_15-callbacks-the-event-loop",[15,47300,47301,47305,47337],{},[18,47302,47304],{"id":47303},"q1-what-does-it-actually-mean-that-javascript-is-single-threaded-in-terms-of-the-call-stack-and-the-event-loop","Q1. What does it actually mean that \"JavaScript is single-threaded,\" in terms of the call stack and the event loop?",[23,47306,47308,47314,47325,47331],{"className":47307},[26],[28,47309,47311,47313],{"className":47310},[31],[33,47312],{"disabled":35,"type":36}," JS can only execute one function at a time on its single call stack; the event loop, task queues, and the browser\u002FNode runtime's own APIs work alongside that one thread to schedule async callbacks, without ever running two pieces of JS code simultaneously",[28,47315,47317,47319,47320,99,47322],{"className":47316},[31],[33,47318],{"disabled":35,"type":36}," JS spawns a new OS thread for every async operation, such as ",[39,47321,9578],{},[39,47323,47324],{},"fetch",[28,47326,47328,47330],{"className":47327},[31],[33,47329],{"disabled":35,"type":36}," Single-threaded means JavaScript cannot use callbacks at all",[28,47332,47334,47336],{"className":47333},[31],[33,47335],{"disabled":35,"type":36}," Single-threaded only describes Node.js; browsers run JS on multiple threads",[66,47338,47339,47341,47346],{},[69,47340,71],{},[73,47342,47343,47345],{},[76,47344,78],{}," A — JS can only execute one function at a time on its single call stack; the event loop, task queues, and the browser\u002FNode runtime's own APIs work alongside that one thread to schedule async callbacks, without ever running two pieces of JS code simultaneously",[73,47347,47348,47350,47351,47354,47355,47357],{},[76,47349,84],{}," There is exactly one call stack per JS realm, and only one frame ever executes at a time. Timers, network requests, and file I\u002FO are handled by the surrounding environment (browser Web APIs, or Node's ",[39,47352,47353],{},"libuv","), which may internally use threads, but the JS callback that eventually reports the result always gets funneled back onto the single call stack, one at a time, via the event loop. Option B is a common misconception — ",[39,47356,9578],{}," itself doesn't spawn a thread for your callback; only some underlying runtime plumbing might. Option C is nonsensical. Option D is wrong — the main JS thread in a browser tab is just as single-threaded as Node's.",[15,47359,47360,47368,47405],{},[18,47361,47363,47364,47367],{"id":47362},"q2-which-of-the-following-is-classified-as-a-microtask-rather-than-a-macrotask","Q2. Which of the following is classified as a ",[76,47365,47366],{},"microtask"," rather than a macrotask?",[23,47369,47371,47379,47387,47395],{"className":47370},[26],[28,47372,47374,812,47376,47378],{"className":47373},[31],[33,47375],{"disabled":35,"type":36},[39,47377,9578],{}," callback",[28,47380,47382,812,47384,47378],{"className":47381},[31],[33,47383],{"disabled":35,"type":36},[39,47385,47386],{},"setInterval",[28,47388,47390,47392,47393,47378],{"className":47389},[31],[33,47391],{"disabled":35,"type":36}," A Promise's ",[39,47394,46149],{},[28,47396,47398,47400,47401,47404],{"className":47397},[31],[33,47399],{"disabled":35,"type":36}," A UI ",[39,47402,47403],{},"click"," event handler callback",[66,47406,47407,47409,47416],{},[69,47408,71],{},[73,47410,47411,47413,47414,47378],{},[76,47412,78],{}," C — A Promise's ",[39,47415,46149],{},[73,47417,47418,47420,47421,446,47424,446,47427,47430,47431,47434,47435,42,47437,47439,47440,47442],{},[76,47419,84],{}," The microtask queue holds promise reaction callbacks (",[39,47422,47423],{},".then",[39,47425,47426],{},".catch",[39,47428,47429],{},".finally",") and anything scheduled with ",[39,47432,47433],{},"queueMicrotask",". Timers (",[39,47436,9578],{},[39,47438,47386],{},"), I\u002FO completions, and UI events like ",[39,47441,47403],{}," are all macrotasks (sometimes just called \"tasks\"). This distinction matters because the event loop always fully drains the microtask queue between one macrotask and the next — a rule tested throughout this quiz.",[15,47444,47445,47449,47534,47569],{"language":247},[18,47446,47448],{"id":47447},"q3-what-does-this-code-log-and-in-what-order","Q3. What does this code log, and in what order?",[257,47450,47451],{"language":247},[260,47452,47454],{"className":262,"code":47453,"language":247,"meta":264,"style":264},"console.log(\"start\");\nsetTimeout(() => console.log(\"timeout\"), 0);\nPromise.resolve().then(() => console.log(\"promise\"));\nconsole.log(\"end\");\n",[39,47455,47456,47469,47492,47521],{"__ignoreMap":264},[268,47457,47458,47460,47462,47464,47467],{"class":270,"line":271},[268,47459,1353],{"class":282},[268,47461,1356],{"class":278},[268,47463,622],{"class":282},[268,47465,47466],{"class":289},"\"start\"",[268,47468,628],{"class":282},[268,47470,47471,47473,47475,47477,47479,47481,47483,47486,47488,47490],{"class":270,"line":286},[268,47472,9578],{"class":278},[268,47474,9411],{"class":282},[268,47476,9414],{"class":274},[268,47478,9417],{"class":282},[268,47480,1356],{"class":278},[268,47482,622],{"class":282},[268,47484,47485],{"class":289},"\"timeout\"",[268,47487,33111],{"class":282},[268,47489,3307],{"class":305},[268,47491,628],{"class":282},[268,47493,47494,47496,47498,47501,47503,47506,47508,47510,47512,47514,47516,47519],{"class":270,"line":296},[268,47495,91],{"class":305},[268,47497,462],{"class":282},[268,47499,47500],{"class":278},"resolve",[268,47502,19341],{"class":282},[268,47504,47505],{"class":278},"then",[268,47507,9411],{"class":282},[268,47509,9414],{"class":274},[268,47511,9417],{"class":282},[268,47513,1356],{"class":278},[268,47515,622],{"class":282},[268,47517,47518],{"class":289},"\"promise\"",[268,47520,4818],{"class":282},[268,47522,47523,47525,47527,47529,47532],{"class":270,"line":311},[268,47524,1353],{"class":282},[268,47526,1356],{"class":278},[268,47528,622],{"class":282},[268,47530,47531],{"class":289},"\"end\"",[268,47533,628],{"class":282},[23,47535,47537,47545,47553,47561],{"className":47536},[26],[28,47538,47540,355,47542],{"className":47539},[31],[33,47541],{"disabled":35,"type":36},[39,47543,47544],{},"start, promise, end, timeout",[28,47546,47548,355,47550],{"className":47547},[31],[33,47549],{"disabled":35,"type":36},[39,47551,47552],{},"start, end, timeout, promise",[28,47554,47556,355,47558],{"className":47555},[31],[33,47557],{"disabled":35,"type":36},[39,47559,47560],{},"start, promise, timeout, end",[28,47562,47564,355,47566],{"className":47563},[31],[33,47565],{"disabled":35,"type":36},[39,47567,47568],{},"start, end, promise, timeout",[66,47570,47571,47573,47579],{},[69,47572,71],{},[73,47574,47575,6901,47577],{},[76,47576,78],{},[39,47578,47568],{},[73,47580,47581,47583,47584,3493,47586,47588,47589,47591,47592,47595,47596,47598,47599,47601],{},[76,47582,84],{}," All synchronous code runs first to completion (",[39,47585,13946],{},[39,47587,13951],{},"), regardless of what async work was scheduled in between. Once the call stack is empty, the event loop drains the microtask queue completely before touching the macrotask queue, so the resolved promise's ",[39,47590,47423],{}," callback (",[39,47593,47594],{},"promise",") runs next. Only after the microtask queue is empty does the loop pick up the next macrotask, running the timeout callback (",[39,47597,7414],{},") last. Option A wrongly assumes an already-resolved promise interrupts synchronous code — it never does, ",[39,47600,47423],{}," callbacks are always deferred at least to the microtask queue. Option B reverses microtask\u002Fmacrotask priority.",[15,47603,47604,47608,47729,47764],{"language":247},[18,47605,47607],{"id":47606},"q4-what-does-this-code-log-and-in-what-order","Q4. What does this code log, and in what order?",[257,47609,47610],{"language":247},[260,47611,47613],{"className":262,"code":47612,"language":247,"meta":264,"style":264},"console.log(\"A\");\n\nsetTimeout(() => console.log(\"B\"), 0);\n\nPromise.resolve()\n  .then(() => console.log(\"C\"))\n  .then(() => console.log(\"D\"));\n\nconsole.log(\"E\");\n",[39,47614,47615,47628,47632,47654,47658,47669,47691,47712,47716],{"__ignoreMap":264},[268,47616,47617,47619,47621,47623,47626],{"class":270,"line":271},[268,47618,1353],{"class":282},[268,47620,1356],{"class":278},[268,47622,622],{"class":282},[268,47624,47625],{"class":289},"\"A\"",[268,47627,628],{"class":282},[268,47629,47630],{"class":270,"line":286},[268,47631,5033],{"emptyLinePlaceholder":35},[268,47633,47634,47636,47638,47640,47642,47644,47646,47648,47650,47652],{"class":270,"line":296},[268,47635,9578],{"class":278},[268,47637,9411],{"class":282},[268,47639,9414],{"class":274},[268,47641,9417],{"class":282},[268,47643,1356],{"class":278},[268,47645,622],{"class":282},[268,47647,26749],{"class":289},[268,47649,33111],{"class":282},[268,47651,3307],{"class":305},[268,47653,628],{"class":282},[268,47655,47656],{"class":270,"line":311},[268,47657,5033],{"emptyLinePlaceholder":35},[268,47659,47660,47662,47664,47666],{"class":270,"line":788},[268,47661,91],{"class":305},[268,47663,462],{"class":282},[268,47665,47500],{"class":278},[268,47667,47668],{"class":282},"()\n",[268,47670,47671,47673,47675,47677,47679,47681,47683,47685,47688],{"class":270,"line":1951},[268,47672,41697],{"class":282},[268,47674,47505],{"class":278},[268,47676,9411],{"class":282},[268,47678,9414],{"class":274},[268,47680,9417],{"class":282},[268,47682,1356],{"class":278},[268,47684,622],{"class":282},[268,47686,47687],{"class":289},"\"C\"",[268,47689,47690],{"class":282},"))\n",[268,47692,47693,47695,47697,47699,47701,47703,47705,47707,47710],{"class":270,"line":8955},[268,47694,41697],{"class":282},[268,47696,47505],{"class":278},[268,47698,9411],{"class":282},[268,47700,9414],{"class":274},[268,47702,9417],{"class":282},[268,47704,1356],{"class":278},[268,47706,622],{"class":282},[268,47708,47709],{"class":289},"\"D\"",[268,47711,4818],{"class":282},[268,47713,47714],{"class":270,"line":8966},[268,47715,5033],{"emptyLinePlaceholder":35},[268,47717,47718,47720,47722,47724,47727],{"class":270,"line":8974},[268,47719,1353],{"class":282},[268,47721,1356],{"class":278},[268,47723,622],{"class":282},[268,47725,47726],{"class":289},"\"E\"",[268,47728,628],{"class":282},[23,47730,47732,47740,47748,47756],{"className":47731},[26],[28,47733,47735,355,47737],{"className":47734},[31],[33,47736],{"disabled":35,"type":36},[39,47738,47739],{},"A, E, B, C, D",[28,47741,47743,355,47745],{"className":47742},[31],[33,47744],{"disabled":35,"type":36},[39,47746,47747],{},"A, E, C, D, B",[28,47749,47751,355,47753],{"className":47750},[31],[33,47752],{"disabled":35,"type":36},[39,47754,47755],{},"A, C, D, E, B",[28,47757,47759,355,47761],{"className":47758},[31],[33,47760],{"disabled":35,"type":36},[39,47762,47763],{},"A, E, C, B, D",[66,47765,47766,47768,47774],{},[69,47767,71],{},[73,47769,47770,1727,47772],{},[76,47771,78],{},[39,47773,47747],{},[73,47775,47776,355,47778,47780,47781,42,47784,47787,47788,47790,47791,47794,47795,355,47798,47800,47801,47804,47805,47808,47809,47811,47812,47815],{},[76,47777,84],{},[76,47779,365],{}," synchronous code runs first (",[39,47782,47783],{},"A",[39,47785,47786],{},"E","). The first ",[39,47789,47423],{}," then logs ",[39,47792,47793],{},"C",", and in the process of resolving it, the ",[104,47796,47797],{},"second",[39,47799,47423],{}," gets queued as a brand-new microtask — but the event loop doesn't care that it was queued \"late\"; it keeps draining the microtask queue as long as anything is in it, so ",[39,47802,47803],{},"D"," runs before the loop is even allowed to consider the next macrotask. Only once the microtask queue is truly empty does ",[39,47806,47807],{},"B"," (the timeout) finally run. Option D wrongly inserts the macrotask between the two chained ",[39,47810,47423],{}," calls, which would only happen if microtasks queued ",[104,47813,47814],{},"during"," draining were deferred to the next loop turn — they are not.",[15,47817,47818,47822,47940,47976],{"language":247},[18,47819,47821],{"id":47820},"q5-what-does-this-code-log-and-in-what-order","Q5. What does this code log, and in what order?",[257,47823,47824],{"language":247},[260,47825,47827],{"className":262,"code":47826,"language":247,"meta":264,"style":264},"function first() {\n  console.log(\"first\");\n}\nfunction second() {\n  setTimeout(() => console.log(\"second\"), 0);\n}\nfunction third() {\n  console.log(\"third\");\n}\n\nfirst();\nsecond();\nthird();\n",[39,47828,47829,47838,47851,47855,47864,47887,47891,47900,47913,47917,47921,47927,47933],{"__ignoreMap":264},[268,47830,47831,47833,47836],{"class":270,"line":271},[268,47832,275],{"class":274},[268,47834,47835],{"class":278}," first",[268,47837,283],{"class":282},[268,47839,47840,47842,47844,47846,47849],{"class":270,"line":286},[268,47841,5556],{"class":282},[268,47843,1356],{"class":278},[268,47845,622],{"class":282},[268,47847,47848],{"class":289},"\"first\"",[268,47850,628],{"class":282},[268,47852,47853],{"class":270,"line":296},[268,47854,314],{"class":282},[268,47856,47857,47859,47862],{"class":270,"line":311},[268,47858,275],{"class":274},[268,47860,47861],{"class":278}," second",[268,47863,283],{"class":282},[268,47865,47866,47868,47870,47872,47874,47876,47878,47881,47883,47885],{"class":270,"line":788},[268,47867,9408],{"class":278},[268,47869,9411],{"class":282},[268,47871,9414],{"class":274},[268,47873,9417],{"class":282},[268,47875,1356],{"class":278},[268,47877,622],{"class":282},[268,47879,47880],{"class":289},"\"second\"",[268,47882,33111],{"class":282},[268,47884,3307],{"class":305},[268,47886,628],{"class":282},[268,47888,47889],{"class":270,"line":1951},[268,47890,314],{"class":282},[268,47892,47893,47895,47898],{"class":270,"line":8955},[268,47894,275],{"class":274},[268,47896,47897],{"class":278}," third",[268,47899,283],{"class":282},[268,47901,47902,47904,47906,47908,47911],{"class":270,"line":8966},[268,47903,5556],{"class":282},[268,47905,1356],{"class":278},[268,47907,622],{"class":282},[268,47909,47910],{"class":289},"\"third\"",[268,47912,628],{"class":282},[268,47914,47915],{"class":270,"line":8974},[268,47916,314],{"class":282},[268,47918,47919],{"class":270,"line":8985},[268,47920,5033],{"emptyLinePlaceholder":35},[268,47922,47923,47925],{"class":270,"line":8990},[268,47924,12590],{"class":278},[268,47926,794],{"class":282},[268,47928,47929,47931],{"class":270,"line":8997},[268,47930,47797],{"class":278},[268,47932,794],{"class":282},[268,47934,47935,47938],{"class":270,"line":9002},[268,47936,47937],{"class":278},"third",[268,47939,794],{"class":282},[23,47941,47943,47951,47959,47967],{"className":47942},[26],[28,47944,47946,355,47948],{"className":47945},[31],[33,47947],{"disabled":35,"type":36},[39,47949,47950],{},"first, second, third",[28,47952,47954,355,47956],{"className":47953},[31],[33,47955],{"disabled":35,"type":36},[39,47957,47958],{},"second, first, third",[28,47960,47962,355,47964],{"className":47961},[31],[33,47963],{"disabled":35,"type":36},[39,47965,47966],{},"first, third, second",[28,47968,47970,355,47972,47975],{"className":47969},[31],[33,47971],{"disabled":35,"type":36},[39,47973,47974],{},"first, third",", then a thrown error",[66,47977,47978,47980,47986],{},[69,47979,71],{},[73,47981,47982,1004,47984],{},[76,47983,78],{},[39,47985,47966],{},[73,47987,47988,355,47990,30900,47992,47995,47996,47999,48000,48002,48003,48005,48006,48008,48009,42,48012,42,48014,48017,48018,3493,48020,7152,48022,48024,48025,48027,48028,48030,48031,48034],{},[76,47989,84],{},[76,47991,365],{},[39,47993,47994],{},"second()"," doesn't log anything itself — it only ",[104,47997,47998],{},"registers"," a macrotask via ",[39,48001,9578],{},"; the string ",[39,48004,47880],{}," lives inside the deferred arrow function, not in ",[39,48007,47994],{},"'s own body. So the synchronous call order (",[39,48010,48011],{},"first()",[39,48013,47994],{},[39,48015,48016],{},"third()",") produces ",[39,48019,12590],{},[39,48021,47937],{},[39,48023,47994],{}," produces no immediate output), and only after the stack is empty does the deferred callback finally run, logging ",[39,48026,47797],{}," last. The trap here is conflating \"the function named ",[39,48029,47797],{}," was called second\" with \"the value ",[39,48032,48033],{},"\\\"second\\\""," logs second\" — they're unrelated once a timer is involved.",[15,48036,48037,48041,48173,48208],{"language":247},[18,48038,48040],{"id":48039},"q6-what-does-this-code-log-and-in-what-order","Q6. What does this code log, and in what order?",[257,48042,48043],{"language":247},[260,48044,48046],{"className":262,"code":48045,"language":247,"meta":264,"style":264},"function loopMicrotasks(n) {\n  if (n \u003C= 0) return;\n  queueMicrotask(() => {\n    console.log(\"microtask\", n);\n    loopMicrotasks(n - 1);\n  });\n}\n\nconsole.log(\"sync\");\nloopMicrotasks(3);\nsetTimeout(() => console.log(\"timeout\"), 0);\n",[39,48047,48048,48061,48077,48088,48102,48115,48119,48123,48127,48140,48151],{"__ignoreMap":264},[268,48049,48050,48052,48055,48057,48059],{"class":270,"line":271},[268,48051,275],{"class":274},[268,48053,48054],{"class":278}," loopMicrotasks",[268,48056,622],{"class":282},[268,48058,4599],{"class":1222},[268,48060,1235],{"class":282},[268,48062,48063,48065,48067,48069,48071,48073,48075],{"class":270,"line":286},[268,48064,9863],{"class":274},[268,48066,13562],{"class":282},[268,48068,6776],{"class":274},[268,48070,5728],{"class":305},[268,48072,6131],{"class":282},[268,48074,9151],{"class":274},[268,48076,293],{"class":282},[268,48078,48079,48082,48084,48086],{"class":270,"line":296},[268,48080,48081],{"class":278},"  queueMicrotask",[268,48083,9411],{"class":282},[268,48085,9414],{"class":274},[268,48087,9914],{"class":282},[268,48089,48090,48092,48094,48096,48099],{"class":270,"line":311},[268,48091,9707],{"class":282},[268,48093,1356],{"class":278},[268,48095,622],{"class":282},[268,48097,48098],{"class":289},"\"microtask\"",[268,48100,48101],{"class":282},", n);\n",[268,48103,48104,48107,48109,48111,48113],{"class":270,"line":788},[268,48105,48106],{"class":278},"    loopMicrotasks",[268,48108,13376],{"class":282},[268,48110,6244],{"class":274},[268,48112,2199],{"class":305},[268,48114,628],{"class":282},[268,48116,48117],{"class":270,"line":1951},[268,48118,39914],{"class":282},[268,48120,48121],{"class":270,"line":8955},[268,48122,314],{"class":282},[268,48124,48125],{"class":270,"line":8966},[268,48126,5033],{"emptyLinePlaceholder":35},[268,48128,48129,48131,48133,48135,48138],{"class":270,"line":8974},[268,48130,1353],{"class":282},[268,48132,1356],{"class":278},[268,48134,622],{"class":282},[268,48136,48137],{"class":289},"\"sync\"",[268,48139,628],{"class":282},[268,48141,48142,48145,48147,48149],{"class":270,"line":8985},[268,48143,48144],{"class":278},"loopMicrotasks",[268,48146,622],{"class":282},[268,48148,3423],{"class":305},[268,48150,628],{"class":282},[268,48152,48153,48155,48157,48159,48161,48163,48165,48167,48169,48171],{"class":270,"line":8990},[268,48154,9578],{"class":278},[268,48156,9411],{"class":282},[268,48158,9414],{"class":274},[268,48160,9417],{"class":282},[268,48162,1356],{"class":278},[268,48164,622],{"class":282},[268,48166,47485],{"class":289},[268,48168,33111],{"class":282},[268,48170,3307],{"class":305},[268,48172,628],{"class":282},[23,48174,48176,48184,48192,48200],{"className":48175},[26],[28,48177,48179,355,48181],{"className":48178},[31],[33,48180],{"disabled":35,"type":36},[39,48182,48183],{},"sync, microtask 3, microtask 2, microtask 1, timeout",[28,48185,48187,355,48189],{"className":48186},[31],[33,48188],{"disabled":35,"type":36},[39,48190,48191],{},"sync, timeout, microtask 3, microtask 2, microtask 1",[28,48193,48195,355,48197],{"className":48194},[31],[33,48196],{"disabled":35,"type":36},[39,48198,48199],{},"sync, microtask 3, timeout, microtask 2, microtask 1",[28,48201,48203,355,48205],{"className":48202},[31],[33,48204],{"disabled":35,"type":36},[39,48206,48207],{},"timeout, sync, microtask 3, microtask 2, microtask 1",[66,48209,48210,48212,48218],{},[69,48211,71],{},[73,48213,48214,3459,48216],{},[76,48215,78],{},[39,48217,48183],{},[73,48219,48220,355,48222,48224,48225,48228,48229,48231],{},[76,48221,84],{},[76,48223,438],{}," each queued microtask here schedules ",[104,48226,48227],{},"another"," microtask before returning, and the spec says the event loop keeps processing the microtask queue until it is completely empty — including microtasks added while draining — before it's allowed to move to the next macrotask. So all three self-chaining microtasks run back-to-back, and only then does the ",[39,48230,7414],{}," macrotask get a turn. This is the mechanism behind a real production hazard: a runaway chain of self-queuing microtasks (or promises) can starve macrotasks — including timers and even browser rendering — indefinitely, since the loop never \"gets around\" to them while microtasks keep refilling the queue.",[15,48233,48234,48238,48333,48360],{"language":247},[18,48235,48237],{"id":48236},"q7-setting-aside-whether-it-works-what-is-the-primary-maintainability-problem-with-this-pattern","Q7. Setting aside whether it works, what is the primary maintainability problem with this pattern?",[257,48239,48240],{"language":247},[260,48241,48243],{"className":262,"code":48242,"language":247,"meta":264,"style":264},"getUser(id, (err, user) => {\n  getPosts(user.id, (err, posts) => {\n    getComments(posts[0].id, (err, comments) => {\n      render(user, posts, comments);\n    });\n  });\n});\n",[39,48244,48245,48266,48287,48313,48321,48325,48329],{"__ignoreMap":264},[268,48246,48247,48250,48253,48256,48258,48260,48262,48264],{"class":270,"line":271},[268,48248,48249],{"class":278},"getUser",[268,48251,48252],{"class":282},"(id, (",[268,48254,48255],{"class":1222},"err",[268,48257,42],{"class":282},[268,48259,4155],{"class":1222},[268,48261,6131],{"class":282},[268,48263,9414],{"class":274},[268,48265,9914],{"class":282},[268,48267,48268,48271,48274,48276,48278,48281,48283,48285],{"class":270,"line":286},[268,48269,48270],{"class":278},"  getPosts",[268,48272,48273],{"class":282},"(user.id, (",[268,48275,48255],{"class":1222},[268,48277,42],{"class":282},[268,48279,48280],{"class":1222},"posts",[268,48282,6131],{"class":282},[268,48284,9414],{"class":274},[268,48286,9914],{"class":282},[268,48288,48289,48292,48295,48297,48300,48302,48304,48307,48309,48311],{"class":270,"line":296},[268,48290,48291],{"class":278},"    getComments",[268,48293,48294],{"class":282},"(posts[",[268,48296,3307],{"class":305},[268,48298,48299],{"class":282},"].id, (",[268,48301,48255],{"class":1222},[268,48303,42],{"class":282},[268,48305,48306],{"class":1222},"comments",[268,48308,6131],{"class":282},[268,48310,9414],{"class":274},[268,48312,9914],{"class":282},[268,48314,48315,48318],{"class":270,"line":311},[268,48316,48317],{"class":278},"      render",[268,48319,48320],{"class":282},"(user, posts, comments);\n",[268,48322,48323],{"class":270,"line":788},[268,48324,35432],{"class":282},[268,48326,48327],{"class":270,"line":1951},[268,48328,39914],{"class":282},[268,48330,48331],{"class":270,"line":8955},[268,48332,20047],{"class":282},[23,48334,48336,48342,48348,48354],{"className":48335},[26],[28,48337,48339,48341],{"className":48338},[31],[33,48340],{"disabled":35,"type":36}," It runs slower than equivalent synchronous code",[28,48343,48345,48347],{"className":48344},[31],[33,48346],{"disabled":35,"type":36}," JavaScript enforces a maximum callback nesting depth of 3",[28,48349,48351,48353],{"className":48350},[31],[33,48352],{"disabled":35,"type":36}," Nested callbacks cannot access variables from outer scopes",[28,48355,48357,48359],{"className":48356},[31],[33,48358],{"disabled":35,"type":36}," Each nested callback adds indentation and couples unrelated steps into one deeply nested closure, making the code hard to read, test, or modify in isolation — the classic \"pyramid of doom\"",[66,48361,48362,48364,48369],{},[69,48363,71],{},[73,48365,48366,48368],{},[76,48367,78],{}," D — Each nested callback adds indentation and couples unrelated steps into one deeply nested closure, making the code hard to read, test, or modify in isolation — the classic \"pyramid of doom\"",[73,48370,48371,48373,48374,48376,48377,186,48379,48381],{},[76,48372,84],{}," This is a structural readability problem, not a functional or performance one: every step is defined inline inside the previous step's callback, so the logic marches rightward and none of the steps can be tested, named, or reused independently. Option B invents a nonexistent engine limit — nesting can go arbitrarily deep (until you run out of patience or screen width). Option C is backwards — nested callbacks ",[104,48375,11176],{}," close over outer-scope variables (that's exactly how ",[39,48378,4155],{},[39,48380,48280],{}," stay accessible inward), which is what makes this pattern work at all, just not cleanly. Option A is unrelated; this code's async cost is the same regardless of nesting style.",[15,48383,48384,48388,48531,48558],{"language":247},[18,48385,48387],{"id":48386},"q8-compared-to-the-deeply-nested-version-in-q7-what-does-refactoring-into-named-top-level-functions-actually-fix","Q8. Compared to the deeply nested version in Q7, what does refactoring into named top-level functions actually fix?",[257,48389,48390],{"language":247},[260,48391,48393],{"className":262,"code":48392,"language":247,"meta":264,"style":264},"function onComments(err, comments) {\n  if (err) return handleError(err);\n  render(comments);\n}\nfunction onPosts(err, posts) {\n  if (err) return handleError(err);\n  getComments(posts[0].id, onComments);\n}\nfunction onUser(err, user) {\n  if (err) return handleError(err);\n  getPosts(user.id, onPosts);\n}\ngetUser(id, onUser);\n",[39,48394,48395,48412,48427,48435,48439,48456,48468,48480,48484,48501,48513,48520,48524],{"__ignoreMap":264},[268,48396,48397,48399,48402,48404,48406,48408,48410],{"class":270,"line":271},[268,48398,275],{"class":274},[268,48400,48401],{"class":278}," onComments",[268,48403,622],{"class":282},[268,48405,48255],{"class":1222},[268,48407,42],{"class":282},[268,48409,48306],{"class":1222},[268,48411,1235],{"class":282},[268,48413,48414,48416,48419,48421,48424],{"class":270,"line":286},[268,48415,9863],{"class":274},[268,48417,48418],{"class":282}," (err) ",[268,48420,9151],{"class":274},[268,48422,48423],{"class":278}," handleError",[268,48425,48426],{"class":282},"(err);\n",[268,48428,48429,48432],{"class":270,"line":296},[268,48430,48431],{"class":278},"  render",[268,48433,48434],{"class":282},"(comments);\n",[268,48436,48437],{"class":270,"line":311},[268,48438,314],{"class":282},[268,48440,48441,48443,48446,48448,48450,48452,48454],{"class":270,"line":788},[268,48442,275],{"class":274},[268,48444,48445],{"class":278}," onPosts",[268,48447,622],{"class":282},[268,48449,48255],{"class":1222},[268,48451,42],{"class":282},[268,48453,48280],{"class":1222},[268,48455,1235],{"class":282},[268,48457,48458,48460,48462,48464,48466],{"class":270,"line":1951},[268,48459,9863],{"class":274},[268,48461,48418],{"class":282},[268,48463,9151],{"class":274},[268,48465,48423],{"class":278},[268,48467,48426],{"class":282},[268,48469,48470,48473,48475,48477],{"class":270,"line":8955},[268,48471,48472],{"class":278},"  getComments",[268,48474,48294],{"class":282},[268,48476,3307],{"class":305},[268,48478,48479],{"class":282},"].id, onComments);\n",[268,48481,48482],{"class":270,"line":8966},[268,48483,314],{"class":282},[268,48485,48486,48488,48491,48493,48495,48497,48499],{"class":270,"line":8974},[268,48487,275],{"class":274},[268,48489,48490],{"class":278}," onUser",[268,48492,622],{"class":282},[268,48494,48255],{"class":1222},[268,48496,42],{"class":282},[268,48498,4155],{"class":1222},[268,48500,1235],{"class":282},[268,48502,48503,48505,48507,48509,48511],{"class":270,"line":8985},[268,48504,9863],{"class":274},[268,48506,48418],{"class":282},[268,48508,9151],{"class":274},[268,48510,48423],{"class":278},[268,48512,48426],{"class":282},[268,48514,48515,48517],{"class":270,"line":8990},[268,48516,48270],{"class":278},[268,48518,48519],{"class":282},"(user.id, onPosts);\n",[268,48521,48522],{"class":270,"line":8997},[268,48523,314],{"class":282},[268,48525,48526,48528],{"class":270,"line":9002},[268,48527,48249],{"class":278},[268,48529,48530],{"class":282},"(id, onUser);\n",[23,48532,48534,48540,48546,48552],{"className":48533},[26],[28,48535,48537,48539],{"className":48536},[31],[33,48538],{"disabled":35,"type":36}," It makes the code run synchronously instead of asynchronously",[28,48541,48543,48545],{"className":48542},[31],[33,48544],{"disabled":35,"type":36}," It flattens the visual nesting, gives each step a name, and lets each step be tested independently — but the underlying callback-based control flow (and its complexity) is otherwise unchanged",[28,48547,48549,48551],{"className":48548},[31],[33,48550],{"disabled":35,"type":36}," It converts the callbacks into Promises automatically",[28,48553,48555,48557],{"className":48554},[31],[33,48556],{"disabled":35,"type":36}," It eliminates the need for error handling entirely",[66,48559,48560,48562,48567],{},[69,48561,71],{},[73,48563,48564,48566],{},[76,48565,78],{}," B — It flattens the visual nesting, gives each step a name, and lets each step be tested independently — but the underlying callback-based control flow (and its complexity) is otherwise unchanged",[73,48568,48569,355,48571,48573,48574,48576,48577,48579],{},[76,48570,84],{},[76,48572,930],{}," naming each step as a top-level function is a genuine readability win over Q7's pyramid — each function can be reasoned about, unit-tested, and reused on its own — but it's a purely structural fix. Execution order, the error-first convention (checking ",[39,48575,48255],{}," at every single step, as this snippet still does), and the overall async wiring are identical to the nested version. Option D is contradicted by the code itself, which explicitly checks ",[39,48578,48255],{}," at every level. Option C is false — nothing here touches Promises; that's a separate refactor covered in the next quiz. Option A is false — none of this changes sync\u002Fasync timing.",[15,48581,48582,48590,48626],{},[18,48583,48585,48586,48589],{"id":48584},"q9-in-nodejs-style-apis-like-fsreadfilepath-err-data-what-does-the-error-first-callback-convention-actually-mean","Q9. In Node.js-style APIs like ",[39,48587,48588],{},"fs.readFile(path, (err, data) => {...})",", what does the \"error-first callback\" convention actually mean?",[23,48591,48593,48608,48614,48620],{"className":48592},[26],[28,48594,48596,48598,48599,48602,48603,446,48605,48607],{"className":48595},[31],[33,48597],{"disabled":35,"type":36}," The callback's first parameter is reserved for an ",[39,48600,48601],{},"Error"," object (or ",[39,48604,2650],{},[39,48606,833],{}," on success), and callers must check it before trusting later parameters — this is a community convention, not something the language enforces",[28,48609,48611,48613],{"className":48610},[31],[33,48612],{"disabled":35,"type":36}," The callback function must be declared before any other code in the file",[28,48615,48617,48619],{"className":48616},[31],[33,48618],{"disabled":35,"type":36}," Errors are automatically thrown first, before the callback ever runs",[28,48621,48623,48625],{"className":48622},[31],[33,48624],{"disabled":35,"type":36}," The first argument is always a plain string describing the error message",[66,48627,48628,48630,48641],{},[69,48629,71],{},[73,48631,48632,48634,48635,48602,48637,446,48639,48607],{},[76,48633,78],{}," A — The callback's first parameter is reserved for an ",[39,48636,48601],{},[39,48638,2650],{},[39,48640,833],{},[73,48642,48643,355,48645,48647,48648,48651,48652,48654,48655,48657,48658,48660,48661,48663,48664,48666,48667,48669,48670,48673],{},[76,48644,84],{},[76,48646,930],{}," popularized by early Node.js core APIs, ",[39,48649,48650],{},"callback(err, result)"," puts the error (or ",[39,48653,2650],{}," when there isn't one) in a fixed, predictable position. JavaScript itself does nothing to enforce this — a careless caller who forgets to check ",[39,48656,48255],{}," first will happily read ",[39,48659,5631],{}," even when it's ",[39,48662,833],{}," or garbage, which is a frequent real-world bug source. Option D is wrong because ",[39,48665,48255],{}," is conventionally an ",[39,48668,48601],{}," instance (with a ",[39,48671,48672],{},".message"," property), not a bare string. Options B and C describe behavior nothing in the convention or the language actually provides.",[15,48675,48676,48678,48766,48806],{"language":247},[18,48677,27954],{"id":27953},[257,48679,48680],{"language":247},[260,48681,48683],{"className":262,"code":48682,"language":247,"meta":264,"style":264},"try {\n  setTimeout(() => {\n    throw new Error(\"boom\");\n  }, 0);\n} catch (e) {\n  console.log(\"caught:\", e.message);\n}\nconsole.log(\"after try\u002Fcatch\");\n",[39,48684,48685,48691,48701,48717,48726,48735,48749,48753],{"__ignoreMap":264},[268,48686,48687,48689],{"class":270,"line":271},[268,48688,23142],{"class":274},[268,48690,9914],{"class":282},[268,48692,48693,48695,48697,48699],{"class":270,"line":286},[268,48694,9408],{"class":278},[268,48696,9411],{"class":282},[268,48698,9414],{"class":274},[268,48700,9914],{"class":282},[268,48702,48703,48706,48708,48710,48712,48715],{"class":270,"line":296},[268,48704,48705],{"class":274},"    throw",[268,48707,11370],{"class":274},[268,48709,11593],{"class":278},[268,48711,622],{"class":282},[268,48713,48714],{"class":289},"\"boom\"",[268,48716,628],{"class":282},[268,48718,48719,48722,48724],{"class":270,"line":311},[268,48720,48721],{"class":282},"  }, ",[268,48723,3307],{"class":305},[268,48725,628],{"class":282},[268,48727,48728,48730,48732],{"class":270,"line":788},[268,48729,11235],{"class":282},[268,48731,12488],{"class":274},[268,48733,48734],{"class":282}," (e) {\n",[268,48736,48737,48739,48741,48743,48746],{"class":270,"line":1951},[268,48738,5556],{"class":282},[268,48740,1356],{"class":278},[268,48742,622],{"class":282},[268,48744,48745],{"class":289},"\"caught:\"",[268,48747,48748],{"class":282},", e.message);\n",[268,48750,48751],{"class":270,"line":8955},[268,48752,314],{"class":282},[268,48754,48755,48757,48759,48761,48764],{"class":270,"line":8966},[268,48756,1353],{"class":282},[268,48758,1356],{"class":278},[268,48760,622],{"class":282},[268,48762,48763],{"class":289},"\"after try\u002Fcatch\"",[268,48765,628],{"class":282},[23,48767,48769,48780,48786,48795],{"className":48768},[26],[28,48770,48772,3578,48774,1133,48777],{"className":48771},[31],[33,48773],{"disabled":35,"type":36},[39,48775,48776],{},"caught: boom",[39,48778,48779],{},"after try\u002Fcatch",[28,48781,48783,48785],{"className":48782},[31],[33,48784],{"disabled":35,"type":36}," Nothing logs at all; the error is silently swallowed",[28,48787,48789,48791,48792,48794],{"className":48788},[31],[33,48790],{"disabled":35,"type":36}," The program crashes immediately at the ",[39,48793,9578],{}," line, before anything logs",[28,48796,48798,3578,48800,48802,48803,48805],{"className":48797},[31],[33,48799],{"disabled":35,"type":36},[39,48801,48779],{},", and then the thrown error surfaces as an unhandled exception, because the callback runs in a separate macrotask turn, on a stack that no longer has the original ",[39,48804,23142],{}," block active",[66,48807,48808,48810,48819],{},[69,48809,71],{},[73,48811,48812,48814,48815,48802,48817,48805],{},[76,48813,78],{}," D — Logs ",[39,48816,48779],{},[39,48818,23142],{},[73,48820,48821,355,48823,355,48825,48827,48828,48830,48831,48833,48834,48837,48838,355,48840,48843,48844,48846,48847,48849],{},[76,48822,84],{},[76,48824,365],{},[39,48826,2081],{}," only guards the code actively on the call stack while it's executing. By the time the ",[39,48829,9578],{}," callback finally runs — a fresh call stack, in a later macrotask — the original ",[39,48832,23142],{}," frame is long gone, so the ",[39,48835,48836],{},"throw"," propagates as an uncaught exception (visible as an unhandled error in the console, or a crash in Node without a global handler) rather than being caught. This is one of the most common async beginner traps. The fix is to put ",[39,48839,2081],{},[104,48841,48842],{},"inside"," the callback itself, or to prefer error-first callbacks \u002F promise rejections over ",[39,48845,48836],{}," in async code. Option A is the tempting-but-wrong assumption that a surrounding ",[39,48848,2081],{}," reaches into deferred callbacks.",[15,48851,48852,48856,48974,49009],{"language":247},[18,48853,48855],{"id":48854},"q11-in-nodejs-what-does-this-code-log-and-in-what-order","Q11. In Node.js, what does this code log, and in what order?",[257,48857,48858],{"language":247},[260,48859,48861],{"className":262,"code":48860,"language":247,"meta":264,"style":264},"console.log(\"start\");\n\nsetTimeout(() => console.log(\"timeout\"), 0);\n\nPromise.resolve().then(() => console.log(\"promise\"));\n\nprocess.nextTick(() => console.log(\"nextTick\"));\n\nconsole.log(\"end\");\n",[39,48862,48863,48875,48879,48901,48905,48931,48935,48958,48962],{"__ignoreMap":264},[268,48864,48865,48867,48869,48871,48873],{"class":270,"line":271},[268,48866,1353],{"class":282},[268,48868,1356],{"class":278},[268,48870,622],{"class":282},[268,48872,47466],{"class":289},[268,48874,628],{"class":282},[268,48876,48877],{"class":270,"line":286},[268,48878,5033],{"emptyLinePlaceholder":35},[268,48880,48881,48883,48885,48887,48889,48891,48893,48895,48897,48899],{"class":270,"line":296},[268,48882,9578],{"class":278},[268,48884,9411],{"class":282},[268,48886,9414],{"class":274},[268,48888,9417],{"class":282},[268,48890,1356],{"class":278},[268,48892,622],{"class":282},[268,48894,47485],{"class":289},[268,48896,33111],{"class":282},[268,48898,3307],{"class":305},[268,48900,628],{"class":282},[268,48902,48903],{"class":270,"line":311},[268,48904,5033],{"emptyLinePlaceholder":35},[268,48906,48907,48909,48911,48913,48915,48917,48919,48921,48923,48925,48927,48929],{"class":270,"line":788},[268,48908,91],{"class":305},[268,48910,462],{"class":282},[268,48912,47500],{"class":278},[268,48914,19341],{"class":282},[268,48916,47505],{"class":278},[268,48918,9411],{"class":282},[268,48920,9414],{"class":274},[268,48922,9417],{"class":282},[268,48924,1356],{"class":278},[268,48926,622],{"class":282},[268,48928,47518],{"class":289},[268,48930,4818],{"class":282},[268,48932,48933],{"class":270,"line":1951},[268,48934,5033],{"emptyLinePlaceholder":35},[268,48936,48937,48940,48943,48945,48947,48949,48951,48953,48956],{"class":270,"line":8955},[268,48938,48939],{"class":282},"process.",[268,48941,48942],{"class":278},"nextTick",[268,48944,9411],{"class":282},[268,48946,9414],{"class":274},[268,48948,9417],{"class":282},[268,48950,1356],{"class":278},[268,48952,622],{"class":282},[268,48954,48955],{"class":289},"\"nextTick\"",[268,48957,4818],{"class":282},[268,48959,48960],{"class":270,"line":8966},[268,48961,5033],{"emptyLinePlaceholder":35},[268,48963,48964,48966,48968,48970,48972],{"class":270,"line":8974},[268,48965,1353],{"class":282},[268,48967,1356],{"class":278},[268,48969,622],{"class":282},[268,48971,47531],{"class":289},[268,48973,628],{"class":282},[23,48975,48977,48985,48993,49001],{"className":48976},[26],[28,48978,48980,355,48982],{"className":48979},[31],[33,48981],{"disabled":35,"type":36},[39,48983,48984],{},"start, end, promise, nextTick, timeout",[28,48986,48988,355,48990],{"className":48987},[31],[33,48989],{"disabled":35,"type":36},[39,48991,48992],{},"start, nextTick, end, promise, timeout",[28,48994,48996,355,48998],{"className":48995},[31],[33,48997],{"disabled":35,"type":36},[39,48999,49000],{},"start, end, nextTick, promise, timeout",[28,49002,49004,355,49006],{"className":49003},[31],[33,49005],{"disabled":35,"type":36},[39,49007,49008],{},"start, end, timeout, nextTick, promise",[66,49010,49011,49013,49019],{},[69,49012,71],{},[73,49014,49015,1004,49017],{},[76,49016,78],{},[39,49018,49000],{},[73,49020,49021,355,49023,49025,49026,42,49028,49030,49031,49034,49035,49037,49038,49040,49041,49043,49044,49046,49047,49049,49050,49052,49053,49055],{},[76,49022,84],{},[76,49024,182],{}," synchronous code always runs first (",[39,49027,13946],{},[39,49029,13951],{},"). Node.js gives ",[39,49032,49033],{},"process.nextTick"," callbacks an even higher priority than the standard microtask (promise) queue — Node fully drains the ",[39,49036,48942],{}," queue before it drains promise microtasks, at the end of every phase. So ",[39,49039,48942],{}," logs before ",[39,49042,47594],{},", and only after both queues are empty does the ",[39,49045,7414],{}," macrotask run. This is explicitly a Node-specific, non-standard behavior — there is no ",[39,49048,49033],{}," in browsers, and code that needs a portable \"run this as soon as possible, before other microtasks\" primitive should generally reach for ",[39,49051,47433],{}," instead, which behaves consistently across environments (though still after ",[39,49054,48942],{}," in Node).",[15,49057,49058,49066,49170,49206],{"language":247},[18,49059,49061,49062,49065],{"id":49060},"q12-given-that-the-busy-wait-loop-below-takes-roughly-3-full-seconds-to-finish-when-does-timeout-fired-actually-log-relative-to-the-requested-100ms-delay","Q12. Given that the busy-wait loop below takes roughly 3 full seconds to finish, when does ",[39,49063,49064],{},"\"timeout fired\""," actually log, relative to the requested 100ms delay?",[257,49067,49068],{"language":247},[260,49069,49071],{"className":262,"code":49070,"language":247,"meta":264,"style":264},"console.log(\"start\");\nsetTimeout(() => console.log(\"timeout fired\"), 100);\n\nconst end = Date.now() + 3000;\nwhile (Date.now() \u003C end) {} \u002F\u002F busy-wait for ~3 seconds\n\nconsole.log(\"loop done\");\n",[39,49072,49073,49085,49107,49111,49134,49153,49157],{"__ignoreMap":264},[268,49074,49075,49077,49079,49081,49083],{"class":270,"line":271},[268,49076,1353],{"class":282},[268,49078,1356],{"class":278},[268,49080,622],{"class":282},[268,49082,47466],{"class":289},[268,49084,628],{"class":282},[268,49086,49087,49089,49091,49093,49095,49097,49099,49101,49103,49105],{"class":270,"line":286},[268,49088,9578],{"class":278},[268,49090,9411],{"class":282},[268,49092,9414],{"class":274},[268,49094,9417],{"class":282},[268,49096,1356],{"class":278},[268,49098,622],{"class":282},[268,49100,49064],{"class":289},[268,49102,33111],{"class":282},[268,49104,13912],{"class":305},[268,49106,628],{"class":282},[268,49108,49109],{"class":270,"line":296},[268,49110,5033],{"emptyLinePlaceholder":35},[268,49112,49113,49115,49118,49120,49123,49126,49128,49130,49132],{"class":270,"line":311},[268,49114,243],{"class":274},[268,49116,49117],{"class":305}," end",[268,49119,616],{"class":274},[268,49121,49122],{"class":282}," Date.",[268,49124,49125],{"class":278},"now",[268,49127,16182],{"class":282},[268,49129,1246],{"class":274},[268,49131,7358],{"class":305},[268,49133,293],{"class":282},[268,49135,49136,49138,49141,49143,49145,49147,49150],{"class":270,"line":788},[268,49137,11160],{"class":274},[268,49139,49140],{"class":282}," (Date.",[268,49142,49125],{"class":278},[268,49144,16182],{"class":282},[268,49146,1076],{"class":274},[268,49148,49149],{"class":282}," end) {} ",[268,49151,49152],{"class":29390},"\u002F\u002F busy-wait for ~3 seconds\n",[268,49154,49155],{"class":270,"line":1951},[268,49156,5033],{"emptyLinePlaceholder":35},[268,49158,49159,49161,49163,49165,49168],{"class":270,"line":8955},[268,49160,1353],{"class":282},[268,49162,1356],{"class":278},[268,49164,622],{"class":282},[268,49166,49167],{"class":289},"\"loop done\"",[268,49169,628],{"class":282},[23,49171,49173,49182,49191,49200],{"className":49172},[26],[28,49174,49176,49178,49179,49181],{"className":49175},[31],[33,49177],{"disabled":35,"type":36}," Exactly 100ms after ",[39,49180,13946],{},", on a separate thread, unaffected by the loop",[28,49183,49185,49187,49188,49190],{"className":49184},[31],[33,49186],{"disabled":35,"type":36}," Only after the ~3-second loop finishes and ",[39,49189,49167],{}," logs — the timer became \"due\" around 100ms in, but its callback can't run until the call stack is empty",[28,49192,49194,49196,49197,49199],{"className":49193},[31],[33,49195],{"disabled":35,"type":36}," Immediately after ",[39,49198,13946],{},", before the loop even begins",[28,49201,49203,49205],{"className":49202},[31],[33,49204],{"disabled":35,"type":36}," Never — the busy-wait permanently cancels any pending timers",[66,49207,49208,49210,49217],{},[69,49209,71],{},[73,49211,49212,49214,49215,49190],{},[76,49213,78],{}," B — Only after the ~3-second loop finishes and ",[39,49216,49167],{},[73,49218,49219,355,49221,21599,49223,49226,49227,49230,49231,49233,49234,49237],{},[76,49220,84],{},[76,49222,438],{},[39,49224,49225],{},"100ms"," delay only controls when the callback becomes ",[104,49228,49229],{},"eligible"," to move from the macrotask queue onto the call stack — it says nothing about the stack actually being free at that moment. Since JS is single-threaded (Q1), the synchronous ",[39,49232,11160],{}," loop occupies the only stack there is for the full 3 seconds, so even though the timer is \"ready\" after 100ms, the event loop has nowhere to run it until the loop finally releases the stack. This is the sharpest version of \"delay is a minimum, not a guarantee\": a blocked stack delays every queued callback, including timers that expired long ago. Option A invents a separate thread for the callback itself, which doesn't exist — only the ",[104,49235,49236],{},"waiting"," happens off-thread, not the callback execution.",[15,49239,49240,49248,49349,49387],{"language":247},[18,49241,49243,49244,49247],{"id":49242},"q13-what-is-the-concrete-risk-in-how-loaddata-is-written-here-given-that-a-callbacks-contract-should-specify-how-many-times-it-can-be-invoked","Q13. What is the concrete risk in how ",[39,49245,49246],{},"loadData"," is written here, given that a callback's contract should specify how many times it can be invoked?",[257,49249,49250],{"language":247},[260,49251,49253],{"className":262,"code":49252,"language":247,"meta":264,"style":264},"function loadData(callback) {\n  fetchFromCache((err, cached) => {\n    if (cached) callback(null, cached);\n  });\n  fetchFromNetwork((err, fresh) => {\n    callback(null, fresh);\n  });\n}\n",[39,49254,49255,49269,49289,49305,49309,49329,49341,49345],{"__ignoreMap":264},[268,49256,49257,49259,49262,49264,49267],{"class":270,"line":271},[268,49258,275],{"class":274},[268,49260,49261],{"class":278}," loadData",[268,49263,622],{"class":282},[268,49265,49266],{"class":1222},"callback",[268,49268,1235],{"class":282},[268,49270,49271,49274,49276,49278,49280,49283,49285,49287],{"class":270,"line":286},[268,49272,49273],{"class":278},"  fetchFromCache",[268,49275,6122],{"class":282},[268,49277,48255],{"class":1222},[268,49279,42],{"class":282},[268,49281,49282],{"class":1222},"cached",[268,49284,6131],{"class":282},[268,49286,9414],{"class":274},[268,49288,9914],{"class":282},[268,49290,49291,49293,49296,49298,49300,49302],{"class":270,"line":296},[268,49292,9686],{"class":274},[268,49294,49295],{"class":282}," (cached) ",[268,49297,49266],{"class":278},[268,49299,622],{"class":282},[268,49301,2650],{"class":305},[268,49303,49304],{"class":282},", cached);\n",[268,49306,49307],{"class":270,"line":311},[268,49308,39914],{"class":282},[268,49310,49311,49314,49316,49318,49320,49323,49325,49327],{"class":270,"line":788},[268,49312,49313],{"class":278},"  fetchFromNetwork",[268,49315,6122],{"class":282},[268,49317,48255],{"class":1222},[268,49319,42],{"class":282},[268,49321,49322],{"class":1222},"fresh",[268,49324,6131],{"class":282},[268,49326,9414],{"class":274},[268,49328,9914],{"class":282},[268,49330,49331,49334,49336,49338],{"class":270,"line":1951},[268,49332,49333],{"class":278},"    callback",[268,49335,622],{"class":282},[268,49337,2650],{"class":305},[268,49339,49340],{"class":282},", fresh);\n",[268,49342,49343],{"class":270,"line":8955},[268,49344,39914],{"class":282},[268,49346,49347],{"class":270,"line":8966},[268,49348,314],{"class":282},[23,49350,49352,49361,49370,49381],{"className":49351},[26],[28,49353,49355,49357,49358,49360],{"className":49354},[31],[33,49356],{"disabled":35,"type":36}," If both the cache lookup and the network fetch succeed, ",[39,49359,49266],{}," runs twice — once with cached data, once with fresh data — which can cause consumers to double-render UI, double-submit data, or throw if they assumed single-invocation semantics",[28,49362,49364,49366,49367,49369],{"className":49363},[31],[33,49365],{"disabled":35,"type":36}," It's guaranteed to call ",[39,49368,49266],{}," exactly once, because JavaScript functions can only be invoked once per registration",[28,49371,49373,49375,49376,2833,49378,49380],{"className":49372},[31],[33,49374],{"disabled":35,"type":36}," This code throws a ",[39,49377,1274],{},[39,49379,49266],{}," is referenced in two separate places",[28,49382,49384,49386],{"className":49383},[31],[33,49385],{"disabled":35,"type":36}," Only the network fetch's callback actually runs; the cache branch is unreachable dead code",[66,49388,49389,49391,49398],{},[69,49390,71],{},[73,49392,49393,49395,49396,49360],{},[76,49394,78],{}," A — If both the cache lookup and the network fetch succeed, ",[39,49397,49266],{},[73,49399,49400,355,49402,49404,49405,49407,49408,49410],{},[76,49401,84],{},[76,49403,365],{}," nothing in JavaScript stops a captured function reference from being called any number of times — each independent async operation here holds its own reference to ",[39,49406,49266],{}," and will invoke it on completion regardless of what the other one does. If both succeed, ",[39,49409,49266],{}," fires twice with two different results, which is a genuine, common bug: consumers that assume \"called once\" (a common implicit assumption for callback-based APIs) may double-render, double-submit, or crash on the second call. Fixing it requires an explicit guard (a \"already called\" flag, unregistering after the first call, or restructuring so only one source can win). Option B states an invented guarantee JS does not provide.",[15,49412,49413,49417,49565,49600],{"language":247},[18,49414,49416],{"id":49415},"q14-what-does-this-code-log-and-in-what-order","Q14. What does this code log, and in what order?",[257,49418,49419],{"language":247},[260,49420,49422],{"className":262,"code":49421,"language":247,"meta":264,"style":264},"console.log(1);\n\nsetTimeout(() => console.log(2), 0);\nsetTimeout(() => console.log(3), 0);\n\nPromise.resolve().then(() => {\n  console.log(4);\n  Promise.resolve().then(() => console.log(5));\n});\n\nconsole.log(6);\n",[39,49423,49424,49436,49440,49462,49484,49488,49506,49518,49545,49549,49553],{"__ignoreMap":264},[268,49425,49426,49428,49430,49432,49434],{"class":270,"line":271},[268,49427,1353],{"class":282},[268,49429,1356],{"class":278},[268,49431,622],{"class":282},[268,49433,2255],{"class":305},[268,49435,628],{"class":282},[268,49437,49438],{"class":270,"line":286},[268,49439,5033],{"emptyLinePlaceholder":35},[268,49441,49442,49444,49446,49448,49450,49452,49454,49456,49458,49460],{"class":270,"line":296},[268,49443,9578],{"class":278},[268,49445,9411],{"class":282},[268,49447,9414],{"class":274},[268,49449,9417],{"class":282},[268,49451,1356],{"class":278},[268,49453,622],{"class":282},[268,49455,2258],{"class":305},[268,49457,33111],{"class":282},[268,49459,3307],{"class":305},[268,49461,628],{"class":282},[268,49463,49464,49466,49468,49470,49472,49474,49476,49478,49480,49482],{"class":270,"line":311},[268,49465,9578],{"class":278},[268,49467,9411],{"class":282},[268,49469,9414],{"class":274},[268,49471,9417],{"class":282},[268,49473,1356],{"class":278},[268,49475,622],{"class":282},[268,49477,3423],{"class":305},[268,49479,33111],{"class":282},[268,49481,3307],{"class":305},[268,49483,628],{"class":282},[268,49485,49486],{"class":270,"line":788},[268,49487,5033],{"emptyLinePlaceholder":35},[268,49489,49490,49492,49494,49496,49498,49500,49502,49504],{"class":270,"line":1951},[268,49491,91],{"class":305},[268,49493,462],{"class":282},[268,49495,47500],{"class":278},[268,49497,19341],{"class":282},[268,49499,47505],{"class":278},[268,49501,9411],{"class":282},[268,49503,9414],{"class":274},[268,49505,9914],{"class":282},[268,49507,49508,49510,49512,49514,49516],{"class":270,"line":8955},[268,49509,5556],{"class":282},[268,49511,1356],{"class":278},[268,49513,622],{"class":282},[268,49515,15049],{"class":305},[268,49517,628],{"class":282},[268,49519,49520,49523,49525,49527,49529,49531,49533,49535,49537,49539,49541,49543],{"class":270,"line":8966},[268,49521,49522],{"class":305},"  Promise",[268,49524,462],{"class":282},[268,49526,47500],{"class":278},[268,49528,19341],{"class":282},[268,49530,47505],{"class":278},[268,49532,9411],{"class":282},[268,49534,9414],{"class":274},[268,49536,9417],{"class":282},[268,49538,1356],{"class":278},[268,49540,622],{"class":282},[268,49542,2429],{"class":305},[268,49544,4818],{"class":282},[268,49546,49547],{"class":270,"line":8974},[268,49548,20047],{"class":282},[268,49550,49551],{"class":270,"line":8985},[268,49552,5033],{"emptyLinePlaceholder":35},[268,49554,49555,49557,49559,49561,49563],{"class":270,"line":8990},[268,49556,1353],{"class":282},[268,49558,1356],{"class":278},[268,49560,622],{"class":282},[268,49562,13663],{"class":305},[268,49564,628],{"class":282},[23,49566,49568,49576,49584,49592],{"className":49567},[26],[28,49569,49571,355,49573],{"className":49570},[31],[33,49572],{"disabled":35,"type":36},[39,49574,49575],{},"1, 6, 4, 2, 5, 3",[28,49577,49579,355,49581],{"className":49578},[31],[33,49580],{"disabled":35,"type":36},[39,49582,49583],{},"1, 4, 5, 6, 2, 3",[28,49585,49587,355,49589],{"className":49586},[31],[33,49588],{"disabled":35,"type":36},[39,49590,49591],{},"1, 6, 2, 3, 4, 5",[28,49593,49595,355,49597],{"className":49594},[31],[33,49596],{"disabled":35,"type":36},[39,49598,49599],{},"1, 6, 4, 5, 2, 3",[66,49601,49602,49604,49610],{},[69,49603,71],{},[73,49605,49606,6901,49608],{},[76,49607,78],{},[39,49609,49599],{},[73,49611,49612,49614,49615,42,49617,49619,49620,2269,49622,49624,49625,49627,49628,49630,49631,49633,49634,3493,49636,49638,49639,186,49641,49643],{},[76,49613,84],{}," Synchronous code runs first: ",[39,49616,2255],{},[39,49618,13663],{},". The microtask queue then runs: the first ",[39,49621,47423],{},[39,49623,15049],{}," and, while executing, schedules a nested ",[39,49626,47423],{}," — which joins the ",[104,49629,22779],{}," still-draining microtask queue and therefore still runs before any macrotask, logging ",[39,49632,2429],{},". Only once the microtask queue is completely empty does the event loop move to the two queued timeouts, running them in the order they were queued (",[39,49635,2258],{},[39,49637,3423],{},", since equal 0ms delays preserve FIFO order). Option A wrongly slots a macrotask between ",[39,49640,15049],{},[39,49642,2429],{},". Option C wrongly runs both macrotasks before any microtask.",[15,49645,49646,49650,49739,49773],{"language":247},[18,49647,49649],{"id":49648},"q15-what-does-this-code-log-and-in-what-order","Q15. What does this code log, and in what order?",[257,49651,49652],{"language":247},[260,49653,49655],{"className":262,"code":49654,"language":247,"meta":264,"style":264},"console.log(\"A\");\nqueueMicrotask(() => console.log(\"B\"));\nsetTimeout(() => console.log(\"C\"), 0);\nqueueMicrotask(() => console.log(\"D\"));\nconsole.log(\"E\");\n",[39,49656,49657,49669,49687,49709,49727],{"__ignoreMap":264},[268,49658,49659,49661,49663,49665,49667],{"class":270,"line":271},[268,49660,1353],{"class":282},[268,49662,1356],{"class":278},[268,49664,622],{"class":282},[268,49666,47625],{"class":289},[268,49668,628],{"class":282},[268,49670,49671,49673,49675,49677,49679,49681,49683,49685],{"class":270,"line":286},[268,49672,47433],{"class":278},[268,49674,9411],{"class":282},[268,49676,9414],{"class":274},[268,49678,9417],{"class":282},[268,49680,1356],{"class":278},[268,49682,622],{"class":282},[268,49684,26749],{"class":289},[268,49686,4818],{"class":282},[268,49688,49689,49691,49693,49695,49697,49699,49701,49703,49705,49707],{"class":270,"line":296},[268,49690,9578],{"class":278},[268,49692,9411],{"class":282},[268,49694,9414],{"class":274},[268,49696,9417],{"class":282},[268,49698,1356],{"class":278},[268,49700,622],{"class":282},[268,49702,47687],{"class":289},[268,49704,33111],{"class":282},[268,49706,3307],{"class":305},[268,49708,628],{"class":282},[268,49710,49711,49713,49715,49717,49719,49721,49723,49725],{"class":270,"line":311},[268,49712,47433],{"class":278},[268,49714,9411],{"class":282},[268,49716,9414],{"class":274},[268,49718,9417],{"class":282},[268,49720,1356],{"class":278},[268,49722,622],{"class":282},[268,49724,47709],{"class":289},[268,49726,4818],{"class":282},[268,49728,49729,49731,49733,49735,49737],{"class":270,"line":788},[268,49730,1353],{"class":282},[268,49732,1356],{"class":278},[268,49734,622],{"class":282},[268,49736,47726],{"class":289},[268,49738,628],{"class":282},[23,49740,49742,49750,49758,49766],{"className":49741},[26],[28,49743,49745,355,49747],{"className":49744},[31],[33,49746],{"disabled":35,"type":36},[39,49748,49749],{},"A, B, D, E, C",[28,49751,49753,355,49755],{"className":49752},[31],[33,49754],{"disabled":35,"type":36},[39,49756,49757],{},"A, B, E, D, C",[28,49759,49761,355,49763],{"className":49760},[31],[33,49762],{"disabled":35,"type":36},[39,49764,49765],{},"A, E, B, D, C",[28,49767,49769,355,49771],{"className":49768},[31],[33,49770],{"disabled":35,"type":36},[39,49772,47763],{},[66,49774,49775,49777,49783],{},[69,49776,71],{},[73,49778,49779,1004,49781],{},[76,49780,78],{},[39,49782,49765],{},[73,49784,49785,355,49787,49789,49790,49792,49793,42,49795,49797,49798,42,49800,49802,49803,49805,49806,49808],{},[76,49786,84],{},[39,49788,47433],{}," schedules its callback on the exact same priority tier as promise ",[39,49791,47423],{}," callbacks — it runs after all synchronous code finishes, in the order the microtasks were queued, and always before the next macrotask. So the synchronous log lines finish first (",[39,49794,47783],{},[39,49796,47786],{},"), then the two microtasks run in FIFO order (",[39,49799,47807],{},[39,49801,47803],{},"), and only then does the timeout macrotask fire (",[39,49804,47793],{},"). Options A and B both interleave a microtask before synchronous code (",[39,49807,47786],{},") has finished, which never happens — synchronous execution always runs to completion first.",[15,49810,49811,49819,49850],{},[18,49812,49814,49815,446,49817,8691],{"id":49813},"q16-for-sequencing-several-dependent-async-steps-fetch-a-user-then-their-posts-then-comments-on-the-first-post-why-do-modern-codebases-generally-avoid-deeply-nested-callbacks-in-favor-of-promise-chains-or-asyncawait","Q16. For sequencing several dependent async steps (fetch a user, then their posts, then comments on the first post), why do modern codebases generally avoid deeply nested callbacks in favor of promise chains (or ",[39,49816,379],{},[39,49818,12304],{},[23,49820,49822,49832,49838,49844],{"className":49821},[26],[28,49823,49825,49827,49828,49831],{"className":49824},[31],[33,49826],{"disabled":35,"type":36}," Promise-based sequencing flattens the code into a linear chain, and centralizes error handling — a single rejection can propagate through the whole chain — removing the pyramid-of-doom indentation and the per-step ",[39,49829,49830],{},"if (err) return handleError(err)"," boilerplate that manual callbacks require",[28,49833,49835,49837],{"className":49834},[31],[33,49836],{"disabled":35,"type":36}," Callbacks are deprecated and no longer supported in modern JS engines",[28,49839,49841,49843],{"className":49840},[31],[33,49842],{"disabled":35,"type":36}," Promises execute synchronously, bypassing the event loop entirely, which makes them inherently faster",[28,49845,49847,49849],{"className":49846},[31],[33,49848],{"disabled":35,"type":36}," Callbacks cannot access outer-scope variables, so promises are required for closures to work",[66,49851,49852,49854,49861],{},[69,49853,71],{},[73,49855,49856,49858,49859,49831],{},[76,49857,78],{}," A — Promise-based sequencing flattens the code into a linear chain, and centralizes error handling — a single rejection can propagate through the whole chain — removing the pyramid-of-doom indentation and the per-step ",[39,49860,49830],{},[73,49862,49863,355,49865,49867,49868,49870,49871,49874,49875,49877],{},[76,49864,84],{},[76,49866,930],{}," the win is structural, not about raw speed or capability — promises are, under the hood, still built on callbacks and the microtask queue (Q2), so option C's \"bypasses the event loop\" claim is false. Option D is also false; callbacks close over outer scope perfectly well, which is precisely what made the nested pattern in Q7 possible in the first place. Option B is false — callbacks remain foundational and are not deprecated. The genuine benefit, covered in depth in the next quiz on Promises, is that ",[39,49869,46149],{}," chains read top-to-bottom instead of nesting rightward, and a single trailing ",[39,49872,49873],{},".catch()"," can handle rejection from any step in the chain instead of requiring a manual ",[39,49876,48255],{}," check at every level.",[15,49879,49880,49889,49992,50039],{"language":247},[18,49881,49883,49884,186,49886,49888],{"id":49882},"q17-the-loop-below-takes-roughly-200ms-to-finish-synchronously-given-that-in-what-order-do-a-and-b-log-and-why","Q17. The loop below takes roughly 200ms to finish synchronously. Given that, in what order do ",[39,49885,47625],{},[39,49887,26749],{}," log, and why?",[257,49890,49891],{"language":247},[260,49892,49894],{"className":262,"code":49893,"language":247,"meta":264,"style":264},"setTimeout(() => console.log(\"A\"), 50);\nsetTimeout(() => console.log(\"B\"), 10);\n\nfor (let i = 0; i \u003C 1_000_000_000; i++) {} \u002F\u002F ~200ms of synchronous work\n\nconsole.log(\"done looping\");\n",[39,49895,49896,49918,49940,49944,49975,49979],{"__ignoreMap":264},[268,49897,49898,49900,49902,49904,49906,49908,49910,49912,49914,49916],{"class":270,"line":271},[268,49899,9578],{"class":278},[268,49901,9411],{"class":282},[268,49903,9414],{"class":274},[268,49905,9417],{"class":282},[268,49907,1356],{"class":278},[268,49909,622],{"class":282},[268,49911,47625],{"class":289},[268,49913,33111],{"class":282},[268,49915,32109],{"class":305},[268,49917,628],{"class":282},[268,49919,49920,49922,49924,49926,49928,49930,49932,49934,49936,49938],{"class":270,"line":286},[268,49921,9578],{"class":278},[268,49923,9411],{"class":282},[268,49925,9414],{"class":274},[268,49927,9417],{"class":282},[268,49929,1356],{"class":278},[268,49931,622],{"class":282},[268,49933,26749],{"class":289},[268,49935,33111],{"class":282},[268,49937,5825],{"class":305},[268,49939,628],{"class":282},[268,49941,49942],{"class":270,"line":296},[268,49943,5033],{"emptyLinePlaceholder":35},[268,49945,49946,49948,49950,49952,49954,49956,49958,49960,49962,49965,49967,49969,49972],{"class":270,"line":311},[268,49947,6926],{"class":274},[268,49949,2182],{"class":282},[268,49951,240],{"class":274},[268,49953,9384],{"class":282},[268,49955,302],{"class":274},[268,49957,5728],{"class":305},[268,49959,9391],{"class":282},[268,49961,1076],{"class":274},[268,49963,49964],{"class":305}," 1_000_000_000",[268,49966,9398],{"class":282},[268,49968,9401],{"class":274},[268,49970,49971],{"class":282},") {} ",[268,49973,49974],{"class":29390},"\u002F\u002F ~200ms of synchronous work\n",[268,49976,49977],{"class":270,"line":788},[268,49978,5033],{"emptyLinePlaceholder":35},[268,49980,49981,49983,49985,49987,49990],{"class":270,"line":1951},[268,49982,1353],{"class":282},[268,49984,1356],{"class":278},[268,49986,622],{"class":282},[268,49988,49989],{"class":289},"\"done looping\"",[268,49991,628],{"class":282},[23,49993,49995,50005,50017,50023],{"className":49994},[26],[28,49996,49998,355,50000,3493,50002,50004],{"className":49997},[31],[33,49999],{"disabled":35,"type":36},[39,50001,47783],{},[39,50003,47807],{}," — later-registered timers always run first",[28,50006,50008,50010,50011,50013,50014,50016],{"className":50007},[31],[33,50009],{"disabled":35,"type":36}," Only ",[39,50012,47783],{}," fires; ",[39,50015,47807],{},"'s shorter delay means it gets discarded as \"missed\"",[28,50018,50020,50022],{"className":50019},[31],[33,50021],{"disabled":35,"type":36}," They fire at the exact same moment, since both delays elapsed during the loop",[28,50024,50026,355,50028,3493,50030,50032,50033,50035,50036,50038],{"className":50025},[31],[33,50027],{"disabled":35,"type":36},[39,50029,47807],{},[39,50031,47783],{}," — both delays have long since elapsed by the time the loop finishes, so both callbacks are already queued, in the order their delays expired (",[39,50034,47807],{},"'s 10ms elapsed before ",[39,50037,47783],{},"'s 50ms)",[66,50040,50041,50043,50055],{},[69,50042,71],{},[73,50044,50045,6901,50047,3493,50049,50032,50051,50035,50053,50038],{},[76,50046,78],{},[39,50048,47807],{},[39,50050,47783],{},[39,50052,47807],{},[39,50054,47783],{},[73,50056,50057,50059,50060,50062,50063,50065],{},[76,50058,84],{}," As established in Q12, a busy synchronous loop blocks the stack for its entire duration regardless of what timers become \"due\" in the meantime. By the time the ~200ms loop finally releases the stack, both the 10ms and 50ms timers are well overdue and sitting in the macrotask queue, ordered by when each became eligible — ",[39,50061,47807],{}," (10ms) became due before ",[39,50064,47783],{}," (50ms), so it's queued first and runs first. Option A wrongly uses source-order registration as the tiebreaker instead of elapsed-delay order. Option C is impossible — the event loop only ever runs one macrotask at a time. Option B fabricates a \"missed timer\" behavior that doesn't exist; a late timer still fires, just later than requested.",[15,50067,50068,50076,50212,50247],{"language":247},[18,50069,50071,50072,50075],{"id":50070},"q18-what-does-this-code-log-and-specifically-where-does-executor-appear-in-the-output","Q18. What does this code log, and specifically, where does ",[39,50073,50074],{},"\"executor\""," appear in the output?",[257,50077,50078],{"language":247},[260,50079,50081],{"className":262,"code":50080,"language":247,"meta":264,"style":264},"setTimeout(() => console.log(\"timeout 1\"), 0);\n\nnew Promise((resolve) => {\n  console.log(\"executor\");\n  resolve();\n}).then(() => console.log(\"then 1\"));\n\nsetTimeout(() => console.log(\"timeout 2\"), 0);\n\nconsole.log(\"sync end\");\n",[39,50082,50083,50106,50110,50127,50139,50146,50168,50172,50195,50199],{"__ignoreMap":264},[268,50084,50085,50087,50089,50091,50093,50095,50097,50100,50102,50104],{"class":270,"line":271},[268,50086,9578],{"class":278},[268,50088,9411],{"class":282},[268,50090,9414],{"class":274},[268,50092,9417],{"class":282},[268,50094,1356],{"class":278},[268,50096,622],{"class":282},[268,50098,50099],{"class":289},"\"timeout 1\"",[268,50101,33111],{"class":282},[268,50103,3307],{"class":305},[268,50105,628],{"class":282},[268,50107,50108],{"class":270,"line":286},[268,50109,5033],{"emptyLinePlaceholder":35},[268,50111,50112,50114,50117,50119,50121,50123,50125],{"class":270,"line":296},[268,50113,2689],{"class":274},[268,50115,50116],{"class":305}," Promise",[268,50118,6122],{"class":282},[268,50120,47500],{"class":1222},[268,50122,6131],{"class":282},[268,50124,9414],{"class":274},[268,50126,9914],{"class":282},[268,50128,50129,50131,50133,50135,50137],{"class":270,"line":311},[268,50130,5556],{"class":282},[268,50132,1356],{"class":278},[268,50134,622],{"class":282},[268,50136,50074],{"class":289},[268,50138,628],{"class":282},[268,50140,50141,50144],{"class":270,"line":788},[268,50142,50143],{"class":278},"  resolve",[268,50145,794],{"class":282},[268,50147,50148,50151,50153,50155,50157,50159,50161,50163,50166],{"class":270,"line":1951},[268,50149,50150],{"class":282},"}).",[268,50152,47505],{"class":278},[268,50154,9411],{"class":282},[268,50156,9414],{"class":274},[268,50158,9417],{"class":282},[268,50160,1356],{"class":278},[268,50162,622],{"class":282},[268,50164,50165],{"class":289},"\"then 1\"",[268,50167,4818],{"class":282},[268,50169,50170],{"class":270,"line":8955},[268,50171,5033],{"emptyLinePlaceholder":35},[268,50173,50174,50176,50178,50180,50182,50184,50186,50189,50191,50193],{"class":270,"line":8966},[268,50175,9578],{"class":278},[268,50177,9411],{"class":282},[268,50179,9414],{"class":274},[268,50181,9417],{"class":282},[268,50183,1356],{"class":278},[268,50185,622],{"class":282},[268,50187,50188],{"class":289},"\"timeout 2\"",[268,50190,33111],{"class":282},[268,50192,3307],{"class":305},[268,50194,628],{"class":282},[268,50196,50197],{"class":270,"line":8974},[268,50198,5033],{"emptyLinePlaceholder":35},[268,50200,50201,50203,50205,50207,50210],{"class":270,"line":8985},[268,50202,1353],{"class":282},[268,50204,1356],{"class":278},[268,50206,622],{"class":282},[268,50208,50209],{"class":289},"\"sync end\"",[268,50211,628],{"class":282},[23,50213,50215,50223,50231,50239],{"className":50214},[26],[28,50216,50218,355,50220],{"className":50217},[31],[33,50219],{"disabled":35,"type":36},[39,50221,50222],{},"sync end, executor, then 1, timeout 1, timeout 2",[28,50224,50226,355,50228],{"className":50225},[31],[33,50227],{"disabled":35,"type":36},[39,50229,50230],{},"executor, sync end, then 1, timeout 1, timeout 2",[28,50232,50234,355,50236],{"className":50233},[31],[33,50235],{"disabled":35,"type":36},[39,50237,50238],{},"executor, then 1, sync end, timeout 1, timeout 2",[28,50240,50242,355,50244],{"className":50241},[31],[33,50243],{"disabled":35,"type":36},[39,50245,50246],{},"timeout 1, timeout 2, executor, sync end, then 1",[66,50248,50249,50251,50257],{},[69,50250,71],{},[73,50252,50253,1727,50255],{},[76,50254,78],{},[39,50256,50230],{},[73,50258,50259,355,50261,50263,50264,50267,50268,50271,50272,50274,50275,50277,50278,50280,50281,50283,50284,50287,50288,50290,50291,50293,50294,50296,50297,446,50299,50301],{},[76,50260,84],{},[76,50262,365],{}," the function passed to ",[39,50265,50266],{},"new Promise(...)"," — the \"executor\" — runs ",[76,50269,50270],{},"synchronously and immediately"," the moment the constructor is called; it is not deferred at all. So ",[39,50273,50074],{}," logs right where the ",[39,50276,50266],{}," line sits in the normal synchronous flow, before ",[39,50279,50209],{},". Only the ",[39,50282,46149],{}," reaction is deferred, to the microtask queue, running after all synchronous code (",[39,50285,50286],{},"then 1","), and the two ",[39,50289,9578],{}," callbacks run last, in registration order. The common misconception (option A) treats everything inside ",[39,50292,50266],{}," as automatically async — it isn't; only the resolution ",[104,50295,39644],{}," attached via ",[39,50298,47423],{},[39,50300,47426],{}," get queued.",[15,50303,50304,50323,50366],{},[18,50305,50307,50308,50311,50312,50315,50316,50319,50320,50322],{"id":50306},"q19-a-codebases-saveuseruser-cb-internally-calls-three-callback-based-apis-in-sequence-each-depending-on-the-previous-result-a-teammate-proposes-wrapping-only-the-outermost-call-to-saveuser-in-a-trycatch-to-handle-errors-from-the-whole-chain-why-is-this-unsound-given-the-error-first-callback-convention-from-q9","Q19. A codebase's ",[39,50309,50310],{},"saveUser(user, cb)"," internally calls three callback-based APIs in sequence, each depending on the previous result. A teammate proposes wrapping only the ",[104,50313,50314],{},"outermost"," call to ",[39,50317,50318],{},"saveUser"," in a ",[39,50321,2081],{}," to handle errors from the whole chain. Why is this unsound, given the error-first callback convention from Q9?",[23,50324,50326,50335,50343,50357],{"className":50325},[26],[28,50327,50329,50331,50332,50334],{"className":50328},[31],[33,50330],{"disabled":35,"type":36}," It's a fine approach — ",[39,50333,2081],{}," works identically across synchronous and asynchronous code in JavaScript",[28,50336,50338,355,50340,50342],{"className":50337},[31],[33,50339],{"disabled":35,"type":36},[39,50341,2081],{}," is unnecessary here, because callback-based code never fails",[28,50344,50346,50348,50349,50351,50352,50354,50355],{"className":50345},[31],[33,50347],{"disabled":35,"type":36}," Errors from callback-based async APIs are delivered (by convention) as the ",[39,50350,48255],{}," argument to each individual callback, not thrown onto the call stack that made the initiating call — a surrounding ",[39,50353,2081],{}," cannot intercept them, so each nested callback must check its own ",[39,50356,48255],{},[28,50358,50360,50362,50363,50365],{"className":50359},[31],[33,50361],{"disabled":35,"type":36}," The outer ",[39,50364,2081],{}," will catch errors from the first callback only, not the second or third",[66,50367,50368,50370,50381],{},[69,50369,71],{},[73,50371,50372,50374,50375,50351,50377,50354,50379],{},[76,50373,78],{}," C — Errors from callback-based async APIs are delivered (by convention) as the ",[39,50376,48255],{},[39,50378,2081],{},[39,50380,48255],{},[73,50382,50383,50385,50386,50388,50389,50391,50392,50394,50395,50397,50398,50401,50402,50404,50405,50407],{},[76,50384,84],{}," This is Q10's lesson applied at the API-design level: each nested async step runs in its own later callback invocation, on a call stack that no longer has the outer ",[39,50387,23142],{}," frame active, so wrapping the initiating call provides zero protection for errors surfaced via the ",[39,50390,48255],{},"-first convention — every single callback has to check its own ",[39,50393,48255],{}," and explicitly handle or forward it. Option D sounds like reasonable partial credit but is still wrong — the outer ",[39,50396,2081],{}," catches ",[104,50399,50400],{},"none"," of the async errors, not just the later ones. This exact pain point — manually re-checking ",[39,50403,48255],{}," at every level with no way to centralize it — is one of the strongest motivations for the promise-based ",[39,50406,49873],{}," model covered starting in the next quiz.",[15,50409,50410,50414,50596,50631],{"language":247},[18,50411,50413],{"id":50412},"q20-what-does-this-code-log-and-in-what-order","Q20. What does this code log, and in what order?",[257,50415,50416],{"language":247},[260,50417,50419],{"className":262,"code":50418,"language":247,"meta":264,"style":264},"console.log(\"1\");\n\nsetTimeout(() => {\n  console.log(\"2\");\n  Promise.resolve().then(() => console.log(\"3\"));\n}, 0);\n\nPromise.resolve().then(() => {\n  console.log(\"4\");\n  setTimeout(() => console.log(\"5\"), 0);\n});\n\nqueueMicrotask(() => console.log(\"6\"));\n\nconsole.log(\"7\");\n",[39,50420,50421,50433,50437,50447,50459,50486,50495,50499,50517,50530,50552,50556,50560,50579,50583],{"__ignoreMap":264},[268,50422,50423,50425,50427,50429,50431],{"class":270,"line":271},[268,50424,1353],{"class":282},[268,50426,1356],{"class":278},[268,50428,622],{"class":282},[268,50430,3387],{"class":289},[268,50432,628],{"class":282},[268,50434,50435],{"class":270,"line":286},[268,50436,5033],{"emptyLinePlaceholder":35},[268,50438,50439,50441,50443,50445],{"class":270,"line":296},[268,50440,9578],{"class":278},[268,50442,9411],{"class":282},[268,50444,9414],{"class":274},[268,50446,9914],{"class":282},[268,50448,50449,50451,50453,50455,50457],{"class":270,"line":311},[268,50450,5556],{"class":282},[268,50452,1356],{"class":278},[268,50454,622],{"class":282},[268,50456,9269],{"class":289},[268,50458,628],{"class":282},[268,50460,50461,50463,50465,50467,50469,50471,50473,50475,50477,50479,50481,50484],{"class":270,"line":788},[268,50462,49522],{"class":305},[268,50464,462],{"class":282},[268,50466,47500],{"class":278},[268,50468,19341],{"class":282},[268,50470,47505],{"class":278},[268,50472,9411],{"class":282},[268,50474,9414],{"class":274},[268,50476,9417],{"class":282},[268,50478,1356],{"class":278},[268,50480,622],{"class":282},[268,50482,50483],{"class":289},"\"3\"",[268,50485,4818],{"class":282},[268,50487,50488,50491,50493],{"class":270,"line":1951},[268,50489,50490],{"class":282},"}, ",[268,50492,3307],{"class":305},[268,50494,628],{"class":282},[268,50496,50497],{"class":270,"line":8955},[268,50498,5033],{"emptyLinePlaceholder":35},[268,50500,50501,50503,50505,50507,50509,50511,50513,50515],{"class":270,"line":8966},[268,50502,91],{"class":305},[268,50504,462],{"class":282},[268,50506,47500],{"class":278},[268,50508,19341],{"class":282},[268,50510,47505],{"class":278},[268,50512,9411],{"class":282},[268,50514,9414],{"class":274},[268,50516,9914],{"class":282},[268,50518,50519,50521,50523,50525,50528],{"class":270,"line":8974},[268,50520,5556],{"class":282},[268,50522,1356],{"class":278},[268,50524,622],{"class":282},[268,50526,50527],{"class":289},"\"4\"",[268,50529,628],{"class":282},[268,50531,50532,50534,50536,50538,50540,50542,50544,50546,50548,50550],{"class":270,"line":8985},[268,50533,9408],{"class":278},[268,50535,9411],{"class":282},[268,50537,9414],{"class":274},[268,50539,9417],{"class":282},[268,50541,1356],{"class":278},[268,50543,622],{"class":282},[268,50545,3162],{"class":289},[268,50547,33111],{"class":282},[268,50549,3307],{"class":305},[268,50551,628],{"class":282},[268,50553,50554],{"class":270,"line":8990},[268,50555,20047],{"class":282},[268,50557,50558],{"class":270,"line":8997},[268,50559,5033],{"emptyLinePlaceholder":35},[268,50561,50562,50564,50566,50568,50570,50572,50574,50577],{"class":270,"line":9002},[268,50563,47433],{"class":278},[268,50565,9411],{"class":282},[268,50567,9414],{"class":274},[268,50569,9417],{"class":282},[268,50571,1356],{"class":278},[268,50573,622],{"class":282},[268,50575,50576],{"class":289},"\"6\"",[268,50578,4818],{"class":282},[268,50580,50581],{"class":270,"line":14676},[268,50582,5033],{"emptyLinePlaceholder":35},[268,50584,50585,50587,50589,50591,50594],{"class":270,"line":14681},[268,50586,1353],{"class":282},[268,50588,1356],{"class":278},[268,50590,622],{"class":282},[268,50592,50593],{"class":289},"\"7\"",[268,50595,628],{"class":282},[23,50597,50599,50607,50615,50623],{"className":50598},[26],[28,50600,50602,355,50604],{"className":50601},[31],[33,50603],{"disabled":35,"type":36},[39,50605,50606],{},"1, 7, 4, 6, 2, 5, 3",[28,50608,50610,355,50612],{"className":50609},[31],[33,50611],{"disabled":35,"type":36},[39,50613,50614],{},"1, 7, 4, 6, 2, 3, 5",[28,50616,50618,355,50620],{"className":50617},[31],[33,50619],{"disabled":35,"type":36},[39,50621,50622],{},"1, 4, 6, 7, 2, 3, 5",[28,50624,50626,355,50628],{"className":50625},[31],[33,50627],{"disabled":35,"type":36},[39,50629,50630],{},"1, 7, 6, 4, 2, 3, 5",[66,50632,50633,50635,50641],{},[69,50634,71],{},[73,50636,50637,1727,50639],{},[76,50638,78],{},[39,50640,50614],{},[73,50642,50643,355,50645,50647,50648,42,50650,50652,50653,50655,50656,50659,50660,50662,50663,50665,50666,50669,50670,50673,50674,50676,50677,50679,50680,50682,50683,50685,50686,50688,50689,50691,50692,50694,50695,50697,50698,50700],{},[76,50644,84],{},[76,50646,365],{}," synchronous code runs first: ",[39,50649,2255],{},[39,50651,26963],{},". That leaves two macrotasks queued (the first ",[39,50654,9578],{},", and — later — one more once it's created) and two microtasks queued, in this order: the ",[39,50657,50658],{},"Promise.resolve().then(...)"," handler, then the ",[39,50661,47433],{}," callback. Draining the microtask queue: the promise handler logs ",[39,50664,15049],{}," and, inside it, calls ",[39,50667,50668],{},"setTimeout(...)"," — this only registers a ",[104,50671,50672],{},"new macrotask",", it does not add anything to the microtask queue — so draining continues to the ",[39,50675,47433],{}," callback, logging ",[39,50678,13663],{},". With microtasks now empty, the event loop runs the oldest queued macrotask (the original timeout): it logs ",[39,50681,2258],{},", then schedules a fresh ",[39,50684,50658],{},", which becomes a new microtask — and since microtasks are drained fully before the ",[104,50687,16949],{}," macrotask, ",[39,50690,3423],{}," logs immediately after ",[39,50693,2258],{},". Only then does the loop reach the second macrotask (queued during step ",[39,50696,15049],{},"), logging ",[39,50699,2429],{}," last. Options A and D each misplace one step by forgetting that microtasks queued mid-macrotask still drain before the following macrotask.",[2107,50702,50703],{},"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 pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}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 .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}",{"title":264,"searchDepth":286,"depth":286,"links":50705},[50706,50707,50709,50710,50711,50712,50713,50714,50715,50717,50718,50719,50721,50723,50724,50725,50727,50729,50731,50733],{"id":47303,"depth":296,"text":47304},{"id":47362,"depth":296,"text":50708},"Q2. Which of the following is classified as a microtask rather than a macrotask?",{"id":47447,"depth":296,"text":47448},{"id":47606,"depth":296,"text":47607},{"id":47820,"depth":296,"text":47821},{"id":48039,"depth":296,"text":48040},{"id":48236,"depth":296,"text":48237},{"id":48386,"depth":296,"text":48387},{"id":48584,"depth":296,"text":50716},"Q9. In Node.js-style APIs like fs.readFile(path, (err, data) => {...}), what does the \"error-first callback\" convention actually mean?",{"id":27953,"depth":296,"text":27954},{"id":48854,"depth":296,"text":48855},{"id":49060,"depth":296,"text":50720},"Q12. Given that the busy-wait loop below takes roughly 3 full seconds to finish, when does \"timeout fired\" actually log, relative to the requested 100ms delay?",{"id":49242,"depth":296,"text":50722},"Q13. What is the concrete risk in how loadData is written here, given that a callback's contract should specify how many times it can be invoked?",{"id":49415,"depth":296,"text":49416},{"id":49648,"depth":296,"text":49649},{"id":49813,"depth":296,"text":50726},"Q16. For sequencing several dependent async steps (fetch a user, then their posts, then comments on the first post), why do modern codebases generally avoid deeply nested callbacks in favor of promise chains (or async\u002Fawait)?",{"id":49882,"depth":296,"text":50728},"Q17. The loop below takes roughly 200ms to finish synchronously. Given that, in what order do \"A\" and \"B\" log, and why?",{"id":50070,"depth":296,"text":50730},"Q18. What does this code log, and specifically, where does \"executor\" appear in the output?",{"id":50306,"depth":296,"text":50732},"Q19. A codebase's saveUser(user, cb) internally calls three callback-based APIs in sequence, each depending on the previous result. A teammate proposes wrapping only the outermost call to saveUser in a try\u002Fcatch to handle errors from the whole chain. Why is this unsound, given the error-first callback convention from Q9?",{"id":50412,"depth":296,"text":50413},{},"\u002Fjs\u002F15-callbacks-and-the-event-loop",{"title":47293,"description":264},"js\u002F15-callbacks-and-the-event-loop","sGzht3JTRsfTbqt0vL2uCwIZ9hux6V5YWIX4xJQhUKA",{"id":50740,"title":50741,"body":50742,"description":264,"extension":2144,"meta":54511,"navigation":35,"path":54512,"seo":54513,"stem":54514,"__hash__":54515},"content\u002Fjs\u002F16-promises.md","16 — Promises",{"type":8,"value":50743,"toc":54487},[50744,50747,50806,50963,51096,51320,51531,51695,51878,52064,52207,52481,52634,52905,53165,53368,53499,53677,53840,54033,54198,54484],[11,50745,50741],{"id":50746},"_16-promises",[15,50748,50749,50753,50780],{"language":247},[18,50750,50752],{"id":50751},"q1-what-are-the-three-states-a-promise-can-be-in","Q1. What are the three states a Promise can be in?",[23,50754,50756,50762,50768,50774],{"className":50755},[26],[28,50757,50759,50761],{"className":50758},[31],[33,50760],{"disabled":35,"type":36}," waiting, resolved, errored",[28,50763,50765,50767],{"className":50764},[31],[33,50766],{"disabled":35,"type":36}," pending, fulfilled, rejected",[28,50769,50771,50773],{"className":50770},[31],[33,50772],{"disabled":35,"type":36}," created, running, finished",[28,50775,50777,50779],{"className":50776},[31],[33,50778],{"disabled":35,"type":36}," idle, loading, settled",[66,50781,50782,50784,50789],{},[69,50783,71],{},[73,50785,50786,50788],{},[76,50787,78],{}," B — pending, fulfilled, rejected",[73,50790,50791,50793,50794,50797,50798,50801,50802,50805],{},[76,50792,84],{}," Every Promise starts in the ",[76,50795,50796],{},"pending"," state, then transitions exactly once to either ",[76,50799,50800],{},"fulfilled"," (success, carries a value) or ",[76,50803,50804],{},"rejected"," (failure, carries a reason). There's no fourth state and no \"loading\" or \"waiting\" terminology in the spec — those are the informal names some libraries use, but the ECMAScript spec and every debugger\u002FDevTools panel use pending\u002Ffulfilled\u002Frejected.",[15,50807,50808,50810,50901,50928],{"language":247},[18,50809,12737],{"id":12736},[257,50811,50812],{"language":247},[260,50813,50815],{"className":262,"code":50814,"language":247,"meta":264,"style":264},"const p = new Promise((resolve, reject) => {\n  resolve('first');\n  reject('second');\n  resolve('third');\n});\n\np.then(console.log).catch(console.log);\n",[39,50816,50817,50844,50855,50867,50878,50882,50886],{"__ignoreMap":264},[268,50818,50819,50821,50823,50825,50827,50829,50831,50833,50835,50838,50840,50842],{"class":270,"line":271},[268,50820,243],{"class":274},[268,50822,29927],{"class":305},[268,50824,616],{"class":274},[268,50826,11370],{"class":274},[268,50828,50116],{"class":305},[268,50830,6122],{"class":282},[268,50832,47500],{"class":1222},[268,50834,42],{"class":282},[268,50836,50837],{"class":1222},"reject",[268,50839,6131],{"class":282},[268,50841,9414],{"class":274},[268,50843,9914],{"class":282},[268,50845,50846,50848,50850,50853],{"class":270,"line":286},[268,50847,50143],{"class":278},[268,50849,622],{"class":282},[268,50851,50852],{"class":289},"'first'",[268,50854,628],{"class":282},[268,50856,50857,50860,50862,50865],{"class":270,"line":296},[268,50858,50859],{"class":278},"  reject",[268,50861,622],{"class":282},[268,50863,50864],{"class":289},"'second'",[268,50866,628],{"class":282},[268,50868,50869,50871,50873,50876],{"class":270,"line":311},[268,50870,50143],{"class":278},[268,50872,622],{"class":282},[268,50874,50875],{"class":289},"'third'",[268,50877,628],{"class":282},[268,50879,50880],{"class":270,"line":788},[268,50881,20047],{"class":282},[268,50883,50884],{"class":270,"line":1951},[268,50885,5033],{"emptyLinePlaceholder":35},[268,50887,50888,50891,50893,50896,50898],{"class":270,"line":8955},[268,50889,50890],{"class":282},"p.",[268,50892,47505],{"class":278},[268,50894,50895],{"class":282},"(console.log).",[268,50897,12488],{"class":278},[268,50899,50900],{"class":282},"(console.log);\n",[23,50902,50904,50910,50916,50922],{"className":50903},[26],[28,50905,50907,50909],{"className":50906},[31],[33,50908],{"disabled":35,"type":36}," 'third'",[28,50911,50913,50915],{"className":50912},[31],[33,50914],{"disabled":35,"type":36}," Throws a TypeError for calling resolve\u002Freject more than once",[28,50917,50919,50921],{"className":50918},[31],[33,50920],{"disabled":35,"type":36}," 'first'",[28,50923,50925,50927],{"className":50924},[31],[33,50926],{"disabled":35,"type":36}," 'second'",[66,50929,50930,50932,50937],{},[69,50931,71],{},[73,50933,50934,50936],{},[76,50935,78],{}," C — 'first'",[73,50938,50939,50941,50942,50945,50946,50949,50950,50952,50953,99,50955,50957,50958,446,50960,50962],{},[76,50940,84],{}," A promise can settle ",[76,50943,50944],{},"only once",". The first call — ",[39,50947,50948],{},"resolve('first')"," — locks the promise into the fulfilled state with value ",[39,50951,50852],{},"; every subsequent call to ",[39,50954,47500],{},[39,50956,50837],{}," is silently ignored, no error is thrown. This is a deliberate spec guarantee: once settled, a promise's outcome is immutable, so downstream ",[39,50959,47423],{},[39,50961,47426],{}," handlers never have to worry about a value changing out from under them.",[15,50964,50965,50967,51036,51061],{"language":247},[18,50966,12877],{"id":12876},[257,50968,50969],{"language":247},[260,50970,50972],{"className":262,"code":50971,"language":247,"meta":264,"style":264},"Promise.resolve(1)\n  .then(n => n + 1)\n  .then(n => n + 1)\n  .then(console.log);\n",[39,50973,50974,50988,51008,51028],{"__ignoreMap":264},[268,50975,50976,50978,50980,50982,50984,50986],{"class":270,"line":271},[268,50977,91],{"class":305},[268,50979,462],{"class":282},[268,50981,47500],{"class":278},[268,50983,622],{"class":282},[268,50985,2255],{"class":305},[268,50987,20702],{"class":282},[268,50989,50990,50992,50994,50996,50998,51000,51002,51004,51006],{"class":270,"line":286},[268,50991,41697],{"class":282},[268,50993,47505],{"class":278},[268,50995,622],{"class":282},[268,50997,4599],{"class":1222},[268,50999,14969],{"class":274},[268,51001,13355],{"class":282},[268,51003,1246],{"class":274},[268,51005,2199],{"class":305},[268,51007,20702],{"class":282},[268,51009,51010,51012,51014,51016,51018,51020,51022,51024,51026],{"class":270,"line":296},[268,51011,41697],{"class":282},[268,51013,47505],{"class":278},[268,51015,622],{"class":282},[268,51017,4599],{"class":1222},[268,51019,14969],{"class":274},[268,51021,13355],{"class":282},[268,51023,1246],{"class":274},[268,51025,2199],{"class":305},[268,51027,20702],{"class":282},[268,51029,51030,51032,51034],{"class":270,"line":311},[268,51031,41697],{"class":282},[268,51033,47505],{"class":278},[268,51035,50900],{"class":282},[23,51037,51039,51044,51051,51056],{"className":51038},[26],[28,51040,51042,2199],{"className":51041},[31],[33,51043],{"disabled":35,"type":36},[28,51045,51047,355,51049],{"className":51046},[31],[33,51048],{"disabled":35,"type":36},[268,51050,23888],{},[28,51052,51054,17135],{"className":51053},[31],[33,51055],{"disabled":35,"type":36},[28,51057,51059,3396],{"className":51058},[31],[33,51060],{"disabled":35,"type":36},[66,51062,51063,51065,51070],{},[69,51064,71],{},[73,51066,51067,51069],{},[76,51068,78],{}," D — 3",[73,51071,51072,17028,51074,51076,51077,51080,51081,51083,51084,51086,51087,51089,51090,51092,51093,51095],{},[76,51073,84],{},[39,51075,46149],{}," call returns a ",[76,51078,51079],{},"new promise"," whose resolved value is whatever the callback returns — that's what makes chaining work. The first ",[39,51082,47423],{}," returns a promise resolving to ",[39,51085,2258],{},", the second returns one resolving to ",[39,51088,3423],{},", and the final ",[39,51091,47423],{}," logs that ",[39,51094,3423],{},". If a callback returns a plain (non-promise) value, it's simply wrapped and passed straight to the next link.",[15,51097,51098,51102,51239,51285],{"language":247},[18,51099,51101],{"id":51100},"q4-what-does-this-log-and-in-what-order-does-the-value-arrive","Q4. What does this log, and in what order does the value arrive?",[257,51103,51104],{"language":247},[260,51105,51107],{"className":262,"code":51106,"language":247,"meta":264,"style":264},"function getUser(id) {\n  return Promise.resolve({ id, name: 'Ada' });\n}\n\nfunction getOrders(user) {\n  return Promise.resolve([`order-1 for ${user.name}`]);\n}\n\ngetUser(42)\n  .then(user => getOrders(user))\n  .then(orders => console.log(orders));\n",[39,51108,51109,51122,51139,51143,51147,51160,51185,51189,51193,51203,51220],{"__ignoreMap":264},[268,51110,51111,51113,51116,51118,51120],{"class":270,"line":271},[268,51112,275],{"class":274},[268,51114,51115],{"class":278}," getUser",[268,51117,622],{"class":282},[268,51119,14610],{"class":1222},[268,51121,1235],{"class":282},[268,51123,51124,51126,51128,51130,51132,51135,51137],{"class":270,"line":286},[268,51125,1240],{"class":274},[268,51127,50116],{"class":305},[268,51129,462],{"class":282},[268,51131,47500],{"class":278},[268,51133,51134],{"class":282},"({ id, name: ",[268,51136,26968],{"class":289},[268,51138,36080],{"class":282},[268,51140,51141],{"class":270,"line":296},[268,51142,314],{"class":282},[268,51144,51145],{"class":270,"line":311},[268,51146,5033],{"emptyLinePlaceholder":35},[268,51148,51149,51151,51154,51156,51158],{"class":270,"line":788},[268,51150,275],{"class":274},[268,51152,51153],{"class":278}," getOrders",[268,51155,622],{"class":282},[268,51157,4155],{"class":1222},[268,51159,1235],{"class":282},[268,51161,51162,51164,51166,51168,51170,51172,51175,51177,51179,51181,51183],{"class":270,"line":1951},[268,51163,1240],{"class":274},[268,51165,50116],{"class":305},[268,51167,462],{"class":282},[268,51169,47500],{"class":278},[268,51171,17519],{"class":282},[268,51173,51174],{"class":289},"`order-1 for ${",[268,51176,4155],{"class":282},[268,51178,462],{"class":289},[268,51180,14605],{"class":282},[268,51182,11603],{"class":289},[268,51184,15180],{"class":282},[268,51186,51187],{"class":270,"line":8955},[268,51188,314],{"class":282},[268,51190,51191],{"class":270,"line":8966},[268,51192,5033],{"emptyLinePlaceholder":35},[268,51194,51195,51197,51199,51201],{"class":270,"line":8974},[268,51196,48249],{"class":278},[268,51198,622],{"class":282},[268,51200,4659],{"class":305},[268,51202,20702],{"class":282},[268,51204,51205,51207,51209,51211,51213,51215,51217],{"class":270,"line":8985},[268,51206,41697],{"class":282},[268,51208,47505],{"class":278},[268,51210,622],{"class":282},[268,51212,4155],{"class":1222},[268,51214,14969],{"class":274},[268,51216,51153],{"class":278},[268,51218,51219],{"class":282},"(user))\n",[268,51221,51222,51224,51226,51228,51230,51232,51234,51236],{"class":270,"line":8990},[268,51223,41697],{"class":282},[268,51225,47505],{"class":278},[268,51227,622],{"class":282},[268,51229,43320],{"class":1222},[268,51231,14969],{"class":274},[268,51233,9417],{"class":282},[268,51235,1356],{"class":278},[268,51237,51238],{"class":282},"(orders));\n",[23,51240,51242,51251,51267,51275],{"className":51241},[26],[28,51243,51245,355,51247,51250],{"className":51244},[31],[33,51246],{"disabled":35,"type":36},[268,51248,51249],{},"'order-1 for Ada'"," — the chain automatically waits for the inner promise before continuing",[28,51252,51254,51256,51257],{"className":51253},[31],[33,51255],{"disabled":35,"type":36}," Promise { ",[50796,51258,51259,51260,51262,51263,51266],{}," } — the second ",[39,51261,47423],{}," runs before ",[39,51264,51265],{},"getOrders"," settles",[28,51268,51270,355,51272,51274],{"className":51269},[31],[33,51271],{"disabled":35,"type":36},[268,51273,91],{}," — a promise wrapped inside an array",[28,51276,51278,34517,51280,51282,51283],{"className":51277},[31],[33,51279],{"disabled":35,"type":36},[39,51281,47423],{}," can't return a promise from inside another ",[39,51284,47423],{},[66,51286,51287,51289,51295],{},[69,51288,71],{},[73,51290,51291,3459,51293,51250],{},[76,51292,78],{},[268,51294,51249],{},[73,51296,51297,51299,51300,51302,51303,51306,51307,51309,51310,51312,51313,51315,51316,23506,51318,462],{},[76,51298,84],{}," When a ",[39,51301,47423],{}," callback returns a promise (rather than a plain value), the chain ",[76,51304,51305],{},"auto-flattens",": the outer promise adopts the inner one's eventual state instead of resolving to \"a promise containing a promise.\" So the second ",[39,51308,47423],{}," doesn't run until ",[39,51311,51265],{},"'s returned promise actually settles, and it receives the unwrapped array, not a ",[39,51314,91],{}," object. This is what lets you chain dependent async calls without manually nesting ",[39,51317,47423],{},[39,51319,47423],{},[15,51321,51322,51324,51459,51486],{"language":247},[18,51323,13181],{"id":13180},[257,51325,51326],{"language":247},[260,51327,51329],{"className":262,"code":51328,"language":247,"meta":264,"style":264},"fetchStep1()\n  .then(() => { throw new Error('boom in step 1'); })\n  .then(() => console.log('step 2'))\n  .then(() => console.log('step 3'))\n  .catch(err => console.log('caught:', err.message));\n\nfunction fetchStep1() {\n  return Promise.resolve();\n}\n",[39,51330,51331,51338,51364,51385,51406,51430,51434,51443,51455],{"__ignoreMap":264},[268,51332,51333,51336],{"class":270,"line":271},[268,51334,51335],{"class":278},"fetchStep1",[268,51337,47668],{"class":282},[268,51339,51340,51342,51344,51346,51348,51350,51352,51354,51356,51358,51361],{"class":270,"line":286},[268,51341,41697],{"class":282},[268,51343,47505],{"class":278},[268,51345,9411],{"class":282},[268,51347,9414],{"class":274},[268,51349,20200],{"class":282},[268,51351,48836],{"class":274},[268,51353,11370],{"class":274},[268,51355,11593],{"class":278},[268,51357,622],{"class":282},[268,51359,51360],{"class":289},"'boom in step 1'",[268,51362,51363],{"class":282},"); })\n",[268,51365,51366,51368,51370,51372,51374,51376,51378,51380,51383],{"class":270,"line":296},[268,51367,41697],{"class":282},[268,51369,47505],{"class":278},[268,51371,9411],{"class":282},[268,51373,9414],{"class":274},[268,51375,9417],{"class":282},[268,51377,1356],{"class":278},[268,51379,622],{"class":282},[268,51381,51382],{"class":289},"'step 2'",[268,51384,47690],{"class":282},[268,51386,51387,51389,51391,51393,51395,51397,51399,51401,51404],{"class":270,"line":311},[268,51388,41697],{"class":282},[268,51390,47505],{"class":278},[268,51392,9411],{"class":282},[268,51394,9414],{"class":274},[268,51396,9417],{"class":282},[268,51398,1356],{"class":278},[268,51400,622],{"class":282},[268,51402,51403],{"class":289},"'step 3'",[268,51405,47690],{"class":282},[268,51407,51408,51410,51412,51414,51416,51418,51420,51422,51424,51427],{"class":270,"line":788},[268,51409,41697],{"class":282},[268,51411,12488],{"class":278},[268,51413,622],{"class":282},[268,51415,48255],{"class":1222},[268,51417,14969],{"class":274},[268,51419,9417],{"class":282},[268,51421,1356],{"class":278},[268,51423,622],{"class":282},[268,51425,51426],{"class":289},"'caught:'",[268,51428,51429],{"class":282},", err.message));\n",[268,51431,51432],{"class":270,"line":1951},[268,51433,5033],{"emptyLinePlaceholder":35},[268,51435,51436,51438,51441],{"class":270,"line":8955},[268,51437,275],{"class":274},[268,51439,51440],{"class":278}," fetchStep1",[268,51442,283],{"class":282},[268,51444,51445,51447,51449,51451,51453],{"class":270,"line":8966},[268,51446,1240],{"class":274},[268,51448,50116],{"class":305},[268,51450,462],{"class":282},[268,51452,47500],{"class":278},[268,51454,794],{"class":282},[268,51456,51457],{"class":270,"line":8974},[268,51458,314],{"class":282},[23,51460,51462,51468,51474,51480],{"className":51461},[26],[28,51463,51465,51467],{"className":51464},[31],[33,51466],{"disabled":35,"type":36}," 'step 2' then 'step 3'",[28,51469,51471,51473],{"className":51470},[31],[33,51472],{"disabled":35,"type":36}," 'caught: boom in step 1'",[28,51475,51477,51479],{"className":51476},[31],[33,51478],{"disabled":35,"type":36}," 'step 2' then 'caught: boom in step 1'",[28,51481,51483,51485],{"className":51482},[31],[33,51484],{"disabled":35,"type":36}," Nothing — the error crashes the script before anything logs",[66,51487,51488,51490,51495],{},[69,51489,71],{},[73,51491,51492,51494],{},[76,51493,78],{}," B — 'caught: boom in step 1'",[73,51496,51497,51499,51500,51502,51503,51506,51507,51509,51510,51512,51513,51516,51517,51519,51520,51522,51523,51525,51526,186,51528,51530],{},[76,51498,84],{}," A single ",[39,51501,49873],{}," at the end of a chain catches a rejection from ",[76,51504,51505],{},"any earlier link",", not just the one immediately before it. Once the first ",[39,51508,47423],{}," throws, the promise it returns rejects, and every subsequent ",[39,51511,47423],{}," in the chain is ",[76,51514,51515],{},"skipped"," — rejections propagate past ",[39,51518,47423],{}," handlers (they only have fulfillment callbacks registered) until a handler with a rejection callback (",[39,51521,47426],{},", or the second argument to ",[39,51524,47423],{},") is found. ",[39,51527,51382],{},[39,51529,51403],{}," never run.",[15,51532,51533,51535,51636,51666],{"language":247},[18,51534,13321],{"id":13320},[257,51536,51537],{"language":247},[260,51538,51540],{"className":262,"code":51539,"language":247,"meta":264,"style":264},"Promise.reject(new Error('network down'))\n  .then(\n    value => console.log('fulfilled:', value),\n    err => console.log('rejected in 2nd arg:', err.message)\n  )\n  .catch(err => console.log('caught:', err.message));\n",[39,51541,51542,51563,51571,51590,51609,51614],{"__ignoreMap":264},[268,51543,51544,51546,51548,51550,51552,51554,51556,51558,51561],{"class":270,"line":271},[268,51545,91],{"class":305},[268,51547,462],{"class":282},[268,51549,50837],{"class":278},[268,51551,622],{"class":282},[268,51553,2689],{"class":274},[268,51555,11593],{"class":278},[268,51557,622],{"class":282},[268,51559,51560],{"class":289},"'network down'",[268,51562,47690],{"class":282},[268,51564,51565,51567,51569],{"class":270,"line":286},[268,51566,41697],{"class":282},[268,51568,47505],{"class":278},[268,51570,17096],{"class":282},[268,51572,51573,51576,51578,51580,51582,51584,51587],{"class":270,"line":296},[268,51574,51575],{"class":1222},"    value",[268,51577,14969],{"class":274},[268,51579,9417],{"class":282},[268,51581,1356],{"class":278},[268,51583,622],{"class":282},[268,51585,51586],{"class":289},"'fulfilled:'",[268,51588,51589],{"class":282},", value),\n",[268,51591,51592,51595,51597,51599,51601,51603,51606],{"class":270,"line":311},[268,51593,51594],{"class":1222},"    err",[268,51596,14969],{"class":274},[268,51598,9417],{"class":282},[268,51600,1356],{"class":278},[268,51602,622],{"class":282},[268,51604,51605],{"class":289},"'rejected in 2nd arg:'",[268,51607,51608],{"class":282},", err.message)\n",[268,51610,51611],{"class":270,"line":788},[268,51612,51613],{"class":282},"  )\n",[268,51615,51616,51618,51620,51622,51624,51626,51628,51630,51632,51634],{"class":270,"line":1951},[268,51617,41697],{"class":282},[268,51619,12488],{"class":278},[268,51621,622],{"class":282},[268,51623,48255],{"class":1222},[268,51625,14969],{"class":274},[268,51627,9417],{"class":282},[268,51629,1356],{"class":278},[268,51631,622],{"class":282},[268,51633,51426],{"class":289},[268,51635,51429],{"class":282},[23,51637,51639,51645,51654,51660],{"className":51638},[26],[28,51640,51642,51644],{"className":51641},[31],[33,51643],{"disabled":35,"type":36}," 'caught: network down'",[28,51646,51648,51650,51651,51653],{"className":51647},[31],[33,51649],{"disabled":35,"type":36}," Nothing — passing two arguments to ",[39,51652,47423],{}," is a TypeError",[28,51655,51657,51659],{"className":51656},[31],[33,51658],{"disabled":35,"type":36}," 'rejected in 2nd arg: network down'",[28,51661,51663,51665],{"className":51662},[31],[33,51664],{"disabled":35,"type":36}," Both lines log, in that order",[66,51667,51668,51670,51675],{},[69,51669,71],{},[73,51671,51672,51674],{},[76,51673,78],{}," C — 'rejected in 2nd arg: network down'",[73,51676,51677,355,51679,51682,51683,51685,51686,4912,51688,51691,51692,51694],{},[76,51678,84],{},[39,51680,51681],{},".then(onFulfilled, onRejected)"," registers the second argument as a rejection handler for the promise ",[39,51684,47423],{}," is called ON. Since the original promise is already rejected, that second-argument handler catches it directly, logs the message, and — because it doesn't throw or return a rejected promise — the promise ",[39,51687,47423],{},[76,51689,51690],{},"resolves"," (not rejects). So the trailing ",[39,51693,47426],{}," has nothing to catch and never runs.",[15,51696,51697,51699,51795,51822],{"language":247},[18,51698,13528],{"id":13527},[257,51700,51701],{"language":247},[260,51702,51704],{"className":262,"code":51703,"language":247,"meta":264,"style":264},"Promise.resolve('ok')\n  .then(\n    value => { throw new Error('thrown inside onFulfilled'); },\n    err => console.log('rejected handler:', err.message)\n  )\n  .catch(err => console.log('caught by catch:', err.message));\n",[39,51705,51706,51721,51729,51751,51768,51772],{"__ignoreMap":264},[268,51707,51708,51710,51712,51714,51716,51719],{"class":270,"line":271},[268,51709,91],{"class":305},[268,51711,462],{"class":282},[268,51713,47500],{"class":278},[268,51715,622],{"class":282},[268,51717,51718],{"class":289},"'ok'",[268,51720,20702],{"class":282},[268,51722,51723,51725,51727],{"class":270,"line":286},[268,51724,41697],{"class":282},[268,51726,47505],{"class":278},[268,51728,17096],{"class":282},[268,51730,51731,51733,51735,51737,51739,51741,51743,51745,51748],{"class":270,"line":296},[268,51732,51575],{"class":1222},[268,51734,14969],{"class":274},[268,51736,20200],{"class":282},[268,51738,48836],{"class":274},[268,51740,11370],{"class":274},[268,51742,11593],{"class":278},[268,51744,622],{"class":282},[268,51746,51747],{"class":289},"'thrown inside onFulfilled'",[268,51749,51750],{"class":282},"); },\n",[268,51752,51753,51755,51757,51759,51761,51763,51766],{"class":270,"line":311},[268,51754,51594],{"class":1222},[268,51756,14969],{"class":274},[268,51758,9417],{"class":282},[268,51760,1356],{"class":278},[268,51762,622],{"class":282},[268,51764,51765],{"class":289},"'rejected handler:'",[268,51767,51608],{"class":282},[268,51769,51770],{"class":270,"line":788},[268,51771,51613],{"class":282},[268,51773,51774,51776,51778,51780,51782,51784,51786,51788,51790,51793],{"class":270,"line":1951},[268,51775,41697],{"class":282},[268,51777,12488],{"class":278},[268,51779,622],{"class":282},[268,51781,48255],{"class":1222},[268,51783,14969],{"class":274},[268,51785,9417],{"class":282},[268,51787,1356],{"class":278},[268,51789,622],{"class":282},[268,51791,51792],{"class":289},"'caught by catch:'",[268,51794,51429],{"class":282},[23,51796,51798,51804,51810,51816],{"className":51797},[26],[28,51799,51801,51803],{"className":51800},[31],[33,51802],{"disabled":35,"type":36}," 'rejected handler: thrown inside onFulfilled'",[28,51805,51807,51809],{"className":51806},[31],[33,51808],{"disabled":35,"type":36}," Nothing logs — the throw is swallowed since a rejection handler was already supplied",[28,51811,51813,51815],{"className":51812},[31],[33,51814],{"disabled":35,"type":36}," Both the rejected handler and the catch run",[28,51817,51819,51821],{"className":51818},[31],[33,51820],{"disabled":35,"type":36}," 'caught by catch: thrown inside onFulfilled'",[66,51823,51824,51826,51831],{},[69,51825,71],{},[73,51827,51828,51830],{},[76,51829,78],{}," D — 'caught by catch: thrown inside onFulfilled'",[73,51832,51833,51835,51836,51838,51839,51842,51843,51845,51846,51848,51849,51852,51853,51855,51856,51858,51859,51861,51862,51864,51865,8574,51868,51871,51872,51874,51875,51877],{},[76,51834,84],{}," This is the classic two-arg-",[39,51837,47423],{}," gotcha: the ",[39,51840,51841],{},"onRejected"," second argument only catches a rejection of the promise ",[39,51844,47423],{}," was called on — it does ",[76,51847,95],{}," catch an error thrown from inside the ",[39,51850,51851],{},"onFulfilled"," callback sitting right next to it. Since the original promise was fulfilled, ",[39,51854,51851],{}," runs, throws, and that throw becomes a rejection of the ",[104,51857,2689],{}," promise ",[39,51860,47423],{}," returns — which is exactly what the chained ",[39,51863,49873],{}," picks up. Using ",[39,51866,51867],{},".then(fn).catch(handler)",[39,51869,51870],{},".then(fn, handler)"," is the idiomatic fix precisely because ",[39,51873,47426],{}," sits downstream of ",[39,51876,47423],{},"'s own callback and can catch throws from within it.",[15,51879,51880,51884,51994,52021],{"language":247},[18,51881,51883],{"id":51882},"q8-what-does-this-log-and-in-what-order","Q8. What does this log, and in what order?",[257,51885,51886],{"language":247},[260,51887,51889],{"className":262,"code":51888,"language":247,"meta":264,"style":264},"Promise.resolve('data')\n  .then(val => {\n    console.log('handler:', val);\n    return val.toUpperCase();\n  })\n  .finally(() => console.log('finally ran'))\n  .then(val => console.log('after finally:', val));\n",[39,51890,51891,51906,51920,51933,51944,51948,51970],{"__ignoreMap":264},[268,51892,51893,51895,51897,51899,51901,51904],{"class":270,"line":271},[268,51894,91],{"class":305},[268,51896,462],{"class":282},[268,51898,47500],{"class":278},[268,51900,622],{"class":282},[268,51902,51903],{"class":289},"'data'",[268,51905,20702],{"class":282},[268,51907,51908,51910,51912,51914,51916,51918],{"class":270,"line":286},[268,51909,41697],{"class":282},[268,51911,47505],{"class":278},[268,51913,622],{"class":282},[268,51915,4315],{"class":1222},[268,51917,14969],{"class":274},[268,51919,9914],{"class":282},[268,51921,51922,51924,51926,51928,51931],{"class":270,"line":296},[268,51923,9707],{"class":282},[268,51925,1356],{"class":278},[268,51927,622],{"class":282},[268,51929,51930],{"class":289},"'handler:'",[268,51932,5566],{"class":282},[268,51934,51935,51937,51940,51942],{"class":270,"line":311},[268,51936,9871],{"class":274},[268,51938,51939],{"class":282}," val.",[268,51941,16179],{"class":278},[268,51943,794],{"class":282},[268,51945,51946],{"class":270,"line":788},[268,51947,43278],{"class":282},[268,51949,51950,51952,51955,51957,51959,51961,51963,51965,51968],{"class":270,"line":1951},[268,51951,41697],{"class":282},[268,51953,51954],{"class":278},"finally",[268,51956,9411],{"class":282},[268,51958,9414],{"class":274},[268,51960,9417],{"class":282},[268,51962,1356],{"class":278},[268,51964,622],{"class":282},[268,51966,51967],{"class":289},"'finally ran'",[268,51969,47690],{"class":282},[268,51971,51972,51974,51976,51978,51980,51982,51984,51986,51988,51991],{"class":270,"line":8955},[268,51973,41697],{"class":282},[268,51975,47505],{"class":278},[268,51977,622],{"class":282},[268,51979,4315],{"class":1222},[268,51981,14969],{"class":274},[268,51983,9417],{"class":282},[268,51985,1356],{"class":278},[268,51987,622],{"class":282},[268,51989,51990],{"class":289},"'after finally:'",[268,51992,51993],{"class":282},", val));\n",[23,51995,51997,52003,52009,52015],{"className":51996},[26],[28,51998,52000,52002],{"className":51999},[31],[33,52001],{"disabled":35,"type":36}," 'handler: data' then 'finally ran' then 'after finally: DATA'",[28,52004,52006,52008],{"className":52005},[31],[33,52007],{"disabled":35,"type":36}," 'handler: data' then 'finally ran' then 'after finally: undefined'",[28,52010,52012,52014],{"className":52011},[31],[33,52013],{"disabled":35,"type":36}," 'finally ran' then 'handler: data' then 'after finally: DATA'",[28,52016,52018,52020],{"className":52017},[31],[33,52019],{"disabled":35,"type":36}," 'handler: data' then 'after finally: DATA' then 'finally ran'",[66,52022,52023,52025,52030],{},[69,52024,71],{},[73,52026,52027,52029],{},[76,52028,78],{}," A — 'handler: data' then 'finally ran' then 'after finally: DATA'",[73,52031,52032,355,52034,52037,52038,52041,52042,52044,52045,52048,52049,1179,52051,52054,52055,52057,52058,52060,52061,52063],{},[76,52033,84],{},[39,52035,52036],{},".finally()"," runs after the preceding link settles, regardless of whether it fulfilled or rejected, but its callback receives ",[76,52039,52040],{},"no argument"," — it can't see the value or reason, and it doesn't need to, since its job is cleanup (closing a spinner, releasing a resource) rather than transforming data. Critically, ",[39,52043,52036],{}," passes the original outcome ",[76,52046,52047],{},"through unchanged"," to the next ",[39,52050,47423],{},[39,52052,52053],{},"'DATA'"," survives past the ",[39,52056,51954],{}," untouched — it does not become ",[39,52059,833],{}," just because the ",[39,52062,51954],{}," callback returned nothing.",[15,52065,52066,52068,52139,52175],{"language":247},[18,52067,13927],{"id":13926},[257,52069,52070],{"language":247},[260,52071,52073],{"className":262,"code":52072,"language":247,"meta":264,"style":264},"Promise.reject(new Error('save failed'))\n  .finally(() => console.log('cleanup'))\n  .catch(err => console.log('caught:', err.message));\n",[39,52074,52075,52096,52117],{"__ignoreMap":264},[268,52076,52077,52079,52081,52083,52085,52087,52089,52091,52094],{"class":270,"line":271},[268,52078,91],{"class":305},[268,52080,462],{"class":282},[268,52082,50837],{"class":278},[268,52084,622],{"class":282},[268,52086,2689],{"class":274},[268,52088,11593],{"class":278},[268,52090,622],{"class":282},[268,52092,52093],{"class":289},"'save failed'",[268,52095,47690],{"class":282},[268,52097,52098,52100,52102,52104,52106,52108,52110,52112,52115],{"class":270,"line":286},[268,52099,41697],{"class":282},[268,52101,51954],{"class":278},[268,52103,9411],{"class":282},[268,52105,9414],{"class":274},[268,52107,9417],{"class":282},[268,52109,1356],{"class":278},[268,52111,622],{"class":282},[268,52113,52114],{"class":289},"'cleanup'",[268,52116,47690],{"class":282},[268,52118,52119,52121,52123,52125,52127,52129,52131,52133,52135,52137],{"class":270,"line":296},[268,52120,41697],{"class":282},[268,52122,12488],{"class":278},[268,52124,622],{"class":282},[268,52126,48255],{"class":1222},[268,52128,14969],{"class":274},[268,52130,9417],{"class":282},[268,52132,1356],{"class":278},[268,52134,622],{"class":282},[268,52136,51426],{"class":289},[268,52138,51429],{"class":282},[23,52140,52142,52148,52154,52163],{"className":52141},[26],[28,52143,52145,52147],{"className":52144},[31],[33,52146],{"disabled":35,"type":36}," 'caught: save failed' then 'cleanup'",[28,52149,52151,52153],{"className":52150},[31],[33,52152],{"disabled":35,"type":36}," 'cleanup' then 'caught: save failed'",[28,52155,52157,52159,52160,52162],{"className":52156},[31],[33,52158],{"disabled":35,"type":36}," Nothing logs — ",[39,52161,47429],{}," can't be chained after a rejected promise",[28,52164,52166,52168,52169,52171,52172,52174],{"className":52165},[31],[33,52167],{"disabled":35,"type":36}," Only 'cleanup' — ",[39,52170,47429],{}," consumes the rejection so ",[39,52173,47426],{}," never runs",[66,52176,52177,52179,52184],{},[69,52178,71],{},[73,52180,52181,52183],{},[76,52182,78],{}," B — 'cleanup' then 'caught: save failed'",[73,52185,52186,355,52188,52190,52191,52194,52195,52197,52198,52200,52201,52203,52204,52206],{},[76,52187,84],{},[39,52189,52036],{}," runs its callback on rejection too, but since it doesn't return a value that replaces the outcome, the original rejection ",[76,52192,52193],{},"propagates through"," to the next handler in the chain — it does not get swallowed. So ",[39,52196,52114],{}," logs first (as the finally callback fires), and the still-pending rejection then reaches ",[39,52199,47426],{},", which logs the error message. The one exception (not shown here) is if the ",[39,52202,51954],{}," callback itself throws or returns a rejected promise — then ",[104,52205,7690],{}," new rejection would override the original.",[15,52208,52209,52213,52416,52450],{"language":247},[18,52210,52212],{"id":52211},"q10-three-api-calls-each-take-a-different-amount-of-time-and-one-of-them-fails-what-does-this-log","Q10. Three API calls each take a different amount of time and one of them fails. What does this log?",[257,52214,52215],{"language":247},[260,52216,52218],{"className":262,"code":52217,"language":247,"meta":264,"style":264},"const fast = new Promise(res => setTimeout(() => res('fast done'), 10));\nconst slow = new Promise(res => setTimeout(() => res('slow done'), 100));\nconst broken = new Promise((_, rej) => setTimeout(() => rej(new Error('broke')), 50));\n\nPromise.all([fast, slow, broken])\n  .then(results => console.log('all:', results))\n  .catch(err => console.log('all failed:', err.message));\n",[39,52219,52220,52260,52298,52352,52356,52368,52393],{"__ignoreMap":264},[268,52221,52222,52224,52227,52229,52231,52233,52235,52238,52240,52242,52244,52246,52249,52251,52254,52256,52258],{"class":270,"line":271},[268,52223,243],{"class":274},[268,52225,52226],{"class":305}," fast",[268,52228,616],{"class":274},[268,52230,11370],{"class":274},[268,52232,50116],{"class":305},[268,52234,622],{"class":282},[268,52236,52237],{"class":1222},"res",[268,52239,14969],{"class":274},[268,52241,40796],{"class":278},[268,52243,9411],{"class":282},[268,52245,9414],{"class":274},[268,52247,52248],{"class":278}," res",[268,52250,622],{"class":282},[268,52252,52253],{"class":289},"'fast done'",[268,52255,33111],{"class":282},[268,52257,5825],{"class":305},[268,52259,4818],{"class":282},[268,52261,52262,52264,52267,52269,52271,52273,52275,52277,52279,52281,52283,52285,52287,52289,52292,52294,52296],{"class":270,"line":286},[268,52263,243],{"class":274},[268,52265,52266],{"class":305}," slow",[268,52268,616],{"class":274},[268,52270,11370],{"class":274},[268,52272,50116],{"class":305},[268,52274,622],{"class":282},[268,52276,52237],{"class":1222},[268,52278,14969],{"class":274},[268,52280,40796],{"class":278},[268,52282,9411],{"class":282},[268,52284,9414],{"class":274},[268,52286,52248],{"class":278},[268,52288,622],{"class":282},[268,52290,52291],{"class":289},"'slow done'",[268,52293,33111],{"class":282},[268,52295,13912],{"class":305},[268,52297,4818],{"class":282},[268,52299,52300,52302,52305,52307,52309,52311,52313,52316,52318,52321,52323,52325,52327,52329,52331,52334,52336,52338,52340,52342,52345,52348,52350],{"class":270,"line":296},[268,52301,243],{"class":274},[268,52303,52304],{"class":305}," broken",[268,52306,616],{"class":274},[268,52308,11370],{"class":274},[268,52310,50116],{"class":305},[268,52312,6122],{"class":282},[268,52314,52315],{"class":1222},"_",[268,52317,42],{"class":282},[268,52319,52320],{"class":1222},"rej",[268,52322,6131],{"class":282},[268,52324,9414],{"class":274},[268,52326,40796],{"class":278},[268,52328,9411],{"class":282},[268,52330,9414],{"class":274},[268,52332,52333],{"class":278}," rej",[268,52335,622],{"class":282},[268,52337,2689],{"class":274},[268,52339,11593],{"class":278},[268,52341,622],{"class":282},[268,52343,52344],{"class":289},"'broke'",[268,52346,52347],{"class":282},")), ",[268,52349,32109],{"class":305},[268,52351,4818],{"class":282},[268,52353,52354],{"class":270,"line":311},[268,52355,5033],{"emptyLinePlaceholder":35},[268,52357,52358,52360,52362,52365],{"class":270,"line":788},[268,52359,91],{"class":305},[268,52361,462],{"class":282},[268,52363,52364],{"class":278},"all",[268,52366,52367],{"class":282},"([fast, slow, broken])\n",[268,52369,52370,52372,52374,52376,52379,52381,52383,52385,52387,52390],{"class":270,"line":1951},[268,52371,41697],{"class":282},[268,52373,47505],{"class":278},[268,52375,622],{"class":282},[268,52377,52378],{"class":1222},"results",[268,52380,14969],{"class":274},[268,52382,9417],{"class":282},[268,52384,1356],{"class":278},[268,52386,622],{"class":282},[268,52388,52389],{"class":289},"'all:'",[268,52391,52392],{"class":282},", results))\n",[268,52394,52395,52397,52399,52401,52403,52405,52407,52409,52411,52414],{"class":270,"line":8955},[268,52396,41697],{"class":282},[268,52398,12488],{"class":278},[268,52400,622],{"class":282},[268,52402,48255],{"class":1222},[268,52404,14969],{"class":274},[268,52406,9417],{"class":282},[268,52408,1356],{"class":278},[268,52410,622],{"class":282},[268,52412,52413],{"class":289},"'all failed:'",[268,52415,51429],{"class":282},[23,52417,52419,52425,52435,52444],{"className":52418},[26],[28,52420,52422,52424],{"className":52421},[31],[33,52423],{"disabled":35,"type":36}," 'all failed: broke' — but only after all three have settled at 100ms",[28,52426,52428,52430,52431,52434],{"className":52427},[31],[33,52429],{"disabled":35,"type":36}," 'all: ",[268,52432,52433],{},"'fast done', 'slow done', undefined","'",[28,52436,52438,52440,52441],{"className":52437},[31],[33,52439],{"disabled":35,"type":36}," 'all failed: broke' — logged around the 50ms mark, without waiting for ",[39,52442,52443],{},"slow",[28,52445,52447,52449],{"className":52446},[31],[33,52448],{"disabled":35,"type":36}," Nothing logs because one promise in the array rejected",[66,52451,52452,52454,52461],{},[69,52453,71],{},[73,52455,52456,52458,52459],{},[76,52457,78],{}," C — 'all failed: broke' — logged around the 50ms mark, without waiting for ",[39,52460,52443],{},[73,52462,52463,355,52465,830,52468,52471,52472,20766,52474,52476,52477,52480],{},[76,52464,84],{},[39,52466,52467],{},"Promise.all",[76,52469,52470],{},"fail-fast",": it rejects as soon as any single input promise rejects, immediately propagating that rejection to the ",[39,52473,47426],{},[39,52475,52443],{}," is still pending at that moment (and will keep running in the background, its eventual result simply discarded by this code). This is the key difference from ",[39,52478,52479],{},"Promise.allSettled",", which would wait for every promise to settle no matter what and never short-circuit.",[15,52482,52483,52485,52569,52603],{"language":247},[18,52484,14224],{"id":14223},[257,52486,52487],{"language":247},[260,52488,52490],{"className":262,"code":52489,"language":247,"meta":264,"style":264},"const results = await Promise.allSettled([\n  Promise.resolve('ok-1'),\n  Promise.reject(new Error('bad')),\n  Promise.resolve('ok-2'),\n]);\n",[39,52491,52492,52513,52528,52550,52565],{"__ignoreMap":264},[268,52493,52494,52496,52498,52500,52503,52505,52507,52510],{"class":270,"line":271},[268,52495,243],{"class":274},[268,52497,16541],{"class":305},[268,52499,616],{"class":274},[268,52501,52502],{"class":274}," await",[268,52504,50116],{"class":305},[268,52506,462],{"class":282},[268,52508,52509],{"class":278},"allSettled",[268,52511,52512],{"class":282},"([\n",[268,52514,52515,52517,52519,52521,52523,52526],{"class":270,"line":286},[268,52516,49522],{"class":305},[268,52518,462],{"class":282},[268,52520,47500],{"class":278},[268,52522,622],{"class":282},[268,52524,52525],{"class":289},"'ok-1'",[268,52527,17159],{"class":282},[268,52529,52530,52532,52534,52536,52538,52540,52542,52544,52547],{"class":270,"line":296},[268,52531,49522],{"class":305},[268,52533,462],{"class":282},[268,52535,50837],{"class":278},[268,52537,622],{"class":282},[268,52539,2689],{"class":274},[268,52541,11593],{"class":278},[268,52543,622],{"class":282},[268,52545,52546],{"class":289},"'bad'",[268,52548,52549],{"class":282},")),\n",[268,52551,52552,52554,52556,52558,52560,52563],{"class":270,"line":311},[268,52553,49522],{"class":305},[268,52555,462],{"class":282},[268,52557,47500],{"class":278},[268,52559,622],{"class":282},[268,52561,52562],{"class":289},"'ok-2'",[268,52564,17159],{"class":282},[268,52566,52567],{"class":270,"line":788},[268,52568,15180],{"class":282},[23,52570,52572,52578,52587,52595],{"className":52571},[26],[28,52573,52575,52577],{"className":52574},[31],[33,52576],{"disabled":35,"type":36}," Throws because one of the promises rejected",[28,52579,52581,355,52583,52586],{"className":52580},[31],[33,52582],{"disabled":35,"type":36},[268,52584,52585],{},"'ok-1', 'ok-2'"," — rejected entries are filtered out automatically",[28,52588,52590,355,52592],{"className":52589},[31],[33,52591],{"disabled":35,"type":36},[268,52593,52594],{},"{status: 'fulfilled', value: 'ok-1'}, undefined, {status: 'fulfilled', value: 'ok-2'}",[28,52596,52598,355,52600],{"className":52597},[31],[33,52599],{"disabled":35,"type":36},[268,52601,52602],{},"{status: 'fulfilled', value: 'ok-1'}, {status: 'rejected', reason: Error('bad')}, {status: 'fulfilled', value: 'ok-2'}",[66,52604,52605,52607,52613],{},[69,52606,71],{},[73,52608,52609,6901,52611],{},[76,52610,78],{},[268,52612,52602],{},[73,52614,52615,355,52617,52619,52620,52622,52623,52626,52627,52630,52631,52633],{},[76,52616,84],{},[39,52618,52479],{}," never short-circuits and never rejects — it waits for ",[76,52621,37208],{}," input promise to settle (whether fulfilled or rejected) and resolves with an array of outcome objects, one per input, in the original order. Fulfilled entries get ",[39,52624,52625],{},"{status: 'fulfilled', value}",", rejected entries get ",[39,52628,52629],{},"{status: 'rejected', reason}",". This makes it the right tool when you need results from independent operations even if some of them fail, unlike ",[39,52632,52467],{},"'s all-or-nothing behavior.",[15,52635,52636,52640,52838,52869],{"language":247},[18,52637,52639],{"id":52638},"q12-three-mirrors-of-the-same-resource-are-raced-to-find-whichever-responds-first-what-does-this-log","Q12. Three mirrors of the same resource are raced to find whichever responds first. What does this log?",[257,52641,52642],{"language":247},[260,52643,52645],{"className":262,"code":52644,"language":247,"meta":264,"style":264},"const mirrorA = new Promise(res => setTimeout(() => res('A responded'), 200));\nconst mirrorB = new Promise((_, rej) => setTimeout(() => rej(new Error('B timed out')), 30));\nconst mirrorC = new Promise(res => setTimeout(() => res('C responded'), 150));\n\nPromise.race([mirrorA, mirrorB, mirrorC])\n  .then(v => console.log('winner:', v))\n  .catch(e => console.log('race rejected:', e.message));\n",[39,52646,52647,52685,52735,52773,52777,52789,52814],{"__ignoreMap":264},[268,52648,52649,52651,52654,52656,52658,52660,52662,52664,52666,52668,52670,52672,52674,52676,52679,52681,52683],{"class":270,"line":271},[268,52650,243],{"class":274},[268,52652,52653],{"class":305}," mirrorA",[268,52655,616],{"class":274},[268,52657,11370],{"class":274},[268,52659,50116],{"class":305},[268,52661,622],{"class":282},[268,52663,52237],{"class":1222},[268,52665,14969],{"class":274},[268,52667,40796],{"class":278},[268,52669,9411],{"class":282},[268,52671,9414],{"class":274},[268,52673,52248],{"class":278},[268,52675,622],{"class":282},[268,52677,52678],{"class":289},"'A responded'",[268,52680,33111],{"class":282},[268,52682,40987],{"class":305},[268,52684,4818],{"class":282},[268,52686,52687,52689,52692,52694,52696,52698,52700,52702,52704,52706,52708,52710,52712,52714,52716,52718,52720,52722,52724,52726,52729,52731,52733],{"class":270,"line":286},[268,52688,243],{"class":274},[268,52690,52691],{"class":305}," mirrorB",[268,52693,616],{"class":274},[268,52695,11370],{"class":274},[268,52697,50116],{"class":305},[268,52699,6122],{"class":282},[268,52701,52315],{"class":1222},[268,52703,42],{"class":282},[268,52705,52320],{"class":1222},[268,52707,6131],{"class":282},[268,52709,9414],{"class":274},[268,52711,40796],{"class":278},[268,52713,9411],{"class":282},[268,52715,9414],{"class":274},[268,52717,52333],{"class":278},[268,52719,622],{"class":282},[268,52721,2689],{"class":274},[268,52723,11593],{"class":278},[268,52725,622],{"class":282},[268,52727,52728],{"class":289},"'B timed out'",[268,52730,52347],{"class":282},[268,52732,24274],{"class":305},[268,52734,4818],{"class":282},[268,52736,52737,52739,52742,52744,52746,52748,52750,52752,52754,52756,52758,52760,52762,52764,52767,52769,52771],{"class":270,"line":296},[268,52738,243],{"class":274},[268,52740,52741],{"class":305}," mirrorC",[268,52743,616],{"class":274},[268,52745,11370],{"class":274},[268,52747,50116],{"class":305},[268,52749,622],{"class":282},[268,52751,52237],{"class":1222},[268,52753,14969],{"class":274},[268,52755,40796],{"class":278},[268,52757,9411],{"class":282},[268,52759,9414],{"class":274},[268,52761,52248],{"class":278},[268,52763,622],{"class":282},[268,52765,52766],{"class":289},"'C responded'",[268,52768,33111],{"class":282},[268,52770,38263],{"class":305},[268,52772,4818],{"class":282},[268,52774,52775],{"class":270,"line":311},[268,52776,5033],{"emptyLinePlaceholder":35},[268,52778,52779,52781,52783,52786],{"class":270,"line":788},[268,52780,91],{"class":305},[268,52782,462],{"class":282},[268,52784,52785],{"class":278},"race",[268,52787,52788],{"class":282},"([mirrorA, mirrorB, mirrorC])\n",[268,52790,52791,52793,52795,52797,52800,52802,52804,52806,52808,52811],{"class":270,"line":1951},[268,52792,41697],{"class":282},[268,52794,47505],{"class":278},[268,52796,622],{"class":282},[268,52798,52799],{"class":1222},"v",[268,52801,14969],{"class":274},[268,52803,9417],{"class":282},[268,52805,1356],{"class":278},[268,52807,622],{"class":282},[268,52809,52810],{"class":289},"'winner:'",[268,52812,52813],{"class":282},", v))\n",[268,52815,52816,52818,52820,52822,52824,52826,52828,52830,52832,52835],{"class":270,"line":8955},[268,52817,41697],{"class":282},[268,52819,12488],{"class":278},[268,52821,622],{"class":282},[268,52823,40624],{"class":1222},[268,52825,14969],{"class":274},[268,52827,9417],{"class":282},[268,52829,1356],{"class":278},[268,52831,622],{"class":282},[268,52833,52834],{"class":289},"'race rejected:'",[268,52836,52837],{"class":282},", e.message));\n",[23,52839,52841,52847,52853,52859],{"className":52840},[26],[28,52842,52844,52846],{"className":52843},[31],[33,52845],{"disabled":35,"type":36}," 'race rejected: B timed out'",[28,52848,52850,52852],{"className":52849},[31],[33,52851],{"disabled":35,"type":36}," 'winner: C responded'",[28,52854,52856,52858],{"className":52855},[31],[33,52857],{"disabled":35,"type":36}," 'winner: A responded'",[28,52860,52862,52864,52865,52868],{"className":52861},[31],[33,52863],{"disabled":35,"type":36}," Nothing — ",[39,52866,52867],{},"Promise.race"," requires every input to fulfill, never reject",[66,52870,52871,52873,52878],{},[69,52872,71],{},[73,52874,52875,52877],{},[76,52876,78],{}," A — 'race rejected: B timed out'",[73,52879,52880,355,52882,52884,52885,52888,52889,52892,52893,52896,52897,52900,52901,52904],{},[76,52881,84],{},[39,52883,52867],{}," settles with whichever input promise settles ",[76,52886,52887],{},"first, period"," — fulfillment and rejection are treated identically as \"settling.\" ",[39,52890,52891],{},"mirrorB"," rejects at 30ms, which is earlier than ",[39,52894,52895],{},"mirrorC","'s fulfillment at 150ms or ",[39,52898,52899],{},"mirrorA","'s at 200ms, so the race settles as a rejection even though two of the three mirrors would have eventually succeeded. This trips people up because \"race\" sounds like it should mean \"first success\" — that behavior is actually ",[39,52902,52903],{},"Promise.any",", covered next.",[15,52906,52907,52914,53101,53126],{"language":247},[18,52908,52910,52911,52913],{"id":52909},"q13-using-the-same-three-mirrors-from-the-previous-question-what-does-promiseany-produce","Q13. Using the same three mirrors from the previous question, what does ",[39,52912,52903],{}," produce?",[257,52915,52916],{"language":247},[260,52917,52919],{"className":262,"code":52918,"language":247,"meta":264,"style":264},"const mirrorA = new Promise(res => setTimeout(() => res('A responded'), 200));\nconst mirrorB = new Promise((_, rej) => setTimeout(() => rej(new Error('B timed out')), 30));\nconst mirrorC = new Promise(res => setTimeout(() => res('C responded'), 150));\n\nPromise.any([mirrorA, mirrorB, mirrorC])\n  .then(v => console.log('winner:', v))\n  .catch(e => console.log('any rejected:', e));\n",[39,52920,52921,52957,53005,53041,53045,53055,53077],{"__ignoreMap":264},[268,52922,52923,52925,52927,52929,52931,52933,52935,52937,52939,52941,52943,52945,52947,52949,52951,52953,52955],{"class":270,"line":271},[268,52924,243],{"class":274},[268,52926,52653],{"class":305},[268,52928,616],{"class":274},[268,52930,11370],{"class":274},[268,52932,50116],{"class":305},[268,52934,622],{"class":282},[268,52936,52237],{"class":1222},[268,52938,14969],{"class":274},[268,52940,40796],{"class":278},[268,52942,9411],{"class":282},[268,52944,9414],{"class":274},[268,52946,52248],{"class":278},[268,52948,622],{"class":282},[268,52950,52678],{"class":289},[268,52952,33111],{"class":282},[268,52954,40987],{"class":305},[268,52956,4818],{"class":282},[268,52958,52959,52961,52963,52965,52967,52969,52971,52973,52975,52977,52979,52981,52983,52985,52987,52989,52991,52993,52995,52997,52999,53001,53003],{"class":270,"line":286},[268,52960,243],{"class":274},[268,52962,52691],{"class":305},[268,52964,616],{"class":274},[268,52966,11370],{"class":274},[268,52968,50116],{"class":305},[268,52970,6122],{"class":282},[268,52972,52315],{"class":1222},[268,52974,42],{"class":282},[268,52976,52320],{"class":1222},[268,52978,6131],{"class":282},[268,52980,9414],{"class":274},[268,52982,40796],{"class":278},[268,52984,9411],{"class":282},[268,52986,9414],{"class":274},[268,52988,52333],{"class":278},[268,52990,622],{"class":282},[268,52992,2689],{"class":274},[268,52994,11593],{"class":278},[268,52996,622],{"class":282},[268,52998,52728],{"class":289},[268,53000,52347],{"class":282},[268,53002,24274],{"class":305},[268,53004,4818],{"class":282},[268,53006,53007,53009,53011,53013,53015,53017,53019,53021,53023,53025,53027,53029,53031,53033,53035,53037,53039],{"class":270,"line":296},[268,53008,243],{"class":274},[268,53010,52741],{"class":305},[268,53012,616],{"class":274},[268,53014,11370],{"class":274},[268,53016,50116],{"class":305},[268,53018,622],{"class":282},[268,53020,52237],{"class":1222},[268,53022,14969],{"class":274},[268,53024,40796],{"class":278},[268,53026,9411],{"class":282},[268,53028,9414],{"class":274},[268,53030,52248],{"class":278},[268,53032,622],{"class":282},[268,53034,52766],{"class":289},[268,53036,33111],{"class":282},[268,53038,38263],{"class":305},[268,53040,4818],{"class":282},[268,53042,53043],{"class":270,"line":311},[268,53044,5033],{"emptyLinePlaceholder":35},[268,53046,53047,53049,53051,53053],{"class":270,"line":788},[268,53048,91],{"class":305},[268,53050,462],{"class":282},[268,53052,21375],{"class":278},[268,53054,52788],{"class":282},[268,53056,53057,53059,53061,53063,53065,53067,53069,53071,53073,53075],{"class":270,"line":1951},[268,53058,41697],{"class":282},[268,53060,47505],{"class":278},[268,53062,622],{"class":282},[268,53064,52799],{"class":1222},[268,53066,14969],{"class":274},[268,53068,9417],{"class":282},[268,53070,1356],{"class":278},[268,53072,622],{"class":282},[268,53074,52810],{"class":289},[268,53076,52813],{"class":282},[268,53078,53079,53081,53083,53085,53087,53089,53091,53093,53095,53098],{"class":270,"line":8955},[268,53080,41697],{"class":282},[268,53082,12488],{"class":278},[268,53084,622],{"class":282},[268,53086,40624],{"class":1222},[268,53088,14969],{"class":274},[268,53090,9417],{"class":282},[268,53092,1356],{"class":278},[268,53094,622],{"class":282},[268,53096,53097],{"class":289},"'any rejected:'",[268,53099,53100],{"class":282},", e));\n",[23,53102,53104,53110,53115,53121],{"className":53103},[26],[28,53105,53107,53109],{"className":53106},[31],[33,53108],{"disabled":35,"type":36}," 'any rejected: Error: B timed out'",[28,53111,53113,52852],{"className":53112},[31],[33,53114],{"disabled":35,"type":36},[28,53116,53118,53120],{"className":53117},[31],[33,53119],{"disabled":35,"type":36}," 'winner: B timed out'",[28,53122,53124,52858],{"className":53123},[31],[33,53125],{"disabled":35,"type":36},[66,53127,53128,53130,53135],{},[69,53129,71],{},[73,53131,53132,53134],{},[76,53133,78],{}," B — 'winner: C responded'",[73,53136,53137,355,53139,53141,53142,53145,53146,53148,53149,53152,53153,53155,53156,53158,53159,53161,53162,53164],{},[76,53138,84],{},[39,53140,52903],{}," resolves with the first promise to ",[76,53143,53144],{},"fulfill",", ignoring rejections along the way — it only rejects if ",[104,53147,52364],{}," inputs reject (with an ",[39,53150,53151],{},"AggregateError"," collecting every individual reason). Here ",[39,53154,52891],{}," rejects at 30ms but that's not enough to settle the race; ",[39,53157,52895],{}," is the first to ",[104,53160,53144],{},", at 150ms, so that's the winner, even though ",[39,53163,52891],{}," technically settled earlier.",[15,53166,53167,53171,53299,53338],{"language":247},[18,53168,53170],{"id":53169},"q14-all-three-mirrors-are-down-what-does-this-log","Q14. All three mirrors are down. What does this log?",[257,53172,53173],{"language":247},[260,53174,53176],{"className":262,"code":53175,"language":247,"meta":264,"style":264},"Promise.any([\n  Promise.reject(new Error('A down')),\n  Promise.reject(new Error('B down')),\n  Promise.reject(new Error('C down')),\n]).catch(err => {\n  console.log(err.name);\n  console.log(err.errors.map(e => e.message));\n});\n",[39,53177,53178,53188,53209,53230,53251,53266,53275,53295],{"__ignoreMap":264},[268,53179,53180,53182,53184,53186],{"class":270,"line":271},[268,53181,91],{"class":305},[268,53183,462],{"class":282},[268,53185,21375],{"class":278},[268,53187,52512],{"class":282},[268,53189,53190,53192,53194,53196,53198,53200,53202,53204,53207],{"class":270,"line":286},[268,53191,49522],{"class":305},[268,53193,462],{"class":282},[268,53195,50837],{"class":278},[268,53197,622],{"class":282},[268,53199,2689],{"class":274},[268,53201,11593],{"class":278},[268,53203,622],{"class":282},[268,53205,53206],{"class":289},"'A down'",[268,53208,52549],{"class":282},[268,53210,53211,53213,53215,53217,53219,53221,53223,53225,53228],{"class":270,"line":296},[268,53212,49522],{"class":305},[268,53214,462],{"class":282},[268,53216,50837],{"class":278},[268,53218,622],{"class":282},[268,53220,2689],{"class":274},[268,53222,11593],{"class":278},[268,53224,622],{"class":282},[268,53226,53227],{"class":289},"'B down'",[268,53229,52549],{"class":282},[268,53231,53232,53234,53236,53238,53240,53242,53244,53246,53249],{"class":270,"line":311},[268,53233,49522],{"class":305},[268,53235,462],{"class":282},[268,53237,50837],{"class":278},[268,53239,622],{"class":282},[268,53241,2689],{"class":274},[268,53243,11593],{"class":278},[268,53245,622],{"class":282},[268,53247,53248],{"class":289},"'C down'",[268,53250,52549],{"class":282},[268,53252,53253,53256,53258,53260,53262,53264],{"class":270,"line":788},[268,53254,53255],{"class":282},"]).",[268,53257,12488],{"class":278},[268,53259,622],{"class":282},[268,53261,48255],{"class":1222},[268,53263,14969],{"class":274},[268,53265,9914],{"class":282},[268,53267,53268,53270,53272],{"class":270,"line":1951},[268,53269,5556],{"class":282},[268,53271,1356],{"class":278},[268,53273,53274],{"class":282},"(err.name);\n",[268,53276,53277,53279,53281,53284,53286,53288,53290,53292],{"class":270,"line":8955},[268,53278,5556],{"class":282},[268,53280,1356],{"class":278},[268,53282,53283],{"class":282},"(err.errors.",[268,53285,23950],{"class":278},[268,53287,622],{"class":282},[268,53289,40624],{"class":1222},[268,53291,14969],{"class":274},[268,53293,53294],{"class":282}," e.message));\n",[268,53296,53297],{"class":270,"line":8966},[268,53298,20047],{"class":282},[23,53300,53302,53311,53322,53330],{"className":53301},[26],[28,53303,53305,53307,53308],{"className":53304},[31],[33,53306],{"disabled":35,"type":36}," 'Error' then ",[268,53309,53310],{},"'A down', 'B down', 'C down'",[28,53312,53314,52159,53316,53318,53319,53321],{"className":53313},[31],[33,53315],{"disabled":35,"type":36},[39,53317,47426],{}," never fires because ",[39,53320,52903],{}," can't reject",[28,53323,53325,53327,53328],{"className":53324},[31],[33,53326],{"disabled":35,"type":36}," 'AggregateError' then ",[268,53329,53310],{},[28,53331,53333,53327,53335,53337],{"className":53332},[31],[33,53334],{"disabled":35,"type":36},[268,53336,53206],{},"  — only the first rejection is kept",[66,53339,53340,53342,53349],{},[69,53341,71],{},[73,53343,53344,53346,53347],{},[76,53345,78],{}," C — 'AggregateError' then ",[268,53348,53310],{},[73,53350,53351,45383,53353,53355,53356,53358,53359,29571,53361,53364,53365,53367],{},[76,53352,84],{},[76,53354,37208],{}," input to ",[39,53357,52903],{}," rejects, it rejects with a single ",[39,53360,53151],{},[39,53362,53363],{},".errors"," property is an array holding all the individual rejection reasons in input order — not just the first or last one. This lets a caller inspect exactly why every candidate failed, unlike a plain ",[39,53366,48601],{}," which could only carry one message.",[15,53369,53370,53372,53435,53467],{"language":247},[18,53371,18417],{"id":18416},[257,53373,53374],{"language":247},[260,53375,53377],{"className":262,"code":53376,"language":247,"meta":264,"style":264},"const original = Promise.resolve('value');\nconst wrapped = Promise.resolve(original);\n\nconsole.log(wrapped === original);\n",[39,53378,53379,53400,53417,53421],{"__ignoreMap":264},[268,53380,53381,53383,53385,53387,53389,53391,53393,53395,53398],{"class":270,"line":271},[268,53382,243],{"class":274},[268,53384,20173],{"class":305},[268,53386,616],{"class":274},[268,53388,50116],{"class":305},[268,53390,462],{"class":282},[268,53392,47500],{"class":278},[268,53394,622],{"class":282},[268,53396,53397],{"class":289},"'value'",[268,53399,628],{"class":282},[268,53401,53402,53404,53407,53409,53411,53413,53415],{"class":270,"line":286},[268,53403,243],{"class":274},[268,53405,53406],{"class":305}," wrapped",[268,53408,616],{"class":274},[268,53410,50116],{"class":305},[268,53412,462],{"class":282},[268,53414,47500],{"class":278},[268,53416,22300],{"class":282},[268,53418,53419],{"class":270,"line":296},[268,53420,5033],{"emptyLinePlaceholder":35},[268,53422,53423,53425,53427,53430,53432],{"class":270,"line":311},[268,53424,1353],{"class":282},[268,53426,1356],{"class":278},[268,53428,53429],{"class":282},"(wrapped ",[268,53431,3280],{"class":274},[268,53433,53434],{"class":282}," original);\n",[23,53436,53438,53443,53452,53462],{"className":53437},[26],[28,53439,53441,3200],{"className":53440},[31],[33,53442],{"disabled":35,"type":36},[28,53444,53446,53448,53449,53451],{"className":53445},[31],[33,53447],{"disabled":35,"type":36}," undefined — comparing promises with ",[39,53450,3280],{}," always throws",[28,53453,53455,53457,53458,53461],{"className":53454},[31],[33,53456],{"disabled":35,"type":36}," false, but ",[39,53459,53460],{},"wrapped"," resolves to a Promise object rather than 'value'",[28,53463,53465,7905],{"className":53464},[31],[33,53466],{"disabled":35,"type":36},[66,53468,53469,53471,53476],{},[69,53470,71],{},[73,53472,53473,53475],{},[76,53474,78],{}," D — true",[73,53477,53478,355,53480,53483,53484,53487,53488,53491,53492,53494,53495,53498],{},[76,53479,84],{},[39,53481,53482],{},"Promise.resolve()"," has a special case: if you pass it a value that is ",[76,53485,53486],{},"already a genuine promise",", it returns that exact same promise instance rather than wrapping it in a new one — there's no such thing as a \"promise of a promise\" in the spec's eyes. This differs from passing a plain ",[76,53489,53490],{},"thenable"," (a non-promise object with a ",[39,53493,47423],{}," method), where ",[39,53496,53497],{},"Promise.resolve"," creates a brand-new native promise that adopts the thenable's eventual state instead of returning the thenable itself.",[15,53500,53501,53505,53607,53634],{"language":247},[18,53502,53504],{"id":53503},"q16-what-order-do-these-log-in","Q16. What order do these log in?",[257,53506,53507],{"language":247},[260,53508,53510],{"className":262,"code":53509,"language":247,"meta":264,"style":264},"console.log('1: script start');\n\nnew Promise(resolve => {\n  console.log('2: executor runs');\n  resolve('done');\n}).then(val => console.log('4: then callback,', val));\n\nconsole.log('3: script end');\n",[39,53511,53512,53525,53529,53543,53556,53567,53590,53594],{"__ignoreMap":264},[268,53513,53514,53516,53518,53520,53523],{"class":270,"line":271},[268,53515,1353],{"class":282},[268,53517,1356],{"class":278},[268,53519,622],{"class":282},[268,53521,53522],{"class":289},"'1: script start'",[268,53524,628],{"class":282},[268,53526,53527],{"class":270,"line":286},[268,53528,5033],{"emptyLinePlaceholder":35},[268,53530,53531,53533,53535,53537,53539,53541],{"class":270,"line":296},[268,53532,2689],{"class":274},[268,53534,50116],{"class":305},[268,53536,622],{"class":282},[268,53538,47500],{"class":1222},[268,53540,14969],{"class":274},[268,53542,9914],{"class":282},[268,53544,53545,53547,53549,53551,53554],{"class":270,"line":311},[268,53546,5556],{"class":282},[268,53548,1356],{"class":278},[268,53550,622],{"class":282},[268,53552,53553],{"class":289},"'2: executor runs'",[268,53555,628],{"class":282},[268,53557,53558,53560,53562,53565],{"class":270,"line":788},[268,53559,50143],{"class":278},[268,53561,622],{"class":282},[268,53563,53564],{"class":289},"'done'",[268,53566,628],{"class":282},[268,53568,53569,53571,53573,53575,53577,53579,53581,53583,53585,53588],{"class":270,"line":1951},[268,53570,50150],{"class":282},[268,53572,47505],{"class":278},[268,53574,622],{"class":282},[268,53576,4315],{"class":1222},[268,53578,14969],{"class":274},[268,53580,9417],{"class":282},[268,53582,1356],{"class":278},[268,53584,622],{"class":282},[268,53586,53587],{"class":289},"'4: then callback,'",[268,53589,51993],{"class":282},[268,53591,53592],{"class":270,"line":8955},[268,53593,5033],{"emptyLinePlaceholder":35},[268,53595,53596,53598,53600,53602,53605],{"class":270,"line":8966},[268,53597,1353],{"class":282},[268,53599,1356],{"class":278},[268,53601,622],{"class":282},[268,53603,53604],{"class":289},"'3: script end'",[268,53606,628],{"class":282},[23,53608,53610,53616,53622,53628],{"className":53609},[26],[28,53611,53613,53615],{"className":53612},[31],[33,53614],{"disabled":35,"type":36}," '1: script start', '2: executor runs', '3: script end', '4: then callback, done'",[28,53617,53619,53621],{"className":53618},[31],[33,53620],{"disabled":35,"type":36}," '1: script start', '3: script end', '2: executor runs', '4: then callback, done'",[28,53623,53625,53627],{"className":53624},[31],[33,53626],{"disabled":35,"type":36}," '1: script start', '2: executor runs', '4: then callback, done', '3: script end'",[28,53629,53631,53633],{"className":53630},[31],[33,53632],{"disabled":35,"type":36}," '2: executor runs', '1: script start', '3: script end', '4: then callback, done'",[66,53635,53636,53638,53643],{},[69,53637,71],{},[73,53639,53640,53642],{},[76,53641,78],{}," A — '1: script start', '2: executor runs', '3: script end', '4: then callback, done'",[73,53644,53645,53647,53648,53650,53651,53654,53655,53657,53658,53660,53661,20143,53663,53665,53666,53669,53670,53672,53673,53676],{},[76,53646,84],{}," The function passed to ",[39,53649,50266],{}," — the ",[76,53652,53653],{},"executor"," — runs ",[76,53656,50270],{},", right when the constructor is called, not deferred to a later tick. That's why ",[39,53659,53553],{}," logs in the middle of the synchronous script, before ",[39,53662,53604],{},[39,53664,47423],{}," callbacks are always deferred to the ",[76,53667,53668],{},"microtask queue",", even when the promise is already resolved by the time ",[39,53671,47423],{}," is attached — so ",[39,53674,53675],{},"'4:...'"," can only run after the current synchronous run of the script finishes, landing last.",[15,53678,53679,53681,53777,53807],{"language":247},[18,53680,15311],{"id":15310},[257,53682,53683],{"language":247},[260,53684,53686],{"className":262,"code":53685,"language":247,"meta":264,"style":264},"const p = new Promise((resolve, reject) => {\n  JSON.parse('{ this is not valid json');\n  resolve('never reached');\n});\n\np.catch(err => console.log('caught:', err.constructor.name));\n",[39,53687,53688,53714,53730,53741,53745,53749],{"__ignoreMap":264},[268,53689,53690,53692,53694,53696,53698,53700,53702,53704,53706,53708,53710,53712],{"class":270,"line":271},[268,53691,243],{"class":274},[268,53693,29927],{"class":305},[268,53695,616],{"class":274},[268,53697,11370],{"class":274},[268,53699,50116],{"class":305},[268,53701,6122],{"class":282},[268,53703,47500],{"class":1222},[268,53705,42],{"class":282},[268,53707,50837],{"class":1222},[268,53709,6131],{"class":282},[268,53711,9414],{"class":274},[268,53713,9914],{"class":282},[268,53715,53716,53719,53721,53723,53725,53728],{"class":270,"line":286},[268,53717,53718],{"class":305},"  JSON",[268,53720,462],{"class":282},[268,53722,22274],{"class":278},[268,53724,622],{"class":282},[268,53726,53727],{"class":289},"'{ this is not valid json'",[268,53729,628],{"class":282},[268,53731,53732,53734,53736,53739],{"class":270,"line":296},[268,53733,50143],{"class":278},[268,53735,622],{"class":282},[268,53737,53738],{"class":289},"'never reached'",[268,53740,628],{"class":282},[268,53742,53743],{"class":270,"line":311},[268,53744,20047],{"class":282},[268,53746,53747],{"class":270,"line":788},[268,53748,5033],{"emptyLinePlaceholder":35},[268,53750,53751,53753,53755,53757,53759,53761,53763,53765,53767,53769,53772,53774],{"class":270,"line":1951},[268,53752,50890],{"class":282},[268,53754,12488],{"class":278},[268,53756,622],{"class":282},[268,53758,48255],{"class":1222},[268,53760,14969],{"class":274},[268,53762,9417],{"class":282},[268,53764,1356],{"class":278},[268,53766,622],{"class":282},[268,53768,51426],{"class":289},[268,53770,53771],{"class":282},", err.",[268,53773,23189],{"class":305},[268,53775,53776],{"class":282},".name));\n",[23,53778,53780,53786,53792,53801],{"className":53779},[26],[28,53781,53783,53785],{"className":53782},[31],[33,53784],{"disabled":35,"type":36}," Nothing — the malformed JSON crashes the script since it's thrown outside a try\u002Fcatch",[28,53787,53789,53791],{"className":53788},[31],[33,53790],{"disabled":35,"type":36}," 'caught: SyntaxError'",[28,53793,53795,53797,53798,53800],{"className":53794},[31],[33,53796],{"disabled":35,"type":36}," The promise stays pending forever because ",[39,53799,50837],{}," was never explicitly called",[28,53802,53804,53806],{"className":53803},[31],[33,53805],{"disabled":35,"type":36}," 'caught: undefined'",[66,53808,53809,53811,53816],{},[69,53810,71],{},[73,53812,53813,53815],{},[76,53814,78],{}," B — 'caught: SyntaxError'",[73,53817,53818,53820,53821,53824,53825,2278,53827,53829,53830,53833,53834,53836,53837,53839],{},[76,53819,84],{}," Any synchronous throw inside a promise executor is ",[76,53822,53823],{},"automatically caught by the Promise machinery itself"," and converted into a rejection with that thrown value as the reason — you don't need your own try\u002Fcatch inside the executor. ",[39,53826,22423],{},[39,53828,1274],{}," on malformed input, that throw never reaches ",[39,53831,53832],{},"resolve('never reached')",", and the promise settles as rejected with the ",[39,53835,1274],{}," as its reason, which ",[39,53838,47426],{}," then receives.",[15,53841,53842,53849,53947,53990],{"language":247},[18,53843,53845,53846,53848],{"id":53844},"q18-this-promise-chain-has-no-catch-anywhere-whats-the-most-accurate-description-of-what-happens-when-it-runs-eg-in-a-browser","Q18. This promise chain has no ",[39,53847,49873],{}," anywhere. What's the most accurate description of what happens when it runs (e.g., in a browser)?",[257,53850,53851],{"language":247},[260,53852,53854],{"className":262,"code":53853,"language":247,"meta":264,"style":264},"function loadUserProfile(id) {\n  return fetch(`\u002Fapi\u002Fusers\u002F${id}`)\n    .then(res => res.json())\n    .then(data => data.profile.avatarUrl.toUpperCase());\n}\n\nloadUserProfile(999);\n",[39,53855,53856,53869,53887,53908,53927,53931,53935],{"__ignoreMap":264},[268,53857,53858,53860,53863,53865,53867],{"class":270,"line":271},[268,53859,275],{"class":274},[268,53861,53862],{"class":278}," loadUserProfile",[268,53864,622],{"class":282},[268,53866,14610],{"class":1222},[268,53868,1235],{"class":282},[268,53870,53871,53873,53876,53878,53881,53883,53885],{"class":270,"line":286},[268,53872,1240],{"class":274},[268,53874,53875],{"class":278}," fetch",[268,53877,622],{"class":282},[268,53879,53880],{"class":289},"`\u002Fapi\u002Fusers\u002F${",[268,53882,14610],{"class":282},[268,53884,11603],{"class":289},[268,53886,20702],{"class":282},[268,53888,53889,53892,53894,53896,53898,53900,53903,53905],{"class":270,"line":296},[268,53890,53891],{"class":282},"    .",[268,53893,47505],{"class":278},[268,53895,622],{"class":282},[268,53897,52237],{"class":1222},[268,53899,14969],{"class":274},[268,53901,53902],{"class":282}," res.",[268,53904,1751],{"class":278},[268,53906,53907],{"class":282},"())\n",[268,53909,53910,53912,53914,53916,53918,53920,53923,53925],{"class":270,"line":311},[268,53911,53891],{"class":282},[268,53913,47505],{"class":278},[268,53915,622],{"class":282},[268,53917,21188],{"class":1222},[268,53919,14969],{"class":274},[268,53921,53922],{"class":282}," data.profile.avatarUrl.",[268,53924,16179],{"class":278},[268,53926,8174],{"class":282},[268,53928,53929],{"class":270,"line":788},[268,53930,314],{"class":282},[268,53932,53933],{"class":270,"line":1951},[268,53934,5033],{"emptyLinePlaceholder":35},[268,53936,53937,53940,53942,53945],{"class":270,"line":8955},[268,53938,53939],{"class":278},"loadUserProfile",[268,53941,622],{"class":282},[268,53943,53944],{"class":305},"999",[268,53946,628],{"class":282},[23,53948,53950,53959,53969,53979],{"className":53949},[26],[28,53951,53953,53955,53956,53958],{"className":53952},[31],[33,53954],{"disabled":35,"type":36}," JavaScript automatically logs the error to the console and continues as if ",[39,53957,47426],{}," had been attached",[28,53960,53962,53964,53965,53968],{"className":53961},[31],[33,53963],{"disabled":35,"type":36}," The entire script halts immediately at ",[39,53966,53967],{},"loadUserProfile(999)",", exactly like an uncaught synchronous throw",[28,53970,53972,53974,53975,53978],{"className":53971},[31],[33,53973],{"disabled":35,"type":36}," If any link in the chain rejects, the rejection goes unhandled: the runtime fires an ",[39,53976,53977],{},"unhandledrejection"," event (and Node can be configured to crash the process on it), but the error is otherwise silently swallowed from the caller's perspective",[28,53980,53982,53984,53985,53987,53988],{"className":53981},[31],[33,53983],{"disabled":35,"type":36}," Nothing special happens — a promise chain without ",[39,53986,47426],{}," behaves identically to one with ",[39,53989,47426],{},[66,53991,53992,53994,54001],{},[69,53993,71],{},[73,53995,53996,53998,53999,53978],{},[76,53997,78],{}," C — If any link in the chain rejects, the rejection goes unhandled: the runtime fires an ",[39,54000,53977],{},[73,54002,54003,54005,54006,54008,54009,54012,54013,54016,54017,54020,54021,54023,54024,54026,54027,54029,54030,54032],{},[76,54004,84],{}," Without a terminal ",[39,54007,49873],{}," (or a rejection handler somewhere downstream), a rejection anywhere in this chain — a network failure, a missing ",[39,54010,54011],{},"profile"," field making ",[39,54014,54015],{},".avatarUrl"," throw — becomes an ",[76,54018,54019],{},"unhandled rejection",". Browsers surface this via the ",[39,54022,53977],{}," event on ",[39,54025,189],{}," (usually just a console warning); Node.js emits the same event and, depending on configuration, can terminate the process. Critically, the calling code (",[39,54028,53967],{}," here) gets no synchronous exception and no return value indicating failure — the error simply vanishes from the caller's point of view unless something is listening for that event or a ",[39,54031,47426],{}," exists in the chain.",[15,54034,54035,54039,54105,54154],{"language":247},[18,54036,54038],{"id":54037},"q19-which-change-makes-this-function-follow-best-practice-for-promise-based-error-handling","Q19. Which change makes this function follow best practice for promise-based error handling?",[257,54040,54041],{"language":247},[260,54042,54044],{"className":262,"code":54043,"language":247,"meta":264,"style":264},"function saveDraft(doc) {\n  db.write(doc)\n    .then(() => notifyAutosaveSuccess())\n    .then(() => updateLastSavedTimestamp());\n}\n",[39,54045,54046,54060,54071,54086,54101],{"__ignoreMap":264},[268,54047,54048,54050,54053,54055,54058],{"class":270,"line":271},[268,54049,275],{"class":274},[268,54051,54052],{"class":278}," saveDraft",[268,54054,622],{"class":282},[268,54056,54057],{"class":1222},"doc",[268,54059,1235],{"class":282},[268,54061,54062,54065,54068],{"class":270,"line":286},[268,54063,54064],{"class":282},"  db.",[268,54066,54067],{"class":278},"write",[268,54069,54070],{"class":282},"(doc)\n",[268,54072,54073,54075,54077,54079,54081,54084],{"class":270,"line":296},[268,54074,53891],{"class":282},[268,54076,47505],{"class":278},[268,54078,9411],{"class":282},[268,54080,9414],{"class":274},[268,54082,54083],{"class":278}," notifyAutosaveSuccess",[268,54085,53907],{"class":282},[268,54087,54088,54090,54092,54094,54096,54099],{"class":270,"line":311},[268,54089,53891],{"class":282},[268,54091,47505],{"class":278},[268,54093,9411],{"class":282},[268,54095,9414],{"class":274},[268,54097,54098],{"class":278}," updateLastSavedTimestamp",[268,54100,8174],{"class":282},[268,54102,54103],{"class":270,"line":788},[268,54104,314],{"class":282},[23,54106,54108,54117,54128,54138],{"className":54107},[26],[28,54109,54111,54113,54114,54116],{"className":54110},[31],[33,54112],{"disabled":35,"type":36}," Nothing needs to change — chains without ",[39,54115,47426],{}," are fine as long as the individual functions don't throw",[28,54118,54120,54122,54123,2029,54125,54127],{"className":54119},[31],[33,54121],{"disabled":35,"type":36}," Replace ",[39,54124,47423],{},[39,54126,47429],{}," on every step so failures are automatically retried",[28,54129,54131,54133,54134,54137],{"className":54130},[31],[33,54132],{"disabled":35,"type":36}," Wrap the whole function body in ",[39,54135,54136],{},"try { } catch { }"," instead — that's sufficient to catch promise rejections",[28,54139,54141,54143,54144,54146,54147,54149,54150,54153],{"className":54140},[31],[33,54142],{"disabled":35,"type":36}," Add a ",[39,54145,49873],{}," at the end of the chain (and ",[39,54148,9151],{}," the chain) so a failure in ",[39,54151,54152],{},"db.write",", the notify step, or the timestamp update is handled instead of becoming an unhandled rejection",[66,54155,54156,54158,54169],{},[69,54157,71],{},[73,54159,54160,54162,54163,54146,54165,54149,54167,54153],{},[76,54161,78],{}," D — Add a ",[39,54164,49873],{},[39,54166,9151],{},[39,54168,54152],{},[73,54170,54171,355,54173,54175,54176,54178,54179,54181,54182,54185,54186,54188,54189,54191,54192,54194,54195,54197],{},[76,54172,84],{},[76,54174,930],{}," every promise chain should terminate in a ",[39,54177,49873],{}," (or otherwise have its rejection handled by the caller) — otherwise a failure at any link becomes an unhandled rejection that silently disappears instead of being logged, retried, or surfaced to the user. A plain synchronous ",[39,54180,2081],{}," wrapped around code that merely ",[104,54183,54184],{},"starts"," a promise chain does ",[76,54187,95],{}," catch asynchronous rejections that happen later, since the ",[39,54190,23142],{}," block has already finished executing by the time ",[39,54193,47423],{}," callbacks run — that's a common misconception. ",[39,54196,47429],{}," is for cleanup, not retries, and doesn't handle rejections either.",[15,54199,54200,54202,54411,54441],{"language":247},[18,54201,19301],{"id":19300},[257,54203,54204],{"language":247},[260,54205,54207],{"className":262,"code":54206,"language":247,"meta":264,"style":264},"function chargeCard(amount) {\n  return new Promise((resolve, reject) => {\n    if (amount \u003C= 0) {\n      reject(new Error('invalid amount'));\n      return;\n    }\n    resolve(`charged $${amount}`);\n  });\n}\n\nchargeCard(-5)\n  .then(receipt => receipt)\n  .then(receipt => console.log('receipt:', receipt))\n  .catch(err => console.log('charge failed:', err.message))\n  .then(() => console.log('cleanup: closing dialog'));\n",[39,54208,54209,54222,54244,54257,54275,54281,54285,54301,54305,54309,54313,54326,54342,54366,54390],{"__ignoreMap":264},[268,54210,54211,54213,54216,54218,54220],{"class":270,"line":271},[268,54212,275],{"class":274},[268,54214,54215],{"class":278}," chargeCard",[268,54217,622],{"class":282},[268,54219,31848],{"class":1222},[268,54221,1235],{"class":282},[268,54223,54224,54226,54228,54230,54232,54234,54236,54238,54240,54242],{"class":270,"line":286},[268,54225,1240],{"class":274},[268,54227,11370],{"class":274},[268,54229,50116],{"class":305},[268,54231,6122],{"class":282},[268,54233,47500],{"class":1222},[268,54235,42],{"class":282},[268,54237,50837],{"class":1222},[268,54239,6131],{"class":282},[268,54241,9414],{"class":274},[268,54243,9914],{"class":282},[268,54245,54246,54248,54251,54253,54255],{"class":270,"line":296},[268,54247,9686],{"class":274},[268,54249,54250],{"class":282}," (amount ",[268,54252,6776],{"class":274},[268,54254,5728],{"class":305},[268,54256,1235],{"class":282},[268,54258,54259,54262,54264,54266,54268,54270,54273],{"class":270,"line":311},[268,54260,54261],{"class":278},"      reject",[268,54263,622],{"class":282},[268,54265,2689],{"class":274},[268,54267,11593],{"class":278},[268,54269,622],{"class":282},[268,54271,54272],{"class":289},"'invalid amount'",[268,54274,4818],{"class":282},[268,54276,54277,54279],{"class":270,"line":788},[268,54278,10451],{"class":274},[268,54280,293],{"class":282},[268,54282,54283],{"class":270,"line":1951},[268,54284,11972],{"class":282},[268,54286,54287,54290,54292,54295,54297,54299],{"class":270,"line":8955},[268,54288,54289],{"class":278},"    resolve",[268,54291,622],{"class":282},[268,54293,54294],{"class":289},"`charged $${",[268,54296,31848],{"class":282},[268,54298,11603],{"class":289},[268,54300,628],{"class":282},[268,54302,54303],{"class":270,"line":8966},[268,54304,39914],{"class":282},[268,54306,54307],{"class":270,"line":8974},[268,54308,314],{"class":282},[268,54310,54311],{"class":270,"line":8985},[268,54312,5033],{"emptyLinePlaceholder":35},[268,54314,54315,54318,54320,54322,54324],{"class":270,"line":8990},[268,54316,54317],{"class":278},"chargeCard",[268,54319,622],{"class":282},[268,54321,6244],{"class":274},[268,54323,2429],{"class":305},[268,54325,20702],{"class":282},[268,54327,54328,54330,54332,54334,54337,54339],{"class":270,"line":8997},[268,54329,41697],{"class":282},[268,54331,47505],{"class":278},[268,54333,622],{"class":282},[268,54335,54336],{"class":1222},"receipt",[268,54338,14969],{"class":274},[268,54340,54341],{"class":282}," receipt)\n",[268,54343,54344,54346,54348,54350,54352,54354,54356,54358,54360,54363],{"class":270,"line":9002},[268,54345,41697],{"class":282},[268,54347,47505],{"class":278},[268,54349,622],{"class":282},[268,54351,54336],{"class":1222},[268,54353,14969],{"class":274},[268,54355,9417],{"class":282},[268,54357,1356],{"class":278},[268,54359,622],{"class":282},[268,54361,54362],{"class":289},"'receipt:'",[268,54364,54365],{"class":282},", receipt))\n",[268,54367,54368,54370,54372,54374,54376,54378,54380,54382,54384,54387],{"class":270,"line":14676},[268,54369,41697],{"class":282},[268,54371,12488],{"class":278},[268,54373,622],{"class":282},[268,54375,48255],{"class":1222},[268,54377,14969],{"class":274},[268,54379,9417],{"class":282},[268,54381,1356],{"class":278},[268,54383,622],{"class":282},[268,54385,54386],{"class":289},"'charge failed:'",[268,54388,54389],{"class":282},", err.message))\n",[268,54391,54392,54394,54396,54398,54400,54402,54404,54406,54409],{"class":270,"line":14681},[268,54393,41697],{"class":282},[268,54395,47505],{"class":278},[268,54397,9411],{"class":282},[268,54399,9414],{"class":274},[268,54401,9417],{"class":282},[268,54403,1356],{"class":278},[268,54405,622],{"class":282},[268,54407,54408],{"class":289},"'cleanup: closing dialog'",[268,54410,4818],{"class":282},[23,54412,54414,54420,54426,54435],{"className":54413},[26],[28,54415,54417,54419],{"className":54416},[31],[33,54418],{"disabled":35,"type":36}," 'charge failed: invalid amount' then 'cleanup: closing dialog'",[28,54421,54423,54425],{"className":54422},[31],[33,54424],{"disabled":35,"type":36}," 'receipt: undefined' then 'cleanup: closing dialog'",[28,54427,54429,54431,54432,54434],{"className":54428},[31],[33,54430],{"disabled":35,"type":36}," 'charge failed: invalid amount' — the final ",[39,54433,47423],{}," never runs because the chain already rejected",[28,54436,54438,54440],{"className":54437},[31],[33,54439],{"disabled":35,"type":36}," 'cleanup: closing dialog' then 'charge failed: invalid amount'",[66,54442,54443,54445,54450],{},[69,54444,71],{},[73,54446,54447,54449],{},[76,54448,78],{}," A — 'charge failed: invalid amount' then 'cleanup: closing dialog'",[73,54451,54452,355,54454,54457,54458,54461,54462,54464,54465,54467,54468,54470,54471,54474,54475,54477,54478,54480,54481,54483],{},[76,54453,84],{},[39,54455,54456],{},"chargeCard(-5)"," rejects, so both intermediate ",[39,54459,54460],{},".then(receipt => receipt)"," calls are skipped (rejections skip past ",[39,54463,47423],{}," handlers with no rejection callback) until ",[39,54466,47426],{}," picks it up and logs the message. Since that ",[39,54469,47426],{}," callback returns normally (doesn't throw or return a rejected promise), the promise it produces ",[76,54472,54473],{},"fulfills",", so the chain is back in the \"happy path\" — the final ",[39,54476,47423],{}," runs normally and logs the cleanup line. This is the same \"catch resets the chain to fulfilled\" mechanism that lets a single ",[39,54479,47426],{}," recover from an error and let subsequent ",[39,54482,47423],{}," steps continue.",[2107,54485,54486],{},"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 .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-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 .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);}",{"title":264,"searchDepth":286,"depth":286,"links":54488},[54489,54490,54491,54492,54493,54494,54495,54496,54497,54498,54499,54500,54501,54503,54504,54505,54506,54507,54509,54510],{"id":50751,"depth":296,"text":50752},{"id":12736,"depth":296,"text":12737},{"id":12876,"depth":296,"text":12877},{"id":51100,"depth":296,"text":51101},{"id":13180,"depth":296,"text":13181},{"id":13320,"depth":296,"text":13321},{"id":13527,"depth":296,"text":13528},{"id":51882,"depth":296,"text":51883},{"id":13926,"depth":296,"text":13927},{"id":52211,"depth":296,"text":52212},{"id":14223,"depth":296,"text":14224},{"id":52638,"depth":296,"text":52639},{"id":52909,"depth":296,"text":54502},"Q13. Using the same three mirrors from the previous question, what does Promise.any produce?",{"id":53169,"depth":296,"text":53170},{"id":18416,"depth":296,"text":18417},{"id":53503,"depth":296,"text":53504},{"id":15310,"depth":296,"text":15311},{"id":53844,"depth":296,"text":54508},"Q18. This promise chain has no .catch() anywhere. What's the most accurate description of what happens when it runs (e.g., in a browser)?",{"id":54037,"depth":296,"text":54038},{"id":19300,"depth":296,"text":19301},{},"\u002Fjs\u002F16-promises",{"title":50741,"description":264},"js\u002F16-promises","qXj4mbOH14QUqDCu0jI3imY5lsWvGA0bHUfr0-_wba8",{"id":54517,"title":54518,"body":54519,"description":264,"extension":2144,"meta":57633,"navigation":35,"path":57634,"seo":57635,"stem":57636,"__hash__":57637},"content\u002Fjs\u002F17-async-await.md","17 — Async\u002FAwait",{"type":8,"value":54520,"toc":57600},[54521,54524,54663,54832,55029,55215,55347,55489,55619,55812,55977,56170,56346,56520,56680,56817,56892,57128,57210,57367,57526,57597],[11,54522,54518],{"id":54523},"_17-asyncawait",[15,54525,54526,54530,54584,54621],{"language":247},[18,54527,54529],{"id":54528},"q1-what-does-the-following-code-actually-log","Q1. What does the following code actually log?",[257,54531,54532],{"language":247},[260,54533,54535],{"className":262,"code":54534,"language":247,"meta":264,"style":264},"async function getNum() {\n  return 42;\n}\n\nconst result = getNum();\nconsole.log(result);\n",[39,54536,54537,54548,54556,54560,54564,54576],{"__ignoreMap":264},[268,54538,54539,54541,54543,54546],{"class":270,"line":271},[268,54540,379],{"class":274},[268,54542,12080],{"class":274},[268,54544,54545],{"class":278}," getNum",[268,54547,283],{"class":282},[268,54549,54550,54552,54554],{"class":270,"line":286},[268,54551,1240],{"class":274},[268,54553,779],{"class":305},[268,54555,293],{"class":282},[268,54557,54558],{"class":270,"line":296},[268,54559,314],{"class":282},[268,54561,54562],{"class":270,"line":311},[268,54563,5033],{"emptyLinePlaceholder":35},[268,54565,54566,54568,54570,54572,54574],{"class":270,"line":788},[268,54567,243],{"class":274},[268,54569,5583],{"class":305},[268,54571,616],{"class":274},[268,54573,54545],{"class":278},[268,54575,794],{"class":282},[268,54577,54578,54580,54582],{"class":270,"line":1951},[268,54579,1353],{"class":282},[268,54581,1356],{"class":278},[268,54583,6852],{"class":282},[23,54585,54587,54592,54602,54609],{"className":54586},[26],[28,54588,54590,779],{"className":54589},[31],[33,54591],{"disabled":35,"type":36},[28,54593,54595,812,54597,54599,54600],{"className":54594},[31],[33,54596],{"disabled":35,"type":36},[39,54598,91],{}," that resolves to ",[39,54601,4659],{},[28,54603,54605,355,54607],{"className":54604},[31],[33,54606],{"disabled":35,"type":36},[39,54608,833],{},[28,54610,54612,812,54614,54616,54617,54599,54619],{"className":54611},[31],[33,54613],{"disabled":35,"type":36},[39,54615,91],{}," that resolves to a ",[39,54618,91],{},[39,54620,4659],{},[66,54622,54623,54625,54633],{},[69,54624,71],{},[73,54626,54627,853,54629,54599,54631],{},[76,54628,78],{},[39,54630,91],{},[39,54632,4659],{},[73,54634,54635,54637,54638,54640,54641,54643,54644,54647,54648,54651,54652,54654,54655,54658,54659,54662],{},[76,54636,84],{}," An ",[39,54639,12405],{}," always returns a ",[39,54642,91],{},", no matter what its body does. A plain ",[39,54645,54646],{},"return value;"," is automatically wrapped, so ",[39,54649,54650],{},"getNum()"," immediately returns a (soon-to-be-fulfilled) ",[39,54653,91],{}," object, not the raw number — ",[39,54656,54657],{},"console.log(result)"," prints something like ",[39,54660,54661],{},"Promise { 42 }",". Option A is the classic beginner mistake of forgetting the auto-wrap. Option D is wrong because JS never nests promises like that — returned promises\u002Fthenables are flattened, not stacked (see Q4).",[15,54664,54665,54669,54762,54789],{"language":247},[18,54666,54668],{"id":54667},"q2-what-order-do-the-logs-print-in","Q2. What order do the logs print in?",[257,54670,54671],{"language":247},[260,54672,54674],{"className":262,"code":54673,"language":247,"meta":264,"style":264},"async function delayedLog() {\n  console.log(\"A\");\n  await new Promise(resolve => setTimeout(resolve, 0));\n  console.log(\"B\");\n}\n\ndelayedLog();\nconsole.log(\"C\");\n",[39,54675,54676,54687,54699,54723,54735,54739,54743,54750],{"__ignoreMap":264},[268,54677,54678,54680,54682,54685],{"class":270,"line":271},[268,54679,379],{"class":274},[268,54681,12080],{"class":274},[268,54683,54684],{"class":278}," delayedLog",[268,54686,283],{"class":282},[268,54688,54689,54691,54693,54695,54697],{"class":270,"line":286},[268,54690,5556],{"class":282},[268,54692,1356],{"class":278},[268,54694,622],{"class":282},[268,54696,47625],{"class":289},[268,54698,628],{"class":282},[268,54700,54701,54704,54706,54708,54710,54712,54714,54716,54719,54721],{"class":270,"line":296},[268,54702,54703],{"class":274},"  await",[268,54705,11370],{"class":274},[268,54707,50116],{"class":305},[268,54709,622],{"class":282},[268,54711,47500],{"class":1222},[268,54713,14969],{"class":274},[268,54715,40796],{"class":278},[268,54717,54718],{"class":282},"(resolve, ",[268,54720,3307],{"class":305},[268,54722,4818],{"class":282},[268,54724,54725,54727,54729,54731,54733],{"class":270,"line":311},[268,54726,5556],{"class":282},[268,54728,1356],{"class":278},[268,54730,622],{"class":282},[268,54732,26749],{"class":289},[268,54734,628],{"class":282},[268,54736,54737],{"class":270,"line":788},[268,54738,314],{"class":282},[268,54740,54741],{"class":270,"line":1951},[268,54742,5033],{"emptyLinePlaceholder":35},[268,54744,54745,54748],{"class":270,"line":8955},[268,54746,54747],{"class":278},"delayedLog",[268,54749,794],{"class":282},[268,54751,54752,54754,54756,54758,54760],{"class":270,"line":8966},[268,54753,1353],{"class":282},[268,54755,1356],{"class":278},[268,54757,622],{"class":282},[268,54759,47687],{"class":289},[268,54761,628],{"class":282},[23,54763,54765,54771,54777,54783],{"className":54764},[26],[28,54766,54768,54770],{"className":54767},[31],[33,54769],{"disabled":35,"type":36}," A, C, B",[28,54772,54774,54776],{"className":54773},[31],[33,54775],{"disabled":35,"type":36}," A, B, C",[28,54778,54780,54782],{"className":54779},[31],[33,54781],{"disabled":35,"type":36}," C, A, B",[28,54784,54786,54788],{"className":54785},[31],[33,54787],{"disabled":35,"type":36}," Order can't be determined — it's a race condition",[66,54790,54791,54793,54798],{},[69,54792,71],{},[73,54794,54795,54797],{},[76,54796,78],{}," A — A, C, B",[73,54799,54800,355,54802,3990,54804,54806,54807,54810,54811,54814,54815,54817,54818,54821,54822,54825,54826,54828,54829,54831],{},[76,54801,84],{},[76,54803,16523],{},[39,54805,12304],{}," only pauses the ",[104,54808,54809],{},"async function itself",", not the whole program. ",[39,54812,54813],{},"delayedLog()"," runs synchronously up to the ",[39,54816,12304],{},", logging \"A\", then immediately hands control back to the caller — so ",[39,54819,54820],{},"console.log(\"C\")"," runs next. Only after the current synchronous code and the microtask queue drain does the ",[39,54823,54824],{},"setTimeout(..., 0)"," macrotask fire, resuming ",[39,54827,54747],{}," and logging \"B\" last. This is the core misconception people bring from single-threaded, blocking languages: ",[39,54830,12304],{}," does not freeze the whole thread.",[15,54833,54834,54841,54947,54982],{"language":247},[18,54835,23672,54837,54840],{"id":54836},"q3-what-does-fetchuser1thenconsolelog-print",[39,54838,54839],{},"fetchUser(1).then(console.log)"," print?",[257,54842,54843],{"language":247},[260,54844,54846],{"className":262,"code":54845,"language":247,"meta":264,"style":264},"async function fetchUser(id) {\n  try {\n    const res = await Promise.reject(new Error(\"Network down\"));\n    return res;\n  } catch (err) {\n    return err.message;\n  }\n}\n\nfetchUser(1).then(console.log);\n",[39,54847,54848,54863,54870,54899,54906,54914,54921,54925,54929,54933],{"__ignoreMap":264},[268,54849,54850,54852,54854,54857,54859,54861],{"class":270,"line":271},[268,54851,379],{"class":274},[268,54853,12080],{"class":274},[268,54855,54856],{"class":278}," fetchUser",[268,54858,622],{"class":282},[268,54860,14610],{"class":1222},[268,54862,1235],{"class":282},[268,54864,54865,54868],{"class":270,"line":286},[268,54866,54867],{"class":274},"  try",[268,54869,9914],{"class":282},[268,54871,54872,54874,54876,54878,54880,54882,54884,54886,54888,54890,54892,54894,54897],{"class":270,"line":296},[268,54873,37893],{"class":274},[268,54875,52248],{"class":305},[268,54877,616],{"class":274},[268,54879,52502],{"class":274},[268,54881,50116],{"class":305},[268,54883,462],{"class":282},[268,54885,50837],{"class":278},[268,54887,622],{"class":282},[268,54889,2689],{"class":274},[268,54891,11593],{"class":278},[268,54893,622],{"class":282},[268,54895,54896],{"class":289},"\"Network down\"",[268,54898,4818],{"class":282},[268,54900,54901,54903],{"class":270,"line":311},[268,54902,9871],{"class":274},[268,54904,54905],{"class":282}," res;\n",[268,54907,54908,54910,54912],{"class":270,"line":788},[268,54909,9881],{"class":282},[268,54911,12488],{"class":274},[268,54913,12491],{"class":282},[268,54915,54916,54918],{"class":270,"line":1951},[268,54917,9871],{"class":274},[268,54919,54920],{"class":282}," err.message;\n",[268,54922,54923],{"class":270,"line":8955},[268,54924,1948],{"class":282},[268,54926,54927],{"class":270,"line":8966},[268,54928,314],{"class":282},[268,54930,54931],{"class":270,"line":8974},[268,54932,5033],{"emptyLinePlaceholder":35},[268,54934,54935,54937,54939,54941,54943,54945],{"class":270,"line":8985},[268,54936,47058],{"class":278},[268,54938,622],{"class":282},[268,54940,2255],{"class":305},[268,54942,6232],{"class":282},[268,54944,47505],{"class":278},[268,54946,50900],{"class":282},[23,54948,54950,54959,54966,54973],{"className":54949},[26],[28,54951,54953,54955,54956],{"className":54952},[31],[33,54954],{"disabled":35,"type":36}," Throws an uncaught ",[39,54957,54958],{},"Error: Network down",[28,54960,54962,3578,54964],{"className":54961},[31],[33,54963],{"disabled":35,"type":36},[39,54965,833],{},[28,54967,54969,3578,54971],{"className":54968},[31],[33,54970],{"disabled":35,"type":36},[39,54972,54896],{},[28,54974,54976,54978,54979,54981],{"className":54975},[31],[33,54977],{"disabled":35,"type":36}," Logs the ",[39,54980,48601],{}," object itself",[66,54983,54984,54986,54993],{},[69,54985,71],{},[73,54987,54988,54990,54991],{},[76,54989,78],{}," C — Logs ",[39,54992,54896],{},[73,54994,54995,355,54997,54999,55000,55002,55003,55005,55006,55008,55009,55012,55013,55016,55017,55019,55020,55022,55023,55025,55026,55028],{},[76,54996,84],{},[39,54998,12304],{}," on a rejected promise throws the rejection reason right at the ",[39,55001,12304],{}," expression, exactly like a synchronous ",[39,55004,48836],{},". Here that's the ",[39,55007,48601],{}," object, which the ",[39,55010,55011],{},"catch (err)"," block receives; ",[39,55014,55015],{},"err.message"," pulls out the string ",[39,55018,54896],{},", which is what ",[39,55021,47058],{}," returns (and therefore resolves its own promise with). Option D is wrong because ",[39,55024,48672],{}," extracts the string, not the ",[39,55027,48601],{}," instance. Option A is wrong because the rejection is caught locally, so it never escapes as uncaught.",[15,55030,55031,55033,55139,55185],{"language":247},[18,55032,13032],{"id":13031},[257,55034,55035],{"language":247},[260,55036,55038],{"className":262,"code":55037,"language":247,"meta":264,"style":264},"async function inner() {\n  return Promise.resolve(\"done\");\n}\n\nasync function outer() {\n  const value = await inner();\n  return value;\n}\n\nouter().then(v => console.log(typeof v, v));\n",[39,55039,55040,55050,55067,55071,55075,55085,55100,55106,55110,55114],{"__ignoreMap":264},[268,55041,55042,55044,55046,55048],{"class":270,"line":271},[268,55043,379],{"class":274},[268,55045,12080],{"class":274},[268,55047,15153],{"class":278},[268,55049,283],{"class":282},[268,55051,55052,55054,55056,55058,55060,55062,55065],{"class":270,"line":286},[268,55053,1240],{"class":274},[268,55055,50116],{"class":305},[268,55057,462],{"class":282},[268,55059,47500],{"class":278},[268,55061,622],{"class":282},[268,55063,55064],{"class":289},"\"done\"",[268,55066,628],{"class":282},[268,55068,55069],{"class":270,"line":296},[268,55070,314],{"class":282},[268,55072,55073],{"class":270,"line":311},[268,55074,5033],{"emptyLinePlaceholder":35},[268,55076,55077,55079,55081,55083],{"class":270,"line":788},[268,55078,379],{"class":274},[268,55080,12080],{"class":274},[268,55082,9700],{"class":278},[268,55084,283],{"class":282},[268,55086,55087,55089,55092,55094,55096,55098],{"class":270,"line":1951},[268,55088,12441],{"class":274},[268,55090,55091],{"class":305}," value",[268,55093,616],{"class":274},[268,55095,52502],{"class":274},[268,55097,15153],{"class":278},[268,55099,794],{"class":282},[268,55101,55102,55104],{"class":270,"line":8955},[268,55103,1240],{"class":274},[268,55105,22065],{"class":282},[268,55107,55108],{"class":270,"line":8966},[268,55109,314],{"class":282},[268,55111,55112],{"class":270,"line":8974},[268,55113,5033],{"emptyLinePlaceholder":35},[268,55115,55116,55118,55120,55122,55124,55126,55128,55130,55132,55134,55136],{"class":270,"line":8985},[268,55117,9628],{"class":278},[268,55119,19341],{"class":282},[268,55121,47505],{"class":278},[268,55123,622],{"class":282},[268,55125,52799],{"class":1222},[268,55127,14969],{"class":274},[268,55129,9417],{"class":282},[268,55131,1356],{"class":278},[268,55133,622],{"class":282},[268,55135,1361],{"class":274},[268,55137,55138],{"class":282}," v, v));\n",[23,55140,55142,55156,55164,55172],{"className":55141},[26],[28,55143,55145,355,55147,55149,55150,42,55152,55155],{"className":55144},[31],[33,55146],{"disabled":35,"type":36},[39,55148,2664],{}," (an unresolved ",[39,55151,91],{},[39,55153,55154],{},"done"," never appears)",[28,55157,55159,355,55161],{"className":55158},[31],[33,55160],{"disabled":35,"type":36},[39,55162,55163],{},"string done",[28,55165,55167,355,55169],{"className":55166},[31],[33,55168],{"disabled":35,"type":36},[39,55170,55171],{},"undefined undefined",[28,55173,55175,55177,55178,1243,55180,55182,55183],{"className":55174},[31],[33,55176],{"disabled":35,"type":36}," Throws — you can't ",[39,55179,9151],{},[39,55181,91],{}," from an ",[39,55184,12405],{},[66,55186,55187,55189,55195],{},[69,55188,71],{},[73,55190,55191,1727,55193],{},[76,55192,78],{},[39,55194,55163],{},[73,55196,55197,55199,55200,55202,55203,55206,55207,137,55209,2018,55212,55214],{},[76,55198,84],{}," Returning a promise (or any thenable) from an ",[39,55201,12405],{}," doesn't create a promise-wrapped-in-a-promise — the outer promise is flattened to adopt the state and value of the returned one. So ",[39,55204,55205],{},"inner()"," effectively resolves with ",[39,55208,55064],{},[39,55210,55211],{},"await inner()",[39,55213,9628],{}," unwraps that down to the plain string. Option A represents the common \"double-wrapping\" misconception. Option D is false: returning a promise from an async function is completely normal and is exactly how flattening is triggered.",[15,55216,55217,55227,55286,55313],{"language":247},[18,55218,55220,55221,186,55223,55226],{"id":55219},"q5-fetchuser-and-fetchstats-are-independent-neither-depends-on-the-others-result-and-each-takes-300ms","Q5. ",[39,55222,47015],{},[39,55224,55225],{},"fetchStats()"," are independent — neither depends on the other's result, and each takes ~300ms.",[257,55228,55229],{"language":247},[260,55230,55232],{"className":262,"code":55231,"language":247,"meta":264,"style":264},"async function loadDashboard() {\n  const user = await fetchUser();\n  const stats = await fetchStats();\n  return { user, stats };\n}\n",[39,55233,55234,55245,55259,55275,55282],{"__ignoreMap":264},[268,55235,55236,55238,55240,55243],{"class":270,"line":271},[268,55237,379],{"class":274},[268,55239,12080],{"class":274},[268,55241,55242],{"class":278}," loadDashboard",[268,55244,283],{"class":282},[268,55246,55247,55249,55251,55253,55255,55257],{"class":270,"line":286},[268,55248,12441],{"class":274},[268,55250,4071],{"class":305},[268,55252,616],{"class":274},[268,55254,52502],{"class":274},[268,55256,54856],{"class":278},[268,55258,794],{"class":282},[268,55260,55261,55263,55266,55268,55270,55273],{"class":270,"line":296},[268,55262,12441],{"class":274},[268,55264,55265],{"class":305}," stats",[268,55267,616],{"class":274},[268,55269,52502],{"class":274},[268,55271,55272],{"class":278}," fetchStats",[268,55274,794],{"class":282},[268,55276,55277,55279],{"class":270,"line":311},[268,55278,1240],{"class":274},[268,55280,55281],{"class":282}," { user, stats };\n",[268,55283,55284],{"class":270,"line":788},[268,55285,314],{"class":282},[23,55287,55289,55295,55301,55307],{"className":55288},[26],[28,55290,55292,55294],{"className":55291},[31],[33,55293],{"disabled":35,"type":36}," ~150ms",[28,55296,55298,55300],{"className":55297},[31],[33,55299],{"disabled":35,"type":36}," ~300ms",[28,55302,55304,55306],{"className":55303},[31],[33,55305],{"disabled":35,"type":36}," Indeterminate — depends on the event loop",[28,55308,55310,55312],{"className":55309},[31],[33,55311],{"disabled":35,"type":36}," ~600ms",[66,55314,55315,55317,55322],{},[69,55316,71],{},[73,55318,55319,55321],{},[76,55320,78],{}," D — ~600ms",[73,55323,55324,355,55326,3990,55329,55331,55332,55335,55336,6033,55338,55340,55341,55343,55344,55346],{},[76,55325,84],{},[76,55327,55328],{},"Performance",[39,55330,55225],{}," isn't even ",[104,55333,55334],{},"called"," until the ",[39,55337,12304],{},[39,55339,47015],{}," finishes, so the two 300ms operations run back-to-back instead of overlapping, even though nothing about them requires that. This is one of the most common async\u002Fawait performance footguns: writing two independent operations as consecutive ",[39,55342,12304],{}," lines silently serializes them. The fix is to start both before awaiting either (Q6) or use ",[39,55345,52467],{}," (Q7).",[15,55348,55349,55353,55432,55462],{"language":247},[18,55350,55352],{"id":55351},"q6-same-independent-300ms-calls-as-q5-but-written-like-this-instead","Q6. Same independent, ~300ms calls as Q5, but written like this instead:",[257,55354,55355],{"language":247},[260,55356,55358],{"className":262,"code":55357,"language":247,"meta":264,"style":264},"async function loadDashboard() {\n  const userPromise = fetchUser();\n  const statsPromise = fetchStats();\n  const user = await userPromise;\n  const stats = await statsPromise;\n  return { user, stats };\n}\n",[39,55359,55360,55370,55383,55396,55409,55422,55428],{"__ignoreMap":264},[268,55361,55362,55364,55366,55368],{"class":270,"line":271},[268,55363,379],{"class":274},[268,55365,12080],{"class":274},[268,55367,55242],{"class":278},[268,55369,283],{"class":282},[268,55371,55372,55374,55377,55379,55381],{"class":270,"line":286},[268,55373,12441],{"class":274},[268,55375,55376],{"class":305}," userPromise",[268,55378,616],{"class":274},[268,55380,54856],{"class":278},[268,55382,794],{"class":282},[268,55384,55385,55387,55390,55392,55394],{"class":270,"line":296},[268,55386,12441],{"class":274},[268,55388,55389],{"class":305}," statsPromise",[268,55391,616],{"class":274},[268,55393,55272],{"class":278},[268,55395,794],{"class":282},[268,55397,55398,55400,55402,55404,55406],{"class":270,"line":311},[268,55399,12441],{"class":274},[268,55401,4071],{"class":305},[268,55403,616],{"class":274},[268,55405,52502],{"class":274},[268,55407,55408],{"class":282}," userPromise;\n",[268,55410,55411,55413,55415,55417,55419],{"class":270,"line":788},[268,55412,12441],{"class":274},[268,55414,55265],{"class":305},[268,55416,616],{"class":274},[268,55418,52502],{"class":274},[268,55420,55421],{"class":282}," statsPromise;\n",[268,55423,55424,55426],{"class":270,"line":1951},[268,55425,1240],{"class":274},[268,55427,55281],{"class":282},[268,55429,55430],{"class":270,"line":8955},[268,55431,314],{"class":282},[23,55433,55435,55441,55447,55453],{"className":55434},[26],[28,55436,55438,55440],{"className":55437},[31],[33,55439],{"disabled":35,"type":36}," ~300ms total — both calls start immediately and run concurrently",[28,55442,55444,55446],{"className":55443},[31],[33,55445],{"disabled":35,"type":36}," ~600ms — identical timing to Q5",[28,55448,55450,55452],{"className":55449},[31],[33,55451],{"disabled":35,"type":36}," Throws a race-condition error since both are in flight at once",[28,55454,55456,55458,55459,55461],{"className":55455},[31],[33,55457],{"disabled":35,"type":36}," ~300ms, but only if ",[39,55460,47058],{}," happens to resolve first",[66,55463,55464,55466,55471],{},[69,55465,71],{},[73,55467,55468,55470],{},[76,55469,78],{}," A — ~300ms total — both calls start immediately and run concurrently",[73,55472,55473,355,55475,55477,55478,186,55480,55482,55483,55485,55486,55488],{},[76,55474,84],{},[76,55476,55328],{}," — Calling ",[39,55479,47015],{},[39,55481,55225],{}," without immediately awaiting them kicks off both underlying operations right away; they run concurrently while the async function is paused. The later ",[39,55484,12304],{}," calls just wait on promises that are already in flight, so total wall time is bounded by the slower of the two (~300ms), not their sum. Option D is a trap: correctness here doesn't depend on which resolves first, since each ",[39,55487,12304],{}," targets its own dedicated promise variable.",[15,55490,55491,55495,55559,55589],{"language":247},[18,55492,55494],{"id":55493},"q7-how-does-this-version-compare-to-q6s-manual-start-both-then-await-both-pattern","Q7. How does this version compare to Q6's manual \"start both, then await both\" pattern?",[257,55496,55497],{"language":247},[260,55498,55500],{"className":262,"code":55499,"language":247,"meta":264,"style":264},"async function loadDashboard() {\n  const [user, stats] = await Promise.all([fetchUser(), fetchStats()]);\n  return { user, stats };\n}\n",[39,55501,55502,55512,55549,55555],{"__ignoreMap":264},[268,55503,55504,55506,55508,55510],{"class":270,"line":271},[268,55505,379],{"class":274},[268,55507,12080],{"class":274},[268,55509,55242],{"class":278},[268,55511,283],{"class":282},[268,55513,55514,55516,55518,55520,55522,55525,55527,55529,55531,55533,55535,55537,55539,55541,55543,55546],{"class":270,"line":286},[268,55515,12441],{"class":274},[268,55517,8710],{"class":282},[268,55519,4155],{"class":305},[268,55521,42],{"class":282},[268,55523,55524],{"class":305},"stats",[268,55526,19897],{"class":282},[268,55528,302],{"class":274},[268,55530,52502],{"class":274},[268,55532,50116],{"class":305},[268,55534,462],{"class":282},[268,55536,52364],{"class":278},[268,55538,17519],{"class":282},[268,55540,47058],{"class":278},[268,55542,37368],{"class":282},[268,55544,55545],{"class":278},"fetchStats",[268,55547,55548],{"class":282},"()]);\n",[268,55550,55551,55553],{"class":270,"line":296},[268,55552,1240],{"class":274},[268,55554,55281],{"class":282},[268,55556,55557],{"class":270,"line":311},[268,55558,314],{"class":282},[23,55560,55562,55571,55577,55583],{"className":55561},[26],[28,55563,55565,55567,55568,55570],{"className":55564},[31],[33,55566],{"disabled":35,"type":36}," It's slower — ",[39,55569,52467],{}," adds meaningful overhead",[28,55572,55574,55576],{"className":55573},[31],[33,55575],{"disabled":35,"type":36}," It behaves exactly like the sequential version in Q5",[28,55578,55580,55582],{"className":55579},[31],[33,55581],{"disabled":35,"type":36}," It runs the same operations concurrently as Q6, as one idiomatic expression, and fails fast if any promise rejects",[28,55584,55586,55588],{"className":55585},[31],[33,55587],{"disabled":35,"type":36}," It only works when there are exactly two promises in the array",[66,55590,55591,55593,55598],{},[69,55592,71],{},[73,55594,55595,55597],{},[76,55596,78],{}," C — It runs the same operations concurrently as Q6, as one idiomatic expression, and fails fast if any promise rejects",[73,55599,55600,355,55602,3990,55604,55607,55608,186,55610,55612,55613,55615,55616,55618],{},[76,55601,84],{},[76,55603,17307],{},[39,55605,55606],{},"Promise.all([...])"," is the standard, idiomatic way to fan out independent async work: ",[39,55609,47015],{},[39,55611,55225],{}," are both invoked synchronously when the array literal is built, so timing matches Q6, just more concisely. Its key extra behavior is fail-fast semantics: the combined promise rejects as soon as ",[104,55614,21375],{}," input promise rejects, without waiting for the rest (use ",[39,55617,52479],{}," if you need every result regardless of individual failures).",[15,55620,55621,55629,55721,55765],{"language":247},[18,55622,55624,55625,55628],{"id":55623},"q8-riskyoperation-returns-a-promise-that-may-reject-what-happens-if-it-does","Q8. ",[39,55626,55627],{},"riskyOperation()"," returns a promise that may reject. What happens if it does?",[257,55630,55631],{"language":247},[260,55632,55634],{"className":262,"code":55633,"language":247,"meta":264,"style":264},"async function process() {\n  const promise = riskyOperation();\n  try {\n    doSomethingElse();\n  } catch (err) {\n    console.log(\"caught:\", err.message);\n  }\n  const result = await promise;\n  return result;\n}\n",[39,55635,55636,55646,55660,55666,55673,55681,55694,55698,55711,55717],{"__ignoreMap":264},[268,55637,55638,55640,55642,55644],{"class":270,"line":271},[268,55639,379],{"class":274},[268,55641,12080],{"class":274},[268,55643,10851],{"class":278},[268,55645,283],{"class":282},[268,55647,55648,55650,55653,55655,55658],{"class":270,"line":286},[268,55649,12441],{"class":274},[268,55651,55652],{"class":305}," promise",[268,55654,616],{"class":274},[268,55656,55657],{"class":278}," riskyOperation",[268,55659,794],{"class":282},[268,55661,55662,55664],{"class":270,"line":296},[268,55663,54867],{"class":274},[268,55665,9914],{"class":282},[268,55667,55668,55671],{"class":270,"line":311},[268,55669,55670],{"class":278},"    doSomethingElse",[268,55672,794],{"class":282},[268,55674,55675,55677,55679],{"class":270,"line":788},[268,55676,9881],{"class":282},[268,55678,12488],{"class":274},[268,55680,12491],{"class":282},[268,55682,55683,55685,55687,55689,55691],{"class":270,"line":1951},[268,55684,9707],{"class":282},[268,55686,1356],{"class":278},[268,55688,622],{"class":282},[268,55690,48745],{"class":289},[268,55692,55693],{"class":282},", err.message);\n",[268,55695,55696],{"class":270,"line":8955},[268,55697,1948],{"class":282},[268,55699,55700,55702,55704,55706,55708],{"class":270,"line":8966},[268,55701,12441],{"class":274},[268,55703,5583],{"class":305},[268,55705,616],{"class":274},[268,55707,52502],{"class":274},[268,55709,55710],{"class":282}," promise;\n",[268,55712,55713,55715],{"class":270,"line":8974},[268,55714,1240],{"class":274},[268,55716,10895],{"class":282},[268,55718,55719],{"class":270,"line":8985},[268,55720,314],{"class":282},[23,55722,55724,55738,55751,55757],{"className":55723},[26],[28,55725,55727,55729,55730,55732,55733,55735,55736],{"className":55726},[31],[33,55728],{"disabled":35,"type":36}," It's caught by the ",[39,55731,12488],{}," block, since ",[39,55734,47594],{}," was created before the ",[39,55737,23142],{},[28,55739,55741,55743,55744,55746,55747,55750],{"className":55740},[31],[33,55742],{"disabled":35,"type":36}," It is NOT caught by the ",[39,55745,12488],{}," block — the rejection propagates out of ",[39,55748,55749],{},"process()"," as a rejected promise",[28,55752,55754,55756],{"className":55753},[31],[33,55755],{"disabled":35,"type":36}," The program throws synchronously and crashes immediately",[28,55758,55760,55762,55763],{"className":55759},[31],[33,55761],{"disabled":35,"type":36}," The runtime automatically retries ",[39,55764,55627],{},[66,55766,55767,55769,55778],{},[69,55768,71],{},[73,55770,55771,55773,55774,55746,55776,55750],{},[76,55772,78],{}," B — It is NOT caught by the ",[39,55775,12488],{},[39,55777,55749],{},[73,55779,55780,355,55782,3990,55784,55786,55787,21599,55790,55792,55793,55796,55797,55799,55800,55802,55803,55806,55807,55809,55810,462],{},[76,55781,84],{},[76,55783,16523],{},[39,55785,2081],{}," only catches errors from code that runs ",[104,55788,55789],{},"textually inside",[39,55791,23142],{}," block. Here ",[39,55794,55795],{},"await promise"," sits after the ",[39,55798,2081],{}," entirely, so its rejection isn't caught locally at all — it makes ",[39,55801,55749],{},"'s own returned promise reject. Where the promise was ",[104,55804,55805],{},"created"," is irrelevant; what matters is where the ",[39,55808,12304],{}," keyword itself sits relative to ",[39,55811,2081],{},[15,55813,55814,55827,55905,55948],{"language":247},[18,55815,55817,55818,55820,55821,55823,55824,55826],{"id":55816},"q9-now-the-await-has-moved-inside-the-try-block-even-though-riskyoperation-is-still-called-before-it","Q9. Now the ",[39,55819,12304],{}," has moved inside the ",[39,55822,23142],{}," block, even though ",[39,55825,55627],{}," is still called before it:",[257,55828,55829],{"language":247},[260,55830,55832],{"className":262,"code":55831,"language":247,"meta":264,"style":264},"async function process() {\n  const promise = riskyOperation();\n  try {\n    const result = await promise;\n    return result;\n  } catch (err) {\n    return \"fallback\";\n  }\n}\n",[39,55833,55834,55844,55856,55862,55874,55880,55888,55897,55901],{"__ignoreMap":264},[268,55835,55836,55838,55840,55842],{"class":270,"line":271},[268,55837,379],{"class":274},[268,55839,12080],{"class":274},[268,55841,10851],{"class":278},[268,55843,283],{"class":282},[268,55845,55846,55848,55850,55852,55854],{"class":270,"line":286},[268,55847,12441],{"class":274},[268,55849,55652],{"class":305},[268,55851,616],{"class":274},[268,55853,55657],{"class":278},[268,55855,794],{"class":282},[268,55857,55858,55860],{"class":270,"line":296},[268,55859,54867],{"class":274},[268,55861,9914],{"class":282},[268,55863,55864,55866,55868,55870,55872],{"class":270,"line":311},[268,55865,37893],{"class":274},[268,55867,5583],{"class":305},[268,55869,616],{"class":274},[268,55871,52502],{"class":274},[268,55873,55710],{"class":282},[268,55875,55876,55878],{"class":270,"line":788},[268,55877,9871],{"class":274},[268,55879,10895],{"class":282},[268,55881,55882,55884,55886],{"class":270,"line":1951},[268,55883,9881],{"class":282},[268,55885,12488],{"class":274},[268,55887,12491],{"class":282},[268,55889,55890,55892,55895],{"class":270,"line":8955},[268,55891,9871],{"class":274},[268,55893,55894],{"class":289}," \"fallback\"",[268,55896,293],{"class":282},[268,55898,55899],{"class":270,"line":8966},[268,55900,1948],{"class":282},[268,55902,55903],{"class":270,"line":8974},[268,55904,314],{"class":282},[23,55906,55908,55918,55929,55937],{"className":55907},[26],[28,55909,55911,4396,55913,55915,55916],{"className":55910},[31],[33,55912],{"disabled":35,"type":36},[39,55914,12488],{}," block never runs because the promise was created outside the ",[39,55917,23142],{},[28,55919,55921,55923,55924,55926,55927,11115],{"className":55920},[31],[33,55922],{"disabled":35,"type":36}," This is a syntax error — you can't ",[39,55925,12304],{}," a promise defined outside a ",[39,55928,23142],{},[28,55930,55932,55934,55935,1966],{"className":55931},[31],[33,55933],{"disabled":35,"type":36}," An unhandled rejection warning still fires even though ",[39,55936,12488],{},[28,55938,55940,4396,55942,55944,55945,55947],{"className":55939},[31],[33,55941],{"disabled":35,"type":36},[39,55943,12488],{}," block correctly handles the rejection, because what matters is where ",[39,55946,12304],{}," is written, not where the promise was created",[66,55949,55950,55952,55961],{},[69,55951,71],{},[73,55953,55954,55956,55957,55944,55959,55947],{},[76,55955,78],{}," D — The ",[39,55958,12488],{},[39,55960,12304],{},[73,55962,55963,355,55965,55967,55968,55970,55971,55973,55974,55976],{},[76,55964,84],{},[76,55966,16523],{}," — This mirrors Q8 from the other direction: a promise can be constructed anywhere; only the location of the ",[39,55969,12304],{}," expression relative to ",[39,55972,2081],{}," determines whether its rejection is caught. No unhandled-rejection warning fires here, because a catch handler is effectively attached (via ",[39,55975,12304],{},"'s internal machinery) before the rejection is ever reported as unhandled. Options A and C represent the same \"creation site matters\" misconception this pair of questions is built to correct.",[15,55978,55979,55992,56084,56125],{"language":247},[18,55980,55982,55983,830,55985,55987,55988,55991],{"id":55981},"q10-saveuser-is-async-what-order-do-the-logs-print-in-when-handlesubmituser-runs","Q10. ",[39,55984,50318],{},[39,55986,379],{},". What order do the logs print in when ",[39,55989,55990],{},"handleSubmit(user)"," runs?",[257,55993,55994],{"language":247},[260,55995,55997],{"className":262,"code":55996,"language":247,"meta":264,"style":264},"async function saveUser(user) {\n  await db.insert(user);\n  console.log(\"saved\");\n}\n\nfunction handleSubmit(user) {\n  saveUser(user);\n  console.log(\"submitted\");\n}\n",[39,55998,55999,56014,56026,56039,56043,56047,56060,56067,56080],{"__ignoreMap":264},[268,56000,56001,56003,56005,56008,56010,56012],{"class":270,"line":271},[268,56002,379],{"class":274},[268,56004,12080],{"class":274},[268,56006,56007],{"class":278}," saveUser",[268,56009,622],{"class":282},[268,56011,4155],{"class":1222},[268,56013,1235],{"class":282},[268,56015,56016,56018,56021,56024],{"class":270,"line":286},[268,56017,54703],{"class":274},[268,56019,56020],{"class":282}," db.",[268,56022,56023],{"class":278},"insert",[268,56025,19797],{"class":282},[268,56027,56028,56030,56032,56034,56037],{"class":270,"line":296},[268,56029,5556],{"class":282},[268,56031,1356],{"class":278},[268,56033,622],{"class":282},[268,56035,56036],{"class":289},"\"saved\"",[268,56038,628],{"class":282},[268,56040,56041],{"class":270,"line":311},[268,56042,314],{"class":282},[268,56044,56045],{"class":270,"line":788},[268,56046,5033],{"emptyLinePlaceholder":35},[268,56048,56049,56051,56054,56056,56058],{"class":270,"line":1951},[268,56050,275],{"class":274},[268,56052,56053],{"class":278}," handleSubmit",[268,56055,622],{"class":282},[268,56057,4155],{"class":1222},[268,56059,1235],{"class":282},[268,56061,56062,56065],{"class":270,"line":8955},[268,56063,56064],{"class":278},"  saveUser",[268,56066,19797],{"class":282},[268,56068,56069,56071,56073,56075,56078],{"class":270,"line":8966},[268,56070,5556],{"class":282},[268,56072,1356],{"class":278},[268,56074,622],{"class":282},[268,56076,56077],{"class":289},"\"submitted\"",[268,56079,628],{"class":282},[268,56081,56082],{"class":270,"line":8974},[268,56083,314],{"class":282},[23,56085,56087,56101,56110,56119],{"className":56086},[26],[28,56088,56090,56092,56093,56096,56097,56100],{"className":56089},[31],[33,56091],{"disabled":35,"type":36}," \"submitted\" logs before \"saved\", because ",[39,56094,56095],{},"saveUser(user)"," isn't awaited so ",[39,56098,56099],{},"handleSubmit"," doesn't pause for it",[28,56102,56104,56106,56107,56109],{"className":56103},[31],[33,56105],{"disabled":35,"type":36}," \"saved\" always logs first, because ",[39,56108,50318],{}," was called first",[28,56111,56113,56115,56116,56118],{"className":56112},[31],[33,56114],{"disabled":35,"type":36}," Only \"submitted\" logs — \"saved\" never logs since ",[39,56117,50318],{}," wasn't awaited",[28,56120,56122,56124],{"className":56121},[31],[33,56123],{"disabled":35,"type":36}," This throws a runtime error: \"must await async function\"",[66,56126,56127,56129,56138],{},[69,56128,71],{},[73,56130,56131,56133,56134,56096,56136,56100],{},[76,56132,78],{}," A — \"submitted\" logs before \"saved\", because ",[39,56135,56095],{},[39,56137,56099],{},[73,56139,56140,355,56142,56144,56145,56147,56148,56151,56152,56154,56155,56157,56158,56161,56162,31326,56164,56166,56167,56169],{},[76,56141,84],{},[76,56143,16523],{}," — Calling an async function without ",[39,56146,12304],{}," still ",[104,56149,56150],{},"runs"," it — the call isn't skipped, only the pausing is. ",[39,56153,56099],{}," fires ",[39,56156,56095],{},", immediately gets back a promise it ignores, and moves straight to ",[39,56159,56160],{},"console.log(\"submitted\")",". Meanwhile ",[39,56163,50318],{},[39,56165,12304],{}," yields to the microtask queue, so its ",[39,56168,56036],{}," log lands afterward. Option C is the common wrong guess — the function body absolutely still executes, just asynchronously and unobserved.",[15,56171,56172,56181,56256,56305],{"language":247},[18,56173,56175,56176,830,56178,56180],{"id":56174},"q11-saveuser-is-async-and-may-reject-internally-what-happens-when-it-does","Q11. ",[39,56177,50318],{},[39,56179,379],{}," and may reject internally. What happens when it does?",[257,56182,56183],{"language":247},[260,56184,56186],{"className":262,"code":56185,"language":247,"meta":264,"style":264},"async function handleSubmit(user) {\n  try {\n    saveUser(user);\n    console.log(\"submitted\");\n  } catch (err) {\n    console.log(\"error:\", err.message);\n  }\n}\n",[39,56187,56188,56202,56208,56215,56227,56235,56248,56252],{"__ignoreMap":264},[268,56189,56190,56192,56194,56196,56198,56200],{"class":270,"line":271},[268,56191,379],{"class":274},[268,56193,12080],{"class":274},[268,56195,56053],{"class":278},[268,56197,622],{"class":282},[268,56199,4155],{"class":1222},[268,56201,1235],{"class":282},[268,56203,56204,56206],{"class":270,"line":286},[268,56205,54867],{"class":274},[268,56207,9914],{"class":282},[268,56209,56210,56213],{"class":270,"line":296},[268,56211,56212],{"class":278},"    saveUser",[268,56214,19797],{"class":282},[268,56216,56217,56219,56221,56223,56225],{"class":270,"line":311},[268,56218,9707],{"class":282},[268,56220,1356],{"class":278},[268,56222,622],{"class":282},[268,56224,56077],{"class":289},[268,56226,628],{"class":282},[268,56228,56229,56231,56233],{"class":270,"line":788},[268,56230,9881],{"class":282},[268,56232,12488],{"class":274},[268,56234,12491],{"class":282},[268,56236,56237,56239,56241,56243,56246],{"class":270,"line":1951},[268,56238,9707],{"class":282},[268,56240,1356],{"class":278},[268,56242,622],{"class":282},[268,56244,56245],{"class":289},"\"error:\"",[268,56247,55693],{"class":282},[268,56249,56250],{"class":270,"line":8955},[268,56251,1948],{"class":282},[268,56253,56254],{"class":270,"line":8966},[268,56255,314],{"class":282},[23,56257,56259,56271,56282,56296],{"className":56258},[26],[28,56260,56262,4396,56264,56266,56267,56270],{"className":56261},[31],[33,56263],{"disabled":35,"type":36},[39,56265,12488],{}," block logs ",[39,56268,56269],{},"\"error: ...\""," as expected",[28,56272,56274,56276,56277,21200,56279,56281],{"className":56273},[31],[33,56275],{"disabled":35,"type":36}," It throws synchronously and crashes ",[39,56278,56099],{},[39,56280,56077],{}," logs",[28,56283,56285,4396,56287,56289,56290,56292,56293,56295],{"className":56284},[31],[33,56286],{"disabled":35,"type":36},[39,56288,12488],{}," block never runs — instead an unhandled promise rejection occurs elsewhere, since nothing awaits or ",[39,56291,47426],{},"es ",[39,56294,50318],{},"'s returned promise",[28,56297,56299,56301,56302,56304],{"className":56298},[31],[33,56300],{"disabled":35,"type":36}," JavaScript silently converts the missed ",[39,56303,12304],{}," into a synchronous call",[66,56306,56307,56309,56320],{},[69,56308,71],{},[73,56310,56311,56313,56314,56289,56316,56292,56318,56295],{},[76,56312,78],{}," C — The ",[39,56315,12488],{},[39,56317,47426],{},[39,56319,50318],{},[73,56321,56322,355,56324,56326,56327,56329,56330,56332,56333,56335,56336,56338,56339,56342,56343,56345],{},[76,56323,84],{},[76,56325,16523],{}," — Because ",[39,56328,56095],{}," isn't awaited, its returned promise is orphaned; there's no ",[39,56331,12304],{}," linking its eventual rejection back into this ",[39,56334,2081],{},", so the local ",[39,56337,12488],{}," simply never sees it. The rejection instead surfaces later as an unhandled promise rejection (Node's ",[39,56340,56341],{},"unhandledRejection"," event, or a browser console warning). This is one of the most common real-world async\u002Fawait bugs — forgetting a single ",[39,56344,12304],{}," silently defeats the surrounding error handling.",[15,56347,56348,56361,56447,56480],{"language":247},[18,56349,56351,56352,830,56355,56357,56358,55991],{"id":56350},"q12-saveitem-is-async-what-happens-when-processall-runs","Q12. ",[39,56353,56354],{},"saveItem",[39,56356,379],{},". What happens when ",[39,56359,56360],{},"processAll",[257,56362,56363],{"language":247},[260,56364,56366],{"className":262,"code":56365,"language":247,"meta":264,"style":264},"async function processAll(items) {\n  items.forEach(async (item) => {\n    await saveItem(item);\n    console.log(\"saved\", item.id);\n  });\n  console.log(\"all done\");\n}\n",[39,56367,56368,56383,56404,56413,56426,56430,56443],{"__ignoreMap":264},[268,56369,56370,56372,56374,56376,56378,56381],{"class":270,"line":271},[268,56371,379],{"class":274},[268,56373,12080],{"class":274},[268,56375,12251],{"class":278},[268,56377,622],{"class":282},[268,56379,56380],{"class":1222},"items",[268,56382,1235],{"class":282},[268,56384,56385,56388,56390,56392,56394,56396,56398,56400,56402],{"class":270,"line":286},[268,56386,56387],{"class":282},"  items.",[268,56389,12330],{"class":278},[268,56391,622],{"class":282},[268,56393,379],{"class":274},[268,56395,2182],{"class":282},[268,56397,14793],{"class":1222},[268,56399,6131],{"class":282},[268,56401,9414],{"class":274},[268,56403,9914],{"class":282},[268,56405,56406,56408,56411],{"class":270,"line":296},[268,56407,12278],{"class":274},[268,56409,56410],{"class":278}," saveItem",[268,56412,11808],{"class":282},[268,56414,56415,56417,56419,56421,56423],{"class":270,"line":311},[268,56416,9707],{"class":282},[268,56418,1356],{"class":278},[268,56420,622],{"class":282},[268,56422,56036],{"class":289},[268,56424,56425],{"class":282},", item.id);\n",[268,56427,56428],{"class":270,"line":788},[268,56429,39914],{"class":282},[268,56431,56432,56434,56436,56438,56441],{"class":270,"line":1951},[268,56433,5556],{"class":282},[268,56435,1356],{"class":278},[268,56437,622],{"class":282},[268,56439,56440],{"class":289},"\"all done\"",[268,56442,628],{"class":282},[268,56444,56445],{"class":270,"line":8955},[268,56446,314],{"class":282},[23,56448,56450,56456,56465,56474],{"className":56449},[26],[28,56451,56453,56455],{"className":56452},[31],[33,56454],{"disabled":35,"type":36}," \"all done\" logs only after every item has been saved, in order",[28,56457,56459,56461,56462,56464],{"className":56458},[31],[33,56460],{"disabled":35,"type":36}," \"all done\" logs immediately, before any \"saved\" messages, because ",[39,56463,12330],{}," doesn't wait for the async callbacks it invokes",[28,56466,56468,56470,56471,56473],{"className":56467},[31],[33,56469],{"disabled":35,"type":36}," This throws, because ",[39,56472,12330],{}," doesn't accept async callbacks",[28,56475,56477,56479],{"className":56476},[31],[33,56478],{"disabled":35,"type":36}," Each iteration automatically awaits the previous one since they share the same array",[66,56481,56482,56484,56491],{},[69,56483,71],{},[73,56485,56486,56488,56489,56464],{},[76,56487,78],{}," B — \"all done\" logs immediately, before any \"saved\" messages, because ",[39,56490,12330],{},[73,56492,56493,355,56495,3990,56497,56499,56500,56502,56503,56505,56506,56508,56509,56511,56512,56514,56515,2029,56517,56519],{},[76,56494,84],{},[76,56496,16523],{},[39,56498,12384],{}," ignores whatever its callback returns, promise or not, and never awaits it — it just fires every callback invocation and moves straight on. Marking the callback ",[39,56501,379],{}," doesn't change that contract; it just means each call quietly starts its own promise chain in the background while ",[39,56504,12330],{}," itself barrels ahead. So ",[39,56507,56440],{}," logs before any ",[39,56510,56036],{}," line, and the saves may finish in arbitrary order. This is an extremely common real-world bug — use a ",[39,56513,9163],{}," loop (Q13) for sequential awaiting or ",[39,56516,52467],{},[39,56518,23950],{}," (Q14) for parallel awaiting.",[15,56521,56522,56528,56603,56642],{"language":247},[18,56523,56525,56526,10728],{"id":56524},"q13-same-task-rewritten-with-forof","Q13. Same task, rewritten with ",[39,56527,9163],{},[257,56529,56530],{"language":247},[260,56531,56533],{"className":262,"code":56532,"language":247,"meta":264,"style":264},"async function processAll(items) {\n  for (const item of items) {\n    await saveItem(item);\n    console.log(\"saved\", item.id);\n  }\n  console.log(\"all done\");\n}\n",[39,56534,56535,56549,56563,56571,56583,56587,56599],{"__ignoreMap":264},[268,56536,56537,56539,56541,56543,56545,56547],{"class":270,"line":271},[268,56538,379],{"class":274},[268,56540,12080],{"class":274},[268,56542,12251],{"class":278},[268,56544,622],{"class":282},[268,56546,56380],{"class":1222},[268,56548,1235],{"class":282},[268,56550,56551,56553,56555,56557,56559,56561],{"class":270,"line":286},[268,56552,9659],{"class":274},[268,56554,2182],{"class":282},[268,56556,243],{"class":274},[268,56558,11794],{"class":305},[268,56560,9229],{"class":274},[268,56562,11799],{"class":282},[268,56564,56565,56567,56569],{"class":270,"line":296},[268,56566,12278],{"class":274},[268,56568,56410],{"class":278},[268,56570,11808],{"class":282},[268,56572,56573,56575,56577,56579,56581],{"class":270,"line":311},[268,56574,9707],{"class":282},[268,56576,1356],{"class":278},[268,56578,622],{"class":282},[268,56580,56036],{"class":289},[268,56582,56425],{"class":282},[268,56584,56585],{"class":270,"line":788},[268,56586,1948],{"class":282},[268,56588,56589,56591,56593,56595,56597],{"class":270,"line":1951},[268,56590,5556],{"class":282},[268,56592,1356],{"class":278},[268,56594,622],{"class":282},[268,56596,56440],{"class":289},[268,56598,628],{"class":282},[268,56600,56601],{"class":270,"line":8955},[268,56602,314],{"class":282},[23,56604,56606,56615,56626,56634],{"className":56605},[26],[28,56607,56609,56611,56612,56614],{"className":56608},[31],[33,56610],{"disabled":35,"type":36}," Behaves identically to the ",[39,56613,12330],{}," version in Q12",[28,56616,56618,56620,56621,56623,56624],{"className":56617},[31],[33,56619],{"disabled":35,"type":36}," This throws — ",[39,56622,9163],{}," bodies can't contain ",[39,56625,12304],{},[28,56627,56629,56631,56632],{"className":56628},[31],[33,56630],{"disabled":35,"type":36}," Items save concurrently, the same as ",[39,56633,52467],{},[28,56635,56637,17028,56639,56641],{"className":56636},[31],[33,56638],{"disabled":35,"type":36},[39,56640,12304],{}," genuinely pauses the loop until that item's save completes, so items save one at a time, in order, before \"all done\" logs",[66,56643,56644,56646,56653],{},[69,56645,71],{},[73,56647,56648,56650,56651,56641],{},[76,56649,78],{}," D — Each ",[39,56652,12304],{},[73,56654,56655,355,56657,56659,56660,42,56662,56664,56665,56667,56668,56670,56671,56673,56674,56676,56677,56679],{},[76,56656,84],{},[76,56658,17307],{}," — Unlike ",[39,56661,12330],{},[39,56663,9163],{}," is ordinary synchronous control flow wrapped around each iteration; the ",[39,56666,12304],{}," inside the loop body genuinely suspends the enclosing ",[39,56669,12405],{}," until that iteration's promise settles before advancing. This makes ",[39,56672,9163],{}," the right tool when you need strictly sequential, ordered, one-at-a-time processing — reach for ",[39,56675,52467],{}," + ",[39,56678,23950],{}," (Q14) instead when order doesn't matter and speed does.",[15,56681,56682,56686,56749,56787],{"language":247},[18,56683,56685],{"id":56684},"q14-same-task-again-this-time-written-as","Q14. Same task again, this time written as:",[257,56687,56688],{"language":247},[260,56689,56691],{"className":262,"code":56690,"language":247,"meta":264,"style":264},"async function processAll(items) {\n  await Promise.all(items.map(item => saveItem(item)));\n  console.log(\"all done\");\n}\n",[39,56692,56693,56707,56733,56745],{"__ignoreMap":264},[268,56694,56695,56697,56699,56701,56703,56705],{"class":270,"line":271},[268,56696,379],{"class":274},[268,56698,12080],{"class":274},[268,56700,12251],{"class":278},[268,56702,622],{"class":282},[268,56704,56380],{"class":1222},[268,56706,1235],{"class":282},[268,56708,56709,56711,56713,56715,56717,56720,56722,56724,56726,56728,56730],{"class":270,"line":286},[268,56710,54703],{"class":274},[268,56712,50116],{"class":305},[268,56714,462],{"class":282},[268,56716,52364],{"class":278},[268,56718,56719],{"class":282},"(items.",[268,56721,23950],{"class":278},[268,56723,622],{"class":282},[268,56725,14793],{"class":1222},[268,56727,14969],{"class":274},[268,56729,56410],{"class":278},[268,56731,56732],{"class":282},"(item)));\n",[268,56734,56735,56737,56739,56741,56743],{"class":270,"line":296},[268,56736,5556],{"class":282},[268,56738,1356],{"class":278},[268,56740,622],{"class":282},[268,56742,56440],{"class":289},[268,56744,628],{"class":282},[268,56746,56747],{"class":270,"line":311},[268,56748,314],{"class":282},[23,56750,56752,56761,56769,56778],{"className":56751},[26],[28,56753,56755,56757,56758,56760],{"className":56754},[31],[33,56756],{"disabled":35,"type":36}," All ",[39,56759,56354],{}," calls start essentially simultaneously, and \"all done\" logs only once every one has settled successfully",[28,56762,56764,56766,56767,56614],{"className":56763},[31],[33,56765],{"disabled":35,"type":36}," This behaves exactly like the ",[39,56768,12330],{},[28,56770,56772,355,56774,56777],{"className":56771},[31],[33,56773],{"disabled":35,"type":36},[39,56775,56776],{},"items.map"," isn't allowed to return promises",[28,56779,56781,56783,56784,56786],{"className":56780},[31],[33,56782],{"disabled":35,"type":36}," Only the first ",[39,56785,56354],{}," call actually runs — the rest are discarded",[66,56788,56789,56791,56798],{},[69,56790,71],{},[73,56792,56793,56795,56796,56760],{},[76,56794,78],{}," A — All ",[39,56797,56354],{},[73,56799,56800,355,56802,446,56804,3990,56806,56809,56810,56812,56813,56816],{},[76,56801,84],{},[76,56803,55328],{},[76,56805,17307],{},[39,56807,56808],{},"items.map(item => saveItem(item))"," synchronously invokes ",[39,56811,56354],{}," for every item up front, producing an array of promises; ",[39,56814,56815],{},"Promise.all(...)"," then awaits them all together, resolving only once every one has fulfilled (or rejecting fast on the first failure). This is the idiomatic way to process a collection concurrently when per-item ordering isn't required, and it directly fixes Q12's bug by actually awaiting the work instead of silently dropping it.",[15,56818,56819,56826,56862],{"language":247},[18,56820,56822,56823,56825],{"id":56821},"q15-in-an-es-module-a-top-level-await-that-takes-2-seconds-to-settle-will","Q15. In an ES module, a top-level ",[39,56824,12304],{}," that takes 2 seconds to settle will...",[23,56827,56829,56835,56847,56856],{"className":56828},[26],[28,56830,56832,56834],{"className":56831},[31],[33,56833],{"disabled":35,"type":36}," Only delay code within that same module file — importing modules are unaffected",[28,56836,56838,56840,56841,56843,56844,56846],{"className":56837},[31],[33,56839],{"disabled":35,"type":36}," Cause a syntax error, since ",[39,56842,12304],{}," is only legal inside ",[39,56845,379],{}," functions",[28,56848,56850,56852,56853,56855],{"className":56849},[31],[33,56851],{"disabled":35,"type":36}," Delay evaluation of the entire module, and any module that imports it will also wait for that evaluation (including the top-level ",[39,56854,12304],{},") to finish before it can use the imports",[28,56857,56859,56861],{"className":56858},[31],[33,56860],{"disabled":35,"type":36}," Run in the background without blocking anything, since ESM loading is inherently async already",[66,56863,56864,56866,56873],{},[69,56865,71],{},[73,56867,56868,56870,56871,56855],{},[76,56869,78],{}," C — Delay evaluation of the entire module, and any module that imports it will also wait for that evaluation (including the top-level ",[39,56872,12304],{},[73,56874,56875,355,56877,446,56879,56881,56882,56884,56885,56888,56889,56891],{},[76,56876,84],{},[76,56878,16523],{},[76,56880,55328],{}," — Top-level ",[39,56883,12304],{}," (ESM-only) pauses the ",[104,56886,56887],{},"evaluation of the containing module itself"," at that point until the awaited promise settles. Because the module graph is evaluated respecting dependency order, any module that imports the awaiting module must wait for it to fully finish evaluating — top-level ",[39,56890,12304],{}," included — before the importer can proceed. This can cascade delays through an entire dependency graph, which is why it's best reserved for genuinely required async setup (like initializing a WASM module) rather than used casually.",[15,56893,56894,56908,57034,57083],{"language":247},[18,56895,56897,56898,56901,56902,56904,56905,56907],{"id":56896},"q16-getconfig-is-called-without-await-what-happens-if-key-is-falsy","Q16. ",[39,56899,56900],{},"getConfig"," is called without ",[39,56903,12304],{},". What happens if ",[39,56906,19849],{}," is falsy?",[257,56909,56910],{"language":247},[260,56911,56913],{"className":262,"code":56912,"language":247,"meta":264,"style":264},"const getConfig = async (key) => {\n  if (!key) {\n    throw new Error(\"key is required\");\n  }\n  return await loadFromDisk(key);\n};\n\ntry {\n  const result = getConfig();\n  console.log(result);\n} catch (err) {\n  console.log(\"caught:\", err.message);\n}\n",[39,56914,56915,56935,56946,56961,56965,56976,56980,56984,56990,57002,57010,57018,57030],{"__ignoreMap":264},[268,56916,56917,56919,56921,56923,56925,56927,56929,56931,56933],{"class":270,"line":271},[268,56918,243],{"class":274},[268,56920,8034],{"class":278},[268,56922,616],{"class":274},[268,56924,1091],{"class":274},[268,56926,2182],{"class":282},[268,56928,19849],{"class":1222},[268,56930,6131],{"class":282},[268,56932,9414],{"class":274},[268,56934,9914],{"class":282},[268,56936,56937,56939,56941,56943],{"class":270,"line":286},[268,56938,9863],{"class":274},[268,56940,2182],{"class":282},[268,56942,5418],{"class":274},[268,56944,56945],{"class":282},"key) {\n",[268,56947,56948,56950,56952,56954,56956,56959],{"class":270,"line":296},[268,56949,48705],{"class":274},[268,56951,11370],{"class":274},[268,56953,11593],{"class":278},[268,56955,622],{"class":282},[268,56957,56958],{"class":289},"\"key is required\"",[268,56960,628],{"class":282},[268,56962,56963],{"class":270,"line":311},[268,56964,1948],{"class":282},[268,56966,56967,56969,56971,56974],{"class":270,"line":788},[268,56968,1240],{"class":274},[268,56970,52502],{"class":274},[268,56972,56973],{"class":278}," loadFromDisk",[268,56975,12131],{"class":282},[268,56977,56978],{"class":270,"line":1951},[268,56979,12940],{"class":282},[268,56981,56982],{"class":270,"line":8955},[268,56983,5033],{"emptyLinePlaceholder":35},[268,56985,56986,56988],{"class":270,"line":8966},[268,56987,23142],{"class":274},[268,56989,9914],{"class":282},[268,56991,56992,56994,56996,56998,57000],{"class":270,"line":8974},[268,56993,12441],{"class":274},[268,56995,5583],{"class":305},[268,56997,616],{"class":274},[268,56999,8034],{"class":278},[268,57001,794],{"class":282},[268,57003,57004,57006,57008],{"class":270,"line":8985},[268,57005,5556],{"class":282},[268,57007,1356],{"class":278},[268,57009,6852],{"class":282},[268,57011,57012,57014,57016],{"class":270,"line":8990},[268,57013,11235],{"class":282},[268,57015,12488],{"class":274},[268,57017,12491],{"class":282},[268,57019,57020,57022,57024,57026,57028],{"class":270,"line":8997},[268,57021,5556],{"class":282},[268,57023,1356],{"class":278},[268,57025,622],{"class":282},[268,57027,48745],{"class":289},[268,57029,55693],{"class":282},[268,57031,57032],{"class":270,"line":9002},[268,57033,314],{"class":282},[23,57035,57037,57049,57061,57073],{"className":57036},[26],[28,57038,57040,355,57042,57045,57046,57048],{"className":57039},[31],[33,57041],{"disabled":35,"type":36},[39,57043,57044],{},"\"caught: key is required\""," logs, since ",[39,57047,48836],{}," always produces a synchronous exception",[28,57050,57052,4396,57054,57056,57057,57060],{"className":57051},[31],[33,57053],{"disabled":35,"type":36},[39,57055,12488],{}," block does NOT run — ",[39,57058,57059],{},"getConfig()"," returns a rejected promise instead, and the rejection goes unhandled",[28,57062,57064,57066,57067,57069,57070,57072],{"className":57063},[31],[33,57065],{"disabled":35,"type":36}," Both the ",[39,57068,23142],{}," block's log and the ",[39,57071,12488],{}," block run",[28,57074,57076,812,57078,816,57080,57082],{"className":57075},[31],[33,57077],{"disabled":35,"type":36},[39,57079,815],{},[39,57081,19849],{}," is undefined",[66,57084,57085,57087,57096],{},[69,57086,71],{},[73,57088,57089,57091,57092,57056,57094,57060],{},[76,57090,78],{}," B — The ",[39,57093,12488],{},[39,57095,57059],{},[73,57097,57098,355,57100,57102,57103,57105,57106,57108,57109,57111,57112,57114,57115,57117,57118,57121,57122,57124,57125,57127],{},[76,57099,84],{},[76,57101,16523],{}," — Marking a function ",[39,57104,379],{}," changes what ",[39,57107,48836],{}," does inside it: even a ",[39,57110,48836],{}," that happens before any ",[39,57113,12304],{}," never becomes a synchronous JS-engine exception at the call site — it's converted into a rejected promise returned by ",[39,57116,57059],{},". Since the caller doesn't ",[39,57119,57120],{},"await getConfig()",", the surrounding ",[39,57123,2081],{}," (which only sees synchronous throws and awaited rejections) never observes it, and the rejection surfaces later as unhandled. This trips up developers used to \"validate then ",[39,57126,48836],{},"\" patterns in plain synchronous functions.",[15,57129,57130,57140,57184],{"language":247},[18,57131,57133,57134,10394,57137,1685],{"id":57132},"q17-which-statement-correctly-describes-async-function-combined-with-for-awaitof","Q17. Which statement correctly describes ",[39,57135,57136],{},"async function*",[39,57138,57139],{},"for await...of",[23,57141,57143,57155,57161,57171],{"className":57142},[26],[28,57144,57146,57148,57149,57151,57152,57154],{"className":57145},[31],[33,57147],{"disabled":35,"type":36}," It's identical to a regular generator; ",[39,57150,57139],{}," is just syntax sugar for ",[39,57153,9163],{}," with no behavioral difference",[28,57156,57158,57160],{"className":57157},[31],[33,57159],{"disabled":35,"type":36}," Async generators can only be used with arrays, not streams or async iterables",[28,57162,57164,355,57166,57168,57169],{"className":57163},[31],[33,57165],{"disabled":35,"type":36},[39,57167,57139],{}," requires all values to be available synchronously upfront, unlike ",[39,57170,9163],{},[28,57172,57174,57176,57177,57180,57181,57183],{"className":57173},[31],[33,57175],{"disabled":35,"type":36}," An async generator's ",[39,57178,57179],{},"yield"," can produce values that are themselves promises (or come from awaited async work), and ",[39,57182,57139],{}," automatically awaits each yielded value before running the loop body",[66,57185,57186,57188,57197],{},[69,57187,71],{},[73,57189,57190,57192,57193,57180,57195,57183],{},[76,57191,78],{}," D — An async generator's ",[39,57194,57179],{},[39,57196,57139],{},[73,57198,57199,54637,57201,57203,57204,57206,57207,57209],{},[76,57200,84],{},[39,57202,57136],{}," produces an async iterator; ",[39,57205,57139],{}," consumes it by awaiting each yielded item automatically, one at a time. This makes it a natural fit for representing sequences of values that arrive over time — paginated API results, or chunks read from a stream — which a plain generator plus ",[39,57208,9163],{}," can't express since those only handle synchronous iteration. Options A, B, and C each misstate that relationship.",[15,57211,57212,57216,57277,57330],{"language":247},[18,57213,57215],{"id":57214},"q18-is-this-code-valid-and-is-it-good-style","Q18. Is this code valid, and is it good style?",[257,57217,57218],{"language":247},[260,57219,57221],{"className":262,"code":57220,"language":247,"meta":264,"style":264},"async function loadProfile(id) {\n  const user = await fetchUser(id);\n  return fetchPosts(user.id).then(posts => ({ user, posts }));\n}\n",[39,57222,57223,57238,57252,57273],{"__ignoreMap":264},[268,57224,57225,57227,57229,57232,57234,57236],{"class":270,"line":271},[268,57226,379],{"class":274},[268,57228,12080],{"class":274},[268,57230,57231],{"class":278}," loadProfile",[268,57233,622],{"class":282},[268,57235,14610],{"class":1222},[268,57237,1235],{"class":282},[268,57239,57240,57242,57244,57246,57248,57250],{"class":270,"line":286},[268,57241,12441],{"class":274},[268,57243,4071],{"class":305},[268,57245,616],{"class":274},[268,57247,52502],{"class":274},[268,57249,54856],{"class":278},[268,57251,12284],{"class":282},[268,57253,57254,57256,57259,57262,57264,57266,57268,57270],{"class":270,"line":296},[268,57255,1240],{"class":274},[268,57257,57258],{"class":278}," fetchPosts",[268,57260,57261],{"class":282},"(user.id).",[268,57263,47505],{"class":278},[268,57265,622],{"class":282},[268,57267,48280],{"class":1222},[268,57269,14969],{"class":274},[268,57271,57272],{"class":282}," ({ user, posts }));\n",[268,57274,57275],{"class":270,"line":311},[268,57276,314],{"class":282},[23,57278,57280,57291,57304,57316],{"className":57279},[26],[28,57281,57283,57285,57286,186,57288,57290],{"className":57282},[31],[33,57284],{"disabled":35,"type":36}," It's valid, but mixing ",[39,57287,12304],{},[39,57289,46149],{}," chains in the same function is generally considered inconsistent style — sticking to one approach throughout improves readability",[28,57292,57294,57296,57297,1243,57299,57301,57302],{"className":57293},[31],[33,57295],{"disabled":35,"type":36}," It throws a syntax error — you can't ",[39,57298,9151],{},[39,57300,46149],{}," chain from an ",[39,57303,12405],{},[28,57305,57307,355,57309,57312,57313,57315],{"className":57306},[31],[33,57308],{"disabled":35,"type":36},[39,57310,57311],{},"fetchPosts(user.id).then(...)"," runs synchronously before ",[39,57314,47058],{}," resolves",[28,57317,57319,4396,57321,57323,57324,57327,57328],{"className":57318},[31],[33,57320],{"disabled":35,"type":36},[39,57322,46149],{}," chain's returned promise is discarded — ",[39,57325,57326],{},"loadProfile"," always resolves to ",[39,57329,833],{},[66,57331,57332,57334,57343],{},[69,57333,71],{},[73,57335,57336,57338,57339,186,57341,57290],{},[76,57337,78],{}," A — It's valid, but mixing ",[39,57340,12304],{},[39,57342,46149],{},[73,57344,57345,355,57347,57349,57350,2029,57352,446,57354,57356,57357,57359,57360,57362,57363,57366],{},[76,57346,84],{},[76,57348,17307],{}," — Nothing here is actually broken: async functions can freely mix ",[39,57351,12304],{},[39,57353,46149],{},[39,57355,49873],{}," chains, and the promise returned by ",[39,57358,46149],{}," is flattened into ",[39,57361,57326],{},"'s own return value, same as Q4. The issue is purely readability\u002Fconsistency — switching styles mid-function makes control flow harder to scan. The idiomatic fix is ",[39,57364,57365],{},"const posts = await fetchPosts(user.id); return { user, posts };",", keeping the whole function in one style.",[15,57368,57369,57373,57449,57487],{"language":247},[18,57370,57372],{"id":57371},"q19-what-order-do-the-logs-print-in","Q19. What order do the logs print in?",[257,57374,57375],{"language":247},[260,57376,57378],{"className":262,"code":57377,"language":247,"meta":264,"style":264},"async function test() {\n  console.log(\"1\");\n  await 42;\n  console.log(\"2\");\n}\n\ntest();\nconsole.log(\"3\");\n",[39,57379,57380,57390,57402,57410,57422,57426,57430,57437],{"__ignoreMap":264},[268,57381,57382,57384,57386,57388],{"class":270,"line":271},[268,57383,379],{"class":274},[268,57385,12080],{"class":274},[268,57387,11056],{"class":278},[268,57389,283],{"class":282},[268,57391,57392,57394,57396,57398,57400],{"class":270,"line":286},[268,57393,5556],{"class":282},[268,57395,1356],{"class":278},[268,57397,622],{"class":282},[268,57399,3387],{"class":289},[268,57401,628],{"class":282},[268,57403,57404,57406,57408],{"class":270,"line":296},[268,57405,54703],{"class":274},[268,57407,779],{"class":305},[268,57409,293],{"class":282},[268,57411,57412,57414,57416,57418,57420],{"class":270,"line":311},[268,57413,5556],{"class":282},[268,57415,1356],{"class":278},[268,57417,622],{"class":282},[268,57419,9269],{"class":289},[268,57421,628],{"class":282},[268,57423,57424],{"class":270,"line":788},[268,57425,314],{"class":282},[268,57427,57428],{"class":270,"line":1951},[268,57429,5033],{"emptyLinePlaceholder":35},[268,57431,57432,57435],{"class":270,"line":8955},[268,57433,57434],{"class":278},"test",[268,57436,794],{"class":282},[268,57438,57439,57441,57443,57445,57447],{"class":270,"line":8966},[268,57440,1353],{"class":282},[268,57442,1356],{"class":278},[268,57444,622],{"class":282},[268,57446,50483],{"class":289},[268,57448,628],{"class":282},[23,57450,57452,57461,57467,57473],{"className":57451},[26],[28,57453,57455,57457,57458,57460],{"className":57454},[31],[33,57456],{"disabled":35,"type":36}," 1, 2, 3 — awaiting a plain value like ",[39,57459,4659],{}," doesn't actually pause anything",[28,57462,57464,57466],{"className":57463},[31],[33,57465],{"disabled":35,"type":36}," 3, 1, 2 — the whole async function is deferred until the synchronous code finishes",[28,57468,57470,57472],{"className":57469},[31],[33,57471],{"disabled":35,"type":36}," 1, 3, 2 — awaiting any value, even a non-promise, always yields to the microtask queue before resuming",[28,57474,57476,2398,57478,57480,57481,57483,57484,57486],{"className":57475},[31],[33,57477],{"disabled":35,"type":36},[39,57479,827],{}," — you can only ",[39,57482,12304],{}," actual ",[39,57485,91],{}," objects",[66,57488,57489,57491,57496],{},[69,57490,71],{},[73,57492,57493,57495],{},[76,57494,78],{}," C — 1, 3, 2 — awaiting any value, even a non-promise, always yields to the microtask queue before resuming",[73,57497,57498,355,57500,446,57502,3990,57504,57506,57507,4973,57510,2269,57513,57515,57516,57519,57520,57522,57523,57525],{},[76,57499,84],{},[76,57501,16523],{},[76,57503,55328],{},[39,57505,12304],{}," always suspends the async function and schedules its resumption as a microtask, even when the awaited value isn't a thenable at all — the engine internally treats it as ",[39,57508,57509],{},"Promise.resolve(42)",[39,57511,57512],{},"test()",[39,57514,3387],{},", then immediately yields back to the caller; ",[39,57517,57518],{},"console.log(\"3\")"," runs next synchronously; only then does the microtask queue drain and ",[39,57521,9269],{}," logs. This surprises people who assume \"no real async work happening, so no delay\" — even a trivial ",[39,57524,12304],{}," costs at least one microtask tick.",[15,57527,57528,57532,57567],{"language":247},[18,57529,57531],{"id":57530},"q20-a-function-needs-a-users-profile-their-settings-and-their-notification-count-three-independent-api-calls-that-dont-depend-on-each-others-results-combined-into-one-object-which-approach-is-best-practice","Q20. A function needs a user's profile, their settings, and their notification count — three independent API calls that don't depend on each other's results — combined into one object. Which approach is best practice?",[23,57533,57535,57541,57549,57558],{"className":57534},[26],[28,57536,57538,57540],{"className":57537},[31],[33,57539],{"disabled":35,"type":36}," Await each call sequentially, one after another, for the clearest, most linear-reading code",[28,57542,57544,4353,57546,57548],{"className":57543},[31],[33,57545],{"disabled":35,"type":36},[39,57547,46149],{}," chains for each call, since async\u002Fawait can't combine multiple independent results",[28,57550,57552,57554,57555,57557],{"className":57551},[31],[33,57553],{"disabled":35,"type":36}," Wrap each call in its own ",[39,57556,2081],{}," and await them one at a time so errors stay isolated per call",[28,57559,57561,57563,57564,57566],{"className":57560},[31],[33,57562],{"disabled":35,"type":36}," Kick off all three calls without awaiting immediately (or use ",[39,57565,52467],{},"), then await them together, since running independent operations concurrently minimizes total wait time",[66,57568,57569,57571,57578],{},[69,57570,71],{},[73,57572,57573,57575,57576,57566],{},[76,57574,78],{}," D — Kick off all three calls without awaiting immediately (or use ",[39,57577,52467],{},[73,57579,57580,355,57582,446,57584,57586,57587,57590,57591,57593,57594,57596],{},[76,57581,84],{},[76,57583,55328],{},[76,57585,17307],{}," — When operations don't depend on each other, best practice is to start them concurrently — either call all three functions first and await the results afterward, or more idiomatically write ",[39,57588,57589],{},"const [profile, settings, count] = await Promise.all([...])"," — so total latency is bounded by the slowest call rather than their sum, avoiding Q5's footgun. Option A is the common but suboptimal sequential pattern; option C still serializes the calls despite sounding \"safer\" — per-call isolation with ",[39,57592,2081],{}," isn't required for independent operations (use ",[39,57595,52479],{}," instead if partial-failure tolerance is genuinely needed).",[2107,57598,57599],{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .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}",{"title":264,"searchDepth":286,"depth":286,"links":57601},[57602,57603,57604,57606,57607,57609,57610,57611,57613,57615,57617,57619,57621,57623,57624,57626,57628,57630,57631,57632],{"id":54528,"depth":296,"text":54529},{"id":54667,"depth":296,"text":54668},{"id":54836,"depth":296,"text":57605},"Q3. What does fetchUser(1).then(console.log) print?",{"id":13031,"depth":296,"text":13032},{"id":55219,"depth":296,"text":57608},"Q5. fetchUser() and fetchStats() are independent — neither depends on the other's result, and each takes ~300ms.",{"id":55351,"depth":296,"text":55352},{"id":55493,"depth":296,"text":55494},{"id":55623,"depth":296,"text":57612},"Q8. riskyOperation() returns a promise that may reject. What happens if it does?",{"id":55816,"depth":296,"text":57614},"Q9. Now the await has moved inside the try block, even though riskyOperation() is still called before it:",{"id":55981,"depth":296,"text":57616},"Q10. saveUser is async. What order do the logs print in when handleSubmit(user) runs?",{"id":56174,"depth":296,"text":57618},"Q11. saveUser is async and may reject internally. What happens when it does?",{"id":56350,"depth":296,"text":57620},"Q12. saveItem is async. What happens when processAll runs?",{"id":56524,"depth":296,"text":57622},"Q13. Same task, rewritten with for...of:",{"id":56684,"depth":296,"text":56685},{"id":56821,"depth":296,"text":57625},"Q15. In an ES module, a top-level await that takes 2 seconds to settle will...",{"id":56896,"depth":296,"text":57627},"Q16. getConfig is called without await. What happens if key is falsy?",{"id":57132,"depth":296,"text":57629},"Q17. Which statement correctly describes async function* combined with for await...of?",{"id":57214,"depth":296,"text":57215},{"id":57371,"depth":296,"text":57372},{"id":57530,"depth":296,"text":57531},{},"\u002Fjs\u002F17-async-await",{"title":54518,"description":264},"js\u002F17-async-await","mqHkR68FB6kb6wQpbIEU99eTuBuUjLmFTdhHFlnY7uY",{"id":57639,"title":57640,"body":57641,"description":264,"extension":2144,"meta":61228,"navigation":35,"path":61229,"seo":61230,"stem":61231,"__hash__":61232},"content\u002Fjs\u002F18-error-handling.md","18 — Error Handling",{"type":8,"value":57642,"toc":61200},[57643,57646,57776,57927,58100,58300,58536,58706,58848,59094,59290,59526,59739,59937,60147,60297,60362,60536,60729,60786,61003,61197],[11,57644,57640],{"id":57645},"_18-error-handling",[15,57647,57648,57659,57715],{},[18,57649,57651,57652,57654,57655,57658],{"id":57650},"q1-which-statement-about-the-finally-block-in-a-trycatchfinally-statement-is-true","Q1. Which statement about the ",[39,57653,51954],{}," block in a ",[39,57656,57657],{},"try\u002Fcatch\u002Ffinally"," statement is true?",[23,57660,57662,57673,57693,57704],{"className":57661},[26],[28,57663,57665,355,57667,57669,57670,57672],{"className":57664},[31],[33,57666],{"disabled":35,"type":36},[39,57668,51954],{}," only runs if the ",[39,57671,23142],{}," block completes without throwing",[28,57674,57676,355,57678,57680,57681,446,57683,57685,57686,99,57688,57690,57691],{"className":57675},[31],[33,57677],{"disabled":35,"type":36},[39,57679,51954],{}," runs after every ",[39,57682,23142],{},[39,57684,12488],{}," path, including when ",[39,57687,23142],{},[39,57689,12488],{}," contains a ",[39,57692,9151],{},[28,57694,57696,355,57698,57700,57701,57703],{"className":57695},[31],[33,57697],{"disabled":35,"type":36},[39,57699,51954],{}," is skipped if the ",[39,57702,12488],{}," block itself throws a new error",[28,57705,57707,355,57709,57711,57712,57714],{"className":57706},[31],[33,57708],{"disabled":35,"type":36},[39,57710,51954],{}," only runs when there is no ",[39,57713,12488],{}," block present",[66,57716,57717,57719,57735],{},[69,57718,71],{},[73,57720,57721,1727,57723,57680,57725,446,57727,57685,57729,99,57731,57690,57733],{},[76,57722,78],{},[39,57724,51954],{},[39,57726,23142],{},[39,57728,12488],{},[39,57730,23142],{},[39,57732,12488],{},[39,57734,9151],{},[73,57736,57737,355,57739,57741,57742,446,57744,57746,57747,42,57749,57751,57752,446,57754,57756,57757,57759,57760,57762,57763,57765,57766,57769,57770,57772,57773,57775],{},[76,57738,84],{},[39,57740,51954],{}," always executes regardless of how ",[39,57743,23142],{},[39,57745,12488],{}," exits — normal completion, ",[39,57748,9151],{},[39,57750,48836],{},", or even ",[39,57753,8880],{},[39,57755,9615],{},". Even if ",[39,57758,12488],{}," throws a new error, ",[39,57761,51954],{}," still runs before that error propagates further, which rules out C. A is wrong because ",[39,57764,51954],{}," runs on both success and failure paths, not just success. D is wrong because ",[39,57767,57768],{},"try\u002Ffinally"," (with no ",[39,57771,12488],{}," at all) is perfectly valid, and ",[39,57774,51954],{}," still runs.",[15,57777,57778,57780,57853,57884],{"language":247},[18,57779,12737],{"id":12736},[257,57781,57782],{"language":247},[260,57783,57785],{"className":262,"code":57784,"language":247,"meta":264,"style":264},"function getStatus() {\n  try {\n    return \"success\";\n  } finally {\n    return \"overridden\";\n  }\n}\n\nconsole.log(getStatus());\n",[39,57786,57787,57796,57802,57811,57819,57828,57832,57836,57840],{"__ignoreMap":264},[268,57788,57789,57791,57794],{"class":270,"line":271},[268,57790,275],{"class":274},[268,57792,57793],{"class":278}," getStatus",[268,57795,283],{"class":282},[268,57797,57798,57800],{"class":270,"line":286},[268,57799,54867],{"class":274},[268,57801,9914],{"class":282},[268,57803,57804,57806,57809],{"class":270,"line":296},[268,57805,9871],{"class":274},[268,57807,57808],{"class":289}," \"success\"",[268,57810,293],{"class":282},[268,57812,57813,57815,57817],{"class":270,"line":311},[268,57814,9881],{"class":282},[268,57816,51954],{"class":274},[268,57818,9914],{"class":282},[268,57820,57821,57823,57826],{"class":270,"line":788},[268,57822,9871],{"class":274},[268,57824,57825],{"class":289}," \"overridden\"",[268,57827,293],{"class":282},[268,57829,57830],{"class":270,"line":1951},[268,57831,1948],{"class":282},[268,57833,57834],{"class":270,"line":8955},[268,57835,314],{"class":282},[268,57837,57838],{"class":270,"line":8966},[268,57839,5033],{"emptyLinePlaceholder":35},[268,57841,57842,57844,57846,57848,57851],{"class":270,"line":8974},[268,57843,1353],{"class":282},[268,57845,1356],{"class":278},[268,57847,622],{"class":282},[268,57849,57850],{"class":278},"getStatus",[268,57852,8174],{"class":282},[23,57854,57856,57861,57868,57879],{"className":57855},[26],[28,57857,57859,57808],{"className":57858},[31],[33,57860],{"disabled":35,"type":36},[28,57862,57864,355,57866],{"className":57863},[31],[33,57865],{"disabled":35,"type":36},[39,57867,833],{},[28,57869,57871,812,57873,57875,57876,57878],{"className":57870},[31],[33,57872],{"disabled":35,"type":36},[39,57874,1274],{}," is thrown because you cannot ",[39,57877,9151],{}," twice in one function",[28,57880,57882,57825],{"className":57881},[31],[33,57883],{"disabled":35,"type":36},[66,57885,57886,57888,57893],{},[69,57887,71],{},[73,57889,57890,57892],{},[76,57891,78],{}," D — \"overridden\"",[73,57894,57895,812,57897,23506,57899,57901,57902,57904,57905,57908,57909,57911,57912,57915,57916,57919,57920,9057,57922,57924,57925],{},[76,57896,84],{},[39,57898,9151],{},[39,57900,51954],{}," silently overrides the pending return value from ",[39,57903,23142],{},". The engine has already set up ",[39,57906,57907],{},"\"success\""," as the function's about-to-be-returned value, but before control actually leaves the function, ",[39,57910,51954],{}," runs — and its own ",[39,57913,57914],{},"return \"overridden\""," replaces that pending value entirely. No error is thrown; this is legal but dangerous JavaScript (ESLint's ",[39,57917,57918],{},"no-unsafe-finally"," rule exists specifically to flag it). A is the intuitive-but-wrong guess that ",[39,57921,23142],{},[39,57923,9151],{}," should win. ",[76,57926,16523],{},[15,57928,57929,57931,58010,58051],{"language":247},[18,57930,12877],{"id":12876},[257,57932,57933],{"language":247},[260,57934,57936],{"className":262,"code":57935,"language":247,"meta":264,"style":264},"function loadConfig() {\n  try {\n    throw new Error(\"config missing\");\n  } finally {\n    return \"default-config\";\n  }\n}\n\nconsole.log(loadConfig());\n",[39,57937,57938,57947,57953,57968,57976,57985,57989,57993,57997],{"__ignoreMap":264},[268,57939,57940,57942,57945],{"class":270,"line":271},[268,57941,275],{"class":274},[268,57943,57944],{"class":278}," loadConfig",[268,57946,283],{"class":282},[268,57948,57949,57951],{"class":270,"line":286},[268,57950,54867],{"class":274},[268,57952,9914],{"class":282},[268,57954,57955,57957,57959,57961,57963,57966],{"class":270,"line":296},[268,57956,48705],{"class":274},[268,57958,11370],{"class":274},[268,57960,11593],{"class":278},[268,57962,622],{"class":282},[268,57964,57965],{"class":289},"\"config missing\"",[268,57967,628],{"class":282},[268,57969,57970,57972,57974],{"class":270,"line":311},[268,57971,9881],{"class":282},[268,57973,51954],{"class":274},[268,57975,9914],{"class":282},[268,57977,57978,57980,57983],{"class":270,"line":788},[268,57979,9871],{"class":274},[268,57981,57982],{"class":289}," \"default-config\"",[268,57984,293],{"class":282},[268,57986,57987],{"class":270,"line":1951},[268,57988,1948],{"class":282},[268,57990,57991],{"class":270,"line":8955},[268,57992,314],{"class":282},[268,57994,57995],{"class":270,"line":8966},[268,57996,5033],{"emptyLinePlaceholder":35},[268,57998,57999,58001,58003,58005,58008],{"class":270,"line":8974},[268,58000,1353],{"class":282},[268,58002,1356],{"class":278},[268,58004,622],{"class":282},[268,58006,58007],{"class":278},"loadConfig",[268,58009,8174],{"class":282},[23,58011,58013,58019,58028,58034],{"className":58012},[26],[28,58014,58016,58018],{"className":58015},[31],[33,58017],{"disabled":35,"type":36}," \"default-config\" is logged, and the thrown error is completely swallowed",[28,58020,58022,58024,58025,58027],{"className":58021},[31],[33,58023],{"disabled":35,"type":36}," The function throws \"config missing\" and the ",[39,58026,5627],{}," line never runs",[28,58029,58031,58033],{"className":58030},[31],[33,58032],{"disabled":35,"type":36}," Both the error message and the return value are logged",[28,58035,58037,812,58039,816,58041,58043,58044,58046,58047,2018,58049],{"className":58036},[31],[33,58038],{"disabled":35,"type":36},[39,58040,827],{},[39,58042,51954],{}," cannot contain a ",[39,58045,9151],{}," after a ",[39,58048,48836],{},[39,58050,23142],{},[66,58052,58053,58055,58060],{},[69,58054,71],{},[73,58056,58057,58059],{},[76,58058,78],{}," A — \"default-config\" is logged, and the thrown error is completely swallowed",[73,58061,58062,58064,58065,58067,58068,23506,58070,58072,58073,23941,58076,2018,58079,58081,58082,9057,58084,58087,58088,446,58090,446,58092,23506,58094,3277,58096,8828,58098],{},[76,58063,84],{}," Just like it overrides a pending ",[39,58066,9151],{},", a ",[39,58069,9151],{},[39,58071,51954],{}," also overrides a pending ",[104,58074,58075],{},"exception",[39,58077,58078],{},"throw new Error(\"config missing\")",[39,58080,23142],{}," never propagates because ",[39,58083,51954],{},[39,58085,58086],{},"return \"default-config\""," becomes the completion value of the whole statement instead. This silently discards a real error with no trace it ever happened — a genuinely dangerous pattern, which is why linters flag ",[39,58089,9151],{},[39,58091,8880],{},[39,58093,9615],{},[39,58095,51954],{},[76,58097,16523],{},[76,58099,17613],{},[15,58101,58102,58106,58202,58255],{"language":247},[18,58103,58105],{"id":58104},"q4-what-happens-when-this-runs","Q4. What happens when this runs?",[257,58107,58108],{"language":247},[260,58109,58111],{"className":262,"code":58110,"language":247,"meta":264,"style":264},"class ApiError extends Error {\n  constructor(message, statusCode) {\n    this.statusCode = statusCode;\n    this.message = message;\n  }\n}\n\nconst err = new ApiError(\"Not Found\", 404);\n",[39,58112,58113,58126,58141,58153,58165,58169,58173,58177],{"__ignoreMap":264},[268,58114,58115,58117,58120,58122,58124],{"class":270,"line":271},[268,58116,1468],{"class":274},[268,58118,58119],{"class":278}," ApiError",[268,58121,30481],{"class":274},[268,58123,11593],{"class":278},[268,58125,9914],{"class":282},[268,58127,58128,58130,58132,58134,58136,58139],{"class":270,"line":286},[268,58129,29965],{"class":274},[268,58131,622],{"class":282},[268,58133,43838],{"class":1222},[268,58135,42],{"class":282},[268,58137,58138],{"class":1222},"statusCode",[268,58140,1235],{"class":282},[268,58142,58143,58145,58148,58150],{"class":270,"line":296},[268,58144,22057],{"class":305},[268,58146,58147],{"class":282},".statusCode ",[268,58149,302],{"class":274},[268,58151,58152],{"class":282}," statusCode;\n",[268,58154,58155,58157,58160,58162],{"class":270,"line":311},[268,58156,22057],{"class":305},[268,58158,58159],{"class":282},".message ",[268,58161,302],{"class":274},[268,58163,58164],{"class":282}," message;\n",[268,58166,58167],{"class":270,"line":788},[268,58168,1948],{"class":282},[268,58170,58171],{"class":270,"line":1951},[268,58172,314],{"class":282},[268,58174,58175],{"class":270,"line":8955},[268,58176,5033],{"emptyLinePlaceholder":35},[268,58178,58179,58181,58184,58186,58188,58190,58192,58195,58197,58200],{"class":270,"line":8966},[268,58180,243],{"class":274},[268,58182,58183],{"class":305}," err",[268,58185,616],{"class":274},[268,58187,11370],{"class":274},[268,58189,58119],{"class":278},[268,58191,622],{"class":282},[268,58193,58194],{"class":289},"\"Not Found\"",[268,58196,42],{"class":282},[268,58198,58199],{"class":305},"404",[268,58201,628],{"class":282},[23,58203,58205,58216,58229,58242],{"className":58204},[26],[28,58206,58208,355,58210,58212,58213,58215],{"className":58207},[31],[33,58209],{"disabled":35,"type":36},[39,58211,48255],{}," is created successfully and ",[39,58214,55015],{}," is \"Not Found\"",[28,58217,58219,355,58221,58223,58224,830,58227],{"className":58218},[31],[33,58220],{"disabled":35,"type":36},[39,58222,48255],{}," is created but ",[39,58225,58226],{},"err instanceof Error",[39,58228,2986],{},[28,58230,58232,812,58234,816,58236,58238,58239,58241],{"className":58231},[31],[33,58233],{"disabled":35,"type":36},[39,58235,815],{},[39,58237,950],{}," is accessed before ",[39,58240,30889],{}," is called",[28,58243,58245,355,58247,830,58250,58252,58253],{"className":58244},[31],[33,58246],{"disabled":35,"type":36},[39,58248,58249],{},"err.statusCode",[39,58251,833],{}," because it was set before ",[39,58254,43838],{},[66,58256,58257,58259,58270],{},[69,58258,71],{},[73,58260,58261,58263,58264,816,58266,58238,58268,58241],{},[76,58262,78],{}," C — A ",[39,58265,815],{},[39,58267,950],{},[39,58269,30889],{},[73,58271,58272,58274,58275,58277,58278,58280,58281,58284,58285,58287,58288,58291,58292,58294,58295,58297,58298],{},[76,58273,84],{}," In a derived class, ",[39,58276,950],{}," is not initialized until ",[39,58279,30889],{}," runs. Writing ",[39,58282,58283],{},"this.statusCode = statusCode"," before calling ",[39,58286,30889],{}," throws \"Must call super constructor in derived class before accessing 'this' or returning from derived constructor.\" The fix is ",[39,58289,58290],{},"super(message)"," first, then assign any extra custom fields like ",[39,58293,58138],{},". A is the outcome you'd get ",[104,58296,1747],{}," fixing the bug, not what actually happens here. ",[76,58299,17613],{},[15,58301,58302,58304,58451,58498],{"language":247},[18,58303,13181],{"id":13180},[257,58305,58306],{"language":247},[260,58307,58309],{"className":262,"code":58308,"language":247,"meta":264,"style":264},"class AppError extends Error {}\nclass ValidationError extends AppError {}\n\nfunction validate(input) {\n  if (!input) throw new ValidationError(\"input required\");\n}\n\ntry {\n  validate(null);\n} catch (err) {\n  if (err instanceof AppError) {\n    console.log(\"handled:\", err instanceof ValidationError);\n  }\n}\n",[39,58310,58311,58324,58337,58341,58353,58377,58381,58385,58391,58402,58410,58423,58443,58447],{"__ignoreMap":264},[268,58312,58313,58315,58318,58320,58322],{"class":270,"line":271},[268,58314,1468],{"class":274},[268,58316,58317],{"class":278}," AppError",[268,58319,30481],{"class":274},[268,58321,11593],{"class":278},[268,58323,30486],{"class":282},[268,58325,58326,58328,58331,58333,58335],{"class":270,"line":286},[268,58327,1468],{"class":274},[268,58329,58330],{"class":278}," ValidationError",[268,58332,30481],{"class":274},[268,58334,58317],{"class":278},[268,58336,30486],{"class":282},[268,58338,58339],{"class":270,"line":296},[268,58340,5033],{"emptyLinePlaceholder":35},[268,58342,58343,58345,58347,58349,58351],{"class":270,"line":311},[268,58344,275],{"class":274},[268,58346,39295],{"class":278},[268,58348,622],{"class":282},[268,58350,33],{"class":1222},[268,58352,1235],{"class":282},[268,58354,58355,58357,58359,58361,58364,58366,58368,58370,58372,58375],{"class":270,"line":788},[268,58356,9863],{"class":274},[268,58358,2182],{"class":282},[268,58360,5418],{"class":274},[268,58362,58363],{"class":282},"input) ",[268,58365,48836],{"class":274},[268,58367,11370],{"class":274},[268,58369,58330],{"class":278},[268,58371,622],{"class":282},[268,58373,58374],{"class":289},"\"input required\"",[268,58376,628],{"class":282},[268,58378,58379],{"class":270,"line":1951},[268,58380,314],{"class":282},[268,58382,58383],{"class":270,"line":8955},[268,58384,5033],{"emptyLinePlaceholder":35},[268,58386,58387,58389],{"class":270,"line":8966},[268,58388,23142],{"class":274},[268,58390,9914],{"class":282},[268,58392,58393,58396,58398,58400],{"class":270,"line":8974},[268,58394,58395],{"class":278},"  validate",[268,58397,622],{"class":282},[268,58399,2650],{"class":305},[268,58401,628],{"class":282},[268,58403,58404,58406,58408],{"class":270,"line":8985},[268,58405,11235],{"class":282},[268,58407,12488],{"class":274},[268,58409,12491],{"class":282},[268,58411,58412,58414,58417,58419,58421],{"class":270,"line":8990},[268,58413,9863],{"class":274},[268,58415,58416],{"class":282}," (err ",[268,58418,3707],{"class":274},[268,58420,58317],{"class":278},[268,58422,1235],{"class":282},[268,58424,58425,58427,58429,58431,58434,58437,58439,58441],{"class":270,"line":8997},[268,58426,9707],{"class":282},[268,58428,1356],{"class":278},[268,58430,622],{"class":282},[268,58432,58433],{"class":289},"\"handled:\"",[268,58435,58436],{"class":282},", err ",[268,58438,3707],{"class":274},[268,58440,58330],{"class":278},[268,58442,628],{"class":282},[268,58444,58445],{"class":270,"line":9002},[268,58446,1948],{"class":282},[268,58448,58449],{"class":270,"line":14676},[268,58450,314],{"class":282},[23,58452,58454,58467,58476,58485],{"className":58453},[26],[28,58455,58457,58459,58460,58463,58464],{"className":58456},[31],[33,58458],{"disabled":35,"type":36}," Nothing is logged because ",[39,58461,58462],{},"ValidationError"," does not match ",[39,58465,58466],{},"AppError",[28,58468,58470,58472,58473,58475],{"className":58469},[31],[33,58471],{"disabled":35,"type":36}," \"handled: true\", because ",[39,58474,3707],{}," walks the entire prototype chain",[28,58477,58479,58481,58482,58484],{"className":58478},[31],[33,58480],{"disabled":35,"type":36}," \"handled: false\", because ",[39,58483,3707],{}," only checks the direct class",[28,58486,58488,812,58490,58492,58493,58495,58496],{"className":58487},[31],[33,58489],{"disabled":35,"type":36},[39,58491,827],{}," is thrown since you cannot ",[39,58494,48836],{}," a subclass of a subclass of ",[39,58497,48601],{},[66,58499,58500,58502,58509],{},[69,58501,71],{},[73,58503,58504,58506,58507,58475],{},[76,58505,78],{}," B — \"handled: true\", because ",[39,58508,3707],{},[73,58510,58511,355,58513,58515,58516,58518,58519,58522,58523,58526,58527,58529,58530,58532,58533,58535],{},[76,58512,84],{},[39,58514,3707],{}," checks the full prototype chain, not just the exact constructor. A ",[39,58517,58462],{}," instance is also an ",[39,58520,58521],{},"instanceof AppError"," and an ",[39,58524,58525],{},"instanceof Error",", so both checks in the snippet are ",[39,58528,2185],{},". This lets a broad ",[39,58531,3707],{}," check higher up a hierarchy catch a whole family of related errors while still allowing narrower checks. C describes a common misconception that ",[39,58534,3707],{}," only matches the exact class it was constructed with.",[15,58537,58538,58540,58623,58658],{"language":247},[18,58539,13321],{"id":13320},[257,58541,58542],{"language":247},[260,58543,58545],{"className":262,"code":58544,"language":247,"meta":264,"style":264},"class TimeoutError extends Error {\n  constructor(message) {\n    super(message);\n  }\n}\n\nconst err = new TimeoutError(\"request timed out\");\nconsole.log(err.name, err instanceof TimeoutError);\n",[39,58546,58547,58560,58570,58577,58581,58585,58589,58608],{"__ignoreMap":264},[268,58548,58549,58551,58554,58556,58558],{"class":270,"line":271},[268,58550,1468],{"class":274},[268,58552,58553],{"class":278}," TimeoutError",[268,58555,30481],{"class":274},[268,58557,11593],{"class":278},[268,58559,9914],{"class":282},[268,58561,58562,58564,58566,58568],{"class":270,"line":286},[268,58563,29965],{"class":274},[268,58565,622],{"class":282},[268,58567,43838],{"class":1222},[268,58569,1235],{"class":282},[268,58571,58572,58574],{"class":270,"line":296},[268,58573,30786],{"class":305},[268,58575,58576],{"class":282},"(message);\n",[268,58578,58579],{"class":270,"line":311},[268,58580,1948],{"class":282},[268,58582,58583],{"class":270,"line":788},[268,58584,314],{"class":282},[268,58586,58587],{"class":270,"line":1951},[268,58588,5033],{"emptyLinePlaceholder":35},[268,58590,58591,58593,58595,58597,58599,58601,58603,58606],{"class":270,"line":8955},[268,58592,243],{"class":274},[268,58594,58183],{"class":305},[268,58596,616],{"class":274},[268,58598,11370],{"class":274},[268,58600,58553],{"class":278},[268,58602,622],{"class":282},[268,58604,58605],{"class":289},"\"request timed out\"",[268,58607,628],{"class":282},[268,58609,58610,58612,58614,58617,58619,58621],{"class":270,"line":8966},[268,58611,1353],{"class":282},[268,58613,1356],{"class":278},[268,58615,58616],{"class":282},"(err.name, err ",[268,58618,3707],{"class":274},[268,58620,58553],{"class":278},[268,58622,628],{"class":282},[23,58624,58626,58634,58641,58650],{"className":58625},[26],[28,58627,58629,58631,58632],{"className":58628},[31],[33,58630],{"disabled":35,"type":36}," \"TimeoutError\" and ",[39,58633,2185],{},[28,58635,58637,58631,58639],{"className":58636},[31],[33,58638],{"disabled":35,"type":36},[39,58640,2986],{},[28,58642,58644,355,58646,186,58648],{"className":58643},[31],[33,58645],{"disabled":35,"type":36},[39,58647,833],{},[39,58649,2185],{},[28,58651,58653,58655,58656],{"className":58652},[31],[33,58654],{"disabled":35,"type":36}," \"Error\" and ",[39,58657,2185],{},[66,58659,58660,58662,58669],{},[69,58661,71],{},[73,58663,58664,58666,58667],{},[76,58665,78],{}," D — \"Error\" and ",[39,58668,2185],{},[73,58670,58671,355,58673,58675,58676,5425,58678,58681,58682,58685,58686,58689,58690,58692,58693,58695,58696,8628,58698,58700,58701,58703,58704],{},[76,58672,84],{},[39,58674,48601],{},"'s own constructor sets ",[39,58677,31168],{},[39,58679,58680],{},"\"Error\""," by default; simply extending the class does not update ",[39,58683,58684],{},".name"," to match the subclass — you must explicitly set ",[39,58687,58688],{},"this.name = \"TimeoutError\""," (typically right after ",[39,58691,58290],{},") for logs and error-reporting tools that read ",[39,58694,58684],{}," to show the right label. Meanwhile ",[39,58697,3707],{},[39,58699,2185],{}," because it's driven entirely by the prototype chain, a completely independent mechanism from the ",[39,58702,58684],{}," string — which is exactly what trips people up. ",[76,58705,16523],{},[15,58707,58708,58712,58778,58818],{"language":247},[18,58709,58711],{"id":58710},"q7-whats-the-problem-with-this-code-and-the-best-fix","Q7. What's the problem with this code, and the best fix?",[257,58713,58714],{"language":247},[260,58715,58717],{"className":262,"code":58716,"language":247,"meta":264,"style":264},"async function saveUser(user) {\n  try {\n    await db.insert(user);\n  } catch (err) {\n    console.error(\"saveUser failed:\", err.message);\n  }\n}\n",[39,58718,58719,58733,58739,58749,58757,58770,58774],{"__ignoreMap":264},[268,58720,58721,58723,58725,58727,58729,58731],{"class":270,"line":271},[268,58722,379],{"class":274},[268,58724,12080],{"class":274},[268,58726,56007],{"class":278},[268,58728,622],{"class":282},[268,58730,4155],{"class":1222},[268,58732,1235],{"class":282},[268,58734,58735,58737],{"class":270,"line":286},[268,58736,54867],{"class":274},[268,58738,9914],{"class":282},[268,58740,58741,58743,58745,58747],{"class":270,"line":296},[268,58742,12278],{"class":274},[268,58744,56020],{"class":282},[268,58746,56023],{"class":278},[268,58748,19797],{"class":282},[268,58750,58751,58753,58755],{"class":270,"line":311},[268,58752,9881],{"class":282},[268,58754,12488],{"class":274},[268,58756,12491],{"class":282},[268,58758,58759,58761,58763,58765,58768],{"class":270,"line":788},[268,58760,9707],{"class":282},[268,58762,18282],{"class":278},[268,58764,622],{"class":282},[268,58766,58767],{"class":289},"\"saveUser failed:\"",[268,58769,55693],{"class":282},[268,58771,58772],{"class":270,"line":1951},[268,58773,1948],{"class":282},[268,58775,58776],{"class":270,"line":8955},[268,58777,314],{"class":282},[23,58779,58781,58792,58798,58807],{"className":58780},[26],[28,58782,58784,4396,58786,58788,58789,58791],{"className":58783},[31],[33,58785],{"disabled":35,"type":36},[39,58787,12488],{}," block swallows the error; callers of ",[39,58790,50318],{}," have no way to know it failed unless the error is rethrown after logging",[28,58793,58795,58797],{"className":58794},[31],[33,58796],{"disabled":35,"type":36}," Nothing — logging the error is sufficient error handling",[28,58799,58801,355,58803,12305,58805,11115],{"className":58800},[31],[33,58802],{"disabled":35,"type":36},[39,58804,12304],{},[39,58806,23142],{},[28,58808,58810,58812,58813,8574,58815],{"className":58809},[31],[33,58811],{"disabled":35,"type":36}," The error should be logged with ",[39,58814,5627],{},[39,58816,58817],{},"console.error",[66,58819,58820,58822,58830],{},[69,58821,71],{},[73,58823,58824,43363,58826,58788,58828,58791],{},[76,58825,78],{},[39,58827,12488],{},[39,58829,50318],{},[73,58831,58832,58834,58835,58837,58838,58841,58842,58845,58846],{},[76,58833,84],{}," Logging without rethrowing lets ",[39,58836,50318],{},"'s returned promise resolve successfully even though the insert failed — any caller doing ",[39,58839,58840],{},"await saveUser(user)"," has no way to detect the failure and proceeds as if it succeeded. The log-and-rethrow pattern (log for diagnostics, then ",[39,58843,58844],{},"throw err"," or a wrapped error) keeps both observability and correct control flow intact. ",[76,58847,17307],{},[15,58849,58850,58854,58981,59040],{"language":247},[18,58851,58853],{"id":58852},"q8-compare-the-two-functions-below-which-statement-is-correct","Q8. Compare the two functions below. Which statement is correct?",[257,58855,58856],{"language":247},[260,58857,58859],{"className":262,"code":58858,"language":247,"meta":264,"style":264},"function readFile(path) {\n  try {\n    return fs.readFileSync(path);\n  } catch (err) {\n    throw err;\n  }\n}\n\nfunction readFileWrapped(path) {\n  try {\n    return fs.readFileSync(path);\n  } catch (err) {\n    throw new Error(\"read failed\");\n  }\n}\n",[39,58860,58861,58875,58881,58894,58902,58909,58913,58917,58921,58934,58940,58950,58958,58973,58977],{"__ignoreMap":264},[268,58862,58863,58865,58868,58870,58873],{"class":270,"line":271},[268,58864,275],{"class":274},[268,58866,58867],{"class":278}," readFile",[268,58869,622],{"class":282},[268,58871,58872],{"class":1222},"path",[268,58874,1235],{"class":282},[268,58876,58877,58879],{"class":270,"line":286},[268,58878,54867],{"class":274},[268,58880,9914],{"class":282},[268,58882,58883,58885,58888,58891],{"class":270,"line":296},[268,58884,9871],{"class":274},[268,58886,58887],{"class":282}," fs.",[268,58889,58890],{"class":278},"readFileSync",[268,58892,58893],{"class":282},"(path);\n",[268,58895,58896,58898,58900],{"class":270,"line":311},[268,58897,9881],{"class":282},[268,58899,12488],{"class":274},[268,58901,12491],{"class":282},[268,58903,58904,58906],{"class":270,"line":788},[268,58905,48705],{"class":274},[268,58907,58908],{"class":282}," err;\n",[268,58910,58911],{"class":270,"line":1951},[268,58912,1948],{"class":282},[268,58914,58915],{"class":270,"line":8955},[268,58916,314],{"class":282},[268,58918,58919],{"class":270,"line":8966},[268,58920,5033],{"emptyLinePlaceholder":35},[268,58922,58923,58925,58928,58930,58932],{"class":270,"line":8974},[268,58924,275],{"class":274},[268,58926,58927],{"class":278}," readFileWrapped",[268,58929,622],{"class":282},[268,58931,58872],{"class":1222},[268,58933,1235],{"class":282},[268,58935,58936,58938],{"class":270,"line":8985},[268,58937,54867],{"class":274},[268,58939,9914],{"class":282},[268,58941,58942,58944,58946,58948],{"class":270,"line":8990},[268,58943,9871],{"class":274},[268,58945,58887],{"class":282},[268,58947,58890],{"class":278},[268,58949,58893],{"class":282},[268,58951,58952,58954,58956],{"class":270,"line":8997},[268,58953,9881],{"class":282},[268,58955,12488],{"class":274},[268,58957,12491],{"class":282},[268,58959,58960,58962,58964,58966,58968,58971],{"class":270,"line":9002},[268,58961,48705],{"class":274},[268,58963,11370],{"class":274},[268,58965,11593],{"class":278},[268,58967,622],{"class":282},[268,58969,58970],{"class":289},"\"read failed\"",[268,58972,628],{"class":282},[268,58974,58975],{"class":270,"line":14676},[268,58976,1948],{"class":282},[268,58978,58979],{"class":270,"line":14681},[268,58980,314],{"class":282},[23,58982,58984,58998,59004,59030],{"className":58983},[26],[28,58985,58987,58989,58990,58993,58994,58997],{"className":58986},[31],[33,58988],{"disabled":35,"type":36}," Both functions produce an error whose ",[39,58991,58992],{},".stack"," points to the original ",[39,58995,58996],{},"fs.readFileSync"," failure",[28,58999,59001,59003],{"className":59000},[31],[33,59002],{"disabled":35,"type":36}," Neither function preserves any stack information once the error is caught",[28,59005,59007,355,59009,59012,59013,59015,59016,59019,59020,59022,59023,59026,59027],{"className":59006},[31],[33,59008],{"disabled":35,"type":36},[39,59010,59011],{},"readFile","'s rethrown error keeps its original ",[39,59014,58992],{}," (captured when it was first constructed), but ",[39,59017,59018],{},"readFileWrapped"," creates a brand-new error whose ",[39,59021,58992],{}," starts at the ",[39,59024,59025],{},"new Error(\"read failed\")"," line, losing the original failure site unless passed via ",[39,59028,59029],{},"cause",[28,59031,59033,355,59035,59037,59038,10349],{"className":59032},[31],[33,59034],{"disabled":35,"type":36},[39,59036,59018],{}," automatically appends the original error's stack to the new error's ",[39,59039,58992],{},[66,59041,59042,59044,59057],{},[69,59043,71],{},[73,59045,59046,1004,59048,59012,59050,4948,59052,59054,59055],{},[76,59047,78],{},[39,59049,59011],{},[39,59051,58992],{},[39,59053,59018],{}," loses it unless passed via ",[39,59056,59029],{},[73,59058,59059,54637,59061,9057,59063,59065,59066,2018,59068,59070,59071,59073,59074,59076,59077,59079,59080,59082,59083,59085,59086,59088,59089,3277,59092],{},[76,59060,84],{},[39,59062,48601],{},[39,59064,58992],{}," is captured once, at construction time — not at throw time. ",[39,59067,58844],{},[39,59069,59011],{}," rethrows the exact same object, so ",[39,59072,58992],{}," still shows where ",[39,59075,58996],{}," originally failed. ",[39,59078,59018],{}," constructs a brand-new ",[39,59081,48601],{},", so its ",[39,59084,58992],{}," starts fresh at the ",[39,59087,59025],{}," line; the original failure location is lost unless explicitly preserved, e.g. ",[39,59090,59091],{},"new Error(\"read failed\", { cause: err })",[76,59093,16523],{},[15,59095,59096,59098,59187,59232],{"language":247},[18,59097,13927],{"id":13926},[257,59099,59100],{"language":247},[260,59101,59103],{"className":262,"code":59102,"language":247,"meta":264,"style":264},"function checkAge(age) {\n  if (age \u003C 0) throw \"invalid age\";\n}\n\ntry {\n  checkAge(-5);\n} catch (err) {\n  console.log(err.message, err.stack);\n}\n",[39,59104,59105,59119,59139,59143,59147,59153,59166,59174,59183],{"__ignoreMap":264},[268,59106,59107,59109,59112,59114,59117],{"class":270,"line":271},[268,59108,275],{"class":274},[268,59110,59111],{"class":278}," checkAge",[268,59113,622],{"class":282},[268,59115,59116],{"class":1222},"age",[268,59118,1235],{"class":282},[268,59120,59121,59123,59126,59128,59130,59132,59134,59137],{"class":270,"line":286},[268,59122,9863],{"class":274},[268,59124,59125],{"class":282}," (age ",[268,59127,1076],{"class":274},[268,59129,5728],{"class":305},[268,59131,6131],{"class":282},[268,59133,48836],{"class":274},[268,59135,59136],{"class":289}," \"invalid age\"",[268,59138,293],{"class":282},[268,59140,59141],{"class":270,"line":296},[268,59142,314],{"class":282},[268,59144,59145],{"class":270,"line":311},[268,59146,5033],{"emptyLinePlaceholder":35},[268,59148,59149,59151],{"class":270,"line":788},[268,59150,23142],{"class":274},[268,59152,9914],{"class":282},[268,59154,59155,59158,59160,59162,59164],{"class":270,"line":1951},[268,59156,59157],{"class":278},"  checkAge",[268,59159,622],{"class":282},[268,59161,6244],{"class":274},[268,59163,2429],{"class":305},[268,59165,628],{"class":282},[268,59167,59168,59170,59172],{"class":270,"line":8955},[268,59169,11235],{"class":282},[268,59171,12488],{"class":274},[268,59173,12491],{"class":282},[268,59175,59176,59178,59180],{"class":270,"line":8966},[268,59177,5556],{"class":282},[268,59179,1356],{"class":278},[268,59181,59182],{"class":282},"(err.message, err.stack);\n",[268,59184,59185],{"class":270,"line":8974},[268,59186,314],{"class":282},[23,59188,59190,59196,59208,59219],{"className":59189},[26],[28,59191,59193,59195],{"className":59192},[31],[33,59194],{"disabled":35,"type":36}," \"invalid age\" and a full stack trace are logged",[28,59197,59199,355,59201,59203,59204,99,59206,10349],{"className":59198},[31],[33,59200],{"disabled":35,"type":36},[39,59202,55171],{}," is logged, because a thrown string has no ",[39,59205,48672],{},[39,59207,58992],{},[28,59209,59211,812,59213,59215,59216,59218],{"className":59210},[31],[33,59212],{"disabled":35,"type":36},[39,59214,827],{}," is thrown because only ",[39,59217,48601],{}," instances can be thrown",[28,59220,59222,355,59224,59226,59227,59229,59230],{"className":59221},[31],[33,59223],{"disabled":35,"type":36},[39,59225,48255],{}," is automatically wrapped into an ",[39,59228,48601],{}," object by the JS engine before reaching ",[39,59231,12488],{},[66,59233,59234,59236,59246],{},[69,59235,71],{},[73,59237,59238,1727,59240,59203,59242,99,59244,10349],{},[76,59239,78],{},[39,59241,55171],{},[39,59243,48672],{},[39,59245,58992],{},[73,59247,59248,59250,59251,59253,59254,59256,59257,6405,59260,23506,59262,59264,59265,59268,59269,99,59271,59273,59274,59276,59277,59280,59281,446,59283,446,59285,59287,59288],{},[76,59249,84],{}," JavaScript allows ",[39,59252,48836],{}," on any value — strings, numbers, plain objects — not only ",[39,59255,48601],{}," instances. ",[39,59258,59259],{},"throw \"invalid age\"",[39,59261,48255],{},[39,59263,12488],{}," is literally the string ",[39,59266,59267],{},"\"invalid age\"",", which has no ",[39,59270,48672],{},[39,59272,58992],{},", so both log as ",[39,59275,833],{},". This is a real anti-pattern: always ",[39,59278,59279],{},"throw new Error(...)"," (or a subclass) so consuming code and tooling — debuggers, error trackers, logging libraries — can rely on ",[39,59282,48672],{},[39,59284,58992],{},[39,59286,58684],{}," existing. ",[76,59289,17613],{},[15,59291,59292,59299,59443,59478],{"language":247},[18,59293,59295,59296,55991],{"id":59294},"q10-what-happens-when-handlerequest-runs","Q10. What happens when ",[39,59297,59298],{},"handleRequest",[257,59300,59301],{"language":247},[260,59302,59304],{"className":262,"code":59303,"language":247,"meta":264,"style":264},"async function processOrder(order) {\n  if (!order.items.length) throw new Error(\"empty order\");\n  return \"processed\";\n}\n\nfunction handleRequest(order) {\n  try {\n    processOrder(order);\n    console.log(\"request accepted\");\n  } catch (err) {\n    console.log(\"caught:\", err.message);\n  }\n}\n\nhandleRequest({ items: [] });\n",[39,59305,59306,59320,59348,59357,59361,59365,59378,59384,59391,59404,59412,59424,59428,59432,59436],{"__ignoreMap":264},[268,59307,59308,59310,59312,59314,59316,59318],{"class":270,"line":271},[268,59309,379],{"class":274},[268,59311,12080],{"class":274},[268,59313,11922],{"class":278},[268,59315,622],{"class":282},[268,59317,11927],{"class":1222},[268,59319,1235],{"class":282},[268,59321,59322,59324,59326,59328,59331,59333,59335,59337,59339,59341,59343,59346],{"class":270,"line":286},[268,59323,9863],{"class":274},[268,59325,2182],{"class":282},[268,59327,5418],{"class":274},[268,59329,59330],{"class":282},"order.items.",[268,59332,3567],{"class":305},[268,59334,6131],{"class":282},[268,59336,48836],{"class":274},[268,59338,11370],{"class":274},[268,59340,11593],{"class":278},[268,59342,622],{"class":282},[268,59344,59345],{"class":289},"\"empty order\"",[268,59347,628],{"class":282},[268,59349,59350,59352,59355],{"class":270,"line":296},[268,59351,1240],{"class":274},[268,59353,59354],{"class":289}," \"processed\"",[268,59356,293],{"class":282},[268,59358,59359],{"class":270,"line":311},[268,59360,314],{"class":282},[268,59362,59363],{"class":270,"line":788},[268,59364,5033],{"emptyLinePlaceholder":35},[268,59366,59367,59369,59372,59374,59376],{"class":270,"line":1951},[268,59368,275],{"class":274},[268,59370,59371],{"class":278}," handleRequest",[268,59373,622],{"class":282},[268,59375,11927],{"class":1222},[268,59377,1235],{"class":282},[268,59379,59380,59382],{"class":270,"line":8955},[268,59381,54867],{"class":274},[268,59383,9914],{"class":282},[268,59385,59386,59389],{"class":270,"line":8966},[268,59387,59388],{"class":278},"    processOrder",[268,59390,11962],{"class":282},[268,59392,59393,59395,59397,59399,59402],{"class":270,"line":8974},[268,59394,9707],{"class":282},[268,59396,1356],{"class":278},[268,59398,622],{"class":282},[268,59400,59401],{"class":289},"\"request accepted\"",[268,59403,628],{"class":282},[268,59405,59406,59408,59410],{"class":270,"line":8985},[268,59407,9881],{"class":282},[268,59409,12488],{"class":274},[268,59411,12491],{"class":282},[268,59413,59414,59416,59418,59420,59422],{"class":270,"line":8990},[268,59415,9707],{"class":282},[268,59417,1356],{"class":278},[268,59419,622],{"class":282},[268,59421,48745],{"class":289},[268,59423,55693],{"class":282},[268,59425,59426],{"class":270,"line":8997},[268,59427,1948],{"class":282},[268,59429,59430],{"class":270,"line":9002},[268,59431,314],{"class":282},[268,59433,59434],{"class":270,"line":14676},[268,59435,5033],{"emptyLinePlaceholder":35},[268,59437,59438,59440],{"class":270,"line":14681},[268,59439,59298],{"class":278},[268,59441,59442],{"class":282},"({ items: [] });\n",[23,59444,59446,59452,59460,59468],{"className":59445},[26],[28,59447,59449,59451],{"className":59448},[31],[33,59450],{"disabled":35,"type":36}," \"caught: empty order\" is logged",[28,59453,59455,58459,59457,59459],{"className":59454},[31],[33,59456],{"disabled":35,"type":36},[39,59458,59298],{}," throws synchronously",[28,59461,59463,4396,59465,59467],{"className":59462},[31],[33,59464],{"disabled":35,"type":36},[39,59466,12488],{}," block runs before \"request accepted\" is logged",[28,59469,59471,59473,59474,59477],{"className":59470},[31],[33,59472],{"disabled":35,"type":36}," \"request accepted\" is logged, and the rejection from ",[39,59475,59476],{},"processOrder"," becomes an unhandled promise rejection instead of being caught",[66,59479,59480,59482,59489],{},[69,59481,71],{},[73,59483,59484,59486,59487,59477],{},[76,59485,78],{}," D — \"request accepted\" is logged, and the rejection from ",[39,59488,59476],{},[73,59490,59491,355,59493,830,59495,59497,59498,59500,59501,59503,59504,59506,59507,59509,59510,59512,59513,59515,59516,42467,59519,59521,59522,3277,59524],{},[76,59492,84],{},[39,59494,59476],{},[39,59496,379],{},", so calling it without ",[39,59499,12304],{}," immediately returns a pending promise — the ",[39,59502,48836],{}," inside it rejects that promise rather than throwing synchronously. The surrounding ",[39,59505,2081],{}," only catches synchronous throws (or ",[39,59508,12304],{},"ed rejections), so it never sees this one. ",[39,59511,59401],{}," logs right away, and the rejection later surfaces as an ",[39,59514,53977],{}," event. The fix is to ",[39,59517,59518],{},"await processOrder(order)",[39,59520,23142],{},", or chain an explicit ",[39,59523,49873],{},[76,59525,16523],{},[15,59527,59528,59536,59641,59689],{"language":247},[18,59529,59531,59532,59535],{"id":59530},"q11-what-happens-if-the-request-inside-fetchprofile-fails","Q11. What happens if the request inside ",[39,59533,59534],{},"fetchProfile"," fails?",[257,59537,59538],{"language":247},[260,59539,59541],{"className":262,"code":59540,"language":247,"meta":264,"style":264},"function fetchProfile(id) {\n  return api.get(`\u002Fusers\u002F${id}`)\n    .catch(err => console.error(\"fetch failed:\", err));\n}\n\nfetchProfile(42).then(profile => {\n  console.log(profile.name);\n});\n",[39,59542,59543,59556,59576,59600,59604,59608,59628,59637],{"__ignoreMap":264},[268,59544,59545,59547,59550,59552,59554],{"class":270,"line":271},[268,59546,275],{"class":274},[268,59548,59549],{"class":278}," fetchProfile",[268,59551,622],{"class":282},[268,59553,14610],{"class":1222},[268,59555,1235],{"class":282},[268,59557,59558,59560,59563,59565,59567,59570,59572,59574],{"class":270,"line":286},[268,59559,1240],{"class":274},[268,59561,59562],{"class":282}," api.",[268,59564,32437],{"class":278},[268,59566,622],{"class":282},[268,59568,59569],{"class":289},"`\u002Fusers\u002F${",[268,59571,14610],{"class":282},[268,59573,11603],{"class":289},[268,59575,20702],{"class":282},[268,59577,59578,59580,59582,59584,59586,59588,59590,59592,59594,59597],{"class":270,"line":296},[268,59579,53891],{"class":282},[268,59581,12488],{"class":278},[268,59583,622],{"class":282},[268,59585,48255],{"class":1222},[268,59587,14969],{"class":274},[268,59589,9417],{"class":282},[268,59591,18282],{"class":278},[268,59593,622],{"class":282},[268,59595,59596],{"class":289},"\"fetch failed:\"",[268,59598,59599],{"class":282},", err));\n",[268,59601,59602],{"class":270,"line":311},[268,59603,314],{"class":282},[268,59605,59606],{"class":270,"line":788},[268,59607,5033],{"emptyLinePlaceholder":35},[268,59609,59610,59612,59614,59616,59618,59620,59622,59624,59626],{"class":270,"line":1951},[268,59611,59534],{"class":278},[268,59613,622],{"class":282},[268,59615,4659],{"class":305},[268,59617,6232],{"class":282},[268,59619,47505],{"class":278},[268,59621,622],{"class":282},[268,59623,54011],{"class":1222},[268,59625,14969],{"class":274},[268,59627,9914],{"class":282},[268,59629,59630,59632,59634],{"class":270,"line":8955},[268,59631,5556],{"class":282},[268,59633,1356],{"class":278},[268,59635,59636],{"class":282},"(profile.name);\n",[268,59638,59639],{"class":270,"line":8966},[268,59640,20047],{"class":282},[23,59642,59644,59662,59670,59681],{"className":59643},[26],[28,59645,59647,355,59649,830,59651,23506,59653,59655,59656,59658,59659],{"className":59646},[31],[33,59648],{"disabled":35,"type":36},[39,59650,54011],{},[39,59652,833],{},[39,59654,47423],{},", causing a ",[39,59657,827],{}," when accessing ",[39,59660,59661],{},"profile.name",[28,59663,59665,59667,59668,52174],{"className":59664},[31],[33,59666],{"disabled":35,"type":36}," If the request fails, ",[39,59669,47423],{},[28,59671,59673,4396,59675,59677,59678,59680],{"className":59672},[31],[33,59674],{"disabled":35,"type":36},[39,59676,47426],{}," rethrows automatically, so ",[39,59679,47423],{}," is skipped on failure",[28,59682,59684,355,59686,59688],{"className":59683},[31],[33,59685],{"disabled":35,"type":36},[39,59687,59534],{}," returns a rejected promise on failure, which propagates correctly to the caller",[66,59690,59691,59693,59707],{},[69,59692,71],{},[73,59694,59695,3459,59697,830,59699,23506,59701,59655,59703,59658,59705],{},[76,59696,78],{},[39,59698,54011],{},[39,59700,833],{},[39,59702,47423],{},[39,59704,827],{},[39,59706,59661],{},[73,59708,59709,812,59711,59713,59714,59716,59717,59719,59720,59723,59724,830,59726,137,59728,59730,59731,59733,59734,59736,59737],{},[76,59710,84],{},[39,59712,49873],{}," handler that only logs (and returns nothing) recovers the promise chain — its return value, ",[39,59715,833],{},", becomes the resolved value of the promise ",[39,59718,59534],{}," returns. So on failure, ",[39,59721,59722],{},".then(profile => ...)"," still runs, but ",[39,59725,54011],{},[39,59727,833],{},[39,59729,59661],{}," throws a fresh ",[39,59732,827],{}," far from the real cause. To propagate the failure instead of masking it, the ",[39,59735,12488],{}," handler must rethrow (or the caller shouldn't swallow it there at all). ",[76,59738,17307],{},[15,59740,59741,59743,59868,59906],{"language":247},[18,59742,14382],{"id":14381},[257,59744,59745],{"language":247},[260,59746,59748],{"className":262,"code":59747,"language":247,"meta":264,"style":264},"async function loadUser(id) {\n  try {\n    return await db.query(id);\n  } catch (err) {\n    throw new Error(\"failed to load user\", { cause: err });\n  }\n}\n\ntry {\n  await loadUser(1);\n} catch (e) {\n  console.log(e.message);\n  console.log(e.cause.message);\n}\n",[39,59749,59750,59765,59771,59784,59792,59808,59812,59816,59820,59826,59838,59846,59855,59864],{"__ignoreMap":264},[268,59751,59752,59754,59756,59759,59761,59763],{"class":270,"line":271},[268,59753,379],{"class":274},[268,59755,12080],{"class":274},[268,59757,59758],{"class":278}," loadUser",[268,59760,622],{"class":282},[268,59762,14610],{"class":1222},[268,59764,1235],{"class":282},[268,59766,59767,59769],{"class":270,"line":286},[268,59768,54867],{"class":274},[268,59770,9914],{"class":282},[268,59772,59773,59775,59777,59779,59782],{"class":270,"line":296},[268,59774,9871],{"class":274},[268,59776,52502],{"class":274},[268,59778,56020],{"class":282},[268,59780,59781],{"class":278},"query",[268,59783,12284],{"class":282},[268,59785,59786,59788,59790],{"class":270,"line":311},[268,59787,9881],{"class":282},[268,59789,12488],{"class":274},[268,59791,12491],{"class":282},[268,59793,59794,59796,59798,59800,59802,59805],{"class":270,"line":788},[268,59795,48705],{"class":274},[268,59797,11370],{"class":274},[268,59799,11593],{"class":278},[268,59801,622],{"class":282},[268,59803,59804],{"class":289},"\"failed to load user\"",[268,59806,59807],{"class":282},", { cause: err });\n",[268,59809,59810],{"class":270,"line":1951},[268,59811,1948],{"class":282},[268,59813,59814],{"class":270,"line":8955},[268,59815,314],{"class":282},[268,59817,59818],{"class":270,"line":8966},[268,59819,5033],{"emptyLinePlaceholder":35},[268,59821,59822,59824],{"class":270,"line":8974},[268,59823,23142],{"class":274},[268,59825,9914],{"class":282},[268,59827,59828,59830,59832,59834,59836],{"class":270,"line":8985},[268,59829,54703],{"class":274},[268,59831,59758],{"class":278},[268,59833,622],{"class":282},[268,59835,2255],{"class":305},[268,59837,628],{"class":282},[268,59839,59840,59842,59844],{"class":270,"line":8990},[268,59841,11235],{"class":282},[268,59843,12488],{"class":274},[268,59845,48734],{"class":282},[268,59847,59848,59850,59852],{"class":270,"line":8997},[268,59849,5556],{"class":282},[268,59851,1356],{"class":278},[268,59853,59854],{"class":282},"(e.message);\n",[268,59856,59857,59859,59861],{"class":270,"line":9002},[268,59858,5556],{"class":282},[268,59860,1356],{"class":278},[268,59862,59863],{"class":282},"(e.cause.message);\n",[268,59865,59866],{"class":270,"line":14676},[268,59867,314],{"class":282},[23,59869,59871,59877,59890,59896],{"className":59870},[26],[28,59872,59874,59876],{"className":59873},[31],[33,59875],{"disabled":35,"type":36}," Only the original database error's message is logged",[28,59878,59880,59882,59883,2833,59885,59887,59888,10349],{"className":59879},[31],[33,59881],{"disabled":35,"type":36}," \"failed to load user\" then ",[39,59884,833],{},[39,59886,59029],{}," is not a real ",[39,59889,48601],{},[28,59891,59893,59895],{"className":59892},[31],[33,59894],{"disabled":35,"type":36}," \"failed to load user\" then the original database error's message",[28,59897,59899,812,59901,183,59903,59905],{"className":59898},[31],[33,59900],{"disabled":35,"type":36},[39,59902,1274],{},[39,59904,48601],{}," does not accept a second argument",[66,59907,59908,59910,59915],{},[69,59909,71],{},[73,59911,59912,59914],{},[76,59913,78],{}," C — \"failed to load user\" then the original database error's message",[73,59916,59917,59919,59920,355,59922,59924,59925,59928,59929,59931,59932,59934,59935],{},[76,59918,84],{}," The ES2022 ",[39,59921,48601],{},[39,59923,59029],{}," option lets you construct a new, higher-level error while preserving the original one on ",[39,59926,59927],{},"e.cause",", so downstream code (or a debugger) can inspect both the friendly outer message and the root technical cause without losing information the way plain re-wrapping does. B is wrong because ",[39,59930,59029],{}," has been a standard, widely-supported ",[39,59933,48601],{}," constructor option since ES2022. ",[76,59936,17307],{},[15,59938,59939,59943,60053,60109],{"language":247},[18,59940,59942],{"id":59941},"q13-is-this-valid-javascript-and-what-does-it-demonstrate","Q13. Is this valid JavaScript, and what does it demonstrate?",[257,59944,59945],{"language":247},[260,59946,59948],{"className":262,"code":59947,"language":247,"meta":264,"style":264},"try {\n  JSON.parse(rawInput);\n} catch (err) {\n  if (err instanceof SyntaxError) {\n    console.log(\"bad JSON\");\n  } else if (err instanceof TypeError) {\n    console.log(\"bad input type\");\n  } else {\n    throw err;\n  }\n}\n",[39,59949,59950,59956,59967,59975,59988,60001,60018,60031,60039,60045,60049],{"__ignoreMap":264},[268,59951,59952,59954],{"class":270,"line":271},[268,59953,23142],{"class":274},[268,59955,9914],{"class":282},[268,59957,59958,59960,59962,59964],{"class":270,"line":286},[268,59959,53718],{"class":305},[268,59961,462],{"class":282},[268,59963,22274],{"class":278},[268,59965,59966],{"class":282},"(rawInput);\n",[268,59968,59969,59971,59973],{"class":270,"line":296},[268,59970,11235],{"class":282},[268,59972,12488],{"class":274},[268,59974,12491],{"class":282},[268,59976,59977,59979,59981,59983,59986],{"class":270,"line":311},[268,59978,9863],{"class":274},[268,59980,58416],{"class":282},[268,59982,3707],{"class":274},[268,59984,59985],{"class":278}," SyntaxError",[268,59987,1235],{"class":282},[268,59989,59990,59992,59994,59996,59999],{"class":270,"line":788},[268,59991,9707],{"class":282},[268,59993,1356],{"class":278},[268,59995,622],{"class":282},[268,59997,59998],{"class":289},"\"bad JSON\"",[268,60000,628],{"class":282},[268,60002,60003,60005,60007,60009,60011,60013,60016],{"class":270,"line":1951},[268,60004,9881],{"class":282},[268,60006,9884],{"class":274},[268,60008,9887],{"class":274},[268,60010,58416],{"class":282},[268,60012,3707],{"class":274},[268,60014,60015],{"class":278}," TypeError",[268,60017,1235],{"class":282},[268,60019,60020,60022,60024,60026,60029],{"class":270,"line":8955},[268,60021,9707],{"class":282},[268,60023,1356],{"class":278},[268,60025,622],{"class":282},[268,60027,60028],{"class":289},"\"bad input type\"",[268,60030,628],{"class":282},[268,60032,60033,60035,60037],{"class":270,"line":8966},[268,60034,9881],{"class":282},[268,60036,9884],{"class":274},[268,60038,9914],{"class":282},[268,60040,60041,60043],{"class":270,"line":8974},[268,60042,48705],{"class":274},[268,60044,58908],{"class":282},[268,60046,60047],{"class":270,"line":8985},[268,60048,1948],{"class":282},[268,60050,60051],{"class":270,"line":8990},[268,60052,314],{"class":282},[23,60054,60056,60068,60083,60099],{"className":60055},[26],[28,60057,60059,60061,60062,60064,60065],{"className":60058},[31],[33,60060],{"disabled":35,"type":36}," This code is invalid — JavaScript requires a separate ",[39,60063,12488],{}," clause per error type, like ",[39,60066,60067],{},"catch (SyntaxError e)",[28,60069,60071,60073,60074,60076,60077,60079,60080,60082],{"className":60070},[31],[33,60072],{"disabled":35,"type":36}," JavaScript has only one ",[39,60075,12488],{}," clause per ",[39,60078,23142],{},"; differentiating error types is done manually with ",[39,60081,3707],{}," checks inside it, as shown here",[28,60084,60086,355,60088,60091,60092,183,60094,60096,60097],{"className":60085},[31],[33,60087],{"disabled":35,"type":36},[39,60089,60090],{},"instanceof SyntaxError"," will never be ",[39,60093,2185],{},[39,60095,22423],{}," throws a plain ",[39,60098,48601],{},[28,60100,60102,4396,60104,60106,60107],{"className":60101},[31],[33,60103],{"disabled":35,"type":36},[39,60105,9884],{}," branch causes an infinite loop by re-throwing inside a ",[39,60108,12488],{},[66,60110,60111,60113,60124],{},[69,60112,71],{},[73,60114,60115,60117,60118,60076,60120,60079,60122,60082],{},[76,60116,78],{}," B — JavaScript has only one ",[39,60119,12488],{},[39,60121,23142],{},[39,60123,3707],{},[73,60125,60126,60128,60129,60131,60132,60134,60135,60137,60138,60140,60141,60143,60144,60146],{},[76,60127,84],{}," Unlike languages such as Java or Python that support multiple typed ",[39,60130,12488],{}," clauses, JavaScript's ",[39,60133,23142],{}," statement allows exactly one ",[39,60136,12488],{}," block. The idiomatic way to branch on error type is ",[39,60139,3707],{}," checks inside that single block, rethrowing (or handling generically) anything unrecognized. ",[39,60142,22423],{}," genuinely throws a ",[39,60145,1274],{}," on malformed JSON, so C is false, and A describes syntax that doesn't exist in JS.",[15,60148,60149,60153,60225,60265],{"language":247},[18,60150,60152],{"id":60151},"q14-what-is-this-syntax-and-when-is-it-appropriate","Q14. What is this syntax, and when is it appropriate?",[257,60154,60155],{"language":247},[260,60156,60158],{"className":262,"code":60157,"language":247,"meta":264,"style":264},"async function isPortAvailable(port) {\n  try {\n    await net.connect(port);\n    return false;\n  } catch {\n    return true;\n  }\n}\n",[39,60159,60160,60175,60181,60193,60201,60209,60217,60221],{"__ignoreMap":264},[268,60161,60162,60164,60166,60169,60171,60173],{"class":270,"line":271},[268,60163,379],{"class":274},[268,60165,12080],{"class":274},[268,60167,60168],{"class":278}," isPortAvailable",[268,60170,622],{"class":282},[268,60172,14248],{"class":1222},[268,60174,1235],{"class":282},[268,60176,60177,60179],{"class":270,"line":286},[268,60178,54867],{"class":274},[268,60180,9914],{"class":282},[268,60182,60183,60185,60188,60190],{"class":270,"line":296},[268,60184,12278],{"class":274},[268,60186,60187],{"class":282}," net.",[268,60189,14292],{"class":278},[268,60191,60192],{"class":282},"(port);\n",[268,60194,60195,60197,60199],{"class":270,"line":311},[268,60196,9871],{"class":274},[268,60198,3200],{"class":305},[268,60200,293],{"class":282},[268,60202,60203,60205,60207],{"class":270,"line":788},[268,60204,9881],{"class":282},[268,60206,12488],{"class":274},[268,60208,9914],{"class":282},[268,60210,60211,60213,60215],{"class":270,"line":1951},[268,60212,9871],{"class":274},[268,60214,7905],{"class":305},[268,60216,293],{"class":282},[268,60218,60219],{"class":270,"line":8955},[268,60220,1948],{"class":282},[268,60222,60223],{"class":270,"line":8966},[268,60224,314],{"class":282},[23,60226,60228,60239,60250,60259],{"className":60227},[26],[28,60229,60231,60233,60234,60236,60237],{"className":60230},[31],[33,60232],{"disabled":35,"type":36}," This is a syntax error — ",[39,60235,12488],{}," always requires a parenthesized parameter like ",[39,60238,55011],{},[28,60240,60242,355,60244,60246,60247,60249],{"className":60241},[31],[33,60243],{"disabled":35,"type":36},[39,60245,12488],{}," without a parameter silently ignores only ",[39,60248,827],{},"s and lets everything else propagate",[28,60251,60253,60255,60256,60258],{"className":60252},[31],[33,60254],{"disabled":35,"type":36}," This works, but ",[39,60257,48255],{}," is still implicitly available as a global variable inside the block",[28,60260,60262,60264],{"className":60261},[31],[33,60263],{"disabled":35,"type":36}," This is valid ES2019+ syntax called optional catch binding, used when the caught error's details aren't needed",[66,60266,60267,60269,60274],{},[69,60268,71],{},[73,60270,60271,60273],{},[76,60272,78],{}," D — This is valid ES2019+ syntax called optional catch binding, used when the caught error's details aren't needed",[73,60275,60276,60278,60279,60282,60283,60286,60287,60290,60291,60294,60295],{},[76,60277,84],{}," Optional catch binding (",[39,60280,60281],{},"catch { ... }"," with no ",[39,60284,60285],{},"(err)",") has been valid syntax since ES2019 for exactly this situation — reacting to the fact that something failed without needing the error object itself. It's cleaner than ",[39,60288,60289],{},"catch (_)"," or an unused ",[39,60292,60293],{},"catch (err) { ... }"," parameter and avoids unused-variable lint warnings. ",[76,60296,17307],{},[15,60298,60299,60311,60341],{},[18,60300,60302,60303,9530,60306,60308,60309,1685],{"id":60301},"q15-why-are-windowonerror-and-the-unhandledrejection-event-described-as-last-resort-global-error-handlers-rather-than-a-replacement-for-local-trycatch","Q15. Why are ",[39,60304,60305],{},"window.onerror",[39,60307,53977],{}," event described as \"last resort\" global error handlers rather than a replacement for local ",[39,60310,2081],{},[23,60312,60314,60320,60326,60332],{"className":60313},[26],[28,60315,60317,60319],{"className":60316},[31],[33,60318],{"disabled":35,"type":36}," By the time they fire, the error has already escaped its original context — you've lost the chance to retry, show inline UI feedback, or recover gracefully; they're best used for logging\u002Freporting errors that were missed locally",[28,60321,60323,60325],{"className":60322},[31],[33,60324],{"disabled":35,"type":36}," They only fire in browsers, not in Node.js, so relying on them breaks server-side code",[28,60327,60329,60331],{"className":60328},[31],[33,60330],{"disabled":35,"type":36}," They automatically retry the failed operation, which is usually undesirable",[28,60333,60335,60337,60338,60340],{"className":60334},[31],[33,60336],{"disabled":35,"type":36}," They can only catch errors thrown inside ",[39,60339,23142],{}," blocks, not truly uncaught ones",[66,60342,60343,60345,60350],{},[69,60344,71],{},[73,60346,60347,60349],{},[76,60348,78],{}," A — By the time they fire, the error has already escaped its original context — you've lost the chance to retry, show inline UI feedback, or recover gracefully; they're best used for logging\u002Freporting errors that were missed locally",[73,60351,60352,60354,60355,446,60358,60361],{},[76,60353,84],{}," Global handlers are a safety net for observability, e.g. shipping errors to a monitoring service, but they run after the stack has already unwound, so there's no way to resume the original operation, show contextual UI, or apply targeted recovery logic. Meaningful recovery requires catching close to the failure. B is false (Node has its analogous ",[39,60356,60357],{},"process.on('uncaughtException')",[39,60359,60360],{},"process.on('unhandledRejection')","); D is false — they exist specifically to catch what wasn't caught locally.",[15,60363,60364,60371,60463,60504],{"language":247},[18,60365,60367,60368,55991],{"id":60366},"q16-what-happens-when-schedulework-runs","Q16. What happens when ",[39,60369,60370],{},"scheduleWork",[257,60372,60373],{"language":247},[260,60374,60376],{"className":262,"code":60375,"language":247,"meta":264,"style":264},"function scheduleWork() {\n  try {\n    setTimeout(() => {\n      throw new Error(\"boom\");\n    }, 100);\n  } catch (err) {\n    console.log(\"caught:\", err.message);\n  }\n}\n\nscheduleWork();\n",[39,60377,60378,60387,60393,60403,60417,60425,60433,60445,60449,60453,60457],{"__ignoreMap":264},[268,60379,60380,60382,60385],{"class":270,"line":271},[268,60381,275],{"class":274},[268,60383,60384],{"class":278}," scheduleWork",[268,60386,283],{"class":282},[268,60388,60389,60391],{"class":270,"line":286},[268,60390,54867],{"class":274},[268,60392,9914],{"class":282},[268,60394,60395,60397,60399,60401],{"class":270,"line":296},[268,60396,35594],{"class":278},[268,60398,9411],{"class":282},[268,60400,9414],{"class":274},[268,60402,9914],{"class":282},[268,60404,60405,60407,60409,60411,60413,60415],{"class":270,"line":311},[268,60406,11588],{"class":274},[268,60408,11370],{"class":274},[268,60410,11593],{"class":278},[268,60412,622],{"class":282},[268,60414,48714],{"class":289},[268,60416,628],{"class":282},[268,60418,60419,60421,60423],{"class":270,"line":788},[268,60420,35618],{"class":282},[268,60422,13912],{"class":305},[268,60424,628],{"class":282},[268,60426,60427,60429,60431],{"class":270,"line":1951},[268,60428,9881],{"class":282},[268,60430,12488],{"class":274},[268,60432,12491],{"class":282},[268,60434,60435,60437,60439,60441,60443],{"class":270,"line":8955},[268,60436,9707],{"class":282},[268,60438,1356],{"class":278},[268,60440,622],{"class":282},[268,60442,48745],{"class":289},[268,60444,55693],{"class":282},[268,60446,60447],{"class":270,"line":8966},[268,60448,1948],{"class":282},[268,60450,60451],{"class":270,"line":8974},[268,60452,314],{"class":282},[268,60454,60455],{"class":270,"line":8985},[268,60456,5033],{"emptyLinePlaceholder":35},[268,60458,60459,60461],{"class":270,"line":8990},[268,60460,60370],{"class":278},[268,60462,794],{"class":282},[23,60464,60466,60472,60483,60492],{"className":60465},[26],[28,60467,60469,60471],{"className":60468},[31],[33,60470],{"disabled":35,"type":36}," \"caught: boom\" is logged after 100ms",[28,60473,60475,4396,60477,60479,60480,60482],{"className":60474},[31],[33,60476],{"disabled":35,"type":36},[39,60478,2081],{}," prevents ",[39,60481,9578],{}," from ever calling the callback",[28,60484,60486,60488,60489,60491],{"className":60485},[31],[33,60487],{"disabled":35,"type":36}," Nothing is logged by the ",[39,60490,12488],{},"; the error becomes an uncaught exception once the timer callback runs, in a later turn of the event loop",[28,60493,60495,812,60497,60499,60500,10834,60502,47378],{"className":60494},[31],[33,60496],{"disabled":35,"type":36},[39,60498,827],{}," is thrown immediately because you cannot ",[39,60501,48836],{},[39,60503,9578],{},[66,60505,60506,60508,60515],{},[69,60507,71],{},[73,60509,60510,60512,60513,60491],{},[76,60511,78],{}," C — Nothing is logged by the ",[39,60514,12488],{},[73,60516,60517,355,60519,60521,60522,60524,60525,60527,60528,60530,60531,60533,60534],{},[76,60518,84],{},[39,60520,2081],{}," can only catch synchronous exceptions that occur while it's actively on the call stack. ",[39,60523,9578],{}," schedules its callback to run later, in a completely separate event-loop turn — by the time it executes, the original ",[39,60526,2081],{}," has already finished and is off the stack, so it has no way to intercept the throw. The error surfaces as an uncaught exception (Node) or via ",[39,60529,60305],{}," (browsers). The fix is to put the ",[39,60532,2081],{}," inside the callback itself. ",[76,60535,16523],{},[15,60537,60538,60548,60650,60687],{"language":247},[18,60539,60541,60542,60545,60546,55991],{"id":60540},"q17-if-saveitem-rejects-for-one-item-what-happens-when-processall-runs","Q17. If ",[39,60543,60544],{},"save(item)"," rejects for one item, what happens when ",[39,60547,56360],{},[257,60549,60550],{"language":247},[260,60551,60553],{"className":262,"code":60552,"language":247,"meta":264,"style":264},"async function processAll(items) {\n  try {\n    items.forEach(async (item) => {\n      await save(item);\n    });\n    console.log(\"all done\");\n  } catch (err) {\n    console.log(\"caught:\", err.message);\n  }\n}\n",[39,60554,60555,60569,60575,60596,60606,60610,60622,60630,60642,60646],{"__ignoreMap":264},[268,60556,60557,60559,60561,60563,60565,60567],{"class":270,"line":271},[268,60558,379],{"class":274},[268,60560,12080],{"class":274},[268,60562,12251],{"class":278},[268,60564,622],{"class":282},[268,60566,56380],{"class":1222},[268,60568,1235],{"class":282},[268,60570,60571,60573],{"class":270,"line":286},[268,60572,54867],{"class":274},[268,60574,9914],{"class":282},[268,60576,60577,60580,60582,60584,60586,60588,60590,60592,60594],{"class":270,"line":296},[268,60578,60579],{"class":282},"    items.",[268,60581,12330],{"class":278},[268,60583,622],{"class":282},[268,60585,379],{"class":274},[268,60587,2182],{"class":282},[268,60589,14793],{"class":1222},[268,60591,6131],{"class":282},[268,60593,9414],{"class":274},[268,60595,9914],{"class":282},[268,60597,60598,60601,60604],{"class":270,"line":311},[268,60599,60600],{"class":274},"      await",[268,60602,60603],{"class":278}," save",[268,60605,11808],{"class":282},[268,60607,60608],{"class":270,"line":788},[268,60609,35432],{"class":282},[268,60611,60612,60614,60616,60618,60620],{"class":270,"line":1951},[268,60613,9707],{"class":282},[268,60615,1356],{"class":278},[268,60617,622],{"class":282},[268,60619,56440],{"class":289},[268,60621,628],{"class":282},[268,60623,60624,60626,60628],{"class":270,"line":8955},[268,60625,9881],{"class":282},[268,60627,12488],{"class":274},[268,60629,12491],{"class":282},[268,60631,60632,60634,60636,60638,60640],{"class":270,"line":8966},[268,60633,9707],{"class":282},[268,60635,1356],{"class":278},[268,60637,622],{"class":282},[268,60639,48745],{"class":289},[268,60641,55693],{"class":282},[268,60643,60644],{"class":270,"line":8974},[268,60645,1948],{"class":282},[268,60647,60648],{"class":270,"line":8985},[268,60649,314],{"class":282},[23,60651,60653,60661,60669,60679],{"className":60652},[26],[28,60654,60656,60658,60659],{"className":60655},[31],[33,60657],{"disabled":35,"type":36}," \"all done\" logs immediately, and the rejection becomes an unhandled promise rejection, uncaught by the surrounding ",[39,60660,2081],{},[28,60662,60664,4396,60666,60668],{"className":60663},[31],[33,60665],{"disabled":35,"type":36},[39,60667,12488],{}," block logs the rejection's error message",[28,60670,60672,355,60674,60676,60677],{"className":60671},[31],[33,60673],{"disabled":35,"type":36},[39,60675,56360],{}," itself rejects, and the caller must add a ",[39,60678,49873],{},[28,60680,60682,355,60684,60686],{"className":60681},[31],[33,60683],{"disabled":35,"type":36},[39,60685,12330],{}," waits for all async callbacks to settle before moving to the next line",[66,60688,60689,60691,60698],{},[69,60690,71],{},[73,60692,60693,60695,60696],{},[76,60694,78],{}," A — \"all done\" logs immediately, and the rejection becomes an unhandled promise rejection, uncaught by the surrounding ",[39,60697,2081],{},[73,60699,60700,355,60702,60704,60705,60707,60708,60711,60712,60714,60715,60717,60718,383,60720,42467,60723,3277,60725,8828,60727],{},[76,60701,84],{},[39,60703,12384],{}," does not await the promises returned by its (async) callback, nor does it propagate their rejections — it fires all callbacks and moves on immediately, so ",[39,60706,56440],{}," logs right away regardless of what ",[39,60709,60710],{},"save"," does. Any rejection inside one of those detached async callbacks becomes an unhandled promise rejection instead of surfacing in the surrounding ",[39,60713,2081],{},". The idiomatic fix is a ",[39,60716,9163],{}," loop with ",[39,60719,12304],{},[39,60721,60722],{},"Promise.all(items.map(item => save(item)))",[39,60724,23142],{},[76,60726,55328],{},[76,60728,16523],{},[15,60730,60731,60735,60765],{},[18,60732,60734],{"id":60733},"q18-a-function-three-layers-deep-in-a-call-stack-fails-to-write-to-a-cache-a-non-critical-recoverable-failure-while-a-top-level-function-fails-to-authenticate-a-user-a-critical-failure-the-caller-must-react-to-whats-the-best-practice-approach-to-where-each-error-is-caught","Q18. A function three layers deep in a call stack fails to write to a cache (a non-critical, recoverable failure), while a top-level function fails to authenticate a user (a critical failure the caller must react to). What's the best-practice approach to where each error is caught?",[23,60736,60738,60744,60750,60756],{"className":60737},[26],[28,60739,60741,60743],{"className":60740},[31],[33,60742],{"disabled":35,"type":36}," Catch both errors at the very top of the application in a single global handler, to keep error-handling logic centralized",[28,60745,60747,60749],{"className":60746},[31],[33,60748],{"disabled":35,"type":36}," Never catch errors inside deeply nested functions; always let every error bubble to the top",[28,60751,60753,60755],{"className":60752},[31],[33,60754],{"disabled":35,"type":36}," Catch every error immediately where it's thrown and never rethrow, to avoid unhandled rejections",[28,60757,60759,60761,60762,60764],{"className":60758},[31],[33,60760],{"disabled":35,"type":36}," Catch the cache-write failure close to where it happens (a fallback, like skipping the cache, is possible there), and let the authentication failure propagate up to a caller that can actually decide what to do, attaching context via ",[39,60763,59029],{}," or custom fields as it goes",[66,60766,60767,60769,60776],{},[69,60768,71],{},[73,60770,60771,60773,60774,60764],{},[76,60772,78],{}," D — Catch the cache-write failure close to where it happens, and let the authentication failure propagate up to a caller that can actually decide what to do, attaching context via ",[39,60775,59029],{},[73,60777,60778,60780,60781,60783,60784],{},[76,60779,84],{}," The right layer to catch an error is the layer that can do something meaningful about it. A recoverable, local failure (skip the cache, continue) should be handled where the fallback is known; a failure that requires a caller-level decision (redirect to login, retry, surface to the user) should propagate — ideally enriched with ",[39,60782,59029],{}," or extra fields at each hop — rather than being caught prematurely and silently discarded. A centralizes logic but loses recovery opportunities; C swallows everything, hiding real failures from callers who need to know. ",[76,60785,17307],{},[15,60787,60788,60790,60929,60956],{"language":247},[18,60789,26306],{"id":26305},[257,60791,60792],{"language":247},[260,60793,60795],{"className":262,"code":60794,"language":247,"meta":264,"style":264},"function transferFunds(amount) {\n  try {\n    throw new Error(\"insufficient balance\");\n  } finally {\n    validateAudit();\n  }\n}\n\nfunction validateAudit() {\n  throw new Error(\"audit log unavailable\");\n}\n\ntry {\n  transferFunds(100);\n} catch (err) {\n  console.log(err.message);\n}\n",[39,60796,60797,60810,60816,60831,60839,60846,60850,60854,60858,60867,60883,60887,60891,60897,60908,60916,60925],{"__ignoreMap":264},[268,60798,60799,60801,60804,60806,60808],{"class":270,"line":271},[268,60800,275],{"class":274},[268,60802,60803],{"class":278}," transferFunds",[268,60805,622],{"class":282},[268,60807,31848],{"class":1222},[268,60809,1235],{"class":282},[268,60811,60812,60814],{"class":270,"line":286},[268,60813,54867],{"class":274},[268,60815,9914],{"class":282},[268,60817,60818,60820,60822,60824,60826,60829],{"class":270,"line":296},[268,60819,48705],{"class":274},[268,60821,11370],{"class":274},[268,60823,11593],{"class":278},[268,60825,622],{"class":282},[268,60827,60828],{"class":289},"\"insufficient balance\"",[268,60830,628],{"class":282},[268,60832,60833,60835,60837],{"class":270,"line":311},[268,60834,9881],{"class":282},[268,60836,51954],{"class":274},[268,60838,9914],{"class":282},[268,60840,60841,60844],{"class":270,"line":788},[268,60842,60843],{"class":278},"    validateAudit",[268,60845,794],{"class":282},[268,60847,60848],{"class":270,"line":1951},[268,60849,1948],{"class":282},[268,60851,60852],{"class":270,"line":8955},[268,60853,314],{"class":282},[268,60855,60856],{"class":270,"line":8966},[268,60857,5033],{"emptyLinePlaceholder":35},[268,60859,60860,60862,60865],{"class":270,"line":8974},[268,60861,275],{"class":274},[268,60863,60864],{"class":278}," validateAudit",[268,60866,283],{"class":282},[268,60868,60869,60872,60874,60876,60878,60881],{"class":270,"line":8985},[268,60870,60871],{"class":274},"  throw",[268,60873,11370],{"class":274},[268,60875,11593],{"class":278},[268,60877,622],{"class":282},[268,60879,60880],{"class":289},"\"audit log unavailable\"",[268,60882,628],{"class":282},[268,60884,60885],{"class":270,"line":8990},[268,60886,314],{"class":282},[268,60888,60889],{"class":270,"line":8997},[268,60890,5033],{"emptyLinePlaceholder":35},[268,60892,60893,60895],{"class":270,"line":9002},[268,60894,23142],{"class":274},[268,60896,9914],{"class":282},[268,60898,60899,60902,60904,60906],{"class":270,"line":14676},[268,60900,60901],{"class":278},"  transferFunds",[268,60903,622],{"class":282},[268,60905,13912],{"class":305},[268,60907,628],{"class":282},[268,60909,60910,60912,60914],{"class":270,"line":14681},[268,60911,11235],{"class":282},[268,60913,12488],{"class":274},[268,60915,12491],{"class":282},[268,60917,60918,60920,60922],{"class":270,"line":31051},[268,60919,5556],{"class":282},[268,60921,1356],{"class":278},[268,60923,60924],{"class":282},"(err.message);\n",[268,60926,60927],{"class":270,"line":31071},[268,60928,314],{"class":282},[23,60930,60932,60938,60944,60950],{"className":60931},[26],[28,60933,60935,60937],{"className":60934},[31],[33,60936],{"disabled":35,"type":36}," \"audit log unavailable\" is logged, and \"insufficient balance\" is discarded entirely",[28,60939,60941,60943],{"className":60940},[31],[33,60942],{"disabled":35,"type":36}," \"insufficient balance\" is logged",[28,60945,60947,60949],{"className":60946},[31],[33,60948],{"disabled":35,"type":36}," Both error messages are logged, joined together",[28,60951,60953,60955],{"className":60952},[31],[33,60954],{"disabled":35,"type":36}," Nothing is logged because two errors in one call stack crash the process",[66,60957,60958,60960,60965],{},[69,60959,71],{},[73,60961,60962,60964],{},[76,60963,78],{}," A — \"audit log unavailable\" is logged, and \"insufficient balance\" is discarded entirely",[73,60966,60967,60969,60970,2018,60972,60974,60975,60977,60978,446,60980,3990,60982,60984,60985,183,60987,31326,60989,60992,60993,60995,60996,60998,60999,8828,61001],{},[76,60968,84],{}," Just as an explicit ",[39,60971,9151],{},[39,60973,51954],{}," overrides a pending return or throw, a new exception thrown inside ",[39,60976,51954],{}," also overrides whatever was propagating from ",[39,60979,23142],{},[39,60981,12488],{},[39,60983,60828],{}," never reaches the outer ",[39,60986,12488],{},[39,60988,51954],{},[39,60990,60991],{},"throw new Error(\"audit log unavailable\")"," replaces it as the statement's outcome. This is why code inside ",[39,60994,51954],{}," should be simple and defensive (or wrapped in its own ",[39,60997,2081],{},") — an unrelated failure there can silently mask the real error. ",[76,61000,16523],{},[76,61002,17613],{},[15,61004,61005,61009,61098,61155],{"language":247},[18,61006,61008],{"id":61007},"q20-which-statement-best-describes-why-this-implementation-follows-good-error-handling-practice","Q20. Which statement best describes why this implementation follows good error-handling practice?",[257,61010,61011],{"language":247},[260,61012,61014],{"className":262,"code":61013,"language":247,"meta":264,"style":264},"async function loadSettings(raw) {\n  try {\n    const parsed = JSON.parse(raw);\n    return await applyDefaults(parsed);\n  } catch (err) {\n    throw new Error(\"could not load settings\", { cause: err });\n  }\n}\n",[39,61015,61016,61031,61037,61055,61067,61075,61090,61094],{"__ignoreMap":264},[268,61017,61018,61020,61022,61025,61027,61029],{"class":270,"line":271},[268,61019,379],{"class":274},[268,61021,12080],{"class":274},[268,61023,61024],{"class":278}," loadSettings",[268,61026,622],{"class":282},[268,61028,18827],{"class":1222},[268,61030,1235],{"class":282},[268,61032,61033,61035],{"class":270,"line":286},[268,61034,54867],{"class":274},[268,61036,9914],{"class":282},[268,61038,61039,61041,61044,61046,61048,61050,61052],{"class":270,"line":296},[268,61040,37893],{"class":274},[268,61042,61043],{"class":305}," parsed",[268,61045,616],{"class":274},[268,61047,21715],{"class":305},[268,61049,462],{"class":282},[268,61051,22274],{"class":278},[268,61053,61054],{"class":282},"(raw);\n",[268,61056,61057,61059,61061,61064],{"class":270,"line":311},[268,61058,9871],{"class":274},[268,61060,52502],{"class":274},[268,61062,61063],{"class":278}," applyDefaults",[268,61065,61066],{"class":282},"(parsed);\n",[268,61068,61069,61071,61073],{"class":270,"line":788},[268,61070,9881],{"class":282},[268,61072,12488],{"class":274},[268,61074,12491],{"class":282},[268,61076,61077,61079,61081,61083,61085,61088],{"class":270,"line":1951},[268,61078,48705],{"class":274},[268,61080,11370],{"class":274},[268,61082,11593],{"class":278},[268,61084,622],{"class":282},[268,61086,61087],{"class":289},"\"could not load settings\"",[268,61089,59807],{"class":282},[268,61091,61092],{"class":270,"line":8955},[268,61093,1948],{"class":282},[268,61095,61096],{"class":270,"line":8966},[268,61097,314],{"class":282},[23,61099,61101,61116,61127,61145],{"className":61100},[26],[28,61102,61104,61106,61107,61109,61110,61112,61113,61115],{"className":61103},[31],[33,61105],{"disabled":35,"type":36}," It is flawed because ",[39,61108,2081],{}," cannot wrap both a synchronous call (",[39,61111,22423],{},") and an ",[39,61114,12304],{}," expression in the same block",[28,61117,61119,61121,61122,61124,61125,56846],{"className":61118},[31],[33,61120],{"disabled":35,"type":36}," It is flawed because throwing inside a ",[39,61123,12488],{}," block is not allowed in ",[39,61126,379],{},[28,61128,61130,61132,61133,20968,61135,61137,61138,61141,61142,61144],{"className":61129},[31],[33,61131],{"disabled":35,"type":36}," It catches both the potential ",[39,61134,1274],{},[39,61136,22423],{}," and any rejection from ",[39,61139,61140],{},"applyDefaults"," in a single block, wraps them in a descriptive higher-level error, and preserves the original failure via ",[39,61143,59029],{}," — all without swallowing it",[28,61146,61148,61150,61151,61154],{"className":61147},[31],[33,61149],{"disabled":35,"type":36}," It should use ",[39,61152,61153],{},"catch {}"," with no binding, since the original error is discarded anyway",[66,61156,61157,61159,61172],{},[69,61158,71],{},[73,61160,61161,61163,61164,20968,61166,61137,61168,61141,61170,61144],{},[76,61162,78],{}," C — It catches both the potential ",[39,61165,1274],{},[39,61167,22423],{},[39,61169,61140],{},[39,61171,59029],{},[73,61173,61174,51499,61176,61178,61179,61181,61182,61184,61185,61188,61189,61191,61192,61194,61195],{},[76,61175,84],{},[39,61177,23142],{}," can legally mix synchronous statements and ",[39,61180,12304],{},"ed expressions — either kind of failure lands in the same ",[39,61183,12488],{},". Wrapping with a clearer message while attaching ",[39,61186,61187],{},"{ cause: err }"," gives callers a readable error and preserves the root cause for logs and debuggers, rather than either swallowing the original error or leaking a raw ",[39,61190,1274],{},"\u002Frejection with no context. A and B describe restrictions that don't exist in JS; D is wrong because the original error is deliberately preserved via ",[39,61193,59029],{},", not discarded. ",[76,61196,17307],{},[2107,61198,61199],{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-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 .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}",{"title":264,"searchDepth":286,"depth":286,"links":61201},[61202,61204,61205,61206,61207,61208,61209,61210,61211,61212,61214,61216,61217,61218,61219,61221,61223,61225,61226,61227],{"id":57650,"depth":296,"text":61203},"Q1. Which statement about the finally block in a try\u002Fcatch\u002Ffinally statement is true?",{"id":12736,"depth":296,"text":12737},{"id":12876,"depth":296,"text":12877},{"id":58104,"depth":296,"text":58105},{"id":13180,"depth":296,"text":13181},{"id":13320,"depth":296,"text":13321},{"id":58710,"depth":296,"text":58711},{"id":58852,"depth":296,"text":58853},{"id":13926,"depth":296,"text":13927},{"id":59294,"depth":296,"text":61213},"Q10. What happens when handleRequest runs?",{"id":59530,"depth":296,"text":61215},"Q11. What happens if the request inside fetchProfile fails?",{"id":14381,"depth":296,"text":14382},{"id":59941,"depth":296,"text":59942},{"id":60151,"depth":296,"text":60152},{"id":60301,"depth":296,"text":61220},"Q15. Why are window.onerror and the unhandledrejection event described as \"last resort\" global error handlers rather than a replacement for local try\u002Fcatch?",{"id":60366,"depth":296,"text":61222},"Q16. What happens when scheduleWork runs?",{"id":60540,"depth":296,"text":61224},"Q17. If save(item) rejects for one item, what happens when processAll runs?",{"id":60733,"depth":296,"text":60734},{"id":26305,"depth":296,"text":26306},{"id":61007,"depth":296,"text":61008},{},"\u002Fjs\u002F18-error-handling",{"title":57640,"description":264},"js\u002F18-error-handling","cKRRdjFMLTcaogDw96bxS9KvtRm-ZB-UZDJEqIpMr88",{"id":61234,"title":61235,"body":61236,"description":264,"extension":2144,"meta":64534,"navigation":35,"path":64535,"seo":64536,"stem":64537,"__hash__":64538},"content\u002Fjs\u002F19-the-dom.md","19 — The DOM",{"type":8,"value":61237,"toc":64496},[61238,61241,61351,61568,61777,61946,62092,62306,62381,62541,62740,62929,63104,63204,63400,63531,63715,63858,64106,64228,64408,64493],[11,61239,61235],{"id":61240},"_19-the-dom",[15,61242,61243,61261,61310],{},[18,61244,61246,61247,61250,61251,61254,61255,186,61258,1685],{"id":61245},"q1-a-page-has-multiple-li-classitem-elements-inside-a-ul-what-is-the-key-structural-difference-between-the-results-of-documentqueryselectorallitem-and-documentgetelementsbyclassnameitem","Q1. A page has multiple ",[39,61248,61249],{},"\u003Cli class=\"item\">"," elements inside a ",[39,61252,61253],{},"\u003Cul>",". What is the key structural difference between the results of ",[39,61256,61257],{},"document.querySelectorAll('.item')",[39,61259,61260],{},"document.getElementsByClassName('item')",[23,61262,61264,61274,61291,61304],{"className":61263},[26],[28,61265,61267,61269,61270,61273],{"className":61266},[31],[33,61268],{"disabled":35,"type":36}," Both return a live ",[39,61271,61272],{},"HTMLCollection"," that updates automatically as the DOM changes",[28,61275,61277,355,61279,25735,61281,61283,61284,61287,61288,61290],{"className":61276},[31],[33,61278],{"disabled":35,"type":36},[39,61280,25662],{},[39,61282,25738],{}," snapshot taken at call time; ",[39,61285,61286],{},"getElementsByClassName"," returns a live ",[39,61289,61272],{}," that reflects later DOM changes",[28,61292,61294,355,61296,61287,61298,2272,61300,25735,61302],{"className":61293},[31],[33,61295],{"disabled":35,"type":36},[39,61297,25662],{},[39,61299,61272],{},[39,61301,61286],{},[39,61303,25738],{},[28,61305,61307,61309],{"className":61306},[31],[33,61308],{"disabled":35,"type":36}," Both return static arrays that never update, regardless of which method is used",[66,61311,61312,61314,61326],{},[69,61313,71],{},[73,61315,61316,1727,61318,25735,61320,61283,61322,61287,61324,61290],{},[76,61317,78],{},[39,61319,25662],{},[39,61321,25738],{},[39,61323,61286],{},[39,61325,61272],{},[73,61327,61328,355,61330,2338,61332,61335,61336,61338,61339,42,61341,137,61344,61347,61348,61350],{},[76,61329,84],{},[39,61331,25662],{},[39,61333,61334],{},"querySelector",") always builds a static ",[39,61337,25738],{}," — a frozen snapshot of what matched at the moment the query ran, unaffected by later DOM mutations. The older ",[39,61340,61286],{},[39,61342,61343],{},"getElementsByTagName",[39,61345,61346],{},"getElementsByName"," methods return live ",[39,61349,61272],{},"s, which behave like a saved query that automatically re-evaluates as the document changes. Option C reverses the two — a very common mix-up. Options A and D collapse a real, load-bearing distinction that later questions build on.",[15,61352,61353,61359,61468,61522],{"language":247},[18,61354,61356,61357,54840],{"id":61355},"q2-what-does-the-second-consolelog-print","Q2. What does the second ",[39,61358,5627],{},[257,61360,61361],{"language":247},[260,61362,61364],{"className":262,"code":61363,"language":247,"meta":264,"style":264},"const items = document.querySelectorAll('.item');\nconsole.log(items.length); \u002F\u002F 3\n\nconst li = document.createElement('li');\nli.className = 'item';\ndocument.querySelector('ul').appendChild(li);\n\nconsole.log(items.length);\n",[39,61365,61366,61385,61400,61404,61422,61434,61452,61456],{"__ignoreMap":264},[268,61367,61368,61370,61372,61374,61376,61378,61380,61383],{"class":270,"line":271},[268,61369,243],{"class":274},[268,61371,11725],{"class":305},[268,61373,616],{"class":274},[268,61375,25659],{"class":282},[268,61377,25662],{"class":278},[268,61379,622],{"class":282},[268,61381,61382],{"class":289},"'.item'",[268,61384,628],{"class":282},[268,61386,61387,61389,61391,61393,61395,61397],{"class":270,"line":286},[268,61388,1353],{"class":282},[268,61390,1356],{"class":278},[268,61392,56719],{"class":282},[268,61394,3567],{"class":305},[268,61396,5789],{"class":282},[268,61398,61399],{"class":29390},"\u002F\u002F 3\n",[268,61401,61402],{"class":270,"line":296},[268,61403,5033],{"emptyLinePlaceholder":35},[268,61405,61406,61408,61410,61412,61414,61416,61418,61420],{"class":270,"line":311},[268,61407,243],{"class":274},[268,61409,40550],{"class":305},[268,61411,616],{"class":274},[268,61413,25659],{"class":282},[268,61415,40557],{"class":278},[268,61417,622],{"class":282},[268,61419,25667],{"class":289},[268,61421,628],{"class":282},[268,61423,61424,61427,61429,61432],{"class":270,"line":788},[268,61425,61426],{"class":282},"li.className ",[268,61428,302],{"class":274},[268,61430,61431],{"class":289}," 'item'",[268,61433,293],{"class":282},[268,61435,61436,61439,61441,61443,61446,61448,61450],{"class":270,"line":1951},[268,61437,61438],{"class":282},"document.",[268,61440,61334],{"class":278},[268,61442,622],{"class":282},[268,61444,61445],{"class":289},"'ul'",[268,61447,6232],{"class":282},[268,61449,40592],{"class":278},[268,61451,40595],{"class":282},[268,61453,61454],{"class":270,"line":8955},[268,61455,5033],{"emptyLinePlaceholder":35},[268,61457,61458,61460,61462,61464,61466],{"class":270,"line":8966},[268,61459,1353],{"class":282},[268,61461,1356],{"class":278},[268,61463,56719],{"class":282},[268,61465,3567],{"class":305},[268,61467,628],{"class":282},[23,61469,61471,61484,61496,61507],{"className":61470},[26],[28,61472,61474,355,61476,3990,61478,61480,61481,61483],{"className":61473},[31],[33,61475],{"disabled":35,"type":36},[39,61477,3423],{},[39,61479,56380],{}," is a static ",[39,61482,25738],{}," captured at query time and does not reflect the element added afterward",[28,61485,61487,355,61489,3990,61491,61493,61494],{"className":61486},[31],[33,61488],{"disabled":35,"type":36},[39,61490,15049],{},[39,61492,25662],{}," always returns a live collection, just like ",[39,61495,61286],{},[28,61497,61499,355,61501,61503,61504,61506],{"className":61498},[31],[33,61500],{"disabled":35,"type":36},[39,61502,3423],{},", then it throws a ",[39,61505,827],{}," on the second access because the DOM changed underneath it",[28,61508,61510,355,61512,61514,61515,61518,61519,61521],{"className":61509},[31],[33,61511],{"disabled":35,"type":36},[39,61513,833],{}," — reassigning ",[39,61516,61517],{},"document.querySelector('ul')"," invalidates the earlier ",[39,61520,56380],{}," reference",[66,61523,61524,61526,61536],{},[69,61525,71],{},[73,61527,61528,3459,61530,3990,61532,61480,61534,61483],{},[76,61529,78],{},[39,61531,3423],{},[39,61533,56380],{},[39,61535,25738],{},[73,61537,61538,355,61540,61542,61543,61546,61547,61550,61551,61553,61554,7415,61556,61558,61559,61561,61562,61564,61565,61567],{},[76,61539,84],{},[39,61541,25662],{}," freezes its result at call time. The new ",[39,61544,61545],{},"\u003Cli>"," appended afterward matches the original ",[39,61548,61549],{},".item"," selector conceptually, but ",[39,61552,56380],{}," was never wired up to re-run that query — it's just an array-like snapshot, so its ",[39,61555,3643],{},[39,61557,3423],{}," forever unless you call ",[39,61560,25662],{}," again. Option B is the classic live-collection assumption bleeding over from ",[39,61563,61286],{}," (contrasted directly in Q3). Options C and D invent errors that don't occur — reading a stale static ",[39,61566,25738],{}," is completely safe, just potentially outdated.",[15,61569,61570,61581,61685,61732],{"language":247},[18,61571,61573,61574,8574,61576,61578,61579,54840],{"id":61572},"q3-using-getelementsbyclassname-instead-of-queryselectorall-for-the-same-scenario-what-does-the-second-consolelog-print","Q3. Using ",[39,61575,61286],{},[39,61577,25662],{}," for the same scenario, what does the second ",[39,61580,5627],{},[257,61582,61583],{"language":247},[260,61584,61586],{"className":262,"code":61585,"language":247,"meta":264,"style":264},"const items = document.getElementsByClassName('item');\nconsole.log(items.length); \u002F\u002F 3\n\nconst li = document.createElement('li');\nli.className = 'item';\ndocument.querySelector('ul').appendChild(li);\n\nconsole.log(items.length);\n",[39,61587,61588,61607,61621,61625,61643,61653,61669,61673],{"__ignoreMap":264},[268,61589,61590,61592,61594,61596,61598,61600,61602,61605],{"class":270,"line":271},[268,61591,243],{"class":274},[268,61593,11725],{"class":305},[268,61595,616],{"class":274},[268,61597,25659],{"class":282},[268,61599,61286],{"class":278},[268,61601,622],{"class":282},[268,61603,61604],{"class":289},"'item'",[268,61606,628],{"class":282},[268,61608,61609,61611,61613,61615,61617,61619],{"class":270,"line":286},[268,61610,1353],{"class":282},[268,61612,1356],{"class":278},[268,61614,56719],{"class":282},[268,61616,3567],{"class":305},[268,61618,5789],{"class":282},[268,61620,61399],{"class":29390},[268,61622,61623],{"class":270,"line":296},[268,61624,5033],{"emptyLinePlaceholder":35},[268,61626,61627,61629,61631,61633,61635,61637,61639,61641],{"class":270,"line":311},[268,61628,243],{"class":274},[268,61630,40550],{"class":305},[268,61632,616],{"class":274},[268,61634,25659],{"class":282},[268,61636,40557],{"class":278},[268,61638,622],{"class":282},[268,61640,25667],{"class":289},[268,61642,628],{"class":282},[268,61644,61645,61647,61649,61651],{"class":270,"line":788},[268,61646,61426],{"class":282},[268,61648,302],{"class":274},[268,61650,61431],{"class":289},[268,61652,293],{"class":282},[268,61654,61655,61657,61659,61661,61663,61665,61667],{"class":270,"line":1951},[268,61656,61438],{"class":282},[268,61658,61334],{"class":278},[268,61660,622],{"class":282},[268,61662,61445],{"class":289},[268,61664,6232],{"class":282},[268,61666,40592],{"class":278},[268,61668,40595],{"class":282},[268,61670,61671],{"class":270,"line":8955},[268,61672,5033],{"emptyLinePlaceholder":35},[268,61674,61675,61677,61679,61681,61683],{"class":270,"line":8966},[268,61676,1353],{"class":282},[268,61678,1356],{"class":278},[268,61680,56719],{"class":282},[268,61682,3567],{"class":305},[268,61684,628],{"class":282},[23,61686,61688,61698,61708,61720],{"className":61687},[26],[28,61689,61691,355,61693,3990,61695,61697],{"className":61690},[31],[33,61692],{"disabled":35,"type":36},[39,61694,3423],{},[39,61696,61272],{}," becomes static once it's assigned to a variable",[28,61699,61701,355,61703,3990,61705,61707],{"className":61700},[31],[33,61702],{"disabled":35,"type":36},[39,61704,833],{},[39,61706,56380],{}," becomes stale as soon as the DOM mutates",[28,61709,61711,355,61713,3990,61715,61287,61717,61719],{"className":61710},[31],[33,61712],{"disabled":35,"type":36},[39,61714,15049],{},[39,61716,61286],{},[39,61718,61272],{}," that automatically reflects DOM changes matching the query",[28,61721,61723,355,61725,61727,61728,21561,61730],{"className":61722},[31],[33,61724],{"disabled":35,"type":36},[39,61726,3423],{},", then it throws because ",[39,61729,56380],{},[39,61731,243],{},[66,61733,61734,61736,61746],{},[69,61735,71],{},[73,61737,61738,1004,61740,3990,61742,61287,61744,61719],{},[76,61739,78],{},[39,61741,15049],{},[39,61743,61286],{},[39,61745,61272],{},[73,61747,61748,61750,61751,61753,61754,61756,61757,61760,61761,61763,61764,21599,61767,61769,61770,61773,61774,61776],{},[76,61749,84],{}," A live ",[39,61752,61272],{}," isn't a snapshot at all — it's a view maintained by the DOM implementation that re-evaluates its matching criteria whenever the tree changes, so appending a new ",[39,61755,61549],{}," node immediately shows up in ",[39,61758,61759],{},"items.length"," with zero extra code. Option D confuses ",[39,61762,243],{},"'s restriction (you can't ",[104,61765,61766],{},"reassign",[39,61768,56380],{}," binding) with the collection's ",[104,61771,61772],{},"internal"," mutability, which ",[39,61775,243],{}," has no effect on — the object itself is still free to change. Option A is exactly the incorrect assumption this question tests. Option B invents behavior that doesn't happen.",[15,61778,61779,61787,61859,61897],{"language":247},[18,61780,61782,61783,61786],{"id":61781},"q4-given-4-elements-with-class-flagged-what-actually-happens-when-this-loop-runs","Q4. Given 4 elements with class ",[39,61784,61785],{},"\"flagged\"",", what actually happens when this loop runs?",[257,61788,61789],{"language":247},[260,61790,61792],{"className":262,"code":61791,"language":247,"meta":264,"style":264},"const items = document.getElementsByClassName('flagged');\nfor (let i = 0; i \u003C items.length; i++) {\n  items[i].classList.remove('flagged');\n}\n",[39,61793,61794,61813,61841,61855],{"__ignoreMap":264},[268,61795,61796,61798,61800,61802,61804,61806,61808,61811],{"class":270,"line":271},[268,61797,243],{"class":274},[268,61799,11725],{"class":305},[268,61801,616],{"class":274},[268,61803,25659],{"class":282},[268,61805,61286],{"class":278},[268,61807,622],{"class":282},[268,61809,61810],{"class":289},"'flagged'",[268,61812,628],{"class":282},[268,61814,61815,61817,61819,61821,61823,61825,61827,61829,61831,61833,61835,61837,61839],{"class":270,"line":286},[268,61816,6926],{"class":274},[268,61818,2182],{"class":282},[268,61820,240],{"class":274},[268,61822,9384],{"class":282},[268,61824,302],{"class":274},[268,61826,5728],{"class":305},[268,61828,9391],{"class":282},[268,61830,1076],{"class":274},[268,61832,11762],{"class":282},[268,61834,3567],{"class":305},[268,61836,9398],{"class":282},[268,61838,9401],{"class":274},[268,61840,1235],{"class":282},[268,61842,61843,61846,61849,61851,61853],{"class":270,"line":296},[268,61844,61845],{"class":282},"  items[i].classList.",[268,61847,61848],{"class":278},"remove",[268,61850,622],{"class":282},[268,61852,61810],{"class":289},[268,61854,628],{"class":282},[268,61856,61857],{"class":270,"line":311},[268,61858,314],{"class":282},[23,61860,61862,61868,61878,61884],{"className":61861},[26],[28,61863,61865,61867],{"className":61864},[31],[33,61866],{"disabled":35,"type":36}," It removes the class from all 4 elements as expected, then exits cleanly",[28,61869,61871,1271,61873,183,61875,61877],{"className":61870},[31],[33,61872],{"disabled":35,"type":36},[39,61874,17732],{},[39,61876,61759],{}," changes while the loop is running",[28,61879,61881,61883],{"className":61880},[31],[33,61882],{"disabled":35,"type":36}," It removes the class from only the last 2 elements, leaving the first 2 unchanged",[28,61885,61887,61889,61890,20968,61893,61896],{"className":61886},[31],[33,61888],{"disabled":35,"type":36}," It removes the class from only every other element — removing ",[39,61891,61892],{},"flagged",[39,61894,61895],{},"items[0]"," shrinks the live collection and shifts the next element into index 0, which the incrementing loop then skips over",[66,61898,61899,61901,61910],{},[69,61900,71],{},[73,61902,61903,61905,61906,20968,61908,61896],{},[76,61904,78],{}," D — It removes the class from only every other element — removing ",[39,61907,61892],{},[39,61909,61895],{},[73,61911,61912,355,61914,61287,61916,61918,61919,61921,61922,61924,61925,61927,61928,61930,61931,61933,61934,61937,61938,3277,61940,61942,61943,61945],{},[76,61913,84],{},[39,61915,61286],{},[39,61917,61272],{}," (Q3), so the moment ",[39,61920,61895],{}," loses the ",[39,61923,61892],{}," class, it drops out of the collection entirely — every remaining matched element shifts down one index, and ",[39,61926,61759],{}," shrinks by one. But the loop's ",[39,61929,9509],{}," still increments to ",[39,61932,2255],{},", which now points at what used to be ",[39,61935,61936],{},"items[2]",", silently skipping the element that shifted into slot ",[39,61939,3307],{},[76,61941,365],{}," this is the canonical live-collection mutation bug — fix it by iterating a static copy (",[39,61944,25765],{},"), snapshotting the length up front, or walking backwards from the end. Options A and B are the naive assumptions; C names a plausible-sounding but incorrect specific outcome.",[15,61947,61948,61960,62024],{},[18,61949,61951,61952,61955,61956,61959],{"id":61950},"q5-a-developer-writes-documentgetelementsbytagnameimgforeachimg-imgloading-lazy-and-gets-typeerror-itemsforeach-is-not-a-function-why-and-whats-the-correct-fix","Q5. A developer writes ",[39,61953,61954],{},"document.getElementsByTagName('img').forEach(img => img.loading = 'lazy')"," and gets ",[39,61957,61958],{},"TypeError: items.forEach is not a function",". Why, and what's the correct fix?",[23,61961,61963,61974,62000,62012],{"className":61962},[26],[28,61964,61966,355,61968,61970,61971,61973],{"className":61965},[31],[33,61967],{"disabled":35,"type":36},[39,61969,12330],{}," was removed from all DOM collections in newer browsers; a ",[39,61972,9163],{}," loop is now required universally",[28,61975,61977,355,61979,61981,61982,61984,61985,61987,61988,20968,61990,61992,61993,61996,61997],{"className":61976},[31],[33,61978],{"disabled":35,"type":36},[39,61980,61272],{}," (returned by ",[39,61983,61343],{},") never implemented ",[39,61986,12330],{},", unlike ",[39,61989,25738],{},[39,61991,25662],{},"; convert it first with ",[39,61994,61995],{},"Array.from(collection)"," or the spread ",[39,61998,61999],{},"[...collection]",[28,62001,62003,62005,62006,2833,62009,62011],{"className":62002},[31],[33,62004],{"disabled":35,"type":36}," The code should call ",[39,62007,62008],{},".values().forEach(...)",[39,62010,61272],{}," only exposes an iterator, not array methods",[28,62013,62015,355,62017,62020,62021,62023],{"className":62014},[31],[33,62016],{"disabled":35,"type":36},[39,62018,62019],{},"img"," elements are specifically excluded from ",[39,62022,12330],{}," for security reasons; other tags work fine",[66,62025,62026,62028,62046],{},[69,62027,71],{},[73,62029,62030,1727,62032,61981,62034,61984,62036,61987,62038,20968,62040,61992,62042,61996,62044],{},[76,62031,78],{},[39,62033,61272],{},[39,62035,61343],{},[39,62037,12330],{},[39,62039,25738],{},[39,62041,25662],{},[39,62043,61995],{},[39,62045,61999],{},[73,62047,62048,355,62050,62053,62054,62056,62057,62059,62060,62062,62063,62065,62066,62069,62070,62073,62074,99,62076,62078,62079,42,62081,42,62083,62085,62086,62088,62089,62091],{},[76,62049,84],{},[39,62051,62052],{},"NodeList.prototype"," was given ",[39,62055,12330],{}," directly, so a ",[39,62058,25662],{}," result supports it out of the box. ",[39,62061,61272],{}," is a different, older interface exposing only ",[39,62064,3567],{},", indexed access, and ",[39,62067,62068],{},"namedItem"," — it was never extended with array methods, so calling ",[39,62071,62072],{},".forEach"," on it throws. ",[39,62075,61995],{},[39,62077,61999],{}," produces a real array with the full method set (",[39,62080,12330],{},[39,62082,23950],{},[39,62084,14962],{},", and so on). Option A is false — ",[39,62087,25738],{}," still has ",[39,62090,12330],{},". Option C invents a nonexistent API surface. Option D is nonsensical; there's no tag-based restriction.",[15,62093,62094,62104,62194,62258],{"language":247},[18,62095,62097,62098,62100,62101,62103],{"id":62096},"q6-what-does-the-second-consolelog-print-and-why-does-it-complicate-the-nodelist-static-takeaway-from-q2","Q6. What does the second ",[39,62099,5627],{}," print, and why does it complicate the \"",[39,62102,25738],{}," = static\" takeaway from Q2?",[257,62105,62106],{"language":247},[260,62107,62109],{"className":262,"code":62108,"language":247,"meta":264,"style":264},"const container = document.querySelector('#box');\nconst nodes = container.childNodes;\nconsole.log(nodes.length); \u002F\u002F 2\n\ncontainer.appendChild(document.createElement('span'));\nconsole.log(nodes.length);\n",[39,62110,62111,62131,62143,62159,62163,62182],{"__ignoreMap":264},[268,62112,62113,62115,62118,62120,62122,62124,62126,62129],{"class":270,"line":271},[268,62114,243],{"class":274},[268,62116,62117],{"class":305}," container",[268,62119,616],{"class":274},[268,62121,25659],{"class":282},[268,62123,61334],{"class":278},[268,62125,622],{"class":282},[268,62127,62128],{"class":289},"'#box'",[268,62130,628],{"class":282},[268,62132,62133,62135,62138,62140],{"class":270,"line":286},[268,62134,243],{"class":274},[268,62136,62137],{"class":305}," nodes",[268,62139,616],{"class":274},[268,62141,62142],{"class":282}," container.childNodes;\n",[268,62144,62145,62147,62149,62152,62154,62156],{"class":270,"line":296},[268,62146,1353],{"class":282},[268,62148,1356],{"class":278},[268,62150,62151],{"class":282},"(nodes.",[268,62153,3567],{"class":305},[268,62155,5789],{"class":282},[268,62157,62158],{"class":29390},"\u002F\u002F 2\n",[268,62160,62161],{"class":270,"line":311},[268,62162,5033],{"emptyLinePlaceholder":35},[268,62164,62165,62168,62170,62173,62175,62177,62180],{"class":270,"line":788},[268,62166,62167],{"class":282},"container.",[268,62169,40592],{"class":278},[268,62171,62172],{"class":282},"(document.",[268,62174,40557],{"class":278},[268,62176,622],{"class":282},[268,62178,62179],{"class":289},"'span'",[268,62181,4818],{"class":282},[268,62183,62184,62186,62188,62190,62192],{"class":270,"line":1951},[268,62185,1353],{"class":282},[268,62187,1356],{"class":278},[268,62189,62151],{"class":282},[268,62191,3567],{"class":305},[268,62193,628],{"class":282},[23,62195,62197,62217,62231,62248],{"className":62196},[26],[28,62198,62200,355,62202,26077,62204,62206,62207,62210,62211,355,62214,62216],{"className":62199},[31],[33,62201],{"disabled":35,"type":36},[39,62203,3423],{},[39,62205,25662],{},"'s result, ",[39,62208,62209],{},".childNodes"," returns a ",[104,62212,62213],{},"live",[39,62215,25738],{}," that updates as children are added or removed",[28,62218,62220,355,62222,62224,62225,62227,62228,62230],{"className":62219},[31],[33,62221],{"disabled":35,"type":36},[39,62223,2258],{}," — every ",[39,62226,25738],{},", including ",[39,62229,62209],{},", is a static snapshot",[28,62232,62234,355,62236,62238,62239,62241,62242,62244,62245,62247],{"className":62233},[31],[33,62235],{"disabled":35,"type":36},[39,62237,3423],{}," — because ",[39,62240,62209],{}," actually returns an ",[39,62243,61272],{},", not a ",[39,62246,25738],{},", despite its name",[28,62249,62251,62253,62254,62257],{"className":62250},[31],[33,62252],{"disabled":35,"type":36}," It throws, because ",[39,62255,62256],{},"nodes"," was assigned before the DOM mutation occurred",[66,62259,62260,62262,62276],{},[69,62261,71],{},[73,62263,62264,3459,62266,26077,62268,62206,62270,62210,62272,355,62274,62216],{},[76,62265,78],{},[39,62267,3423],{},[39,62269,25662],{},[39,62271,62209],{},[104,62273,62213],{},[39,62275,25738],{},[73,62277,62278,62280,62281,62284,62285,62287,62288,62290,62291,62293,62294,62296,62297,62299,62300,62302,62303,62305],{},[76,62279,84],{}," \"Static vs. live\" is a property of ",[104,62282,62283],{},"how a collection is produced",", not of the ",[39,62286,25738],{}," type itself. ",[39,62289,25662],{}," is specified to always build a static snapshot, but other DOM properties — ",[39,62292,62209],{}," chief among them — are specified to return a live ",[39,62295,25738],{}," that tracks the tree in real time. So \"",[39,62298,25738],{},"\" and \"static\" are not synonyms, which trips up anyone who over-generalizes from ",[39,62301,25662],{}," alone. Option C is wrong on the interface type — it genuinely is a ",[39,62304,25738],{},", just a live one. Option B is the over-generalization this question targets. Option D fabricates an error that doesn't occur.",[15,62307,62308,62312,62347],{},[18,62309,62311],{"id":62310},"q7-in-browser-rendering-what-is-the-actual-difference-between-a-reflow-layout-and-a-repaint","Q7. In browser rendering, what is the actual difference between a \"reflow\" (layout) and a \"repaint\"?",[23,62313,62315,62325,62331,62337],{"className":62314},[26],[28,62316,62318,62320,62321,62324],{"className":62317},[31],[33,62319],{"disabled":35,"type":36}," Reflow only affects ",[39,62322,62323],{},"\u003Ccanvas>"," elements; repaint affects every other element",[28,62326,62328,62330],{"className":62327},[31],[33,62329],{"disabled":35,"type":36}," They are two names for the exact same browser operation",[28,62332,62334,62336],{"className":62333},[31],[33,62335],{"disabled":35,"type":36}," Reflow recalculates element geometry and position, and can cascade to affect ancestors, descendants, and siblings; repaint only redraws pixels (e.g., a color change) without recomputing any layout, which makes it cheaper",[28,62338,62340,62342,62343,62346],{"className":62339},[31],[33,62341],{"disabled":35,"type":36}," Repaint happens on every ",[39,62344,62345],{},"scroll"," event; reflow only ever happens once, on initial page load",[66,62348,62349,62351,62356],{},[69,62350,71],{},[73,62352,62353,62355],{},[76,62354,78],{}," C — Reflow recalculates element geometry and position, and can cascade to affect ancestors, descendants, and siblings; repaint only redraws pixels (e.g., a color change) without recomputing any layout, which makes it cheaper",[73,62357,62358,62360,62361,62364,62365,42,62368,62371,62372,99,62374,62377,62378,62380],{},[76,62359,84],{}," Reflow (layout) computes size and position for elements in the render tree, and because layout is fundamentally a tree-wide computation, a change to one element's box can ripple outward to affect its neighbors. Repaint (paint) only redraws the ",[104,62362,62363],{},"appearance"," of already-laid-out pixels — ",[39,62366,62367],{},"background-color",[39,62369,62370],{},"visibility",", and similar properties — reusing the existing geometry, so it skips the expensive remeasurement step entirely. Changing something like ",[39,62373,32233],{},[39,62375,62376],{},"left"," triggers a reflow (and a subsequent repaint); changing only ",[39,62379,29370],{}," triggers just a repaint. Options A and D fabricate rules that don't reflect how the rendering pipeline actually works; option B collapses a distinction that matters a great deal for performance, as the next questions show.",[15,62382,62383,62387,62455,62499],{"language":247},[18,62384,62386],{"id":62385},"q8-why-is-this-loop-considered-layout-thrashing-and-what-makes-it-especially-expensive","Q8. Why is this loop considered \"layout thrashing,\" and what makes it especially expensive?",[257,62388,62389],{"language":247},[260,62390,62392],{"className":262,"code":62391,"language":247,"meta":264,"style":264},"const boxes = document.querySelectorAll('.box');\nboxes.forEach(box => {\n  box.style.width = '200px';\n  console.log(box.offsetHeight);\n});\n",[39,62393,62394,62414,62430,62442,62451],{"__ignoreMap":264},[268,62395,62396,62398,62401,62403,62405,62407,62409,62412],{"class":270,"line":271},[268,62397,243],{"class":274},[268,62399,62400],{"class":305}," boxes",[268,62402,616],{"class":274},[268,62404,25659],{"class":282},[268,62406,25662],{"class":278},[268,62408,622],{"class":282},[268,62410,62411],{"class":289},"'.box'",[268,62413,628],{"class":282},[268,62415,62416,62419,62421,62423,62426,62428],{"class":270,"line":286},[268,62417,62418],{"class":282},"boxes.",[268,62420,12330],{"class":278},[268,62422,622],{"class":282},[268,62424,62425],{"class":1222},"box",[268,62427,14969],{"class":274},[268,62429,9914],{"class":282},[268,62431,62432,62435,62437,62440],{"class":270,"line":296},[268,62433,62434],{"class":282},"  box.style.width ",[268,62436,302],{"class":274},[268,62438,62439],{"class":289}," '200px'",[268,62441,293],{"class":282},[268,62443,62444,62446,62448],{"class":270,"line":311},[268,62445,5556],{"class":282},[268,62447,1356],{"class":278},[268,62449,62450],{"class":282},"(box.offsetHeight);\n",[268,62452,62453],{"class":270,"line":788},[268,62454,20047],{"class":282},[23,62456,62458,62467,62476,62484],{"className":62457},[26],[28,62459,62461,355,62463,62466],{"className":62460},[31],[33,62462],{"disabled":35,"type":36},[39,62464,62465],{},"offsetHeight"," is deprecated and logs a console warning on every access",[28,62468,62470,355,62472,62475],{"className":62469},[31],[33,62471],{"disabled":35,"type":36},[39,62473,62474],{},".style.width"," writes are batched automatically by the browser, so this pattern is actually efficient as written",[28,62477,62479,355,62481,62483],{"className":62478},[31],[33,62480],{"disabled":35,"type":36},[39,62482,25662],{}," re-runs the CSS selector engine on every loop iteration, which is the real cost here",[28,62485,62487,62489,62490,62492,62493,62495,62496],{"className":62486},[31],[33,62488],{"disabled":35,"type":36}," Writing ",[39,62491,62474],{}," invalidates the cached layout, and immediately reading ",[39,62494,62465],{}," forces the browser to synchronously recompute layout right then instead of deferring it — repeating this write-then-read pattern for every element forces a full synchronous reflow on ",[104,62497,62498],{},"every single iteration",[66,62500,62501,62503,62514],{},[69,62502,71],{},[73,62504,62505,62507,62508,62492,62510,62495,62512],{},[76,62506,78],{}," D — Writing ",[39,62509,62474],{},[39,62511,62465],{},[104,62513,62498],{},[73,62515,62516,62518,62519,42,62521,42,62524,42,62527,62530,62531,62534,62535,62537,62538,62540],{},[76,62517,84],{}," Browsers normally batch layout-invalidating writes and defer the actual recalculation until it's genuinely needed (typically right before the next paint). But certain \"layout-dependent\" reads — ",[39,62520,62465],{},[39,62522,62523],{},"offsetWidth",[39,62525,62526],{},"getBoundingClientRect()",[39,62528,62529],{},"scrollTop",", computed styles — force an immediate, synchronous flush of any pending layout work so the browser can hand back an accurate number. Interleaving a write then a read inside a loop defeats that batching completely, forcing ",[104,62532,62533],{},"N"," synchronous reflows for ",[104,62536,62533],{}," elements instead of just one. ",[76,62539,438],{}," this \"layout thrashing\" pattern is one of the most common real-world sources of janky UI code. Options A and C are fabricated costs; option B is the literal opposite of what happens in this snippet.",[15,62542,62543,62547,62659,62704],{"language":247},[18,62544,62546],{"id":62545},"q9-how-does-this-rewrite-of-the-q8-pattern-avoid-layout-thrashing","Q9. How does this rewrite of the Q8 pattern avoid layout thrashing?",[257,62548,62549],{"language":247},[260,62550,62552],{"className":262,"code":62551,"language":247,"meta":264,"style":264},"const boxes = document.querySelectorAll('.box');\n\nconst heights = [];\nboxes.forEach(box => heights.push(box.offsetHeight));\n\nboxes.forEach((box, i) => {\n  box.style.width = heights[i] > 100 ? '200px' : '100px';\n});\n",[39,62553,62554,62572,62576,62587,62607,62611,62631,62655],{"__ignoreMap":264},[268,62555,62556,62558,62560,62562,62564,62566,62568,62570],{"class":270,"line":271},[268,62557,243],{"class":274},[268,62559,62400],{"class":305},[268,62561,616],{"class":274},[268,62563,25659],{"class":282},[268,62565,25662],{"class":278},[268,62567,622],{"class":282},[268,62569,62411],{"class":289},[268,62571,628],{"class":282},[268,62573,62574],{"class":270,"line":286},[268,62575,5033],{"emptyLinePlaceholder":35},[268,62577,62578,62580,62583,62585],{"class":270,"line":296},[268,62579,243],{"class":274},[268,62581,62582],{"class":305}," heights",[268,62584,616],{"class":274},[268,62586,12449],{"class":282},[268,62588,62589,62591,62593,62595,62597,62599,62602,62604],{"class":270,"line":311},[268,62590,62418],{"class":282},[268,62592,12330],{"class":278},[268,62594,622],{"class":282},[268,62596,62425],{"class":1222},[268,62598,14969],{"class":274},[268,62600,62601],{"class":282}," heights.",[268,62603,12499],{"class":278},[268,62605,62606],{"class":282},"(box.offsetHeight));\n",[268,62608,62609],{"class":270,"line":788},[268,62610,5033],{"emptyLinePlaceholder":35},[268,62612,62613,62615,62617,62619,62621,62623,62625,62627,62629],{"class":270,"line":1951},[268,62614,62418],{"class":282},[268,62616,12330],{"class":278},[268,62618,6122],{"class":282},[268,62620,62425],{"class":1222},[268,62622,42],{"class":282},[268,62624,9509],{"class":1222},[268,62626,6131],{"class":282},[268,62628,9414],{"class":274},[268,62630,9914],{"class":282},[268,62632,62633,62635,62637,62640,62642,62644,62646,62648,62650,62653],{"class":270,"line":8955},[268,62634,62434],{"class":282},[268,62636,302],{"class":274},[268,62638,62639],{"class":282}," heights[i] ",[268,62641,6435],{"class":274},[268,62643,13821],{"class":305},[268,62645,13362],{"class":274},[268,62647,62439],{"class":289},[268,62649,13367],{"class":274},[268,62651,62652],{"class":289}," '100px'",[268,62654,293],{"class":282},[268,62656,62657],{"class":270,"line":8966},[268,62658,20047],{"class":282},[23,62660,62662,62671,62684,62696],{"className":62661},[26],[28,62663,62665,62667,62668,62670],{"className":62664},[31],[33,62666],{"disabled":35,"type":36}," It doesn't actually help — reading ",[39,62669,62465],{}," in the first loop still forces a reflow for every element, regardless of write timing",[28,62672,62674,62676,62677,62680,62681,62683],{"className":62673},[31],[33,62675],{"disabled":35,"type":36}," It separates every layout-triggering ",[104,62678,62679],{},"read"," into one pass, before any layout-invalidating ",[104,62682,54067],{}," happens; the browser only needs a single reflow to satisfy the whole read pass, and the later write pass never needs to be flushed synchronously because nothing reads from layout afterward",[28,62685,62687,62689,62690,62692,62693,62695],{"className":62686},[31],[33,62688],{"disabled":35,"type":36}," It works because ",[39,62691,25662],{}," automatically caches each element's ",[39,62694,62465],{}," the first time it's accessed",[28,62697,62699,62689,62701,62703],{"className":62698},[31],[33,62700],{"disabled":35,"type":36},[39,62702,62072],{}," runs asynchronously, giving the browser idle time to repaint between the reads and the writes",[66,62705,62706,62708,62717],{},[69,62707,71],{},[73,62709,62710,62712,62713,62680,62715,62683],{},[76,62711,78],{}," B — It separates every layout-triggering ",[104,62714,62679],{},[104,62716,54067],{},[73,62718,62719,62721,62722,62724,62725,62727,62728,62730,62731,62733,62734,62736,62737,62739],{},[76,62720,84],{}," This is the \"read-then-write\" batching idiom (the core idea behind libraries like FastDOM). Since nothing has invalidated layout yet when the first loop reads ",[39,62723,62465],{},", at most one reflow satisfies the entire batch of reads. The second loop's writes can then all queue up freely, because no subsequent read in this code forces the browser to flush them synchronously. ",[76,62726,438],{}," one reflow for a batch beats ",[104,62729,62533],{}," reflows for ",[104,62732,62533],{}," elements by a wide margin as the list grows. Option A misses that a single triggered reflow is vastly cheaper than repeating it per element. Options C and D invent mechanisms that don't exist — ",[39,62735,25662],{}," doesn't cache layout metrics, and ",[39,62738,12330],{}," is fully synchronous.",[15,62741,62742,62746,62846,62895],{"language":247},[18,62743,62745],{"id":62744},"q10-how-should-this-loop-be-rewritten-to-minimize-reflows-when-inserting-1000-items","Q10. How should this loop be rewritten to minimize reflows when inserting 1,000 items?",[257,62747,62748],{"language":247},[260,62749,62751],{"className":262,"code":62750,"language":247,"meta":264,"style":264},"const list = document.querySelector('#list');\nfor (let i = 0; i \u003C 1000; i++) {\n  const li = document.createElement('li');\n  li.textContent = `Item ${i}`;\n  list.appendChild(li);\n}\n",[39,62752,62753,62773,62800,62818,62834,62842],{"__ignoreMap":264},[268,62754,62755,62757,62760,62762,62764,62766,62768,62771],{"class":270,"line":271},[268,62756,243],{"class":274},[268,62758,62759],{"class":305}," list",[268,62761,616],{"class":274},[268,62763,25659],{"class":282},[268,62765,61334],{"class":278},[268,62767,622],{"class":282},[268,62769,62770],{"class":289},"'#list'",[268,62772,628],{"class":282},[268,62774,62775,62777,62779,62781,62783,62785,62787,62789,62791,62794,62796,62798],{"class":270,"line":286},[268,62776,6926],{"class":274},[268,62778,2182],{"class":282},[268,62780,240],{"class":274},[268,62782,9384],{"class":282},[268,62784,302],{"class":274},[268,62786,5728],{"class":305},[268,62788,9391],{"class":282},[268,62790,1076],{"class":274},[268,62792,62793],{"class":305}," 1000",[268,62795,9398],{"class":282},[268,62797,9401],{"class":274},[268,62799,1235],{"class":282},[268,62801,62802,62804,62806,62808,62810,62812,62814,62816],{"class":270,"line":296},[268,62803,12441],{"class":274},[268,62805,40550],{"class":305},[268,62807,616],{"class":274},[268,62809,25659],{"class":282},[268,62811,40557],{"class":278},[268,62813,622],{"class":282},[268,62815,25667],{"class":289},[268,62817,628],{"class":282},[268,62819,62820,62823,62825,62828,62830,62832],{"class":270,"line":311},[268,62821,62822],{"class":282},"  li.textContent ",[268,62824,302],{"class":274},[268,62826,62827],{"class":289}," `Item ${",[268,62829,9509],{"class":282},[268,62831,11603],{"class":289},[268,62833,293],{"class":282},[268,62835,62836,62838,62840],{"class":270,"line":788},[268,62837,40589],{"class":282},[268,62839,40592],{"class":278},[268,62841,40595],{"class":282},[268,62843,62844],{"class":270,"line":1951},[268,62845,314],{"class":282},[23,62847,62849,62865,62874,62885],{"className":62848},[26],[28,62850,62852,62854,62855,62857,62858,62861,62862,62864],{"className":62851},[31],[33,62853],{"disabled":35,"type":36}," Build every ",[39,62856,61545],{}," into a ",[39,62859,62860],{},"DocumentFragment"," first, then append the fragment to ",[39,62863,14924],{}," once after the loop — the fragment lives outside the render tree, so populating it triggers no reflows, and only the single final append touches the live DOM",[28,62866,62868,62870,62871,62873],{"className":62867},[31],[33,62869],{"disabled":35,"type":36}," Nothing needs to change — ",[39,62872,40592],{}," calls inside a loop are already batched by the browser automatically",[28,62875,62877,54122,62879,2029,62881,62884],{"className":62876},[31],[33,62878],{"disabled":35,"type":36},[39,62880,40592],{},[39,62882,62883],{},"insertAdjacentHTML('beforeend', ...)"," inside the loop, since string-based insertion never triggers layout",[28,62886,62888,62890,62891,62894],{"className":62887},[31],[33,62889],{"disabled":35,"type":36}," Wrap the loop body in ",[39,62892,62893],{},"requestAnimationFrame"," so each insertion happens on its own frame",[66,62896,62897,62899,62910],{},[69,62898,71],{},[73,62900,62901,62903,62904,62857,62906,62861,62908,62864],{},[76,62902,78],{}," A — Build every ",[39,62905,61545],{},[39,62907,62860],{},[39,62909,14924],{},[73,62911,62912,812,62914,62916,62917,62919,62920,62922,62923,62925,62926,62928],{},[76,62913,84],{},[39,62915,62860],{}," is a lightweight, in-memory container that is never part of the visible document tree, so appending 1,000 children to it costs no layout or paint work at all. Only the single fragment-into-",[39,62918,14924],{}," append potentially triggers a reflow — one, instead of up to 1,000. ",[76,62921,438],{}," this is the standard batching idiom for bulk DOM insertion. Option B is false: each ",[39,62924,40592],{}," call directly onto a connected ",[39,62927,14924],{}," element is a live-DOM mutation, each one a potential invalidation. Option C still mutates the live DOM on every iteration, with the added cost of re-parsing an HTML string each time. Option D would spread 1,000 insertions across 1,000 separate animation frames — far slower and visibly janky, not faster.",[15,62930,62931,62939,63002,63060],{"language":247},[18,62932,62934,62935,62938],{"id":62933},"q11-what-is-the-primary-risk-with-this-function-if-usersuppliedcomment-comes-from-another-users-input-eg-a-public-comment-form-and-whats-the-safer-alternative","Q11. What is the primary risk with this function if ",[39,62936,62937],{},"userSuppliedComment"," comes from another user's input (e.g., a public comment form), and what's the safer alternative?",[257,62940,62941],{"language":247},[260,62942,62944],{"className":262,"code":62943,"language":247,"meta":264,"style":264},"function showComment(rawText) {\n  const el = document.querySelector('#comment');\n  el.innerHTML = rawText;\n}\nshowComment(userSuppliedComment);\n",[39,62945,62946,62960,62980,62990,62994],{"__ignoreMap":264},[268,62947,62948,62950,62953,62955,62958],{"class":270,"line":271},[268,62949,275],{"class":274},[268,62951,62952],{"class":278}," showComment",[268,62954,622],{"class":282},[268,62956,62957],{"class":1222},"rawText",[268,62959,1235],{"class":282},[268,62961,62962,62964,62967,62969,62971,62973,62975,62978],{"class":270,"line":286},[268,62963,12441],{"class":274},[268,62965,62966],{"class":305}," el",[268,62968,616],{"class":274},[268,62970,25659],{"class":282},[268,62972,61334],{"class":278},[268,62974,622],{"class":282},[268,62976,62977],{"class":289},"'#comment'",[268,62979,628],{"class":282},[268,62981,62982,62985,62987],{"class":270,"line":296},[268,62983,62984],{"class":282},"  el.innerHTML ",[268,62986,302],{"class":274},[268,62988,62989],{"class":282}," rawText;\n",[268,62991,62992],{"class":270,"line":311},[268,62993,314],{"class":282},[268,62995,62996,62999],{"class":270,"line":788},[268,62997,62998],{"class":278},"showComment",[268,63000,63001],{"class":282},"(userSuppliedComment);\n",[23,63003,63005,63018,63029,63046],{"className":63004},[26],[28,63006,63008,355,63010,63013,63014,63017],{"className":63007},[31],[33,63009],{"disabled":35,"type":36},[39,63011,63012],{},"innerHTML"," is merely slower than ",[39,63015,63016],{},"textContent",", so the only real issue here is performance, not correctness",[28,63019,63021,63023,63024,63026,63027],{"className":63020},[31],[33,63022],{"disabled":35,"type":36}," There's no real risk — browsers automatically strip any ",[39,63025,434],{}," tags assigned via ",[39,63028,63012],{},[28,63030,63032,63034,63035,63037,63038,63041,63042,63045],{"className":63031},[31],[33,63033],{"disabled":35,"type":36}," Assigning untrusted input to ",[39,63036,63012],{}," parses it as real HTML, so a comment like ",[39,63039,63040],{},"\u003Cimg src=x onerror=\"steal()\">"," executes arbitrary JavaScript in the page (a classic XSS vector); use ",[39,63043,63044],{},"el.textContent = rawText"," instead, which inserts the string as a raw text node with no HTML parsing at all",[28,63047,63049,63051,63052,8574,63055,4387,63057,63059],{"className":63048},[31],[33,63050],{"disabled":35,"type":36}," The fix is to use ",[39,63053,63054],{},"innerText",[39,63056,63012],{},[39,63058,63054],{}," automatically escapes any HTML in the string",[66,63061,63062,63064,63075],{},[69,63063,71],{},[73,63065,63066,63068,63069,63037,63071,63041,63073,63045],{},[76,63067,78],{}," C — Assigning untrusted input to ",[39,63070,63012],{},[39,63072,63040],{},[39,63074,63044],{},[73,63076,63077,355,63079,355,63081,63083,63084,63086,63087,63090,63091,63093,63094,63096,63097,63100,63101,63103],{},[76,63078,84],{},[76,63080,582],{},[39,63082,63012],{}," hands its string directly to the HTML parser, so any markup or event-handler attribute embedded in untrusted input becomes real, executing HTML\u002FJS — this is exactly how stored and reflected XSS attacks work in practice. ",[39,63085,63016],{}," never parses its argument as markup; the string becomes a literal text node, so ",[39,63088,63089],{},"\u003Cimg ...>"," shows up as visible, inert text rather than an executed tag. Option B is a dangerous misconception — browsers do not sanitize ",[39,63092,63012],{}," input by default; that's entirely the caller's responsibility. Option D is wrong: ",[39,63095,63054],{}," is about ",[104,63098,63099],{},"rendered"," text and layout, not escaping — writing to it has the same \"no HTML parsing\" property as ",[39,63102,63016],{},", but it isn't the idiomatic choice here because of its own layout costs (see Q12).",[15,63105,63106,63119,63169],{},[18,63107,56351,63109,186,63112,63115,63116,63118],{"id":63108},"q12-elementtextcontent-hello-and-elementinnertext-hello-both-set-visible-text-but-why-is-textcontent-generally-preferred-in-performance-sensitive-code",[39,63110,63111],{},"element.textContent = 'Hello'",[39,63113,63114],{},"element.innerText = 'Hello'"," both set visible text, but why is ",[39,63117,63016],{}," generally preferred in performance-sensitive code?",[23,63120,63122,63130,63141,63151],{"className":63121},[26],[28,63123,63125,355,63127,63129],{"className":63124},[31],[33,63126],{"disabled":35,"type":36},[39,63128,63054],{}," cannot hold more than 255 characters without silently truncating",[28,63131,63133,355,63135,63137,63138,63140],{"className":63132},[31],[33,63134],{"disabled":35,"type":36},[39,63136,63016],{}," is deprecated in favor of ",[39,63139,63054],{}," in every modern browser",[28,63142,63144,355,63146,63148,63149,5302],{"className":63143},[31],[33,63145],{"disabled":35,"type":36},[39,63147,63054],{}," parses its argument as HTML while ",[39,63150,63016],{},[28,63152,63154,355,63156,63158,63159,63161,63162,63165,63166,63168],{"className":63153},[31],[33,63155],{"disabled":35,"type":36},[39,63157,63054],{}," is defined in terms of the ",[104,63160,63099],{}," page — it must account for applied CSS (e.g., skipping ",[39,63163,63164],{},"display: none"," content, normalizing whitespace to match what's visually shown) — so reading or writing it can force a synchronous reflow; ",[39,63167,63016],{}," operates purely on the raw text nodes in the DOM tree and never touches layout",[66,63170,63171,63173,63185],{},[69,63172,71],{},[73,63174,63175,6901,63177,63158,63179,63161,63181,63165,63183,63168],{},[76,63176,78],{},[39,63178,63054],{},[104,63180,63099],{},[39,63182,63164],{},[39,63184,63016],{},[73,63186,63187,355,63189,183,63191,63193,63194,63197,63198,63200,63201,63203],{},[76,63188,84],{},[76,63190,438],{},[39,63192,63054],{}," reflects what a user would actually ",[104,63195,63196],{},"see"," — excluding hidden elements, collapsing whitespace the way rendering would, respecting line breaks introduced by CSS — the engine needs up-to-date layout information to compute or apply it, which can trigger the same kind of synchronous reflow flagged back in Q8. ",[39,63199,63016],{}," simply walks the raw text-node tree, entirely layout-agnostic, making it both faster and more predictable. Option C is backwards — neither property parses HTML; that's ",[39,63202,63012],{},"'s job exclusively. Options A and B are fabricated.",[15,63205,63206,63213,63308,63356],{"language":247},[18,63207,63209,63210,55991],{"id":63208},"q13-what-happens-when-copyclick-runs","Q13. What happens when ",[39,63211,63212],{},"copy.click()",[257,63214,63215],{"language":247},[260,63216,63218],{"className":262,"code":63217,"language":247,"meta":264,"style":264},"const original = document.querySelector('#save-btn');\noriginal.addEventListener('click', () => console.log('saved'));\n\nconst copy = original.cloneNode(true);\ndocument.body.appendChild(copy);\ncopy.click();\n",[39,63219,63220,63239,63265,63269,63289,63299],{"__ignoreMap":264},[268,63221,63222,63224,63226,63228,63230,63232,63234,63237],{"class":270,"line":271},[268,63223,243],{"class":274},[268,63225,20173],{"class":305},[268,63227,616],{"class":274},[268,63229,25659],{"class":282},[268,63231,61334],{"class":278},[268,63233,622],{"class":282},[268,63235,63236],{"class":289},"'#save-btn'",[268,63238,628],{"class":282},[268,63240,63241,63244,63246,63248,63250,63252,63254,63256,63258,63260,63263],{"class":270,"line":286},[268,63242,63243],{"class":282},"original.",[268,63245,35737],{"class":278},[268,63247,622],{"class":282},[268,63249,35742],{"class":289},[268,63251,35745],{"class":282},[268,63253,9414],{"class":274},[268,63255,9417],{"class":282},[268,63257,1356],{"class":278},[268,63259,622],{"class":282},[268,63261,63262],{"class":289},"'saved'",[268,63264,4818],{"class":282},[268,63266,63267],{"class":270,"line":296},[268,63268,5033],{"emptyLinePlaceholder":35},[268,63270,63271,63273,63275,63277,63280,63283,63285,63287],{"class":270,"line":311},[268,63272,243],{"class":274},[268,63274,20195],{"class":305},[268,63276,616],{"class":274},[268,63278,63279],{"class":282}," original.",[268,63281,63282],{"class":278},"cloneNode",[268,63284,622],{"class":282},[268,63286,2185],{"class":305},[268,63288,628],{"class":282},[268,63290,63291,63294,63296],{"class":270,"line":788},[268,63292,63293],{"class":282},"document.body.",[268,63295,40592],{"class":278},[268,63297,63298],{"class":282},"(copy);\n",[268,63300,63301,63304,63306],{"class":270,"line":1951},[268,63302,63303],{"class":282},"copy.",[268,63305,47403],{"class":278},[268,63307,794],{"class":282},[23,63309,63311,63322,63337,63348],{"className":63310},[26],[28,63312,63314,30037,63316,3990,63318,63321],{"className":63313},[31],[33,63315],{"disabled":35,"type":36},[39,63317,56036],{},[39,63319,63320],{},"cloneNode(true)"," performs a deep clone that includes all attached event listeners",[28,63323,63325,63327,63328,63330,63331,63333,63334,63336],{"className":63324},[31],[33,63326],{"disabled":35,"type":36}," Nothing is logged — ",[39,63329,63282],{}," copies the element's tag, attributes, and (with ",[39,63332,2185],{},") its descendant nodes, but it never copies listeners attached via ",[39,63335,35737],{},", since those live outside the node's cloneable attribute\u002Fchild data",[28,63338,63340,1271,63342,63344,63345],{"className":63339},[31],[33,63341],{"disabled":35,"type":36},[39,63343,827],{},", because a cloned node cannot dispatch synthetic events like ",[39,63346,63347],{},".click()",[28,63349,63351,30037,63353,63355],{"className":63350},[31],[33,63352],{"disabled":35,"type":36},[39,63354,56036],{}," twice — once for the original element's listener and once for a listener copy on the clone",[66,63357,63358,63360,63371],{},[69,63359,71],{},[73,63361,63362,63364,63365,63330,63367,63333,63369,63336],{},[76,63363,78],{}," B — Nothing is logged — ",[39,63366,63282],{},[39,63368,2185],{},[39,63370,35737],{},[73,63372,63373,355,63375,355,63377,63379,63380,7255,63383,63386,63387,63390,63391,63393,63394,63396,63397,63399],{},[76,63374,84],{},[76,63376,365],{},[39,63378,63320],{}," performs a deep clone, duplicating the tag, every attribute, and all descendant nodes recursively; ",[39,63381,63382],{},"cloneNode(false)",[39,63384,63385],{},"cloneNode()"," with no argument) does the same but shallow, omitting children entirely. In neither case does cloning touch the internal listener list an ",[39,63388,63389],{},"EventTarget"," accumulates via ",[39,63392,35737],{}," — that bookkeeping is stored on the live object, not in the serializable DOM structure the clone algorithm copies. Any ",[39,63395,35737],{},"-based behavior has to be reattached to the clone manually. Option A is an extremely common wrong assumption. Options C and D fabricate behavior — ",[39,63398,63347],{}," works fine on any connected element, and there's no listener present on the clone at all to fire twice.",[15,63401,63402,63414,63474],{},[18,63403,63405,63406,63409,63410,63413],{"id":63404},"q14-a-toggle-visibility-helper-is-implemented-two-ways-version-1-elclassname-elclassnameincludeshidden-elclassnamereplacehidden-elclassname-hidden-version-2-elclasslisttogglehidden-why-is-version-2-the-idiomatic-choice","Q14. A toggle-visibility helper is implemented two ways. Version 1: ",[39,63407,63408],{},"el.className = el.className.includes('hidden') ? el.className.replace('hidden', '') : el.className + ' hidden'",". Version 2: ",[39,63411,63412],{},"el.classList.toggle('hidden')",". Why is Version 2 the idiomatic choice?",[23,63415,63417,63438,63450,63461],{"className":63416},[26],[28,63418,63420,355,63422,63425,63426,63429,63430,63433,63434,63437],{"className":63419},[31],[33,63421],{"disabled":35,"type":36},[39,63423,63424],{},"classList.toggle"," handles the add\u002Fremove logic atomically and correctly regardless of existing whitespace or class order, while manual ",[39,63427,63428],{},"className"," string manipulation is error-prone — ",[39,63431,63432],{},".replace('hidden', '')"," is a plain substring match that can corrupt an unrelated class like ",[39,63435,63436],{},"\"overhidden\"",", and repeated concatenation without a duplicate check can pile up the same class many times over",[28,63439,63441,355,63443,63445,63446,63449],{"className":63440},[31],[33,63442],{"disabled":35,"type":36},[39,63444,63428],{}," was removed from the DOM specification in favor of ",[39,63447,63448],{},"classList",", so Version 1 no longer runs in any browser",[28,63451,63453,355,63455,63457,63458,63460],{"className":63452},[31],[33,63454],{"disabled":35,"type":36},[39,63456,63424],{}," is the only one of the two that triggers a repaint; assigning to ",[39,63459,63428],{}," does not update the visible page at all",[28,63462,63464,63466,63467,63470,63471,63473],{"className":63463},[31],[33,63465],{"disabled":35,"type":36}," Version 1 is actually preferable for performance, since it avoids the overhead of the ",[39,63468,63469],{},"DOMTokenList"," object that ",[39,63472,63448],{}," allocates",[66,63475,63476,63478,63490],{},[69,63477,71],{},[73,63479,63480,3459,63482,63425,63484,63429,63486,63433,63488,63437],{},[76,63481,78],{},[39,63483,63424],{},[39,63485,63428],{},[39,63487,63432],{},[39,63489,63436],{},[73,63491,63492,355,63494,355,63496,63498,63499,2029,63501,446,63503,446,63505,446,63508,63511,63512,63515,63516,63518,63519,63521,63522,63524,63525,63527,63528,63530],{},[76,63493,84],{},[76,63495,930],{},[39,63497,63448],{}," exposes a ",[39,63500,63469],{},[39,63502,41889],{},[39,63504,61848],{},[39,63506,63507],{},"toggle",[39,63509,63510],{},"contains"," that operate correctly on the space-separated token list — ",[39,63513,63514],{},"toggle('hidden')"," is guaranteed to leave the element in exactly one consistent state, with no malformed whitespace and no duplicate tokens. Direct ",[39,63517,63428],{}," string manipulation is a classic source of subtle bugs: ",[39,63520,63432],{}," performs a bare substring match that can silently mangle an unrelated class name that merely ",[104,63523,63510],{}," \"hidden\" as a substring, and naive concatenation without checking ",[39,63526,24350],{}," first can accumulate the same class repeatedly if the function runs more than once. Option B is false — ",[39,63529,63428],{}," remains fully valid, just less ergonomic. Options C and D are fabricated technical claims.",[15,63532,63533,63548,63594,63648],{"language":247},[18,63534,63536,63537,63540,63541,63544,63545,63547],{"id":63535},"q15-given-div-iduser-card-data-user-id482-data-is-verifiedtruediv-what-is-the-correct-way-to-read-the-data-user-id-attribute-via-the-dataset-api-and-what-type-comes-back","Q15. Given ",[39,63538,63539],{},"\u003Cdiv id=\"user-card\" data-user-id=\"482\" data-is-verified=\"true\">\u003C\u002Fdiv>",", what is the correct way to read the ",[39,63542,63543],{},"data-user-id"," attribute via the ",[39,63546,40717],{}," API, and what type comes back?",[257,63549,63550],{"language":247},[260,63551,63553],{"className":262,"code":63552,"language":247,"meta":264,"style":264},"\u002F\u002F \u003Cdiv id=\"user-card\" data-user-id=\"482\" data-is-verified=\"true\">\u003C\u002Fdiv>\nconst card = document.querySelector('#user-card');\nconsole.log(card.dataset.userId, typeof card.dataset.userId);\n",[39,63554,63555,63560,63580],{"__ignoreMap":264},[268,63556,63557],{"class":270,"line":271},[268,63558,63559],{"class":29390},"\u002F\u002F \u003Cdiv id=\"user-card\" data-user-id=\"482\" data-is-verified=\"true\">\u003C\u002Fdiv>\n",[268,63561,63562,63564,63567,63569,63571,63573,63575,63578],{"class":270,"line":286},[268,63563,243],{"class":274},[268,63565,63566],{"class":305}," card",[268,63568,616],{"class":274},[268,63570,25659],{"class":282},[268,63572,61334],{"class":278},[268,63574,622],{"class":282},[268,63576,63577],{"class":289},"'#user-card'",[268,63579,628],{"class":282},[268,63581,63582,63584,63586,63589,63591],{"class":270,"line":296},[268,63583,1353],{"class":282},[268,63585,1356],{"class":278},[268,63587,63588],{"class":282},"(card.dataset.userId, ",[268,63590,1361],{"class":274},[268,63592,63593],{"class":282}," card.dataset.userId);\n",[23,63595,63597,63608,63618,63638],{"className":63596},[26],[28,63598,63600,355,63602,63605,63606],{"className":63599},[31],[33,63601],{"disabled":35,"type":36},[39,63603,63604],{},"card.dataset['data-user-id']",", and it comes back as a ",[39,63607,2682],{},[28,63609,63611,355,63613,63605,63616],{"className":63610},[31],[33,63612],{"disabled":35,"type":36},[39,63614,63615],{},"card.dataset.data_user_id",[39,63617,2685],{},[28,63619,63621,355,63623,63605,63626,2182,63628,63631,63632,63634,63635],{"className":63620},[31],[33,63622],{"disabled":35,"type":36},[39,63624,63625],{},"card.dataset.userId",[39,63627,16721],{},[39,63629,63630],{},"\"482\"",") — ",[39,63633,40717],{}," always yields strings, so numeric-looking values need explicit conversion, e.g. ",[39,63636,63637],{},"Number(card.dataset.userId)",[28,63639,63641,355,63643,63605,63646],{"className":63640},[31],[33,63642],{"disabled":35,"type":36},[39,63644,63645],{},"card.getAttribute('dataset.userId')",[39,63647,16721],{},[66,63649,63650,63652,63666],{},[69,63651,71],{},[73,63653,63654,1004,63656,63605,63658,2182,63660,63631,63662,63634,63664],{},[76,63655,78],{},[39,63657,63625],{},[39,63659,16721],{},[39,63661,63630],{},[39,63663,40717],{},[39,63665,63637],{},[73,63667,63668,4396,63670,63672,63673,63676,63677,7083,63679,137,63682,7083,63685,63688,63689,2758,63691,2272,63694,2758,63697,63699,63700,63703,63704,63707,63708,63710,63711,63714],{},[76,63669,84],{},[39,63671,40717],{}," API automatically converts a hyphen-separated ",[39,63674,63675],{},"data-*"," attribute name into camelCase for property access: ",[39,63678,63543],{},[39,63680,63681],{},"dataset.userId",[39,63683,63684],{},"data-is-verified",[39,63686,63687],{},"dataset.isVerified",". Every value comes back as a plain string regardless of how it looks — ",[39,63690,63630],{},[39,63692,63693],{},"482",[39,63695,63696],{},"\"true\"",[39,63698,2185],{}," — so callers must explicitly coerce with ",[39,63701,63702],{},"Number(...)"," or compare ",[39,63705,63706],{},"=== 'true'"," as needed. Option A uses the wrong key format (it should be camelCase, not the literal hyphenated attribute name as a bracket key) and the wrong type assumption. Option B uses invalid snake_case syntax that the conversion rule doesn't produce. Option D conflates ",[39,63709,40717],{}," (a property) with ",[39,63712,63713],{},"getAttribute"," (a method that takes the literal attribute name, not a dataset key path).",[15,63716,63717,63725,63772,63814],{"language":247},[18,63718,63720,63721,63724],{"id":63719},"q16-what-does-elouterhtml-show-after-this-assignment","Q16. What does ",[39,63722,63723],{},"el.outerHTML"," show after this assignment?",[257,63726,63727],{"language":247},[260,63728,63730],{"className":262,"code":63729,"language":247,"meta":264,"style":264},"const el = document.createElement('div');\nel.dataset.orderStatus = 'pending';\nconsole.log(el.outerHTML);\n",[39,63731,63732,63751,63763],{"__ignoreMap":264},[268,63733,63734,63736,63738,63740,63742,63744,63746,63749],{"class":270,"line":271},[268,63735,243],{"class":274},[268,63737,62966],{"class":305},[268,63739,616],{"class":274},[268,63741,25659],{"class":282},[268,63743,40557],{"class":278},[268,63745,622],{"class":282},[268,63747,63748],{"class":289},"'div'",[268,63750,628],{"class":282},[268,63752,63753,63756,63758,63761],{"class":270,"line":286},[268,63754,63755],{"class":282},"el.dataset.orderStatus ",[268,63757,302],{"class":274},[268,63759,63760],{"class":289}," 'pending'",[268,63762,293],{"class":282},[268,63764,63765,63767,63769],{"class":270,"line":296},[268,63766,1353],{"class":282},[268,63768,1356],{"class":278},[268,63770,63771],{"class":282},"(el.outerHTML);\n",[23,63773,63775,63783,63791,63799],{"className":63774},[26],[28,63776,63778,355,63780],{"className":63777},[31],[33,63779],{"disabled":35,"type":36},[39,63781,63782],{},"\u003Cdiv dataset-order-status=\"pending\">\u003C\u002Fdiv>",[28,63784,63786,355,63788],{"className":63785},[31],[33,63787],{"disabled":35,"type":36},[39,63789,63790],{},"\u003Cdiv data-orderStatus=\"pending\">\u003C\u002Fdiv>",[28,63792,63794,355,63796],{"className":63793},[31],[33,63795],{"disabled":35,"type":36},[39,63797,63798],{},"\u003Cdiv orderStatus=\"pending\">\u003C\u002Fdiv>",[28,63800,63802,355,63804,63807,63808,63810,63811,63813],{"className":63801},[31],[33,63803],{"disabled":35,"type":36},[39,63805,63806],{},"\u003Cdiv data-order-status=\"pending\">\u003C\u002Fdiv>"," — writing to a camelCase ",[39,63809,40717],{}," property converts it back into a hyphen-separated ",[39,63812,63675],{}," attribute on the element",[66,63815,63816,63818,63828],{},[69,63817,71],{},[73,63819,63820,6901,63822,63807,63824,63810,63826,63813],{},[76,63821,78],{},[39,63823,63806],{},[39,63825,40717],{},[39,63827,63675],{},[73,63829,63830,4396,63832,63834,63835,46500,63838,63841,63842,63844,63845,63847,63848,63850,63851,63854,63855,63857],{},[76,63831,84],{},[39,63833,40717],{}," conversion (introduced in Q15) is symmetric: reading turns ",[39,63836,63837],{},"data-order-status",[39,63839,63840],{},"dataset.orderStatus",", and writing to ",[39,63843,63840],{}," creates or updates the ",[39,63846,63837],{}," attribute, inserting a hyphen before each formerly-uppercase letter and lowercasing it. Option A wrongly assumes the word ",[39,63849,40717],{}," itself becomes part of the attribute name. Option B fails to convert the camelCase key back into kebab-case. Option C drops the required ",[39,63852,63853],{},"data-"," prefix entirely, which would just create a non-standard, untracked custom attribute that ",[39,63856,40717],{}," would never pick back up.",[15,63859,63860,63871,64027,64072],{"language":247},[18,63861,60541,63863,63866,63867,63870],{"id":63862},"q17-if-removerowrow-is-called-to-remove-a-row-from-the-visible-table-but-cachedrows-still-holds-a-reference-to-it-what-happens",[39,63864,63865],{},"removeRow(row)"," is called to remove a row from the visible table, but ",[39,63868,63869],{},"cachedRows"," still holds a reference to it, what happens?",[257,63872,63873],{"language":247},[260,63874,63876],{"className":262,"code":63875,"language":247,"meta":264,"style":264},"let cachedRows = [];\n\nfunction removeRow(row) {\n  row.remove();\n}\n\nfunction renderRow(data) {\n  const row = document.createElement('tr');\n  row.textContent = data.label;\n  row.addEventListener('click', () => console.log(data.id));\n  cachedRows.push(row);\n  document.querySelector('tbody').appendChild(row);\n  return row;\n}\n",[39,63877,63878,63889,63893,63907,63916,63920,63924,63937,63957,63967,63988,63998,64016,64023],{"__ignoreMap":264},[268,63879,63880,63882,63885,63887],{"class":270,"line":271},[268,63881,240],{"class":274},[268,63883,63884],{"class":282}," cachedRows ",[268,63886,302],{"class":274},[268,63888,12449],{"class":282},[268,63890,63891],{"class":270,"line":286},[268,63892,5033],{"emptyLinePlaceholder":35},[268,63894,63895,63897,63900,63902,63905],{"class":270,"line":296},[268,63896,275],{"class":274},[268,63898,63899],{"class":278}," removeRow",[268,63901,622],{"class":282},[268,63903,63904],{"class":1222},"row",[268,63906,1235],{"class":282},[268,63908,63909,63912,63914],{"class":270,"line":311},[268,63910,63911],{"class":282},"  row.",[268,63913,61848],{"class":278},[268,63915,794],{"class":282},[268,63917,63918],{"class":270,"line":788},[268,63919,314],{"class":282},[268,63921,63922],{"class":270,"line":1951},[268,63923,5033],{"emptyLinePlaceholder":35},[268,63925,63926,63928,63931,63933,63935],{"class":270,"line":8955},[268,63927,275],{"class":274},[268,63929,63930],{"class":278}," renderRow",[268,63932,622],{"class":282},[268,63934,21188],{"class":1222},[268,63936,1235],{"class":282},[268,63938,63939,63941,63944,63946,63948,63950,63952,63955],{"class":270,"line":8966},[268,63940,12441],{"class":274},[268,63942,63943],{"class":305}," row",[268,63945,616],{"class":274},[268,63947,25659],{"class":282},[268,63949,40557],{"class":278},[268,63951,622],{"class":282},[268,63953,63954],{"class":289},"'tr'",[268,63956,628],{"class":282},[268,63958,63959,63962,63964],{"class":270,"line":8974},[268,63960,63961],{"class":282},"  row.textContent ",[268,63963,302],{"class":274},[268,63965,63966],{"class":282}," data.label;\n",[268,63968,63969,63971,63973,63975,63977,63979,63981,63983,63985],{"class":270,"line":8985},[268,63970,63911],{"class":282},[268,63972,35737],{"class":278},[268,63974,622],{"class":282},[268,63976,35742],{"class":289},[268,63978,35745],{"class":282},[268,63980,9414],{"class":274},[268,63982,9417],{"class":282},[268,63984,1356],{"class":278},[268,63986,63987],{"class":282},"(data.id));\n",[268,63989,63990,63993,63995],{"class":270,"line":8990},[268,63991,63992],{"class":282},"  cachedRows.",[268,63994,12499],{"class":278},[268,63996,63997],{"class":282},"(row);\n",[268,63999,64000,64003,64005,64007,64010,64012,64014],{"class":270,"line":8997},[268,64001,64002],{"class":282},"  document.",[268,64004,61334],{"class":278},[268,64006,622],{"class":282},[268,64008,64009],{"class":289},"'tbody'",[268,64011,6232],{"class":282},[268,64013,40592],{"class":278},[268,64015,63997],{"class":282},[268,64017,64018,64020],{"class":270,"line":9002},[268,64019,1240],{"class":274},[268,64021,64022],{"class":282}," row;\n",[268,64024,64025],{"class":270,"line":14676},[268,64026,314],{"class":282},[23,64028,64030,64041,64053,64062],{"className":64029},[26],[28,64031,64033,64035,64036,22769,64038,64040],{"className":64032},[31],[33,64034],{"disabled":35,"type":36}," The browser automatically clears ",[39,64037,63904],{},[39,64039,63869],{}," once it's removed from the DOM, since detached nodes are garbage-collected immediately",[28,64042,64044,64046,64047,64049,64050,64052],{"className":64043},[31],[33,64045],{"disabled":35,"type":36}," The row becomes a \"detached\" DOM node — no longer part of the visible document tree, but still reachable through the ",[39,64048,63869],{}," array — so it, its closure over ",[39,64051,21188],{},", and its click listener can never be garbage-collected; repeating this pattern for many rows leaks memory",[28,64054,64056,355,64058,64061],{"className":64055},[31],[33,64057],{"disabled":35,"type":36},[39,64059,64060],{},"row.remove()"," throws an error if any other references to that node still exist elsewhere in the program",[28,64063,64065,64067,64068,64071],{"className":64064},[31],[33,64066],{"disabled":35,"type":36}," The click listener is automatically stripped by ",[39,64069,64070],{},".remove()",", so only the empty node itself leaks, which is negligible",[66,64073,64074,64076,64085],{},[69,64075,71],{},[73,64077,64078,64080,64081,64049,64083,64052],{},[76,64079,78],{}," B — The row becomes a \"detached\" DOM node — no longer part of the visible document tree, but still reachable through the ",[39,64082,63869],{},[39,64084,21188],{},[73,64086,64087,355,64089,355,64091,64093,64094,64096,64097,64099,64100,64102,64103,64105],{},[76,64088,84],{},[76,64090,438],{},[39,64092,64070],{}," only detaches a node from its parent in the render tree — it does nothing to any ",[104,64095,33735],{}," JavaScript reference pointing at that same node object. As long as something (an array, a closure, an event registry) still holds it, the garbage collector must keep the entire reachable object graph alive, including the ",[39,64098,35737],{}," closure capturing ",[39,64101,21188],{},". This is a genuinely common leak pattern in single-page apps that cache row\u002Fitem references without cleaning them up alongside DOM removal. Options A and C invent automatic cleanup that doesn't exist — the GC only reclaims objects that are truly unreachable. Option D wrongly assumes ",[39,64104,64070],{}," also strips listeners; it doesn't — they persist on the detached node and would even still fire if the node were ever re-appended.",[15,64107,64108,64122,64170],{},[18,64109,64111,64112,56676,64115,64118,64119,1685],{"id":64110},"q18-when-inserting-new-ui-content-that-includes-some-user-controlled-text-eg-a-username-whats-the-key-tradeoff-between-documentcreateelement-appendchild-versus-elementinsertadjacenthtmlbeforeend-markup","Q18. When inserting new UI content that includes some user-controlled text (e.g., a username), what's the key tradeoff between ",[39,64113,64114],{},"document.createElement(...)",[39,64116,64117],{},"appendChild(...)"," versus ",[39,64120,64121],{},"element.insertAdjacentHTML('beforeend', markup)",[23,64123,64125,64142,64151,64162],{"className":64124},[26],[28,64126,64128,355,64130,446,64132,64134,64135,64137,64138,64141],{"className":64127},[31],[33,64129],{"disabled":35,"type":36},[39,64131,40557],{},[39,64133,40592],{}," requires more code but is inherently safe for user-controlled values when the dynamic part is assigned via ",[39,64136,63016],{}," (no HTML parsing occurs); ",[39,64139,64140],{},"insertAdjacentHTML"," is more concise, but it parses its argument as raw HTML, so any user-controlled value interpolated into that string must be escaped manually or it becomes an XSS vector",[28,64143,64145,64147,64148,64150],{"className":64144},[31],[33,64146],{"disabled":35,"type":36}," Both approaches are equally safe by default — the only real difference is that ",[39,64149,64140],{}," is slightly slower due to extra function-call overhead",[28,64152,64154,355,64156,64158,64159,64161],{"className":64153},[31],[33,64155],{"disabled":35,"type":36},[39,64157,40557],{}," cannot set visible text at all, only attributes, so ",[39,64160,64140],{}," is required whenever text content is involved",[28,64163,64165,355,64167,64169],{"className":64164},[31],[33,64166],{"disabled":35,"type":36},[39,64168,64140],{}," is always the safer choice, because the browser automatically escapes any interpolated template values before parsing the markup",[66,64171,64172,64174,64186],{},[69,64173,71],{},[73,64175,64176,3459,64178,446,64180,64134,64182,64137,64184,64141],{},[76,64177,78],{},[39,64179,40557],{},[39,64181,40592],{},[39,64183,63016],{},[39,64185,64140],{},[73,64187,64188,64190,64191,64193,64194,64196,64197,64200,64201,64204,64205,64208,64209,64211,64212,64214,64215,64217,64218,64220,64221,7255,64224,64227],{},[76,64189,84],{}," Building nodes programmatically and assigning the dynamic part through ",[39,64192,63016],{}," keeps user data inert by construction — there's no parsing step where markup could ever be interpreted as tags. ",[39,64195,64140],{}," hands its string straight to the HTML parser, so a template like ",[39,64198,64199],{},"`\u003Cli>${username}\u003C\u002Fli>`"," lets a ",[39,64202,64203],{},"username"," containing ",[39,64206,64207],{},"\u003Cimg src=x onerror=...>"," execute exactly like the ",[39,64210,63012],{}," case in Q11. The real tradeoff: ",[39,64213,40557],{}," is verbose (multiple statements per element), while ",[39,64216,64140],{}," is compact but pushes all escaping responsibility onto the caller. Options B and D understate or misstate the risk — neither API escapes anything automatically. Option C is simply false; elements built with ",[39,64219,40557],{}," set visible text via ",[39,64222,64223],{},".textContent",[39,64225,64226],{},".innerText",") without issue.",[15,64229,64230,64242,64304,64354],{"language":247},[18,64231,64233,64234,64237,64238,64241],{"id":64232},"q19-given-input-idemail-typetext-valuedefaultexamplecom-after-the-user-clears-the-field-and-types-newexamplecom-what-do-the-two-logs-print","Q19. Given ",[39,64235,64236],{},"\u003Cinput id=\"email\" type=\"text\" value=\"default@example.com\">",", after the user clears the field and types ",[39,64239,64240],{},"\"new@example.com\"",", what do the two logs print?",[257,64243,64244],{"language":247},[260,64245,64247],{"className":262,"code":64246,"language":247,"meta":264,"style":264},"\u002F\u002F \u003Cinput id=\"email\" type=\"text\" value=\"default@example.com\">\nconst input = document.querySelector('#email');\n\u002F\u002F user clears the field and types \"new@example.com\"\nconsole.log(input.value);\nconsole.log(input.getAttribute('value'));\n",[39,64248,64249,64254,64273,64278,64287],{"__ignoreMap":264},[268,64250,64251],{"class":270,"line":271},[268,64252,64253],{"class":29390},"\u002F\u002F \u003Cinput id=\"email\" type=\"text\" value=\"default@example.com\">\n",[268,64255,64256,64258,64260,64262,64264,64266,64268,64271],{"class":270,"line":286},[268,64257,243],{"class":274},[268,64259,17937],{"class":305},[268,64261,616],{"class":274},[268,64263,25659],{"class":282},[268,64265,61334],{"class":278},[268,64267,622],{"class":282},[268,64269,64270],{"class":289},"'#email'",[268,64272,628],{"class":282},[268,64274,64275],{"class":270,"line":296},[268,64276,64277],{"class":29390},"\u002F\u002F user clears the field and types \"new@example.com\"\n",[268,64279,64280,64282,64284],{"class":270,"line":311},[268,64281,1353],{"class":282},[268,64283,1356],{"class":278},[268,64285,64286],{"class":282},"(input.value);\n",[268,64288,64289,64291,64293,64296,64298,64300,64302],{"class":270,"line":788},[268,64290,1353],{"class":282},[268,64292,1356],{"class":278},[268,64294,64295],{"class":282},"(input.",[268,64297,63713],{"class":278},[268,64299,622],{"class":282},[268,64301,53397],{"class":289},[268,64303,4818],{"class":282},[23,64305,64307,64316,64325,64343],{"className":64306},[26],[28,64308,64310,64312,64313,64315],{"className":64309},[31],[33,64311],{"disabled":35,"type":36}," Both print ",[39,64314,64240],{},", since the property and the attribute are always kept in sync",[28,64317,64319,64312,64321,64324],{"className":64318},[31],[33,64320],{"disabled":35,"type":36},[39,64322,64323],{},"\"default@example.com\"",", since neither updates from user interaction, only from explicit JS assignment",[28,64326,64328,355,64330,64333,64334,64336,64337,64333,64340,64342],{"className":64327},[31],[33,64329],{"disabled":35,"type":36},[39,64331,64332],{},"input.value"," prints ",[39,64335,64240],{}," — the live property reflecting what the user actually typed; ",[39,64338,64339],{},"input.getAttribute('value')",[39,64341,64323],{}," — the original HTML attribute, which reflects only the initial\u002Fdefault value and does not track live user input",[28,64344,64346,355,64348,64350,64351,47835],{"className":64345},[31],[33,64347],{"disabled":35,"type":36},[39,64349,64332],{}," throws, because reading the property after user interaction requires calling ",[39,64352,64353],{},"input.reportValidity()",[66,64355,64356,64358,64370],{},[69,64357,71],{},[73,64359,64360,1004,64362,64333,64364,64336,64366,64333,64368,64342],{},[76,64361,78],{},[39,64363,64332],{},[39,64365,64240],{},[39,64367,64339],{},[39,64369,64323],{},[73,64371,64372,355,64374,64376,64377,355,64379,64382,64383,64386,64387,23941,64390,355,64392,64395,64396,64398,64399,42,64401,64404,64405,64407],{},[76,64373,84],{},[76,64375,365],{}," for form controls, the ",[39,64378,4780],{},[104,64380,64381],{},"attribute"," (what's literally written in the markup, and what ",[39,64384,64385],{},"getAttribute('value')"," reads) represents only the initial\u002Fdefault value — it stays frozen at the page's original state unless code explicitly calls ",[39,64388,64389],{},"setAttribute",[39,64391,4780],{},[104,64393,64394],{},"property"," is live and tracks the control's current state continuously as the user types. Most reflected attributes (like ",[39,64397,14610],{},") stay perfectly in sync with their property, which is exactly why this divergence for a handful of stateful form properties (",[39,64400,4780],{},[39,64402,64403],{},"checked",") catches people off guard — a common bug is resetting a form by reading ",[39,64406,64385],{}," and expecting it to reflect what's currently on screen. Options A and B both wrongly assume lockstep behavior; option D fabricates an error that doesn't exist.",[15,64409,64410,64425,64464],{},[18,64411,64413,64414,64417,64418,64421,64422,64424],{"id":64412},"q20-a-widget-needs-to-react-whenever-nodes-are-added-to-a-specific-container-without-knowing-in-advance-which-code-will-trigger-the-change-why-is-mutationobserver-preferred-over-the-older-mutation-events-eg-domnodeinserted-or-manual-setinterval-polling","Q20. A widget needs to react whenever nodes are added to a specific container, without knowing in advance which code will trigger the change. Why is ",[39,64415,64416],{},"MutationObserver"," preferred over the older Mutation Events (e.g., ",[39,64419,64420],{},"DOMNodeInserted",") or manual ",[39,64423,47386],{}," polling?",[23,64426,64428,64436,64445,64454],{"className":64427},[26],[28,64429,64431,355,64433,64435],{"className":64430},[31],[33,64432],{"disabled":35,"type":36},[39,64434,64416],{}," runs synchronously on every single DOM mutation, giving instant, per-change callbacks",[28,64437,64439,64441,64442,64444],{"className":64438},[31],[33,64440],{"disabled":35,"type":36}," Manual polling with ",[39,64443,47386],{}," is actually more efficient, since it avoids the overhead of registering an observer at all",[28,64446,64448,64450,64451,64453],{"className":64447},[31],[33,64449],{"disabled":35,"type":36}," Mutation Events are still the recommended approach in every modern browser; ",[39,64452,64416],{}," was an experimental API that never actually shipped",[28,64455,64457,355,64459,64461,64462],{"className":64456},[31],[33,64458],{"disabled":35,"type":36},[39,64460,64416],{}," delivers batched, asynchronous notifications — queued as a microtask after the relevant DOM changes finish — instead of firing synchronously for every individual mutation the way the deprecated Mutation Events did; this avoids the severe performance cost that got Mutation Events deprecated, while still being far more efficient and timely than polling with ",[39,64463,47386],{},[66,64465,64466,64468,64476],{},[69,64467,71],{},[73,64469,64470,6901,64472,64461,64474],{},[76,64471,78],{},[39,64473,64416],{},[39,64475,47386],{},[73,64477,64478,355,64480,64482,64483,64486,64487,64489,64490,64492],{},[76,64479,84],{},[76,64481,438],{}," the old Mutation Events fired a synchronous DOM event for ",[104,64484,64485],{},"every single mutation",", which could itself trigger more mutations and more events, cascading into severe performance degradation on real pages — this is precisely why browsers deprecated them. ",[39,64488,64416],{}," instead collects mutations into a batch and delivers them together in one callback as a microtask, which is both cheaper (no per-change event-dispatch overhead, changes get coalesced) and safer (no synchronous reentrancy hazard). It also strictly beats ",[39,64491,47386],{}," polling, which either misses fast changes (interval too long) or burns CPU on redundant checks (interval too short) — the observer only fires when something actually changed. Option A misdescribes it as synchronous per-mutation, which is the old, deprecated behavior it was designed to replace. Options B and C are simply false.",[2107,64494,64495],{},"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 pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}",{"title":264,"searchDepth":286,"depth":286,"links":64497},[64498,64500,64502,64504,64506,64508,64510,64511,64512,64513,64514,64516,64518,64520,64522,64524,64526,64528,64530,64532],{"id":61245,"depth":296,"text":64499},"Q1. A page has multiple \u003Cli class=\"item\"> elements inside a \u003Cul>. What is the key structural difference between the results of document.querySelectorAll('.item') and document.getElementsByClassName('item')?",{"id":61355,"depth":296,"text":64501},"Q2. What does the second console.log print?",{"id":61572,"depth":296,"text":64503},"Q3. Using getElementsByClassName instead of querySelectorAll for the same scenario, what does the second console.log print?",{"id":61781,"depth":296,"text":64505},"Q4. Given 4 elements with class \"flagged\", what actually happens when this loop runs?",{"id":61950,"depth":296,"text":64507},"Q5. A developer writes document.getElementsByTagName('img').forEach(img => img.loading = 'lazy') and gets TypeError: items.forEach is not a function. Why, and what's the correct fix?",{"id":62096,"depth":296,"text":64509},"Q6. What does the second console.log print, and why does it complicate the \"NodeList = static\" takeaway from Q2?",{"id":62310,"depth":296,"text":62311},{"id":62385,"depth":296,"text":62386},{"id":62545,"depth":296,"text":62546},{"id":62744,"depth":296,"text":62745},{"id":62933,"depth":296,"text":64515},"Q11. What is the primary risk with this function if userSuppliedComment comes from another user's input (e.g., a public comment form), and what's the safer alternative?",{"id":63108,"depth":296,"text":64517},"Q12. element.textContent = 'Hello' and element.innerText = 'Hello' both set visible text, but why is textContent generally preferred in performance-sensitive code?",{"id":63208,"depth":296,"text":64519},"Q13. What happens when copy.click() runs?",{"id":63404,"depth":296,"text":64521},"Q14. A toggle-visibility helper is implemented two ways. Version 1: el.className = el.className.includes('hidden') ? el.className.replace('hidden', '') : el.className + ' hidden'. Version 2: el.classList.toggle('hidden'). Why is Version 2 the idiomatic choice?",{"id":63535,"depth":296,"text":64523},"Q15. Given \u003Cdiv id=\"user-card\" data-user-id=\"482\" data-is-verified=\"true\">\u003C\u002Fdiv>, what is the correct way to read the data-user-id attribute via the dataset API, and what type comes back?",{"id":63719,"depth":296,"text":64525},"Q16. What does el.outerHTML show after this assignment?",{"id":63862,"depth":296,"text":64527},"Q17. If removeRow(row) is called to remove a row from the visible table, but cachedRows still holds a reference to it, what happens?",{"id":64110,"depth":296,"text":64529},"Q18. When inserting new UI content that includes some user-controlled text (e.g., a username), what's the key tradeoff between document.createElement(...) + appendChild(...) versus element.insertAdjacentHTML('beforeend', markup)?",{"id":64232,"depth":296,"text":64531},"Q19. Given \u003Cinput id=\"email\" type=\"text\" value=\"default@example.com\">, after the user clears the field and types \"new@example.com\", what do the two logs print?",{"id":64412,"depth":296,"text":64533},"Q20. A widget needs to react whenever nodes are added to a specific container, without knowing in advance which code will trigger the change. Why is MutationObserver preferred over the older Mutation Events (e.g., DOMNodeInserted) or manual setInterval polling?",{},"\u002Fjs\u002F19-the-dom",{"title":61235,"description":264},"js\u002F19-the-dom","2BjA9eyJrp2ERHO4Zjr033HyoLZ8z-pxfMuDdN_t7Fw",{"id":64540,"title":64541,"body":64542,"description":264,"extension":2144,"meta":67199,"navigation":35,"path":67200,"seo":67201,"stem":67202,"__hash__":67203},"content\u002Fjs\u002F20-events.md","20 — Events",{"type":8,"value":64543,"toc":67162},[64544,64547,64630,64707,64919,65014,65098,65208,65422,65521,65668,65741,65935,66020,66153,66400,66497,66597,66755,66873,66941,67159],[11,64545,64541],{"id":64546},"_20-events",[15,64548,64549,64564,64609],{},[18,64550,64552,64553,64556,64557,64560,64561,1685],{"id":64551},"q1-in-the-default-event-flow-model-used-by-the-dom-what-happens-when-a-user-clicks-a-deeply-nested-span-inside-several-wrapping-div-elements-assuming-no-listener-calls-stoppropagation","Q1. In the default event flow model used by the DOM, what happens when a user clicks a deeply nested ",[39,64554,64555],{},"\u003Cspan>"," inside several wrapping ",[39,64558,64559],{},"\u003Cdiv>"," elements, assuming no listener calls ",[39,64562,64563],{},"stopPropagation()",[23,64565,64567,64579,64588,64600],{"className":64566},[26],[28,64568,64570,64572,64573,64575,64576],{"className":64569},[31],[33,64571],{"disabled":35,"type":36}," The click event fires on the ",[39,64574,64555],{}," first, then propagates upward, firing on each ancestor in turn up to ",[39,64577,64578],{},"document",[28,64580,64582,64584,64585,64587],{"className":64581},[31],[33,64583],{"disabled":35,"type":36}," The click event fires only on the ",[39,64586,64555],{},"; ancestor elements never see it",[28,64589,64591,64593,64594,64596,64597,64599],{"className":64590},[31],[33,64592],{"disabled":35,"type":36}," The click event fires on ",[39,64595,64578],{}," first, then downward to the ",[39,64598,64555],{},", then stops",[28,64601,64603,64605,64606,64608],{"className":64602},[31],[33,64604],{"disabled":35,"type":36}," The click event fires on every ancestor and the ",[39,64607,64555],{}," at the same time, in an unspecified order",[66,64610,64611,64613,64622],{},[69,64612,71],{},[73,64614,64615,64617,64618,64575,64620],{},[76,64616,78],{}," A — The click event fires on the ",[39,64619,64555],{},[39,64621,64578],{},[73,64623,64624,64626,64627,64629],{},[76,64625,84],{}," This is the bubbling phase, the default direction of event flow: the event originates at the deepest element the user interacted with (the \"target phase\"), then walks up the ancestor chain, firing any matching listener on each ancestor in turn, unless something calls ",[39,64628,64563],{},". Option B ignores bubbling entirely. Option C describes only the capturing phase (which does run top-down, but before the target phase, not instead of bubbling) and incorrectly claims it \"stops.\" Option D is wrong because the phases are strictly sequential and deterministic, never simultaneous.",[15,64631,64632,64640,64678],{},[18,64633,64635,64636,64639],{"id":64634},"q2-by-default-elementaddeventlistenerclick-handler-registers-the-handler-for-which-phase-of-the-event-flow","Q2. By default, ",[39,64637,64638],{},"element.addEventListener('click', handler)"," registers the handler for which phase of the event flow?",[23,64641,64643,64649,64655,64665],{"className":64642},[26],[28,64644,64646,64648],{"className":64645},[31],[33,64647],{"disabled":35,"type":36}," The capturing phase, so it runs before any bubbling-phase listeners on ancestors",[28,64650,64652,64654],{"className":64651},[31],[33,64653],{"disabled":35,"type":36}," The bubbling phase, so it runs after the capturing phase has already passed through this element",[28,64656,64658,64660,64661,64664],{"className":64657},[31],[33,64659],{"disabled":35,"type":36}," Both phases simultaneously, unless ",[39,64662,64663],{},"capture: false"," is explicitly set",[28,64666,64668,64670,64671,64674,64675],{"className":64667},[31],[33,64669],{"disabled":35,"type":36}," Neither phase — plain calls without ",[39,64672,64673],{},"{capture: true}"," only fire when the element is the exact ",[39,64676,64677],{},"event.target",[66,64679,64680,64682,64687],{},[69,64681,71],{},[73,64683,64684,64686],{},[76,64685,78],{}," B — The bubbling phase, so it runs after the capturing phase has already passed through this element",[73,64688,64689,355,64691,64693,64694,64696,64697,64700,64701,64703,64704,64706],{},[76,64690,84],{},[39,64692,35737],{},"'s third argument defaults to ",[39,64695,2986],{}," (or an options object with ",[39,64698,64699],{},"capture"," omitted, which also defaults to ",[39,64702,2986],{},"), meaning the handler is registered for the bubbling phase. The full dispatch always runs capturing (root → target) first, regardless of what any individual listener requests, before bubbling-phase listeners get their turn. Option A describes what ",[39,64705,64673],{}," does. Option C is nonsensical — a listener is bound to one phase's behavior. Option D is too restrictive: a bubbling-phase listener on an ancestor fires too, once the event bubbles up to it, not only when it's the exact target.",[15,64708,64709,64719,64854,64857,64884],{"language":247},[18,64710,64712,64713,64715,64716,64718],{"id":64711},"q3-given-nested-elements-where-inner-is-a-direct-child-of-outer-and-the-following-listeners","Q3. Given nested elements where ",[39,64714,15301],{}," is a direct child of ",[39,64717,9628],{},", and the following listeners:",[257,64720,64721],{"language":247},[260,64722,64724],{"className":262,"code":64723,"language":247,"meta":264,"style":264},"outer.addEventListener(\"click\", () => console.log(\"outer bubble\"));\nouter.addEventListener(\"click\", () => console.log(\"outer capture\"), { capture: true });\n\ninner.addEventListener(\"click\", () => console.log(\"inner capture\"), { capture: true });\ninner.addEventListener(\"click\", () => console.log(\"inner bubble\"));\n\ninner.click();\n",[39,64725,64726,64753,64783,64787,64817,64842,64846],{"__ignoreMap":264},[268,64727,64728,64731,64733,64735,64738,64740,64742,64744,64746,64748,64751],{"class":270,"line":271},[268,64729,64730],{"class":282},"outer.",[268,64732,35737],{"class":278},[268,64734,622],{"class":282},[268,64736,64737],{"class":289},"\"click\"",[268,64739,35745],{"class":282},[268,64741,9414],{"class":274},[268,64743,9417],{"class":282},[268,64745,1356],{"class":278},[268,64747,622],{"class":282},[268,64749,64750],{"class":289},"\"outer bubble\"",[268,64752,4818],{"class":282},[268,64754,64755,64757,64759,64761,64763,64765,64767,64769,64771,64773,64776,64779,64781],{"class":270,"line":286},[268,64756,64730],{"class":282},[268,64758,35737],{"class":278},[268,64760,622],{"class":282},[268,64762,64737],{"class":289},[268,64764,35745],{"class":282},[268,64766,9414],{"class":274},[268,64768,9417],{"class":282},[268,64770,1356],{"class":278},[268,64772,622],{"class":282},[268,64774,64775],{"class":289},"\"outer capture\"",[268,64777,64778],{"class":282},"), { capture: ",[268,64780,2185],{"class":305},[268,64782,36080],{"class":282},[268,64784,64785],{"class":270,"line":296},[268,64786,5033],{"emptyLinePlaceholder":35},[268,64788,64789,64792,64794,64796,64798,64800,64802,64804,64806,64808,64811,64813,64815],{"class":270,"line":311},[268,64790,64791],{"class":282},"inner.",[268,64793,35737],{"class":278},[268,64795,622],{"class":282},[268,64797,64737],{"class":289},[268,64799,35745],{"class":282},[268,64801,9414],{"class":274},[268,64803,9417],{"class":282},[268,64805,1356],{"class":278},[268,64807,622],{"class":282},[268,64809,64810],{"class":289},"\"inner capture\"",[268,64812,64778],{"class":282},[268,64814,2185],{"class":305},[268,64816,36080],{"class":282},[268,64818,64819,64821,64823,64825,64827,64829,64831,64833,64835,64837,64840],{"class":270,"line":788},[268,64820,64791],{"class":282},[268,64822,35737],{"class":278},[268,64824,622],{"class":282},[268,64826,64737],{"class":289},[268,64828,35745],{"class":282},[268,64830,9414],{"class":274},[268,64832,9417],{"class":282},[268,64834,1356],{"class":278},[268,64836,622],{"class":282},[268,64838,64839],{"class":289},"\"inner bubble\"",[268,64841,4818],{"class":282},[268,64843,64844],{"class":270,"line":1951},[268,64845,5033],{"emptyLinePlaceholder":35},[268,64847,64848,64850,64852],{"class":270,"line":8955},[268,64849,64791],{"class":282},[268,64851,47403],{"class":278},[268,64853,794],{"class":282},[73,64855,64856],{},"What is the console output order?",[23,64858,64860,64866,64872,64878],{"className":64859},[26],[28,64861,64863,64865],{"className":64862},[31],[33,64864],{"disabled":35,"type":36}," inner bubble, inner capture, outer bubble, outer capture",[28,64867,64869,64871],{"className":64868},[31],[33,64870],{"disabled":35,"type":36}," outer bubble, outer capture, inner capture, inner bubble",[28,64873,64875,64877],{"className":64874},[31],[33,64876],{"disabled":35,"type":36}," outer capture, inner capture, inner bubble, outer bubble",[28,64879,64881,64883],{"className":64880},[31],[33,64882],{"disabled":35,"type":36}," inner capture, outer capture, outer bubble, inner bubble",[66,64885,64886,64888,64893],{},[69,64887,71],{},[73,64889,64890,64892],{},[76,64891,78],{}," C — outer capture, inner capture, inner bubble, outer bubble",[73,64894,64895,355,64897,64899,64900,64902,64903,64905,64906,64908,64909,64911,64912,64915,64916,64918],{},[76,64896,84],{},[76,64898,27162],{}," The capturing phase travels from the root down to (but not including firing bubble listeners at) the target, so ",[39,64901,9628],{},"'s capture-flagged listener fires first as the event descends toward ",[39,64904,15301],{},". Once the event reaches the target element itself, the dispatch is in the \"at target\" phase — here, both of ",[39,64907,15301],{},"'s listeners fire regardless of their ",[39,64910,64699],{}," flag, in the order they were ",[104,64913,64914],{},"registered",", which is why \"inner capture\" logs before \"inner bubble\" (it was added first in this snippet, not because capture flags dictate ordering at the target). Finally the bubbling phase carries the event back up, firing ",[39,64917,9628],{},"'s bubble-phase listener last. The key gotcha: at the target element, registration order — not the capture flag — decides the sequence.",[15,64920,64921,64943,64986],{},[18,64922,64924,64925,64928,64929,64931,64932,64934,64935,64938,64939,64942],{"id":64923},"q4-a-button-has-two-separate-click-listeners-attached-via-addeventlistener-the-first-one-calls-eventstoppropagation-the-second-one-does-nothing-special-both-are-registered-directly-on-the-button-no-capture-option-no-stopimmediatepropagation-when-the-button-is-clicked-what-happens-to-the-second-listener","Q4. A ",[39,64926,64927],{},"\u003Cbutton>"," has two separate ",[39,64930,47403],{}," listeners attached via ",[39,64933,35737],{},". The first one calls ",[39,64936,64937],{},"event.stopPropagation()","; the second one does nothing special. Both are registered directly on the button (no capture option, no ",[39,64940,64941],{},"stopImmediatePropagation","). When the button is clicked, what happens to the second listener?",[23,64944,64946,64955,64964,64973],{"className":64945},[26],[28,64947,64949,64951,64952,64954],{"className":64948},[31],[33,64950],{"disabled":35,"type":36}," It never runs — ",[39,64953,64563],{}," also stops other listeners on the same element",[28,64956,64958,64960,64961,64963],{"className":64957},[31],[33,64959],{"disabled":35,"type":36}," Neither listener runs — ",[39,64962,64563],{}," cancels the event entirely",[28,64965,64967,64969,64970,64972],{"className":64966},[31],[33,64968],{"disabled":35,"type":36}," Only the second listener runs — ",[39,64971,64563],{}," blocks the listener that called it from completing",[28,64974,64976,64978,64979,64981,64982,64985],{"className":64975},[31],[33,64977],{"disabled":35,"type":36}," It still runs — ",[39,64980,64563],{}," only stops bubbling to ancestor listeners, not sibling listeners on the same element; ",[39,64983,64984],{},"stopImmediatePropagation()"," would be needed to block it too",[66,64987,64988,64990,64999],{},[69,64989,71],{},[73,64991,64992,64994,64995,64981,64997,64985],{},[76,64993,78],{}," D — It still runs — ",[39,64996,64563],{},[39,64998,64984],{},[73,65000,65001,355,65003,355,65005,65007,65008,65010,65011,65013],{},[76,65002,84],{},[76,65004,27162],{},[39,65006,64563],{}," only prevents the event from continuing to travel to ancestor (or, during capturing, descendant) elements — it has no effect on other listeners already queued on the ",[104,65009,22779],{}," element, which all still run in registration order. Only ",[39,65012,64984],{}," additionally halts remaining same-element listeners. Option A is the classic mix-up between the two methods. Option B overstates the effect — propagation control never cancels the event object itself. Option C inverts which listener is affected.",[15,65015,65016,65030,65066],{},[18,65017,65019,65020,10834,65023,65025,65026,65029],{"id":65018},"q5-calling-eventpreventdefault-inside-a-click-handler-on-an-a-hrefpage-link-does-which-of-the-following","Q5. Calling ",[39,65021,65022],{},"event.preventDefault()",[39,65024,47403],{}," handler on an ",[39,65027,65028],{},"\u003Ca href=\"\u002Fpage\">"," link does which of the following?",[23,65031,65033,65046,65054,65060],{"className":65032},[26],[28,65034,65036,65038,65039,65042,65043,65045],{"className":65035},[31],[33,65037],{"disabled":35,"type":36}," Prevents the browser's default navigation to ",[39,65040,65041],{},"\u002Fpage",", but the event still bubbles to ancestor listeners unless ",[39,65044,64563],{}," is also called",[28,65047,65049,65038,65051,65053],{"className":65048},[31],[33,65050],{"disabled":35,"type":36},[39,65052,65041],{},", and also stops the event from bubbling to ancestor listeners",[28,65055,65057,65059],{"className":65056},[31],[33,65058],{"disabled":35,"type":36}," Has no effect unless the listener is registered on the capturing phase",[28,65061,65063,65065],{"className":65062},[31],[33,65064],{"disabled":35,"type":36}," Cancels the entire event, so no other listener on the anchor element runs",[66,65067,65068,65070,65079],{},[69,65069,71],{},[73,65071,65072,65074,65075,65042,65077,65045],{},[76,65073,78],{}," A — Prevents the browser's default navigation to ",[39,65076,65041],{},[39,65078,64563],{},[73,65080,65081,355,65083,65086,65087,65089,65090,446,65092,65094,65095,65097],{},[76,65082,84],{},[39,65084,65085],{},"preventDefault()"," and propagation control are two independent mechanisms: ",[39,65088,65085],{}," only suppresses whatever built-in action the browser would otherwise take (navigating, submitting a form, toggling a checkbox), while propagation continues normally unless ",[39,65091,64563],{},[39,65093,64984],{}," is called separately. Option B conflates the two, a very common assumption. Option C is wrong — ",[39,65096,65085],{}," works from either phase. Option D is wrong — it has no effect on other listeners at all.",[15,65099,65100,65111,65175],{},[18,65101,468,65103,65105,65106,65108,65109,1685],{"id":65102},"q6-a-ul-contains-500-li-items-that-get-added-and-removed-dynamically-which-approach-is-most-robust-for-handling-clicks-on-any-li",[39,65104,61253],{}," contains 500 ",[39,65107,61545],{}," items that get added and removed dynamically. Which approach is most robust for handling clicks on any ",[39,65110,61545],{},[23,65112,65114,65126,65148,65162],{"className":65113},[26],[28,65115,65117,65119,65120,65122,65123,65125],{"className":65116},[31],[33,65118],{"disabled":35,"type":36}," Attach a separate ",[39,65121,47403],{}," listener to every ",[39,65124,61545],{}," when it's created",[28,65127,65129,65131,65132,65134,65135,65137,65138,65140,65141,65144,65145,65147],{"className":65128},[31],[33,65130],{"disabled":35,"type":36}," Attach a single ",[39,65133,47403],{}," listener to the ",[39,65136,61253],{}," and inspect ",[39,65139,64677],{}," (or use ",[39,65142,65143],{},".closest()",") to determine which ",[39,65146,61545],{}," was clicked",[28,65149,65151,4353,65153,65156,65157,8574,65159,65161],{"className":65150},[31],[33,65152],{"disabled":35,"type":36},[39,65154,65155],{},"element.onclick"," on each ",[39,65158,61545],{},[39,65160,35737],{}," since it's faster",[28,65163,65165,65167,65168,65171,65172,65174],{"className":65164},[31],[33,65166],{"disabled":35,"type":36}," Poll ",[39,65169,65170],{},"document.activeElement"," on an interval to detect which ",[39,65173,61545],{}," was interacted with",[66,65176,65177,65179,65194],{},[69,65178,71],{},[73,65180,65181,65183,65184,65134,65186,65137,65188,65140,65190,65144,65192,65147],{},[76,65182,78],{}," B — Attach a single ",[39,65185,47403],{},[39,65187,61253],{},[39,65189,64677],{},[39,65191,65143],{},[39,65193,61545],{},[73,65195,65196,65198,65199,355,65202,65204,65205,65207],{},[76,65197,84],{}," This is event delegation: because clicks bubble up from any descendant, one listener on a stable ancestor catches interactions from every current ",[104,65200,65201],{},"and future",[39,65203,61545],{},", with no per-item wiring or cleanup needed when rows are added or removed. Option A requires re-attaching a listener on every re-render and doesn't scale to large or frequently-changing lists. Option C is false — ",[39,65206,35799],{}," isn't inherently faster, and it still needs to be set per-element. Option D is unrelated to click detection and would miss most interactions entirely.",[15,65209,65210,65218,65300,65320,65377],{"language":247},[18,65211,65213,65214,65217],{"id":65212},"q7-a-delegated-click-listener-on-a-ul-idlist-is-written-as","Q7. A delegated click listener on a ",[39,65215,65216],{},"\u003Cul id=\"list\">"," is written as:",[257,65219,65220],{"language":247},[260,65221,65223],{"className":262,"code":65222,"language":247,"meta":264,"style":264},"list.addEventListener(\"click\", (event) => {\n  const item = event.target.closest(\"li[data-id]\");\n  if (!item) return;\n  console.log(\"Selected:\", item.dataset.id);\n});\n",[39,65224,65225,65247,65267,65282,65296],{"__ignoreMap":264},[268,65226,65227,65229,65231,65233,65235,65238,65241,65243,65245],{"class":270,"line":271},[268,65228,40613],{"class":282},[268,65230,35737],{"class":278},[268,65232,622],{"class":282},[268,65234,64737],{"class":289},[268,65236,65237],{"class":282},", (",[268,65239,65240],{"class":1222},"event",[268,65242,6131],{"class":282},[268,65244,9414],{"class":274},[268,65246,9914],{"class":282},[268,65248,65249,65251,65253,65255,65258,65260,65262,65265],{"class":270,"line":286},[268,65250,12441],{"class":274},[268,65252,11794],{"class":305},[268,65254,616],{"class":274},[268,65256,65257],{"class":282}," event.target.",[268,65259,40642],{"class":278},[268,65261,622],{"class":282},[268,65263,65264],{"class":289},"\"li[data-id]\"",[268,65266,628],{"class":282},[268,65268,65269,65271,65273,65275,65278,65280],{"class":270,"line":296},[268,65270,9863],{"class":274},[268,65272,2182],{"class":282},[268,65274,5418],{"class":274},[268,65276,65277],{"class":282},"item) ",[268,65279,9151],{"class":274},[268,65281,293],{"class":282},[268,65283,65284,65286,65288,65290,65293],{"class":270,"line":311},[268,65285,5556],{"class":282},[268,65287,1356],{"class":278},[268,65289,622],{"class":282},[268,65291,65292],{"class":289},"\"Selected:\"",[268,65294,65295],{"class":282},", item.dataset.id);\n",[268,65297,65298],{"class":270,"line":788},[268,65299,20047],{"class":282},[73,65301,65302,65303,57690,65306,65309,65310,65313,65314,65316,65317,65319],{},"Each ",[39,65304,65305],{},"\u003Cli data-id=\"42\">",[39,65307,65308],{},"\u003Cbutton>\u003Cspan class=\"icon\">×\u003C\u002Fspan> Delete\u003C\u002Fbutton>",". A user clicks directly on the ",[39,65311,65312],{},"\u003Cspan class=\"icon\">",". Why is ",[39,65315,65143],{}," needed here instead of using ",[39,65318,64677],{}," directly?",[23,65321,65323,65336,65347,65363],{"className":65322},[26],[28,65324,65326,355,65328,65330,65331,1179,65333,65335],{"className":65325},[31],[33,65327],{"disabled":35,"type":36},[39,65329,64677],{}," is always the ",[39,65332,61545],{},[39,65334,65143],{}," is redundant",[28,65337,65339,355,65341,65343,65344,65346],{"className":65338},[31],[33,65340],{"disabled":35,"type":36},[39,65342,65143],{}," is required because ",[39,65345,64677],{}," does not exist inside delegated listeners",[28,65348,65350,355,65352,65354,65355,65357,65358,2272,65360,65362],{"className":65349},[31],[33,65351],{"disabled":35,"type":36},[39,65353,64677],{}," will be the innermost clicked element (the ",[39,65356,64555],{},"), not the ",[39,65359,61545],{},[39,65361,65143],{}," walks up from it to find the nearest matching ancestor (or itself)",[28,65364,65366,355,65368,65370,65371,65373,65374,65376],{"className":65365},[31],[33,65367],{"disabled":35,"type":36},[39,65369,65143],{}," searches the descendants of ",[39,65372,64677],{},", which is needed to find the ",[39,65375,61545],{},"'s children",[66,65378,65379,65381,65393],{},[69,65380,71],{},[73,65382,65383,1004,65385,65354,65387,65357,65389,2272,65391,65362],{},[76,65384,78],{},[39,65386,64677],{},[39,65388,64555],{},[39,65390,61545],{},[39,65392,65143],{},[73,65394,65395,65397,65398,65400,65401,65403,65404,65407,65408,65411,65412,65415,65416,65418,65419,65421],{},[76,65396,84],{}," In a delegated listener, ",[39,65399,64677],{}," is whatever the user actually clicked — frequently a deeply nested decorative element like an icon ",[39,65402,64555],{},", not the semantic row you actually care about. ",[39,65405,65406],{},".closest(selector)"," starts at the element itself (inclusive) and searches upward through ancestors for the first match, correctly landing on the ",[39,65409,65410],{},"\u003Cli data-id>"," no matter how deeply the click originated inside it. Option A is false — ",[39,65413,65414],{},"target"," is the deepest node, not the delegated container's child. Option B is false — ",[39,65417,64677],{}," always exists on the event object. Option D reverses the search direction; ",[39,65420,65143],{}," goes up the tree, never down into descendants.",[15,65423,65424,65448,65485],{},[18,65425,65427,65428,65431,65432,65434,65435,65437,65438,65441,65442,186,65444,65447],{"id":65426},"q8-a-div-idouter-contains-a-nested-button-a-single-click-listener-is-attached-to-outer-when-a-user-clicks-the-button-inside-that-listener-eventtarget-and-eventcurrenttarget-are-compared-which-statement-is-correct","Q8. A ",[39,65429,65430],{},"\u003Cdiv id=\"outer\">"," contains a nested ",[39,65433,64927],{},". A single ",[39,65436,47403],{}," listener is attached to ",[39,65439,65440],{},"#outer",". When a user clicks the button, inside that listener ",[39,65443,64677],{},[39,65445,65446],{},"event.currentTarget"," are compared. Which statement is correct?",[23,65449,65451,65457,65468,65474],{"className":65450},[26],[28,65452,65454,65456],{"className":65453},[31],[33,65455],{"disabled":35,"type":36}," Both always refer to the div, since that's where the listener is attached",[28,65458,65460,355,65462,65464,65465,65467],{"className":65459},[31],[33,65461],{"disabled":35,"type":36},[39,65463,64677],{}," is the div (the listener's element); ",[39,65466,65446],{}," is the button (the clicked element)",[28,65469,65471,65473],{"className":65470},[31],[33,65472],{"disabled":35,"type":36}," Both always refer to the button, since that's what was clicked",[28,65475,65477,355,65479,65481,65482,65484],{"className":65476},[31],[33,65478],{"disabled":35,"type":36},[39,65480,64677],{}," is the button (the element that actually triggered the event); ",[39,65483,65446],{}," is the div (the element the listener is attached to) — the two stay fixed to their own definitions throughout the dispatch, and differ whenever the click originates on a descendant",[66,65486,65487,65489,65497],{},[69,65488,71],{},[73,65490,65491,6901,65493,65481,65495,65484],{},[76,65492,78],{},[39,65494,64677],{},[39,65496,65446],{},[73,65498,65499,355,65501,65503,65504,65506,65507,65510,65511,65513,65514,65517,65518,65520],{},[76,65500,84],{},[39,65502,64677],{}," is set once, at the very start of dispatch, to the innermost element the event originated on, and never changes for that dispatch. ",[39,65505,65446],{}," instead tracks whichever element's listener is ",[104,65508,65509],{},"currently executing",", which changes as the event moves through capturing and bubbling — inside this listener it's always ",[39,65512,65440],{},", since that's where the listener lives. This distinction matters when the same handler function is shared across multiple elements: ",[39,65515,65516],{},"currentTarget"," reliably tells you \"which element I'm attached to,\" while ",[39,65519,65414],{}," tells you \"what was actually interacted with.\" Options A and B collapse this distinction incorrectly, and Option C wrongly assumes both track the clicked element.",[15,65522,65523,65527,65596,65599,65634],{"language":247},[18,65524,65526],{"id":65525},"q9-a-developer-writes","Q9. A developer writes:",[257,65528,65529],{"language":247},[260,65530,65532],{"className":262,"code":65531,"language":247,"meta":264,"style":264},"button.addEventListener(\"click\", () => console.log(\"clicked\"));\nbutton.removeEventListener(\"click\", () => console.log(\"clicked\"));\n\nbutton.click();\n",[39,65533,65534,65559,65584,65588],{"__ignoreMap":264},[268,65535,65536,65538,65540,65542,65544,65546,65548,65550,65552,65554,65557],{"class":270,"line":271},[268,65537,35734],{"class":282},[268,65539,35737],{"class":278},[268,65541,622],{"class":282},[268,65543,64737],{"class":289},[268,65545,35745],{"class":282},[268,65547,9414],{"class":274},[268,65549,9417],{"class":282},[268,65551,1356],{"class":278},[268,65553,622],{"class":282},[268,65555,65556],{"class":289},"\"clicked\"",[268,65558,4818],{"class":282},[268,65560,65561,65563,65566,65568,65570,65572,65574,65576,65578,65580,65582],{"class":270,"line":286},[268,65562,35734],{"class":282},[268,65564,65565],{"class":278},"removeEventListener",[268,65567,622],{"class":282},[268,65569,64737],{"class":289},[268,65571,35745],{"class":282},[268,65573,9414],{"class":274},[268,65575,9417],{"class":282},[268,65577,1356],{"class":278},[268,65579,622],{"class":282},[268,65581,65556],{"class":289},[268,65583,4818],{"class":282},[268,65585,65586],{"class":270,"line":296},[268,65587,5033],{"emptyLinePlaceholder":35},[268,65589,65590,65592,65594],{"class":270,"line":311},[268,65591,35734],{"class":282},[268,65593,47403],{"class":278},[268,65595,794],{"class":282},[73,65597,65598],{},"What happens?",[23,65600,65602,65611,65620,65628],{"className":65601},[26],[28,65603,65605,65607,65608,65610],{"className":65604},[31],[33,65606],{"disabled":35,"type":36}," \"clicked\" logs once; the anonymous arrow function passed to ",[39,65609,65565],{}," is a different function reference, so nothing is actually removed",[28,65612,65614,65616,65617,65619],{"className":65613},[31],[33,65615],{"disabled":35,"type":36}," Nothing logs; ",[39,65618,65565],{}," successfully matches and removes the listener",[28,65621,65623,1271,65625,65627],{"className":65622},[31],[33,65624],{"disabled":35,"type":36},[39,65626,827],{}," because you can't remove a listener that hasn't fired yet",[28,65629,65631,65633],{"className":65630},[31],[33,65632],{"disabled":35,"type":36}," \"clicked\" logs twice, once for the add and once for the mismatched remove",[66,65635,65636,65638,65645],{},[69,65637,71],{},[73,65639,65640,65642,65643,65610],{},[76,65641,78],{}," A — \"clicked\" logs once; the anonymous arrow function passed to ",[39,65644,65565],{},[73,65646,65647,355,65649,355,65651,65653,65654,186,65656,65658,65659,65661,65662,65664,65665,65667],{},[76,65648,84],{},[76,65650,27162],{},[39,65652,65565],{}," only removes a listener when it's called with the exact same function reference (plus matching ",[39,65655,8623],{},[39,65657,64699],{}," flag) that was originally passed to ",[39,65660,35737],{},". Two separately-written arrow functions are never ",[39,65663,3280],{}," to each other, even with byte-for-byte identical bodies, so the \"removal\" silently matches nothing and the original listener stays active — no error, no warning. To make a listener removable, store it in a named variable and pass that same reference to both calls. Option C invents an error that never occurs; ",[39,65666,65565],{}," fails silently on non-matches. Option D misunderstands that a non-matching remove call has zero effect on the listener count.",[15,65669,65670,65681,65708],{},[18,65671,65673,65674,65677,65678,65680],{"id":65672},"q10-what-does-passing-once-true-as-the-options-argument-to-addeventlistener-do","Q10. What does passing ",[39,65675,65676],{},"{ once: true }"," as the options argument to ",[39,65679,35737],{}," do?",[23,65682,65684,65690,65696,65702],{"className":65683},[26],[28,65685,65687,65689],{"className":65686},[31],[33,65688],{"disabled":35,"type":36}," It makes the listener run once per animation frame, throttling rapid events",[28,65691,65693,65695],{"className":65692},[31],[33,65694],{"disabled":35,"type":36}," It automatically removes the listener after it has been invoked a single time",[28,65697,65699,65701],{"className":65698},[31],[33,65700],{"disabled":35,"type":36}," It prevents the event from bubbling after the first invocation",[28,65703,65705,65707],{"className":65704},[31],[33,65706],{"disabled":35,"type":36}," It defers the listener to run once the main thread is idle",[66,65709,65710,65712,65717],{},[69,65711,71],{},[73,65713,65714,65716],{},[76,65715,78],{}," B — It automatically removes the listener after it has been invoked a single time",[73,65718,65719,355,65721,65723,65724,65726,65727,65729,65730,65732,65733,65736,65737,65740],{},[76,65720,84],{},[39,65722,65676],{}," tells the browser to invoke the listener at most once, then internally call the equivalent of ",[39,65725,65565],{}," for it — useful for one-shot interactions like a dismiss button or a first-scroll trigger, without needing to manually clean up. Option A confuses it with ",[39,65728,62893],{},"-based throttling, an unrelated technique. Option C confuses it with ",[39,65731,64563],{},". Option D confuses it with ",[39,65734,65735],{},"requestIdleCallback"," scheduling semantics, which ",[39,65738,65739],{},"once"," has nothing to do with.",[15,65742,65743,65747,65845,65851,65895],{"language":247},[18,65744,65746],{"id":65745},"q11-a-component-sets-up-several-listeners-tied-to-one-controller","Q11. A component sets up several listeners tied to one controller:",[257,65748,65749],{"language":247},[260,65750,65752],{"className":262,"code":65751,"language":247,"meta":264,"style":264},"const controller = new AbortController();\nconst { signal } = controller;\n\nbutton.addEventListener(\"click\", onClick, { signal });\nwindow.addEventListener(\"resize\", onResize, { signal });\ndocument.addEventListener(\"keydown\", onKeydown, { signal });\n\ncontroller.abort();\n",[39,65753,65754,65770,65785,65789,65802,65817,65831,65835],{"__ignoreMap":264},[268,65755,65756,65758,65761,65763,65765,65768],{"class":270,"line":271},[268,65757,243],{"class":274},[268,65759,65760],{"class":305}," controller",[268,65762,616],{"class":274},[268,65764,11370],{"class":274},[268,65766,65767],{"class":278}," AbortController",[268,65769,794],{"class":282},[268,65771,65772,65774,65776,65778,65780,65782],{"class":270,"line":286},[268,65773,243],{"class":274},[268,65775,20200],{"class":282},[268,65777,39937],{"class":305},[268,65779,7908],{"class":282},[268,65781,302],{"class":274},[268,65783,65784],{"class":282}," controller;\n",[268,65786,65787],{"class":270,"line":296},[268,65788,5033],{"emptyLinePlaceholder":35},[268,65790,65791,65793,65795,65797,65799],{"class":270,"line":311},[268,65792,35734],{"class":282},[268,65794,35737],{"class":278},[268,65796,622],{"class":282},[268,65798,64737],{"class":289},[268,65800,65801],{"class":282},", onClick, { signal });\n",[268,65803,65804,65807,65809,65811,65814],{"class":270,"line":788},[268,65805,65806],{"class":282},"window.",[268,65808,35737],{"class":278},[268,65810,622],{"class":282},[268,65812,65813],{"class":289},"\"resize\"",[268,65815,65816],{"class":282},", onResize, { signal });\n",[268,65818,65819,65821,65823,65825,65828],{"class":270,"line":1951},[268,65820,61438],{"class":282},[268,65822,35737],{"class":278},[268,65824,622],{"class":282},[268,65826,65827],{"class":289},"\"keydown\"",[268,65829,65830],{"class":282},", onKeydown, { signal });\n",[268,65832,65833],{"class":270,"line":8955},[268,65834,5033],{"emptyLinePlaceholder":35},[268,65836,65837,65840,65843],{"class":270,"line":8966},[268,65838,65839],{"class":282},"controller.",[268,65841,65842],{"class":278},"abort",[268,65844,794],{"class":282},[73,65846,65847,65848,1685],{},"What is the effect of calling ",[39,65849,65850],{},"controller.abort()",[23,65852,65854,65864,65875,65883],{"className":65853},[26],[28,65855,65857,65859,65860,65863],{"className":65856},[31],[33,65858],{"disabled":35,"type":36}," Only the most recently added listener (",[39,65861,65862],{},"keydown",") is removed",[28,65865,65867,52864,65869,65871,65872,65874],{"className":65866},[31],[33,65868],{"disabled":35,"type":36},[39,65870,39934],{}," only cancels ",[39,65873,47324],{}," requests, not event listeners",[28,65876,65878,65880,65881],{"className":65877},[31],[33,65879],{"disabled":35,"type":36}," All three listeners are removed simultaneously, since they all share the same ",[39,65882,39937],{},[28,65884,65886,65888,65889,65891,65892,65894],{"className":65885},[31],[33,65887],{"disabled":35,"type":36}," It throws because ",[39,65890,39937],{}," can only be used with one ",[39,65893,35737],{}," call at a time",[66,65896,65897,65899,65906],{},[69,65898,71],{},[73,65900,65901,65903,65904],{},[76,65902,78],{}," C — All three listeners are removed simultaneously, since they all share the same ",[39,65905,39937],{},[73,65907,65908,65910,65911,65913,65914,65916,65917,65919,65920,65922,65923,65925,65926,65929,65930,42,65932,65934],{},[76,65909,84],{}," Modern ",[39,65912,35737],{}," accepts a ",[39,65915,39937],{}," option, and a single ",[39,65918,39934],{}," can be shared across any number of listeners on any number of elements. Calling ",[39,65921,40012],{}," once removes every listener registered with that signal in one shot, replacing the older pattern of manually calling ",[39,65924,65565],{}," for each one with matching references. Option B is outdated — ",[39,65927,65928],{},"AbortSignal"," is now a general-purpose cancellation primitive used by ",[39,65931,47324],{},[39,65933,35737],{},", and other APIs. Options A and D misdescribe the sharing behavior; nothing limits a signal to a single listener.",[15,65936,65937,65954,65981],{},[18,65938,65940,65941,65944,65945,99,65948,65951,65952,1685],{"id":65939},"q12-why-would-you-add-passive-true-to-a-touchstart-or-wheel-event-listener-that-never-calls-preventdefault","Q12. Why would you add ",[39,65942,65943],{},"{ passive: true }"," to a ",[39,65946,65947],{},"touchstart",[39,65949,65950],{},"wheel"," event listener that never calls ",[39,65953,65085],{},[23,65955,65957,65963,65969,65975],{"className":65956},[26],[28,65958,65960,65962],{"className":65959},[31],[33,65961],{"disabled":35,"type":36}," It makes the listener fire before capturing-phase listeners",[28,65964,65966,65968],{"className":65965},[31],[33,65967],{"disabled":35,"type":36}," It automatically debounces rapid touch\u002Fwheel events for you",[28,65970,65972,65974],{"className":65971},[31],[33,65973],{"disabled":35,"type":36}," It silently ignores any code inside the handler",[28,65976,65978,65980],{"className":65977},[31],[33,65979],{"disabled":35,"type":36}," It tells the browser it can start scrolling immediately without waiting to see if the handler cancels it, improving scroll smoothness",[66,65982,65983,65985,65990],{},[69,65984,71],{},[73,65986,65987,65989],{},[76,65988,78],{}," D — It tells the browser it can start scrolling immediately without waiting to see if the handler cancels it, improving scroll smoothness",[73,65991,65992,355,65994,65997,65998,66000,66001,66003,66004,66006,66007,446,66009,66012,66013,66016,66017,66019],{},[76,65993,84],{},[76,65995,65996],{},"Performance."," Normally the browser must wait for a touch\u002Fwheel handler to finish running — in case it calls ",[39,65999,65085],{}," to cancel native scrolling — before it can start scrolling, which can cause visible jank if the main thread is busy. ",[39,66002,65943],{}," is a promise that the handler will never call ",[39,66005,65085],{},", letting the browser begin the native scroll or fling in parallel immediately. Some browsers even default ",[39,66008,65947],{},[39,66010,66011],{},"touchmove"," listeners to passive for exactly this reason. Options B and C describe behaviors ",[39,66014,66015],{},"passive"," doesn't have. Option A confuses it with the unrelated ",[39,66018,64699],{}," option.",[15,66021,66022,66026,66087,66090,66131],{"language":247},[18,66023,66025],{"id":66024},"q13-a-listener-is-registered-like-this","Q13. A listener is registered like this:",[257,66027,66028],{"language":247},[260,66029,66031],{"className":262,"code":66030,"language":247,"meta":264,"style":264},"document.addEventListener(\n  \"touchstart\",\n  (event) => {\n    event.preventDefault();\n  },\n  { passive: true }\n);\n",[39,66032,66033,66041,66048,66060,66070,66074,66083],{"__ignoreMap":264},[268,66034,66035,66037,66039],{"class":270,"line":271},[268,66036,61438],{"class":282},[268,66038,35737],{"class":278},[268,66040,17096],{"class":282},[268,66042,66043,66046],{"class":270,"line":286},[268,66044,66045],{"class":289},"  \"touchstart\"",[268,66047,1789],{"class":282},[268,66049,66050,66052,66054,66056,66058],{"class":270,"line":296},[268,66051,38868],{"class":282},[268,66053,65240],{"class":1222},[268,66055,6131],{"class":282},[268,66057,9414],{"class":274},[268,66059,9914],{"class":282},[268,66061,66062,66065,66068],{"class":270,"line":311},[268,66063,66064],{"class":282},"    event.",[268,66066,66067],{"class":278},"preventDefault",[268,66069,794],{"class":282},[268,66071,66072],{"class":270,"line":788},[268,66073,19610],{"class":282},[268,66075,66076,66079,66081],{"class":270,"line":1951},[268,66077,66078],{"class":282},"  { passive: ",[268,66080,2185],{"class":305},[268,66082,29394],{"class":282},[268,66084,66085],{"class":270,"line":8955},[268,66086,628],{"class":282},[73,66088,66089],{},"What happens when a user touches the screen?",[23,66091,66093,66101,66109,66120],{"className":66092},[26],[28,66094,66096,355,66098,66100],{"className":66095},[31],[33,66097],{"disabled":35,"type":36},[39,66099,65085],{}," is silently ignored (default scrolling still happens), and most browsers log a console warning",[28,66102,66104,355,66106,66108],{"className":66103},[31],[33,66105],{"disabled":35,"type":36},[39,66107,65085],{}," successfully blocks the default touch behavior (e.g., scrolling)",[28,66110,66112,66114,66115,183,66117,66119],{"className":66111},[31],[33,66113],{"disabled":35,"type":36}," The listener throws a ",[39,66116,827],{},[39,66118,66067],{}," is disabled on passive listeners",[28,66121,66123,66125,66126,186,66128,66130],{"className":66122},[31],[33,66124],{"disabled":35,"type":36}," The event stops firing entirely because ",[39,66127,66015],{},[39,66129,66067],{}," conflict",[66,66132,66133,66135,66141],{},[69,66134,71],{},[73,66136,66137,3459,66139,66100],{},[76,66138,78],{},[39,66140,65085],{},[73,66142,66143,355,66145,355,66147,66149,66150,66152],{},[76,66144,84],{},[76,66146,27162],{},[39,66148,65943],{}," is a contract with the browser that the listener will never cancel the default action. Calling ",[39,66151,65085],{}," inside it doesn't throw, but the call becomes a no-op — the browser has already committed to proceeding with the default scroll without waiting, so nothing is actually blocked. Most browsers (e.g., Chrome) log a console warning such as \"Unable to preventDefault inside passive event listener\" to surface the mistake. Option C overstates the failure mode — it's silent, not an exception. Option D is wrong; the rest of the handler's code still runs, only the cancellation is dropped.",[15,66154,66155,66166,66269,66272,66341],{"language":247},[18,66156,66158,66159,66162,66163,10728],{"id":66157},"q14-given-child-is-a-descendant-of-parent","Q14. Given ",[39,66160,66161],{},"child"," is a descendant of ",[39,66164,66165],{},"parent",[257,66167,66168],{"language":247},[260,66169,66171],{"className":262,"code":66170,"language":247,"meta":264,"style":264},"parent.addEventListener(\"cart:updated\", (e) => {\n  console.log(e.detail.itemCount);\n});\n\nconst event = new CustomEvent(\"cart:updated\", {\n  detail: { itemCount: 3 },\n  bubbles: true,\n});\n\nchild.dispatchEvent(event);\n",[39,66172,66173,66195,66204,66208,66212,66232,66241,66250,66254,66258],{"__ignoreMap":264},[268,66174,66175,66178,66180,66182,66185,66187,66189,66191,66193],{"class":270,"line":271},[268,66176,66177],{"class":282},"parent.",[268,66179,35737],{"class":278},[268,66181,622],{"class":282},[268,66183,66184],{"class":289},"\"cart:updated\"",[268,66186,65237],{"class":282},[268,66188,40624],{"class":1222},[268,66190,6131],{"class":282},[268,66192,9414],{"class":274},[268,66194,9914],{"class":282},[268,66196,66197,66199,66201],{"class":270,"line":286},[268,66198,5556],{"class":282},[268,66200,1356],{"class":278},[268,66202,66203],{"class":282},"(e.detail.itemCount);\n",[268,66205,66206],{"class":270,"line":296},[268,66207,20047],{"class":282},[268,66209,66210],{"class":270,"line":311},[268,66211,5033],{"emptyLinePlaceholder":35},[268,66213,66214,66216,66219,66221,66223,66226,66228,66230],{"class":270,"line":788},[268,66215,243],{"class":274},[268,66217,66218],{"class":305}," event",[268,66220,616],{"class":274},[268,66222,11370],{"class":274},[268,66224,66225],{"class":278}," CustomEvent",[268,66227,622],{"class":282},[268,66229,66184],{"class":289},[268,66231,20379],{"class":282},[268,66233,66234,66237,66239],{"class":270,"line":1951},[268,66235,66236],{"class":282},"  detail: { itemCount: ",[268,66238,3423],{"class":305},[268,66240,20042],{"class":282},[268,66242,66243,66246,66248],{"class":270,"line":8955},[268,66244,66245],{"class":282},"  bubbles: ",[268,66247,2185],{"class":305},[268,66249,1789],{"class":282},[268,66251,66252],{"class":270,"line":8966},[268,66253,20047],{"class":282},[268,66255,66256],{"class":270,"line":8974},[268,66257,5033],{"emptyLinePlaceholder":35},[268,66259,66260,66263,66266],{"class":270,"line":8985},[268,66261,66262],{"class":282},"child.",[268,66264,66265],{"class":278},"dispatchEvent",[268,66267,66268],{"class":282},"(event);\n",[73,66270,66271],{},"What logs?",[23,66273,66275,66287,66308,66325],{"className":66274},[26],[28,66276,66278,52864,66280,66283,66284,66286],{"className":66277},[31],[33,66279],{"disabled":35,"type":36},[39,66281,66282],{},"CustomEvent"," instances never trigger ",[39,66285,35737],{}," listeners",[28,66288,66290,355,66292,66294,66295,66297,66298,66301,66302,66304,66305],{"className":66289},[31],[33,66291],{"disabled":35,"type":36},[39,66293,3423],{}," — the event was dispatched on ",[39,66296,66161],{},", and because ",[39,66299,66300],{},"bubbles: true"," was set, it propagates up to the ",[39,66303,66165],{}," listener, which reads it via ",[39,66306,66307],{},"e.detail",[28,66309,66311,355,66313,3990,66315,66318,66319,2758,66322],{"className":66310},[31],[33,66312],{"disabled":35,"type":36},[39,66314,833],{},[39,66316,66317],{},"detail"," is only accessible via ",[39,66320,66321],{},"event.data",[39,66323,66324],{},"event.detail",[28,66326,66328,812,66330,3990,66332,66334,66335,66337,66338],{"className":66327},[31],[33,66329],{"disabled":35,"type":36},[39,66331,827],{},[39,66333,66265],{}," cannot be used with a ",[39,66336,66282],{},", only with built-in events like ",[39,66339,66340],{},"Event",[66,66342,66343,66345,66359],{},[69,66344,71],{},[73,66346,66347,1727,66349,66294,66351,66297,66353,66301,66355,66304,66357],{},[76,66348,78],{},[39,66350,3423],{},[39,66352,66161],{},[39,66354,66300],{},[39,66356,66165],{},[39,66358,66307],{},[73,66360,66361,355,66363,66365,66366,137,66368,66370,66371,66373,66374,66376,66377,5425,66380,66382,66383,66385,66386,66388,66389,66391,66392,66394,66395,66397,66398,462],{},[76,66362,84],{},[39,66364,66282],{}," lets application code build its own named events carrying an arbitrary payload in ",[39,66367,66317],{},[39,66369,66265],{}," runs it through the exact same capture\u002Ftarget\u002Fbubble pipeline as a real user-triggered event. Note the gotcha: unlike most native UI events (which bubble by default), ",[39,66372,66282],{}," (like the base ",[39,66375,66340],{}," constructor) defaults ",[39,66378,66379],{},"bubbles",[39,66381,2986],{}," — it had to be explicitly set to ",[39,66384,2185],{}," here for ",[39,66387,66165],{},"'s listener to ever see it. Option A is wrong — ",[39,66390,66265],{}," synchronously invokes any matching listeners. Option C invents a nonexistent property name. Option D is false; ",[39,66393,66265],{}," accepts any ",[39,66396,66340],{}," subtype, including ",[39,66399,66282],{},[15,66401,66402,66410,66456],{},[18,66403,66405,66406,66409],{"id":66404},"q15-a-team-wants-to-detect-when-focus-leaves-a-forms-container-entirely-using-event-delegation-with-a-single-listener-on-the-form-element-which-event-should-they-use-and-why","Q15. A team wants to detect when focus leaves a form's container entirely, using event delegation with a single listener on the ",[39,66407,66408],{},"\u003Cform>"," element. Which event should they use, and why?",[23,66411,66413,66422,66433,66445],{"className":66412},[26],[28,66414,66416,355,66418,66421],{"className":66415},[31],[33,66417],{"disabled":35,"type":36},[39,66419,66420],{},"blur",", because it fires on the form itself whenever any child input loses focus",[28,66423,66425,355,66427,66430,66431],{"className":66424},[31],[33,66426],{"disabled":35,"type":36},[39,66428,66429],{},"focus",", because it's the bubbling counterpart to ",[39,66432,66420],{},[28,66434,66436,355,66438,66441,66442,66444],{"className":66435},[31],[33,66437],{"disabled":35,"type":36},[39,66439,66440],{},"focusout",", because unlike ",[39,66443,66420],{},", it bubbles, so a single listener on the form catches focus changes from any descendant input",[28,66446,66448,66450,66451,99,66453,66455],{"className":66447},[31],[33,66449],{"disabled":35,"type":36}," Either ",[39,66452,66420],{},[39,66454,66440],{}," work identically for delegation; the choice is just style preference",[66,66457,66458,66460,66468],{},[69,66459,71],{},[73,66461,66462,1004,66464,66441,66466,66444],{},[76,66463,78],{},[39,66465,66440],{},[39,66467,66420],{},[73,66469,66470,355,66472,355,66474,186,66476,66478,66479,186,66482,66484,66485,66487,66488,66490,66491,66493,66494,66496],{},[76,66471,84],{},[76,66473,27162],{},[39,66475,66429],{},[39,66477,66420],{}," do not bubble by design, so a listener on a container only fires when that exact container element gains or loses focus — not its descendants. ",[39,66480,66481],{},"focusin",[39,66483,66440],{}," are the bubbling equivalents, standardized specifically to support delegation, and are the correct choice here. Option A is the classic mistake: ",[39,66486,66420],{}," on the form fires only if the ",[39,66489,66408],{}," element itself is directly focused, which rarely happens. Option B confuses ",[39,66492,66429],{}," (non-bubbling) with ",[39,66495,66481],{},". Option D is false — the two behave completely differently for delegation.",[15,66498,66499,66513,66558],{},[18,66500,66502,66503,1133,66506,1133,66509,66512],{"id":66501},"q16-a-script-runs-in-order-btnonclick-fna-then-btnonclick-fnb-then-btnaddeventlistenerclick-fnc-when-the-button-is-clicked-which-handlers-run-and-in-what-order","Q16. A script runs, in order: ",[39,66504,66505],{},"btn.onclick = fnA;",[39,66507,66508],{},"btn.onclick = fnB;",[39,66510,66511],{},"btn.addEventListener(\"click\", fnC)",". When the button is clicked, which handlers run, and in what order?",[23,66514,66516,66522,66533,66546],{"className":66515},[26],[28,66517,66519,66521],{"className":66518},[31],[33,66520],{"disabled":35,"type":36}," fnA, then fnB, then fnC — all three coexist because they were assigned at different times",[28,66523,66525,66527,66528,66530,66531,10349],{"className":66524},[31],[33,66526],{"disabled":35,"type":36}," fnC, then fnB — ",[39,66529,35737],{},"-registered handlers always run before the ",[39,66532,35799],{},[28,66534,66536,812,66538,66540,66541,186,66543,66545],{"className":66535},[31],[33,66537],{"disabled":35,"type":36},[39,66539,827],{}," is thrown — ",[39,66542,35799],{},[39,66544,35737],{}," cannot both be used on the same element",[28,66547,66549,66551,66552,66554,66555,66557],{"className":66548},[31],[33,66550],{"disabled":35,"type":36}," fnB, then fnC — the second assignment to ",[39,66553,35799],{}," silently overwrites the first (fnA never runs), while ",[39,66556,35737],{}," maintains its own independent list and runs alongside it",[66,66559,66560,66562,66571],{},[69,66561,71],{},[73,66563,66564,66566,66567,66554,66569,66557],{},[76,66565,78],{}," D — fnB, then fnC — the second assignment to ",[39,66568,35799],{},[39,66570,35737],{},[73,66572,66573,355,66575,355,66577,66579,66580,66583,66584,66587,66588,66590,66591,66593,66594,66596],{},[76,66574,84],{},[76,66576,27162],{},[39,66578,65155],{}," is a plain property, not a collection — each assignment simply replaces whatever function was stored there, so only ",[39,66581,66582],{},"fnB"," (the last assignment) survives, with no error or warning that ",[39,66585,66586],{},"fnA"," was discarded. ",[39,66589,35737],{}," maintains a completely separate internal list of listeners that can hold any number of handlers without clobbering the ",[39,66592,35799],{}," property or each other. Option A wrongly assumes property assignment stacks like ",[39,66595,35737],{}," does. Option B invents a precedence rule that doesn't exist. Option C is false — the two mechanisms coexist without conflict.",[15,66598,66599,66603,66676,66681,66716],{"language":247},[18,66600,66602],{"id":66601},"q17-given","Q17. Given:",[257,66604,66605],{"language":247},[260,66606,66608],{"className":262,"code":66607,"language":247,"meta":264,"style":264},"function handleClick() {\n  console.log(\"clicked\");\n}\n\nbutton.addEventListener(\"click\", handleClick);\nbutton.addEventListener(\"click\", handleClick);\n\nbutton.click();\n",[39,66609,66610,66619,66631,66635,66639,66652,66664,66668],{"__ignoreMap":264},[268,66611,66612,66614,66617],{"class":270,"line":271},[268,66613,275],{"class":274},[268,66615,66616],{"class":278}," handleClick",[268,66618,283],{"class":282},[268,66620,66621,66623,66625,66627,66629],{"class":270,"line":286},[268,66622,5556],{"class":282},[268,66624,1356],{"class":278},[268,66626,622],{"class":282},[268,66628,65556],{"class":289},[268,66630,628],{"class":282},[268,66632,66633],{"class":270,"line":296},[268,66634,314],{"class":282},[268,66636,66637],{"class":270,"line":311},[268,66638,5033],{"emptyLinePlaceholder":35},[268,66640,66641,66643,66645,66647,66649],{"class":270,"line":788},[268,66642,35734],{"class":282},[268,66644,35737],{"class":278},[268,66646,622],{"class":282},[268,66648,64737],{"class":289},[268,66650,66651],{"class":282},", handleClick);\n",[268,66653,66654,66656,66658,66660,66662],{"class":270,"line":1951},[268,66655,35734],{"class":282},[268,66657,35737],{"class":278},[268,66659,622],{"class":282},[268,66661,64737],{"class":289},[268,66663,66651],{"class":282},[268,66665,66666],{"class":270,"line":8955},[268,66667,5033],{"emptyLinePlaceholder":35},[268,66669,66670,66672,66674],{"class":270,"line":8966},[268,66671,35734],{"class":282},[268,66673,47403],{"class":278},[268,66675,794],{"class":282},[73,66677,66678,66679,19524],{},"How many times does ",[39,66680,65556],{},[23,66682,66684,66693,66702,66708],{"className":66683},[26],[28,66685,66687,66689,66690,66692],{"className":66686},[31],[33,66688],{"disabled":35,"type":36}," Once — ",[39,66691,35737],{}," silently ignores a call that has the same type, function reference, and capture\u002Foptions as one already registered",[28,66694,66696,66698,66699,66701],{"className":66695},[31],[33,66697],{"disabled":35,"type":36}," Twice — each ",[39,66700,35737],{}," call registers an independent listener",[28,66703,66705,66707],{"className":66704},[31],[33,66706],{"disabled":35,"type":36}," Zero — registering the same listener twice throws and prevents both from being added",[28,66709,66711,66713,66714],{"className":66710},[31],[33,66712],{"disabled":35,"type":36}," Twice, but only if the second call includes ",[39,66715,65676],{},[66,66717,66718,66720,66727],{},[69,66719,71],{},[73,66721,66722,66724,66725,66692],{},[76,66723,78],{}," A — Once — ",[39,66726,35737],{},[73,66728,66729,355,66731,66733,66734,66736,66737,66739,66740,66742,66743,66745,66746,66748,66749,66751,66752,66754],{},[76,66730,84],{},[76,66732,27162],{}," Per spec, a call to ",[39,66735,35737],{}," is treated as a no-op duplicate — and simply skipped — only when the event ",[39,66738,8623],{},", the exact function reference, and the ",[39,66741,64699],{}," flag all match an entry already registered on that element; here all three match ",[39,66744,36442],{},", so the second call adds nothing and ",[39,66747,65556],{}," logs once. This surprises developers who assume every call adds a new entry. It stops being a duplicate the moment any of the three differs — e.g., a different ",[39,66750,64699],{}," value, or a fresh arrow function created on each call, which is exactly why inline anonymous handlers ",[104,66753,11210],{}," get registered multiple times. Option B is the natural-but-wrong assumption; Option C invents an error that never happens.",[15,66756,66757,66782,66830],{},[18,66758,66760,66761,66763,66764,66767,66768,66771,66772,66774,66775,66778,66779,66781],{"id":66759},"q18-a-single-page-app-renders-a-large-canvas-chart-and-attaches-chartcanvasaddeventlistenermousemove-handlehover-where-handlehover-closes-over-a-large-dataset-array-when-the-user-navigates-away-the-component-removes-the-canvas-from-the-dom-via-chartcanvasremove-but-never-calls-removeeventlistener-whats-the-consequence","Q18. A single-page app renders a large ",[39,66762,62323],{}," chart and attaches ",[39,66765,66766],{},"chartCanvas.addEventListener(\"mousemove\", handleHover)",", where ",[39,66769,66770],{},"handleHover"," closes over a large ",[39,66773,40717],{}," array. When the user navigates away, the component removes the canvas from the DOM via ",[39,66776,66777],{},"chartCanvas.remove()"," but never calls ",[39,66780,65565],{},". What's the consequence?",[23,66783,66785,66791,66809,66819],{"className":66784},[26],[28,66786,66788,66790],{"className":66787},[31],[33,66789],{"disabled":35,"type":36}," None — once an element is detached from the DOM, all of its event listeners and closures are automatically garbage collected",[28,66792,66794,4396,66796,66799,66800,66802,66803,66805,66806,66808],{"className":66793},[31],[33,66795],{"disabled":35,"type":36},[39,66797,66798],{},"chartCanvas"," element — and the ",[39,66801,40717],{}," array ",[39,66804,66770],{}," closes over — can be kept alive in memory as long as something still references ",[39,66807,66798],{}," or the listener, even though it's no longer visible on the page",[28,66810,66812,66814,66815,66818],{"className":66811},[31],[33,66813],{"disabled":35,"type":36}," The browser throws an error on the next ",[39,66816,66817],{},"mousemove"," because the element is detached",[28,66820,66822,355,66824,66826,66827,66829],{"className":66821},[31],[33,66823],{"disabled":35,"type":36},[39,66825,66770],{}," stops being called, but ",[39,66828,40717],{}," is freed immediately regardless of other references",[66,66831,66832,66834,66846],{},[69,66833,71],{},[73,66835,66836,57091,66838,66799,66840,66802,66842,66805,66844,66808],{},[76,66837,78],{},[39,66839,66798],{},[39,66841,40717],{},[39,66843,66770],{},[39,66845,66798],{},[73,66847,66848,355,66850,66852,66853,66855,66856,66858,66859,137,66861,66863,66864,66866,66867,66869,66870,66872],{},[76,66849,84],{},[76,66851,65996],{}," Removing an element from the DOM does not make it eligible for garbage collection by itself — reclamation only happens once nothing reachable still references it. If ",[39,66854,66770],{}," (and its closure over ",[39,66857,40717],{},") is still attached to ",[39,66860,66798],{},[39,66862,66798],{}," itself is still referenced anywhere (a variable, a cache, another closure), the whole chain — including the large ",[39,66865,40717],{}," array — stays resident in memory, invisible on the page but present in the heap. This is the classic \"detached DOM node\" leak, visible in DevTools' heap snapshot tool. The fix is to call ",[39,66868,65565],{}," (or use a shared ",[39,66871,39934],{},") before or when discarding the element. Option A is the false assumption most developers make. Options C and D describe behavior that doesn't occur — detached elements keep functioning normally as long as they're referenced, and nothing is freed just because rendering stopped.",[15,66874,66875,66879,66919],{},[18,66876,66878],{"id":66877},"q19-a-table-renders-10000-rows-each-with-a-delete-button-and-rows-are-frequently-added-and-removed-via-re-renders-which-listener-strategy-is-best-practice-and-why","Q19. A table renders 10,000 rows, each with a \"Delete\" button, and rows are frequently added and removed via re-renders. Which listener strategy is best practice, and why?",[23,66880,66882,66891,66901,66911],{"className":66881},[26],[28,66883,66885,66887,66888,66890],{"className":66884},[31],[33,66886],{"disabled":35,"type":36}," Attach one ",[39,66889,35737],{}," to each \"Delete\" button — it's the most explicit and easiest to reason about",[28,66892,66894,66896,66897,66900],{"className":66893},[31],[33,66895],{"disabled":35,"type":36}," Use inline ",[39,66898,66899],{},"onclick=\"...\""," HTML attributes on each button so there's no JS wiring needed",[28,66902,66904,66906,66907,66910],{"className":66903},[31],[33,66905],{"disabled":35,"type":36}," Attach a single listener to the table (or its container) and use ",[39,66908,66909],{},"event.target.closest(\"button\")"," to identify the clicked row — avoids thousands of listener objects and needs no rewiring when rows change",[28,66912,66914,4353,66916,66918],{"className":66913},[31],[33,66915],{"disabled":35,"type":36},[39,66917,65676],{}," on each button's listener so memory is automatically reclaimed after the first click",[66,66920,66921,66923,66930],{},[69,66922,71],{},[73,66924,66925,66927,66928,66910],{},[76,66926,78],{}," C — Attach a single listener to the table (or its container) and use ",[39,66929,66909],{},[73,66931,66932,355,66934,66936,66937,66940],{},[76,66933,84],{},[76,66935,65996],{}," With 10,000 per-row listeners, both memory and setup cost scale linearly with row count, and every re-render that adds or removes rows must carefully add\u002Fremove matching listeners or risk leaking them. A single delegated listener on a stable ancestor costs one listener object regardless of row count, automatically covers rows added later (bubbling doesn't care when a descendant was created), and needs zero cleanup when rows are removed. Option A is exactly the anti-pattern delegation exists to solve. Option B mixes markup with behavior, supports only one handler per element, and still costs one binding per row. Option D is irrelevant — ",[39,66938,66939],{},"once: true"," only affects a single button's own first click and does nothing to address the scaling problem.",[15,66942,66943,66952,67083,67085,67120],{"language":247},[18,66944,66946,66947,66949,66950,10728],{"id":66945},"q20-given-child-is-nested-inside-parent","Q20. Given ",[39,66948,66161],{}," is nested inside ",[39,66951,66165],{},[257,66953,66954],{"language":247},[260,66955,66957],{"className":262,"code":66956,"language":247,"meta":264,"style":264},"child.addEventListener(\"click\", (e) => {\n  console.log(\"child A\");\n  e.stopImmediatePropagation();\n});\nchild.addEventListener(\"click\", () => {\n  console.log(\"child B\");\n});\nparent.addEventListener(\"click\", () => {\n  console.log(\"parent\");\n});\n\nchild.click();\n",[39,66958,66959,66979,66992,67001,67005,67021,67034,67038,67054,67067,67071,67075],{"__ignoreMap":264},[268,66960,66961,66963,66965,66967,66969,66971,66973,66975,66977],{"class":270,"line":271},[268,66962,66262],{"class":282},[268,66964,35737],{"class":278},[268,66966,622],{"class":282},[268,66968,64737],{"class":289},[268,66970,65237],{"class":282},[268,66972,40624],{"class":1222},[268,66974,6131],{"class":282},[268,66976,9414],{"class":274},[268,66978,9914],{"class":282},[268,66980,66981,66983,66985,66987,66990],{"class":270,"line":286},[268,66982,5556],{"class":282},[268,66984,1356],{"class":278},[268,66986,622],{"class":282},[268,66988,66989],{"class":289},"\"child A\"",[268,66991,628],{"class":282},[268,66993,66994,66997,66999],{"class":270,"line":296},[268,66995,66996],{"class":282},"  e.",[268,66998,64941],{"class":278},[268,67000,794],{"class":282},[268,67002,67003],{"class":270,"line":311},[268,67004,20047],{"class":282},[268,67006,67007,67009,67011,67013,67015,67017,67019],{"class":270,"line":788},[268,67008,66262],{"class":282},[268,67010,35737],{"class":278},[268,67012,622],{"class":282},[268,67014,64737],{"class":289},[268,67016,35745],{"class":282},[268,67018,9414],{"class":274},[268,67020,9914],{"class":282},[268,67022,67023,67025,67027,67029,67032],{"class":270,"line":1951},[268,67024,5556],{"class":282},[268,67026,1356],{"class":278},[268,67028,622],{"class":282},[268,67030,67031],{"class":289},"\"child B\"",[268,67033,628],{"class":282},[268,67035,67036],{"class":270,"line":8955},[268,67037,20047],{"class":282},[268,67039,67040,67042,67044,67046,67048,67050,67052],{"class":270,"line":8966},[268,67041,66177],{"class":282},[268,67043,35737],{"class":278},[268,67045,622],{"class":282},[268,67047,64737],{"class":289},[268,67049,35745],{"class":282},[268,67051,9414],{"class":274},[268,67053,9914],{"class":282},[268,67055,67056,67058,67060,67062,67065],{"class":270,"line":8974},[268,67057,5556],{"class":282},[268,67059,1356],{"class":278},[268,67061,622],{"class":282},[268,67063,67064],{"class":289},"\"parent\"",[268,67066,628],{"class":282},[268,67068,67069],{"class":270,"line":8985},[268,67070,20047],{"class":282},[268,67072,67073],{"class":270,"line":8990},[268,67074,5033],{"emptyLinePlaceholder":35},[268,67076,67077,67079,67081],{"class":270,"line":8997},[268,67078,66262],{"class":282},[268,67080,47403],{"class":278},[268,67082,794],{"class":282},[73,67084,66271],{},[23,67086,67088,67094,67100,67106],{"className":67087},[26],[28,67089,67091,67093],{"className":67090},[31],[33,67092],{"disabled":35,"type":36}," child A, child B, parent",[28,67095,67097,67099],{"className":67096},[31],[33,67098],{"disabled":35,"type":36}," child A, parent — sibling listeners on the same element aren't affected, only propagation is stopped",[28,67101,67103,67105],{"className":67102},[31],[33,67104],{"disabled":35,"type":36}," child B, parent — listeners run in reverse registration order, so B always wins the race before A calls stop",[28,67107,67109,67111,67112,67114,67115,67117,67118],{"className":67108},[31],[33,67110],{"disabled":35,"type":36}," child A only — ",[39,67113,64984],{}," cancels both the remaining sibling listener on ",[39,67116,66161],{}," and propagation up to ",[39,67119,66165],{},[66,67121,67122,67124,67135],{},[69,67123,71],{},[73,67125,67126,67128,67129,67114,67131,67117,67133],{},[76,67127,78],{}," D — child A only — ",[39,67130,64984],{},[39,67132,66161],{},[39,67134,66165],{},[73,67136,67137,355,67139,355,67141,67143,67144,67146,67147,67149,67150,67152,67153,67155,67156,67158],{},[76,67138,84],{},[76,67140,27162],{},[39,67142,64984],{}," is the strictest of the three propagation controls: like ",[39,67145,64563],{},", it halts further travel to ancestors, but it additionally prevents any other listener still queued on the ",[104,67148,22779],{}," element from running at all. Since \"child A\" runs first (listeners fire in registration order) and calls it immediately, \"child B\" never fires, and the event never reaches ",[39,67151,66165],{},"'s listener either. Option A ignores that ",[39,67154,64984],{}," was called. Option B describes plain ",[39,67157,64563],{},"'s behavior, not the stricter method actually used here — the exact distinction this question tests. Option C invents a \"reverse order\" execution rule that doesn't exist; listeners always run in the order they were registered.",[2107,67160,67161],{},"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 pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}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 .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}",{"title":264,"searchDepth":286,"depth":286,"links":67163},[67164,67166,67168,67170,67172,67174,67176,67178,67180,67181,67183,67184,67186,67187,67189,67191,67193,67194,67196,67197],{"id":64551,"depth":296,"text":67165},"Q1. In the default event flow model used by the DOM, what happens when a user clicks a deeply nested \u003Cspan> inside several wrapping \u003Cdiv> elements, assuming no listener calls stopPropagation()?",{"id":64634,"depth":296,"text":67167},"Q2. By default, element.addEventListener('click', handler) registers the handler for which phase of the event flow?",{"id":64711,"depth":296,"text":67169},"Q3. Given nested elements where inner is a direct child of outer, and the following listeners:",{"id":64923,"depth":296,"text":67171},"Q4. A \u003Cbutton> has two separate click listeners attached via addEventListener. The first one calls event.stopPropagation(); the second one does nothing special. Both are registered directly on the button (no capture option, no stopImmediatePropagation). When the button is clicked, what happens to the second listener?",{"id":65018,"depth":296,"text":67173},"Q5. Calling event.preventDefault() inside a click handler on an \u003Ca href=\"\u002Fpage\"> link does which of the following?",{"id":65102,"depth":296,"text":67175},"Q6. A \u003Cul> contains 500 \u003Cli> items that get added and removed dynamically. Which approach is most robust for handling clicks on any \u003Cli>?",{"id":65212,"depth":296,"text":67177},"Q7. A delegated click listener on a \u003Cul id=\"list\"> is written as:",{"id":65426,"depth":296,"text":67179},"Q8. A \u003Cdiv id=\"outer\"> contains a nested \u003Cbutton>. A single click listener is attached to #outer. When a user clicks the button, inside that listener event.target and event.currentTarget are compared. Which statement is correct?",{"id":65525,"depth":296,"text":65526},{"id":65672,"depth":296,"text":67182},"Q10. What does passing { once: true } as the options argument to addEventListener do?",{"id":65745,"depth":296,"text":65746},{"id":65939,"depth":296,"text":67185},"Q12. Why would you add { passive: true } to a touchstart or wheel event listener that never calls preventDefault()?",{"id":66024,"depth":296,"text":66025},{"id":66157,"depth":296,"text":67188},"Q14. Given child is a descendant of parent:",{"id":66404,"depth":296,"text":67190},"Q15. A team wants to detect when focus leaves a form's container entirely, using event delegation with a single listener on the \u003Cform> element. Which event should they use, and why?",{"id":66501,"depth":296,"text":67192},"Q16. A script runs, in order: btn.onclick = fnA; then btn.onclick = fnB; then btn.addEventListener(\"click\", fnC). When the button is clicked, which handlers run, and in what order?",{"id":66601,"depth":296,"text":66602},{"id":66759,"depth":296,"text":67195},"Q18. A single-page app renders a large \u003Ccanvas> chart and attaches chartCanvas.addEventListener(\"mousemove\", handleHover), where handleHover closes over a large dataset array. When the user navigates away, the component removes the canvas from the DOM via chartCanvas.remove() but never calls removeEventListener. What's the consequence?",{"id":66877,"depth":296,"text":66878},{"id":66945,"depth":296,"text":67198},"Q20. Given child is nested inside parent:",{},"\u002Fjs\u002F20-events",{"title":64541,"description":264},"js\u002F20-events","lZ6yPmqvskvo2XFn3ltMWA-gOtUU92byhInTwKUHSNw",{"id":67205,"title":67206,"body":67207,"description":264,"extension":2144,"meta":69411,"navigation":35,"path":69412,"seo":69413,"stem":69414,"__hash__":69415},"content\u002Fjs\u002F21-web-storage-and-apis.md","21 — Web Storage & APIs",{"type":8,"value":67208,"toc":69373},[67209,67212,67304,67395,67543,67623,67715,67881,67986,68065,68138,68212,68270,68415,68545,68700,68764,68854,69059,69120,69298,69370],[11,67210,67206],{"id":67211},"_21-web-storage-apis",[15,67213,67214,67224,67269],{},[18,67215,67217,67218,20968,67221,1685],{"id":67216},"q1-which-statement-correctly-distinguishes-localstorage-from-sessionstorage","Q1. Which statement correctly distinguishes ",[39,67219,67220],{},"localStorage",[39,67222,67223],{},"sessionStorage",[23,67225,67227,67238,67249,67258],{"className":67226},[26],[28,67228,67230,355,67232,67234,67235,67237],{"className":67229},[31],[33,67231],{"disabled":35,"type":36},[39,67233,67220],{}," data is cleared when the browser closes; ",[39,67236,67223],{}," persists indefinitely",[28,67239,67241,355,67243,67245,67246,67248],{"className":67240},[31],[33,67242],{"disabled":35,"type":36},[39,67244,67220],{}," persists across browser restarts until explicitly cleared; ",[39,67247,67223],{}," is cleared when the tab closes",[28,67250,67252,67254,67255,67257],{"className":67251},[31],[33,67253],{"disabled":35,"type":36}," Both persist indefinitely, but ",[39,67256,67223],{}," is shared across all tabs of the same origin",[28,67259,67261,355,67263,67265,67266,67268],{"className":67260},[31],[33,67262],{"disabled":35,"type":36},[39,67264,67220],{}," is per-tab; ",[39,67267,67223],{}," is shared across the whole browser",[66,67270,67271,67273,67281],{},[69,67272,71],{},[73,67274,67275,1727,67277,67245,67279,67248],{},[76,67276,78],{},[39,67278,67220],{},[39,67280,67223],{},[73,67282,67283,355,67285,67287,67288,446,67291,67294,67295,67297,67298,67300,67301,67303],{},[76,67284,84],{},[39,67286,67220],{}," has no expiration and survives browser restarts, page reloads, and navigation — it's only removed by explicit ",[39,67289,67290],{},"removeItem",[39,67292,67293],{},"clear()",", the user clearing site data, or the browser evicting it. ",[39,67296,67223],{}," is scoped to a single tab's lifetime: closing that tab destroys it, even though a page reload within the same tab preserves it. Option A inverts the two. Option C is wrong because ",[39,67299,67223],{}," is explicitly ",[104,67302,95],{}," shared between tabs, even same-origin ones opened to the same URL — each tab gets its own isolated storage area. Option D is backwards.",[15,67305,67306,67315,67346],{},[18,67307,67309,67310,67312,67313,8691],{"id":67308},"q2-a-team-stores-a-jwt-auth-token-in-a-cookie-versus-localstorage-which-behavior-is-unique-to-cookies-not-localstorage","Q2. A team stores a JWT auth token in a cookie versus ",[39,67311,67220],{},". Which behavior is unique to cookies (not ",[39,67314,67220],{},[23,67316,67318,67324,67330,67340],{"className":67317},[26],[28,67319,67321,67323],{"className":67320},[31],[33,67322],{"disabled":35,"type":36}," The value is limited to strings",[28,67325,67327,67329],{"className":67326},[31],[33,67328],{"disabled":35,"type":36}," The value is automatically sent with every same-origin HTTP request to the server (unless flagged otherwise)",[28,67331,67333,67335,67336,67339],{"className":67332},[31],[33,67334],{"disabled":35,"type":36}," The value can be read via JavaScript's ",[39,67337,67338],{},"document.cookie"," or storage APIs",[28,67341,67343,67345],{"className":67342},[31],[33,67344],{"disabled":35,"type":36}," The value is scoped to a single origin",[66,67347,67348,67350,67355],{},[69,67349,71],{},[73,67351,67352,67354],{},[76,67353,78],{}," B — The value is automatically sent with every same-origin HTTP request to the server (unless flagged otherwise)",[73,67356,67357,67359,67360,42,67363,42,67366,137,67369,67372,67373,67375,67376,67379,67380,67382,67383,67386,67387,67389,67390,446,67392,67394],{},[76,67358,84],{}," Cookies are attached to outgoing HTTP requests automatically by the browser (governed by ",[39,67361,67362],{},"Domain",[39,67364,67365],{},"Path",[39,67367,67368],{},"SameSite",[39,67370,67371],{},"Secure"," attributes), which is why they're used for session identifiers the server needs to see. ",[39,67374,67220],{}," is never transmitted automatically — a page must explicitly read it and attach it (e.g., as an ",[39,67377,67378],{},"Authorization"," header). Option A is wrong because both cookies and ",[39,67381,67220],{}," only store strings. Option C is wrong because both are readable via JS unless a cookie is marked ",[39,67384,67385],{},"HttpOnly",", which then hides it from ",[39,67388,67338],{},". Option D is wrong because both are origin-scoped (cookies also add ",[39,67391,67362],{},[39,67393,67365],{}," scoping on top).",[15,67396,67397,67401,67462,67498],{"language":247},[18,67398,67400],{"id":67399},"q3-what-happens-when-you-run-the-following-code","Q3. What happens when you run the following code?",[257,67402,67403],{"language":247},[260,67404,67406],{"className":262,"code":67405,"language":247,"meta":264,"style":264},"const user = { name: \"Ravi\", age: 30 };\nlocalStorage.setItem(\"user\", user);\nconsole.log(localStorage.getItem(\"user\"));\n",[39,67407,67408,67428,67444],{"__ignoreMap":264},[268,67409,67410,67412,67414,67416,67418,67421,67424,67426],{"class":270,"line":271},[268,67411,243],{"class":274},[268,67413,4071],{"class":305},[268,67415,616],{"class":274},[268,67417,4076],{"class":282},[268,67419,67420],{"class":289},"\"Ravi\"",[268,67422,67423],{"class":282},", age: ",[268,67425,24274],{"class":305},[268,67427,2790],{"class":282},[268,67429,67430,67433,67436,67438,67441],{"class":270,"line":286},[268,67431,67432],{"class":282},"localStorage.",[268,67434,67435],{"class":278},"setItem",[268,67437,622],{"class":282},[268,67439,67440],{"class":289},"\"user\"",[268,67442,67443],{"class":282},", user);\n",[268,67445,67446,67448,67450,67453,67456,67458,67460],{"class":270,"line":296},[268,67447,1353],{"class":282},[268,67449,1356],{"class":278},[268,67451,67452],{"class":282},"(localStorage.",[268,67454,67455],{"class":278},"getItem",[268,67457,622],{"class":282},[268,67459,67440],{"class":289},[268,67461,4818],{"class":282},[23,67463,67465,67474,67482,67491],{"className":67464},[26],[28,67466,67468,30037,67470,67473],{"className":67467},[31],[33,67469],{"disabled":35,"type":36},[39,67471,67472],{},"{ name: \"Ravi\", age: 30 }"," as a live object",[28,67475,67477,1271,67479,67481],{"className":67476},[31],[33,67478],{"disabled":35,"type":36},[39,67480,827],{}," because objects can't be stored",[28,67483,67485,67487,67488],{"className":67484},[31],[33,67486],{"disabled":35,"type":36}," It logs the string ",[39,67489,67490],{},"\"[object Object]\"",[28,67492,67494,30037,67496],{"className":67493},[31],[33,67495],{"disabled":35,"type":36},[39,67497,833],{},[66,67499,67500,67502,67509],{},[69,67501,71],{},[73,67503,67504,67506,67507],{},[76,67505,78],{}," C — It logs the string ",[39,67508,67490],{},[73,67510,67511,67513,67514,67516,67517,67520,67521,3295,67523,67526,67527,67529,67530,67532,67533,67535,67536,67539,67540,67542],{},[76,67512,84],{}," The Web Storage API only stores strings. ",[39,67515,67435],{}," coerces any non-string value using ",[39,67518,67519],{},"String(value)",", and the default string conversion of a plain object is ",[39,67522,67490],{},[39,67524,67525],{},"Object.prototype.toString","), silently discarding the actual data. ",[76,67528,930],{}," always ",[39,67531,20555],{}," before storing and ",[39,67534,22423],{}," after reading — there's no error to warn you otherwise, which makes this a common silent-data-loss bug. Option B is tempting because it feels like it ",[104,67537,67538],{},"should"," error, but ",[39,67541,67435],{}," never validates the value's type, it just stringifies it.",[15,67544,67545,67556,67588],{},[18,67546,67548,67549,67552,67553,67555],{"id":67547},"q4-when-does-the-storage-event-fire-on-the-window-object","Q4. When does the ",[39,67550,67551],{},"storage"," event fire on the ",[39,67554,189],{}," object?",[23,67557,67559,67565,67571,67582],{"className":67558},[26],[28,67560,67562,67564],{"className":67561},[31],[33,67563],{"disabled":35,"type":36}," In every tab, including the one that made the change",[28,67566,67568,67570],{"className":67567},[31],[33,67569],{"disabled":35,"type":36}," Only in other tabs\u002Fwindows of the same origin, not the tab that made the change",[28,67572,67574,67576,67577,67579,67580],{"className":67573},[31],[33,67575],{"disabled":35,"type":36}," Only when ",[39,67578,67223],{}," changes, never for ",[39,67581,67220],{},[28,67583,67585,67587],{"className":67584},[31],[33,67586],{"disabled":35,"type":36}," Only when the page is reloaded",[66,67589,67590,67592,67597],{},[69,67591,71],{},[73,67593,67594,67596],{},[76,67595,78],{}," B — Only in other tabs\u002Fwindows of the same origin, not the tab that made the change",[73,67598,67599,4396,67601,67603,67604,67606,67607,67609,67610,67612,67613,446,67615,446,67617,67619,67620,67622],{},[76,67600,84],{},[39,67602,67551],{}," event is the browser's cross-tab notification mechanism for ",[39,67605,67220],{}," changes — it fires on ",[39,67608,189],{}," in every ",[104,67611,33735],{}," document sharing that origin, but never in the document that actually called ",[39,67614,67435],{},[39,67616,67290],{},[39,67618,67293],{},". This is a common gotcha when trying to sync UI state within the same tab: you must update that tab's UI manually since it won't receive its own event. Option A is the tempting-but-wrong assumption. Option C is wrong — ",[39,67621,67223],{}," changes don't fire the storage event at all across tabs since it isn't shared. Option D is unrelated to the trigger condition.",[15,67624,67625,67633,67670],{},[18,67626,67628,67629,67632],{"id":67627},"q5-what-does-fetch-return","Q5. What does ",[39,67630,67631],{},"fetch()"," return?",[23,67634,67636,67642,67653,67661],{"className":67635},[26],[28,67637,67639,67641],{"className":67638},[31],[33,67640],{"disabled":35,"type":36}," The parsed JSON body directly",[28,67643,67645,812,67647,54616,67649,67652],{"className":67644},[31],[33,67646],{"disabled":35,"type":36},[39,67648,91],{},[39,67650,67651],{},"Response"," object",[28,67654,67656,812,67658,67660],{"className":67655},[31],[33,67657],{"disabled":35,"type":36},[39,67659,67651],{}," object synchronously",[28,67662,67664,54637,67666,67669],{"className":67663},[31],[33,67665],{"disabled":35,"type":36},[39,67667,67668],{},"XMLHttpRequest"," instance",[66,67671,67672,67674,67682],{},[69,67673,71],{},[73,67675,67676,853,67678,54616,67680,67652],{},[76,67677,78],{},[39,67679,91],{},[39,67681,67651],{},[73,67683,67684,355,67686,67689,67690,23941,67693,67695,67696,99,67699,67702,67703,67705,67706,67708,67709,67711,67712,67714],{},[76,67685,84],{},[39,67687,67688],{},"fetch(url)"," immediately returns a ",[39,67691,67692],{},"Promise\u003CResponse>",[39,67694,67651],{}," object wraps headers, status, and a body stream — you must call a method like ",[39,67697,67698],{},".json()",[39,67700,67701],{},".text()"," (which itself returns another ",[39,67704,91],{},") to extract the actual payload, meaning a full fetch-and-parse is typically two ",[39,67707,12304],{},"s. Option A is a common beginner shortcut mistake — assuming ",[39,67710,47324],{}," parses JSON for you like some HTTP client libraries do. Option C ignores that network calls are inherently asynchronous. Option D confuses ",[39,67713,47324],{}," with the older callback\u002Fevent-based API it was designed to replace.",[15,67716,67717,67727,67786,67795,67831],{"language":247},[18,67718,67720,67721,67723,67724,67726],{"id":67719},"q6-a-developer-writes-the-following-and-is-confused-why-the-catch-block-never-runs-for-a-404-response","Q6. A developer writes the following and is confused why the ",[39,67722,12488],{}," block never runs for a ",[39,67725,58199],{}," response:",[257,67728,67729],{"language":247},[260,67730,67732],{"className":262,"code":67731,"language":247,"meta":264,"style":264},"fetch(\"\u002Fapi\u002Fusers\u002F999\")\n  .then(res => res.json())\n  .catch(err => console.error(\"Request failed:\", err));\n",[39,67733,67734,67745,67763],{"__ignoreMap":264},[268,67735,67736,67738,67740,67743],{"class":270,"line":271},[268,67737,47324],{"class":278},[268,67739,622],{"class":282},[268,67741,67742],{"class":289},"\"\u002Fapi\u002Fusers\u002F999\"",[268,67744,20702],{"class":282},[268,67746,67747,67749,67751,67753,67755,67757,67759,67761],{"class":270,"line":286},[268,67748,41697],{"class":282},[268,67750,47505],{"class":278},[268,67752,622],{"class":282},[268,67754,52237],{"class":1222},[268,67756,14969],{"class":274},[268,67758,53902],{"class":282},[268,67760,1751],{"class":278},[268,67762,53907],{"class":282},[268,67764,67765,67767,67769,67771,67773,67775,67777,67779,67781,67784],{"class":270,"line":296},[268,67766,41697],{"class":282},[268,67768,12488],{"class":278},[268,67770,622],{"class":282},[268,67772,48255],{"class":1222},[268,67774,14969],{"class":274},[268,67776,9417],{"class":282},[268,67778,18282],{"class":278},[268,67780,622],{"class":282},[268,67782,67783],{"class":289},"\"Request failed:\"",[268,67785,59599],{"class":282},[73,67787,67788,67789,67791,67792,67794],{},"Why doesn't a ",[39,67790,58199],{}," trigger the ",[39,67793,12488],{}," block?",[23,67796,67798,67806,67814,67822],{"className":67797},[26],[28,67799,67801,355,67803,67805],{"className":67800},[31],[33,67802],{"disabled":35,"type":36},[39,67804,47324],{}," only rejects on network failure (e.g., DNS error, offline), not on HTTP error status codes like 404 or 500",[28,67807,67809,355,67811,67813],{"className":67808},[31],[33,67810],{"disabled":35,"type":36},[39,67812,58199],{}," responses are automatically retried, so the error is swallowed",[28,67815,67817,355,67819,67821],{"className":67816},[31],[33,67818],{"disabled":35,"type":36},[39,67820,67698],{}," silently ignores error status codes",[28,67823,67825,67827,67828,67830],{"className":67824},[31],[33,67826],{"disabled":35,"type":36}," This is a bug in the code; ",[39,67829,47324],{}," should reject but doesn't due to a browser inconsistency",[66,67832,67833,67835,67841],{},[69,67834,71],{},[73,67836,67837,3459,67839,67805],{},[76,67838,78],{},[39,67840,47324],{},[73,67842,67843,67845,67846,67848,67849,446,67852,67855,67856,67859,67860,67862,67863,67866,67867,67870,67871,67873,67874,67876,67877,67880],{},[76,67844,84],{}," By design, ",[39,67847,47324],{},"'s promise only rejects for genuine network-level failures — a ",[39,67850,67851],{},"4xx",[39,67853,67854],{},"5xx"," response is still a ",[104,67857,67858],{},"successful"," HTTP exchange as far as ",[39,67861,47324],{}," is concerned, so it resolves normally with ",[39,67864,67865],{},"response.ok === false"," and the appropriate ",[39,67868,67869],{},"response.status",". This is one of the most common ",[39,67872,47324],{}," gotchas and a real source of silently-swallowed errors in production: code that assumes \"no exception means success\" will happily try to parse an error page's body as JSON. ",[76,67875,365],{}," the fix is to explicitly check ",[39,67878,67879],{},"if (!res.ok) throw new Error(...)"," before parsing. Option B and C are fabricated behaviors; option D incorrectly frames intentional spec behavior as a bug.",[15,67882,67883,67894,67931],{},[18,67884,67886,67887,7728,67890,67893],{"id":67885},"q7-what-is-the-key-advantage-of-structuredcloneobj-over-jsonparsejsonstringifyobj-for-deep-copying-data","Q7. What is the key advantage of ",[39,67888,67889],{},"structuredClone(obj)",[39,67891,67892],{},"JSON.parse(JSON.stringify(obj))"," for deep-copying data?",[23,67895,67897,67903,67919,67925],{"className":67896},[26],[28,67898,67900,67902],{"className":67899},[31],[33,67901],{"disabled":35,"type":36}," It is always faster in every browser",[28,67904,67906,67908,67909,42,67911,42,67913,137,67915,67918],{"className":67905},[31],[33,67907],{"disabled":35,"type":36}," It can clone richer types like ",[39,67910,2669],{},[39,67912,2672],{},[39,67914,9306],{},[39,67916,67917],{},"ArrayBuffer"," correctly, and preserves circular references",[28,67920,67922,67924],{"className":67921},[31],[33,67923],{"disabled":35,"type":36}," It can clone functions and DOM nodes without error",[28,67926,67928,67930],{"className":67927},[31],[33,67929],{"disabled":35,"type":36}," It converts numbers to strings for safe transport",[66,67932,67933,67935,67948],{},[69,67934,71],{},[73,67936,67937,67939,67940,42,67942,42,67944,137,67946,67918],{},[76,67938,78],{}," B — It can clone richer types like ",[39,67941,2669],{},[39,67943,2672],{},[39,67945,9306],{},[39,67947,67917],{},[73,67949,67950,355,67952,67954,67955,67957,67958,446,67960,7083,67962,42,67964,67966,67967,3277,67969,67971,67972,67975,67976,67978,67979,67982,67983,67985],{},[76,67951,84],{},[39,67953,20555],{}," silently mangles many types: a ",[39,67956,2669],{}," becomes a string, a ",[39,67959,2672],{},[39,67961,9306],{},[39,67963,2328],{},[39,67965,833],{}," values are dropped, and a circular reference throws a ",[39,67968,827],{},[39,67970,22322],{}," uses the structured clone algorithm (the same one browsers use for ",[39,67973,67974],{},"postMessage","), which correctly round-trips these types and can even clone objects containing circular references back into an equivalent circular structure. Option C is the tempting trap — ",[39,67977,22322],{}," explicitly ",[104,67980,67981],{},"cannot"," clone functions, DOM nodes, or objects with property accessors\u002Fprototypes beyond plain data, and throws a ",[39,67984,22453],{}," if you try. Option A overstates it — performance varies by payload shape. Option D is fabricated.",[15,67987,67988,67996,68035],{},[18,67989,67991,67992,67995],{"id":67990},"q8-a-page-stores-several-megabytes-of-data-over-time-via-repeated-localstoragesetitem-calls-until-the-origins-quota-commonly-510mb-depending-on-browser-is-exceeded-what-happens-on-the-call-that-exceeds-it","Q8. A page stores several megabytes of data over time via repeated ",[39,67993,67994],{},"localStorage.setItem"," calls until the origin's quota (commonly ~5–10MB depending on browser) is exceeded. What happens on the call that exceeds it?",[23,67997,67999,68005,68018,68029],{"className":67998},[26],[28,68000,68002,68004],{"className":68001},[31],[33,68003],{"disabled":35,"type":36}," The call silently does nothing and older data is evicted automatically",[28,68006,68008,1271,68010,68013,68014,68017],{"className":68007},[31],[33,68009],{"disabled":35,"type":36},[39,68011,68012],{},"DOMException"," (commonly named ",[39,68015,68016],{},"QuotaExceededError",") synchronously",[28,68019,68021,4396,68023,68025,68026,68028],{"className":68020},[31],[33,68022],{"disabled":35,"type":36},[39,68024,91],{}," returned by ",[39,68027,67435],{}," rejects",[28,68030,68032,68034],{"className":68031},[31],[33,68033],{"disabled":35,"type":36}," The browser prompts the user to grant more space",[66,68036,68037,68039,68047],{},[69,68038,71],{},[73,68040,68041,1300,68043,68013,68045,68017],{},[76,68042,78],{},[39,68044,68012],{},[39,68046,68016],{},[73,68048,68049,355,68051,68053,68054,68056,68057,68059,68060,50319,68062,68064],{},[76,68050,84],{},[39,68052,67994],{}," is a synchronous API, so quota overflow is reported synchronously by throwing — it does not return a rejected promise (there is no promise at all) and it does not silently evict old data like an LRU cache would. ",[76,68055,365],{}," production code writing to ",[39,68058,67220],{}," in a loop or with user-generated content should wrap ",[39,68061,67435],{},[39,68063,2081],{}," to handle this gracefully instead of crashing the calling code. Option A describes cache-eviction behavior that Web Storage doesn't have. Option C is tempting because so many modern Web APIs are promise-based, but Web Storage predates that convention and stayed synchronous. Option D describes permission-prompt UX that some other APIs (like persistent storage) use, not quota overflow itself.",[15,68066,68067,68079,68114],{},[18,68068,68070,68071,68073,68074,99,68076,68078],{"id":68069},"q9-why-is-heavy-repeated-use-of-localstorage-inside-a-hot-code-path-eg-on-every-scroll-or-mousemove-event-considered-a-performance-anti-pattern","Q9. Why is heavy, repeated use of ",[39,68072,67220],{}," inside a hot code path (e.g., on every ",[39,68075,62345],{},[39,68077,66817],{}," event) considered a performance anti-pattern?",[23,68080,68082,68090,68098,68106],{"className":68081},[26],[28,68083,68085,355,68087,68089],{"className":68084},[31],[33,68086],{"disabled":35,"type":36},[39,68088,67220],{}," operations are always executed on a background thread, so they don't block, but they leak memory over time",[28,68091,68093,355,68095,68097],{"className":68092},[31],[33,68094],{"disabled":35,"type":36},[39,68096,67220],{}," reads and writes are synchronous and block the main thread, so frequent calls can cause jank",[28,68099,68101,355,68103,68105],{"className":68100},[31],[33,68102],{"disabled":35,"type":36},[39,68104,67220],{}," triggers a full page reload on every write",[28,68107,68109,355,68111,68113],{"className":68108},[31],[33,68110],{"disabled":35,"type":36},[39,68112,67220],{}," writes are asynchronous but rate-limited to one per second by the spec",[66,68115,68116,68118,68124],{},[69,68117,71],{},[73,68119,68120,1727,68122,68097],{},[76,68121,78],{},[39,68123,67220],{},[73,68125,68126,4715,68128,68130,68131,68133,68134,68137],{},[76,68127,84],{},[39,68129,67220],{}," read\u002Fwrite happens synchronously on the main thread and, depending on the browser, may involve disk I\u002FO — calling it dozens of times per second inside a scroll or resize handler competes directly with rendering work and can visibly stutter the UI. ",[76,68132,438],{}," the idiomatic fix is to debounce\u002Fthrottle the writes, batch them, or move to ",[39,68135,68136],{},"IndexedDB"," (which is asynchronous) for high-frequency or large-payload storage needs. Option A and D invent async\u002Fthreading behavior Web Storage doesn't have. Option C is simply false — writes don't reload the page.",[15,68139,68140,68147,68180],{},[18,68141,68143,68144,68146],{"id":68142},"q10-a-user-opens-the-same-web-app-in-two-separate-tabs-they-interact-with-tab-a-which-writes-to-sessionstorage-what-does-tab-b-see","Q10. A user opens the same web app in two separate tabs. They interact with Tab A, which writes to ",[39,68145,67223],{},". What does Tab B see?",[23,68148,68150,68159,68168,68174],{"className":68149},[26],[28,68151,68153,68155,68156,68158],{"className":68152},[31],[33,68154],{"disabled":35,"type":36}," Tab B sees the same ",[39,68157,67223],{}," values immediately, since both tabs share the same origin",[28,68160,68162,68164,68165,68167],{"className":68161},[31],[33,68163],{"disabled":35,"type":36}," Tab B has its own independent ",[39,68166,67223],{},", unaffected by Tab A's writes",[28,68169,68171,68173],{"className":68170},[31],[33,68172],{"disabled":35,"type":36}," Tab B sees the values only after Tab A is closed",[28,68175,68177,68179],{"className":68176},[31],[33,68178],{"disabled":35,"type":36}," Tab B sees the values only after both tabs are refreshed",[66,68181,68182,68184,68191],{},[69,68183,71],{},[73,68185,68186,68188,68189,68167],{},[76,68187,78],{}," B — Tab B has its own independent ",[39,68190,67223],{},[73,68192,68193,4030,68195,68197,68198,68200,68201,68203,68204,68206,68207,68209,68210,462],{},[76,68194,84],{},[39,68196,67220],{},", which is shared across every tab\u002Fwindow of the same origin, ",[39,68199,67223],{}," is scoped per top-level browsing context (roughly: per tab). Even two tabs pointed at the identical URL of the identical origin get separate, isolated ",[39,68202,67223],{}," areas — the only exception is that a duplicated tab (e.g., \"duplicate tab\" from the browser menu) inherits a copy of the original's ",[39,68205,67223],{}," at the moment of duplication. Option A confuses it with ",[39,68208,67220],{},"'s sharing behavior. Options C and D fabricate a sync mechanism that doesn't exist for ",[39,68211,67223],{},[15,68213,68214,68218,68245],{},[18,68215,68217],{"id":68216},"q11-why-do-teams-generally-avoid-putting-large-amounts-of-data-in-cookies-beyond-the-4kb-per-cookie-size-limit","Q11. Why do teams generally avoid putting large amounts of data in cookies, beyond the ~4KB per-cookie size limit?",[23,68219,68221,68227,68233,68239],{"className":68220},[26],[28,68222,68224,68226],{"className":68223},[31],[33,68225],{"disabled":35,"type":36}," Cookies are readable by any origin, not just the one that set them",[28,68228,68230,68232],{"className":68229},[31],[33,68231],{"disabled":35,"type":36}," Every cookie for a domain is sent with every matching HTTP request to that domain, adding latency and bandwidth overhead to unrelated requests (e.g., image loads)",[28,68234,68236,68238],{"className":68235},[31],[33,68237],{"disabled":35,"type":36}," Cookies cannot store string data, only numbers",[28,68240,68242,68244],{"className":68241},[31],[33,68243],{"disabled":35,"type":36}," Browsers cap total cookies per domain at 3",[66,68246,68247,68249,68254],{},[69,68248,71],{},[73,68250,68251,68253],{},[76,68252,78],{}," B — Every cookie for a domain is sent with every matching HTTP request to that domain, adding latency and bandwidth overhead to unrelated requests (e.g., image loads)",[73,68255,68256,68258,68259,68261,68262,446,68264,68266,68267,68269],{},[76,68257,84],{}," Because the browser auto-attaches all applicable cookies to ",[104,68260,37208],{}," request to that origin\u002Fpath — including static asset requests like images and stylesheets — bloated cookies add real, repeated overhead to traffic that has nothing to do with the cookie's purpose. This is exactly why session identifiers (small) belong in cookies while bulk data belongs in ",[39,68263,67220],{},[39,68265,68136],{}," (never auto-sent). Option A is false — cross-origin cookie reads are blocked by the same-origin policy (modern ",[39,68268,67368],{}," rules restrict this further). Option C is nonsensical since cookies only ever store strings. Option D fabricates a specific count; the real limit is typically around 50–180 cookies per domain depending on the browser, not 3.",[15,68271,68272,68280,68335,68367],{"language":247},[18,68273,68275,68276,68279],{"id":68274},"q12-what-happens-when-you-call-structuredclone-on-an-object-that-contains-a-function-property","Q12. What happens when you call ",[39,68277,68278],{},"structuredClone()"," on an object that contains a function property?",[257,68281,68282],{"language":247},[260,68283,68285],{"className":262,"code":68284,"language":247,"meta":264,"style":264},"const config = {\n  name: \"widget\",\n  onClick: () => console.log(\"clicked\"),\n};\nstructuredClone(config);\n",[39,68286,68287,68297,68306,68325,68329],{"__ignoreMap":264},[268,68288,68289,68291,68293,68295],{"class":270,"line":271},[268,68290,243],{"class":274},[268,68292,8029],{"class":305},[268,68294,616],{"class":274},[268,68296,9914],{"class":282},[268,68298,68299,68301,68304],{"class":270,"line":286},[268,68300,20028],{"class":282},[268,68302,68303],{"class":289},"\"widget\"",[268,68305,1789],{"class":282},[268,68307,68308,68311,68313,68315,68317,68319,68321,68323],{"class":270,"line":296},[268,68309,68310],{"class":278},"  onClick",[268,68312,34921],{"class":282},[268,68314,9414],{"class":274},[268,68316,9417],{"class":282},[268,68318,1356],{"class":278},[268,68320,622],{"class":282},[268,68322,65556],{"class":289},[268,68324,17159],{"class":282},[268,68326,68327],{"class":270,"line":311},[268,68328,12940],{"class":282},[268,68330,68331,68333],{"class":270,"line":788},[268,68332,22322],{"class":278},[268,68334,7381],{"class":282},[23,68336,68338,68344,68352,68361],{"className":68337},[26],[28,68339,68341,68343],{"className":68340},[31],[33,68342],{"disabled":35,"type":36}," It clones the object and silently drops the function",[28,68345,68347,68349,68350],{"className":68346},[31],[33,68348],{"disabled":35,"type":36}," It clones the object and replaces the function with ",[39,68351,2650],{},[28,68353,68355,1271,68357,2182,68359,2690],{"className":68354},[31],[33,68356],{"disabled":35,"type":36},[39,68358,22453],{},[39,68360,68012],{},[28,68362,68364,68366],{"className":68363},[31],[33,68365],{"disabled":35,"type":36}," It clones the function by reference, so both objects share it",[66,68368,68369,68371,68380],{},[69,68370,71],{},[73,68372,68373,68375,68376,2182,68378,2690],{},[76,68374,78],{}," C — It throws a ",[39,68377,22453],{},[39,68379,68012],{},[73,68381,68382,68384,68385,42,68387,42,68390,42,68392,68394,68395,68398,68399,68401,68402,68405,68406,68408,68409,68411,68412,68414],{},[76,68383,84],{}," The structured clone algorithm has a defined, limited set of cloneable types (primitives, plain objects\u002Farrays, ",[39,68386,2669],{},[39,68388,68389],{},"RegExp",[39,68391,2672],{},[39,68393,9306],{},", typed arrays, ",[39,68396,68397],{},"Blob",", and a few others); functions are explicitly unsupported and cause the call to throw synchronously. This differs from ",[39,68400,20555],{},", which silently ",[104,68403,68404],{},"drops"," function properties instead of throwing (making option A the tempting-but-wrong answer, since it describes ",[39,68407,20555],{},"'s behavior, not ",[39,68410,22322],{},"'s). ",[76,68413,582],{}," if you need to clone an object that might contain callbacks, strip them out first or use a targeted manual copy instead of a blanket deep-clone utility.",[15,68416,68417,68424,68468,68476,68519],{"language":247},[18,68418,68420,68421,68423],{"id":68419},"q13-a-developer-writes-jsonstringify-on-an-object-with-a-self-reference","Q13. A developer writes ",[39,68422,20555],{}," on an object with a self-reference:",[257,68425,68426],{"language":247},[260,68427,68429],{"className":262,"code":68428,"language":247,"meta":264,"style":264},"const node = { value: 1 };\nnode.self = node;\nJSON.stringify(node);\n",[39,68430,68431,68447,68457],{"__ignoreMap":264},[268,68432,68433,68435,68438,68440,68443,68445],{"class":270,"line":271},[268,68434,243],{"class":274},[268,68436,68437],{"class":305}," node",[268,68439,616],{"class":274},[268,68441,68442],{"class":282}," { value: ",[268,68444,2255],{"class":305},[268,68446,2790],{"class":282},[268,68448,68449,68452,68454],{"class":270,"line":286},[268,68450,68451],{"class":282},"node.self ",[268,68453,302],{"class":274},[268,68455,68456],{"class":282}," node;\n",[268,68458,68459,68461,68463,68465],{"class":270,"line":296},[268,68460,21702],{"class":305},[268,68462,462],{"class":282},[268,68464,21707],{"class":278},[268,68466,68467],{"class":282},"(node);\n",[73,68469,68470,68471,64118,68473,1685],{},"What happens with ",[39,68472,20555],{},[39,68474,68475],{},"structuredClone(node)",[23,68477,68479,68485,68498,68510],{"className":68478},[26],[28,68480,68482,68484],{"className":68481},[31],[33,68483],{"disabled":35,"type":36}," Both throw an error for circular references",[28,68486,68488,355,68490,2278,68492,68494,68495,68497],{"className":68487},[31],[33,68489],{"disabled":35,"type":36},[39,68491,20555],{},[39,68493,827],{}," (\"Converting circular structure to JSON\"); ",[39,68496,22322],{}," successfully clones it, preserving the circular reference",[28,68499,68501,355,68503,68505,68506,2272,68508,2318],{"className":68500},[31],[33,68502],{"disabled":35,"type":36},[39,68504,20555],{}," succeeds by cloning the circular part as ",[39,68507,2650],{},[39,68509,22322],{},[28,68511,68513,68515,68516,68518],{"className":68512},[31],[33,68514],{"disabled":35,"type":36}," Both succeed silently, but only ",[39,68517,22322],{}," preserves the cycle",[66,68520,68521,68523,68533],{},[69,68522,71],{},[73,68524,68525,1727,68527,2278,68529,68494,68531,68497],{},[76,68526,78],{},[39,68528,20555],{},[39,68530,827],{},[39,68532,22322],{},[73,68534,68535,68537,68538,68540,68541,68544],{},[76,68536,84],{}," JSON has no representation for cycles, so ",[39,68539,20555],{}," detects the recursion and throws. The structured clone algorithm, by contrast, is graph-aware — it tracks already-visited objects during the clone and correctly reconstructs the same cyclical shape in the copy, which is exactly the capability referenced in Q7. This is a common trap for anyone who reaches for ",[39,68542,68543],{},"JSON.parse(JSON.stringify(x))"," as a \"deep clone\" one-liner without realizing it fails hard on data shapes like linked lists, trees with parent pointers, or event emitters that reference their own listeners.",[15,68546,68547,68561,68621,68655],{"language":247},[18,68548,68550,68551,68553,68554,99,68556,68558,68559,67555],{"id":68549},"q14-a-response-body-has-already-been-consumed-once-via-json-what-happens-on-a-second-call-to-json-or-text-on-the-same-response-object","Q14. A response body has already been consumed once via ",[39,68552,67698],{},". What happens on a second call to ",[39,68555,67698],{},[39,68557,67701],{}," on the same ",[39,68560,67651],{},[257,68562,68563],{"language":247},[260,68564,68566],{"className":262,"code":68565,"language":247,"meta":264,"style":264},"const res = await fetch(\"\u002Fapi\u002Fdata\");\nconst data = await res.json();\nconst dataAgain = await res.json();\n",[39,68567,68568,68587,68604],{"__ignoreMap":264},[268,68569,68570,68572,68574,68576,68578,68580,68582,68585],{"class":270,"line":271},[268,68571,243],{"class":274},[268,68573,52248],{"class":305},[268,68575,616],{"class":274},[268,68577,52502],{"class":274},[268,68579,53875],{"class":278},[268,68581,622],{"class":282},[268,68583,68584],{"class":289},"\"\u002Fapi\u002Fdata\"",[268,68586,628],{"class":282},[268,68588,68589,68591,68594,68596,68598,68600,68602],{"class":270,"line":286},[268,68590,243],{"class":274},[268,68592,68593],{"class":305}," data",[268,68595,616],{"class":274},[268,68597,52502],{"class":274},[268,68599,53902],{"class":282},[268,68601,1751],{"class":278},[268,68603,794],{"class":282},[268,68605,68606,68608,68611,68613,68615,68617,68619],{"class":270,"line":296},[268,68607,243],{"class":274},[268,68609,68610],{"class":305}," dataAgain",[268,68612,616],{"class":274},[268,68614,52502],{"class":274},[268,68616,53902],{"class":282},[268,68618,1751],{"class":278},[268,68620,794],{"class":282},[23,68622,68624,68630,68641,68649],{"className":68623},[26],[28,68625,68627,68629],{"className":68626},[31],[33,68628],{"disabled":35,"type":36}," It returns the same parsed data again, from an internal cache",[28,68631,68633,1271,68635,68637,68638,68640],{"className":68632},[31],[33,68634],{"disabled":35,"type":36},[39,68636,827],{}," because the body stream has already been read (a ",[39,68639,67651],{}," body can only be consumed once)",[28,68642,68644,68646,68647],{"className":68643},[31],[33,68645],{"disabled":35,"type":36}," It returns ",[39,68648,833],{},[28,68650,68652,68654],{"className":68651},[31],[33,68653],{"disabled":35,"type":36}," It re-fetches the URL automatically",[66,68656,68657,68659,68667],{},[69,68658,71],{},[73,68660,68661,1300,68663,68637,68665,68640],{},[76,68662,78],{},[39,68664,827],{},[39,68666,67651],{},[73,68668,68669,812,68671,68673,68674,42,68676,42,68678,42,68681,42,68684,68687,68688,68690,68691,355,68694,68696,68697,68699],{},[76,68670,84],{},[39,68672,67651],{},"'s body is a one-shot readable stream; once a body-reading method (",[39,68675,67698],{},[39,68677,67701],{},[39,68679,68680],{},".blob()",[39,68682,68683],{},".arrayBuffer()",[39,68685,68686],{},".formData()",") has consumed it, the stream is marked \"disturbed\" and any further read attempt throws. ",[76,68689,365],{}," if you need the body in multiple forms or multiple places, call ",[39,68692,68693],{},"res.clone()",[104,68695,11314],{}," the first read to get an independent ",[39,68698,67651],{}," with its own body stream. Option A is the tempting assumption since many other JS APIs are idempotent on repeated calls, but streams are explicitly not.",[15,68701,68702,68706,68739],{},[18,68703,68705],{"id":68704},"q15-for-storing-a-short-lived-ui-preference-like-sidebar-collapsed-true-that-only-matters-for-the-current-browsing-session-which-storage-mechanism-is-most-idiomatic","Q15. For storing a short-lived UI preference like \"sidebar collapsed = true\" that only matters for the current browsing session, which storage mechanism is most idiomatic?",[23,68707,68709,68717,68723,68731],{"className":68708},[26],[28,68710,68712,355,68714,68716],{"className":68711},[31],[33,68713],{"disabled":35,"type":36},[39,68715,67220],{},", so it survives forever",[28,68718,68720,68722],{"className":68719},[31],[33,68721],{"disabled":35,"type":36}," A cookie, so the server can also see it",[28,68724,68726,355,68728,68730],{"className":68725},[31],[33,68727],{"disabled":35,"type":36},[39,68729,67223],{},", since the preference is only meaningful for the current tab session",[28,68732,68734,355,68736,68738],{"className":68733},[31],[33,68735],{"disabled":35,"type":36},[39,68737,68136],{},", for its transactional guarantees",[66,68740,68741,68743,68749],{},[69,68742,71],{},[73,68744,68745,1004,68747,68730],{},[76,68746,78],{},[39,68748,67223],{},[73,68750,68751,355,68753,68755,68756,2758,68758,68760,68761,68763],{},[76,68752,84],{},[76,68754,930],{}," match the storage lifetime to the data's actual lifetime — a value that should reset when the tab closes belongs in ",[39,68757,67223],{},[39,68759,67220],{}," (which would leak stale state into unrelated future sessions) or a cookie (which adds unnecessary request overhead for something the server never needs to know). ",[39,68762,68136],{}," is overkill for a single boolean flag; it's meant for structured, queryable, potentially large datasets, not simple key-value preferences.",[15,68765,68766,68779,68815],{},[18,68767,68769,68770,42,68772,42,68774,68776,68777,1685],{"id":68768},"q16-for-storing-a-sensitive-authentication-token-why-do-security-conscious-teams-generally-prefer-an-httponly-secure-samesite-cookie-over-localstorage","Q16. For storing a sensitive authentication token, why do security-conscious teams generally prefer an ",[39,68771,67385],{},[39,68773,67371],{},[39,68775,67368],{}," cookie over ",[39,68778,67220],{},[23,68780,68782,68788,68799,68807],{"className":68781},[26],[28,68783,68785,68787],{"className":68784},[31],[33,68786],{"disabled":35,"type":36}," Cookies are encrypted automatically by the browser",[28,68789,68791,355,68793,68795,68796,68798],{"className":68790},[31],[33,68792],{"disabled":35,"type":36},[39,68794,67220],{}," is readable by any JavaScript running on the page, so it's fully exposed to XSS attacks; an ",[39,68797,67385],{}," cookie is inaccessible to JavaScript entirely",[28,68800,68802,68804,68805],{"className":68801},[31],[33,68803],{"disabled":35,"type":36}," Cookies have unlimited storage capacity, unlike ",[39,68806,67220],{},[28,68808,68810,355,68812,68814],{"className":68809},[31],[33,68811],{"disabled":35,"type":36},[39,68813,67220],{}," values expire after 24 hours automatically, breaking long sessions",[66,68816,68817,68819,68827],{},[69,68818,71],{},[73,68820,68821,1727,68823,68795,68825,68798],{},[76,68822,78],{},[39,68824,67220],{},[39,68826,67385],{},[73,68828,68829,355,68831,68833,68834,68837,68838,68840,68841,68843,68844,68847,68848,68850,68851,68853],{},[76,68830,84],{},[76,68832,582],{}," any successful XSS injection on the page can run ",[39,68835,68836],{},"localStorage.getItem(...)"," and exfiltrate a token stored there — there's no isolation between \"your\" code and injected code once script execution happens on the page. An ",[39,68839,67385],{}," cookie is deliberately hidden from ",[39,68842,67338],{}," and any storage API, so even a successful XSS payload can't read it directly (though it could still be ",[104,68845,68846],{},"used"," via same-origin requests, which is why ",[39,68849,67368],{}," matters for CSRF — see Q20). Option A is false: cookies are plain text by default, not encrypted. Option C is false: cookies are far more size-constrained than ",[39,68852,67220],{},". Option D is a fabricated default.",[15,68855,68856,68863,68958,69007],{"language":247},[18,68857,68859,68860,68862],{"id":68858},"q17-what-is-the-idiomatic-way-to-handle-a-non-2xx-http-response-with-fetch-given-that-it-doesnt-reject-the-promise","Q17. What is the idiomatic way to handle a non-2xx HTTP response with ",[39,68861,47324],{},", given that it doesn't reject the promise?",[257,68864,68865],{"language":247},[260,68866,68868],{"className":262,"code":68867,"language":247,"meta":264,"style":264},"async function getUser(id) {\n  const res = await fetch(`\u002Fapi\u002Fusers\u002F${id}`);\n  if (!res.ok) {\n    throw new Error(`Request failed with status ${res.status}`);\n  }\n  return res.json();\n}\n",[39,68869,68870,68884,68906,68917,68940,68944,68954],{"__ignoreMap":264},[268,68871,68872,68874,68876,68878,68880,68882],{"class":270,"line":271},[268,68873,379],{"class":274},[268,68875,12080],{"class":274},[268,68877,51115],{"class":278},[268,68879,622],{"class":282},[268,68881,14610],{"class":1222},[268,68883,1235],{"class":282},[268,68885,68886,68888,68890,68892,68894,68896,68898,68900,68902,68904],{"class":270,"line":286},[268,68887,12441],{"class":274},[268,68889,52248],{"class":305},[268,68891,616],{"class":274},[268,68893,52502],{"class":274},[268,68895,53875],{"class":278},[268,68897,622],{"class":282},[268,68899,53880],{"class":289},[268,68901,14610],{"class":282},[268,68903,11603],{"class":289},[268,68905,628],{"class":282},[268,68907,68908,68910,68912,68914],{"class":270,"line":296},[268,68909,9863],{"class":274},[268,68911,2182],{"class":282},[268,68913,5418],{"class":274},[268,68915,68916],{"class":282},"res.ok) {\n",[268,68918,68919,68921,68923,68925,68927,68930,68932,68934,68936,68938],{"class":270,"line":311},[268,68920,48705],{"class":274},[268,68922,11370],{"class":274},[268,68924,11593],{"class":278},[268,68926,622],{"class":282},[268,68928,68929],{"class":289},"`Request failed with status ${",[268,68931,52237],{"class":282},[268,68933,462],{"class":289},[268,68935,13305],{"class":282},[268,68937,11603],{"class":289},[268,68939,628],{"class":282},[268,68941,68942],{"class":270,"line":788},[268,68943,1948],{"class":282},[268,68945,68946,68948,68950,68952],{"class":270,"line":1951},[268,68947,1240],{"class":274},[268,68949,53902],{"class":282},[268,68951,1751],{"class":278},[268,68953,794],{"class":282},[268,68955,68956],{"class":270,"line":8955},[268,68957,314],{"class":282},[23,68959,68961,68970,68983,68995],{"className":68960},[26],[28,68962,68964,68966,68967,68969],{"className":68963},[31],[33,68965],{"disabled":35,"type":36}," This pattern is unnecessary — ",[39,68968,47324],{}," already throws on error statuses",[28,68971,68973,68975,68976,7255,68979,68982],{"className":68972},[31],[33,68974],{"disabled":35,"type":36}," This is the correct idiom: explicitly check ",[39,68977,68978],{},"res.ok",[39,68980,68981],{},"res.status",") and throw before attempting to parse the body",[28,68984,68986,355,68988,68990,68991,68994],{"className":68985},[31],[33,68987],{"disabled":35,"type":36},[39,68989,68978],{}," doesn't exist; you must compare ",[39,68992,68993],{},"res.status === 200"," exactly",[28,68996,68998,69000,69001,8220,69004,69006],{"className":68997},[31],[33,68999],{"disabled":35,"type":36}," You should check ",[39,69002,69003],{},"res.statusText",[39,69005,68978],{}," is deprecated",[66,69008,69009,69011,69020],{},[69,69010,71],{},[73,69012,69013,69015,69016,7255,69018,68982],{},[76,69014,78],{}," B — This is the correct idiom: explicitly check ",[39,69017,68978],{},[39,69019,68981],{},[73,69021,69022,69024,69025,69027,69028,69031,69032,69035,69036,446,69038,69041,69042,69044,69045,69047,69048,186,69051,69054,69055,69058],{},[76,69023,84],{}," Since ",[39,69026,47324],{}," treats any completed HTTP exchange as a resolved promise (per Q6), the standard, idiomatic pattern is to inspect ",[39,69029,69030],{},"response.ok"," (true for status ",[39,69033,69034],{},"200–299",") immediately after awaiting the fetch and manually throw so downstream ",[39,69037,47426],{},[39,69039,69040],{},"try-catch"," logic can treat it as an error. Skipping this check means error bodies (often HTML error pages or JSON error payloads with a different shape) get parsed as if they were success data. Option C is wrong because ",[39,69043,68978],{}," covers the whole 2xx range, not just exactly ",[39,69046,40987],{}," (e.g., ",[39,69049,69050],{},"201 Created",[39,69052,69053],{},"204 No Content"," are also ",[39,69056,69057],{},"ok","). Option D fabricates a deprecation that doesn't exist.",[15,69060,69061,69065,69098],{},[18,69062,69064],{"id":69063},"q18-a-page-needs-to-cache-tens-of-thousands-of-structured-records-eg-an-offline-product-catalog-in-the-browser-which-storage-choice-is-most-appropriate-and-why","Q18. A page needs to cache tens of thousands of structured records (e.g., an offline product catalog) in the browser. Which storage choice is most appropriate, and why?",[23,69066,69068,69076,69082,69090],{"className":69067},[26],[28,69069,69071,355,69073,69075],{"className":69070},[31],[33,69072],{"disabled":35,"type":36},[39,69074,67220],{},", because it's the simplest key-value API",[28,69077,69079,69081],{"className":69078},[31],[33,69080],{"disabled":35,"type":36}," Cookies, because they persist across sessions",[28,69083,69085,355,69087,69089],{"className":69084},[31],[33,69086],{"disabled":35,"type":36},[39,69088,68136],{},", because it's asynchronous, supports much larger storage quotas, and allows indexed queries over structured data",[28,69091,69093,355,69095,69097],{"className":69092},[31],[33,69094],{"disabled":35,"type":36},[39,69096,67223],{},", because it's the fastest storage mechanism available",[66,69099,69100,69102,69108],{},[69,69101,71],{},[73,69103,69104,1004,69106,69089],{},[76,69105,78],{},[39,69107,68136],{},[73,69109,69110,355,69112,355,69114,69116,69117,69119],{},[76,69111,84],{},[76,69113,438],{},[39,69115,67220],{},"'s synchronous API and typically single-digit-megabyte quota make it unsuitable for large or frequently-read datasets — serializing\u002Fdeserializing tens of thousands of records on the main thread on every read would cause visible jank (per Q9). ",[39,69118,68136],{}," is purpose-built for this: it's asynchronous (doesn't block rendering), commonly allows quotas in the hundreds of megabytes or more (subject to browser\u002Fdevice policy), and supports indexes for efficient querying instead of loading everything into memory at once. Cookies (option B) are capped at a few KB total and would blow the size limit almost immediately, plus they'd be sent needlessly with every request.",[15,69121,69122,69132,69220,69258],{"language":247},[18,69123,69125,69126,69128,69129,69131],{"id":69124},"q19-a-search-as-you-type-feature-fires-a-new-fetch-request-on-every-keystroke-why-should-the-code-use-an-abortcontroller-to-cancel-the-previous-in-flight-request-when-a-new-one-starts","Q19. A search-as-you-type feature fires a new ",[39,69127,47324],{}," request on every keystroke. Why should the code use an ",[39,69130,39934],{}," to cancel the previous in-flight request when a new one starts?",[257,69133,69134],{"language":247},[260,69135,69137],{"className":262,"code":69136,"language":247,"meta":264,"style":264},"let controller;\nasync function search(query) {\n  controller?.abort();\n  controller = new AbortController();\n  const res = await fetch(`\u002Fapi\u002Fsearch?q=${query}`, { signal: controller.signal });\n  return res.json();\n}\n",[39,69138,69139,69145,69160,69169,69182,69206,69216],{"__ignoreMap":264},[268,69140,69141,69143],{"class":270,"line":271},[268,69142,240],{"class":274},[268,69144,65784],{"class":282},[268,69146,69147,69149,69151,69154,69156,69158],{"class":270,"line":286},[268,69148,379],{"class":274},[268,69150,12080],{"class":274},[268,69152,69153],{"class":278}," search",[268,69155,622],{"class":282},[268,69157,59781],{"class":1222},[268,69159,1235],{"class":282},[268,69161,69162,69165,69167],{"class":270,"line":296},[268,69163,69164],{"class":282},"  controller?.",[268,69166,65842],{"class":278},[268,69168,794],{"class":282},[268,69170,69171,69174,69176,69178,69180],{"class":270,"line":311},[268,69172,69173],{"class":282},"  controller ",[268,69175,302],{"class":274},[268,69177,11370],{"class":274},[268,69179,65767],{"class":278},[268,69181,794],{"class":282},[268,69183,69184,69186,69188,69190,69192,69194,69196,69199,69201,69203],{"class":270,"line":788},[268,69185,12441],{"class":274},[268,69187,52248],{"class":305},[268,69189,616],{"class":274},[268,69191,52502],{"class":274},[268,69193,53875],{"class":278},[268,69195,622],{"class":282},[268,69197,69198],{"class":289},"`\u002Fapi\u002Fsearch?q=${",[268,69200,59781],{"class":282},[268,69202,11603],{"class":289},[268,69204,69205],{"class":282},", { signal: controller.signal });\n",[268,69207,69208,69210,69212,69214],{"class":270,"line":1951},[268,69209,1240],{"class":274},[268,69211,53902],{"class":282},[268,69213,1751],{"class":278},[268,69215,794],{"class":282},[268,69217,69218],{"class":270,"line":8955},[268,69219,314],{"class":282},[23,69221,69223,69232,69241,69252],{"className":69222},[26],[28,69224,69226,69228,69229,69231],{"className":69225},[31],[33,69227],{"disabled":35,"type":36}," Without it, ",[39,69230,47324],{}," automatically queues requests and only the last one's callback ever runs, so it's purely a style preference",[28,69233,69235,69237,69238,69240],{"className":69234},[31],[33,69236],{"disabled":35,"type":36}," Without it, older slow responses can resolve ",[104,69239,1747],{}," newer, faster ones, overwriting the UI with stale results (a race condition)",[28,69242,69244,355,69246,69248,69249,69251],{"className":69243},[31],[33,69245],{"disabled":35,"type":36},[39,69247,39934],{}," is required by the Fetch spec for every request, or ",[39,69250,47324],{}," throws a warning",[28,69253,69255,69257],{"className":69254},[31],[33,69256],{"disabled":35,"type":36}," It prevents the browser from opening more than one TCP connection at a time",[66,69259,69260,69262,69269],{},[69,69261,71],{},[73,69263,69264,69266,69267,69240],{},[76,69265,78],{}," B — Without it, older slow responses can resolve ",[104,69268,1747],{},[73,69270,69271,69273,69274,69276,69277,69280,69281,69283,69284,69287,69288,69290,69291,69294,69295,69297],{},[76,69272,84],{}," Concurrent ",[39,69275,47324],{}," calls resolve independently and in whatever order the network happens to deliver them — there's no built-in request cancellation or sequencing, so a request for ",[39,69278,69279],{},"\"ca\""," typed early can easily resolve ",[104,69282,1747],{}," a request for ",[39,69285,69286],{},"\"cat\""," typed later if the network conditions vary, leaving stale results rendered last. Calling ",[39,69289,65850],{}," on the previous controller before issuing a new request cancels the outdated one (its promise rejects with an ",[39,69292,69293],{},"AbortError","), preventing it from ever resolving and overwriting fresher data. Option A invents automatic queuing that doesn't exist — every ",[39,69296,47324],{}," call runs independently and concurrently.",[15,69299,69300,69308,69335],{},[18,69301,69303,69304,69307],{"id":69302},"q20-setting-a-cookie-with-set-cookie-sessionabc123-samesitestrict-secure-httponly-primarily-helps-mitigate-which-class-of-attack","Q20. Setting a cookie with ",[39,69305,69306],{},"Set-Cookie: session=abc123; SameSite=Strict; Secure; HttpOnly"," primarily helps mitigate which class of attack?",[23,69309,69311,69317,69323,69329],{"className":69310},[26],[28,69312,69314,69316],{"className":69313},[31],[33,69315],{"disabled":35,"type":36}," SQL injection",[28,69318,69320,69322],{"className":69319},[31],[33,69321],{"disabled":35,"type":36}," Cross-Site Request Forgery (CSRF), by preventing the cookie from being sent on cross-site requests",[28,69324,69326,69328],{"className":69325},[31],[33,69327],{"disabled":35,"type":36}," Cross-Site Scripting (XSS) injection into the page's HTML",[28,69330,69332,69334],{"className":69331},[31],[33,69333],{"disabled":35,"type":36}," DNS spoofing",[66,69336,69337,69339,69344],{},[69,69338,71],{},[73,69340,69341,69343],{},[76,69342,78],{}," B — Cross-Site Request Forgery (CSRF), by preventing the cookie from being sent on cross-site requests",[73,69345,69346,355,69348,355,69350,7255,69353,69356,69357,69359,69360,69363,69364,69366,69367,69369],{},[76,69347,84],{},[76,69349,582],{},[39,69351,69352],{},"SameSite=Strict",[39,69354,69355],{},"Lax",") tells the browser not to attach this cookie to requests initiated from a different site, which directly defeats the classic CSRF pattern of a malicious page silently submitting a form or request to your app while relying on the browser auto-attaching the victim's session cookie. ",[39,69358,67385],{}," (from Q16) protects against XSS ",[104,69361,69362],{},"reading"," the cookie via JavaScript, but that's a separate, complementary protection, not what ",[39,69365,67368],{}," is for — so option C conflates the two attributes' purposes. ",[39,69368,67371],{}," only ensures the cookie is sent solely over HTTPS, unrelated to injection attacks. Neither attribute has anything to do with SQL injection or DNS-layer attacks.",[2107,69371,69372],{},"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 .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}",{"title":264,"searchDepth":286,"depth":286,"links":69374},[69375,69377,69379,69380,69382,69384,69386,69388,69390,69392,69394,69395,69397,69399,69401,69402,69404,69406,69407,69409],{"id":67216,"depth":296,"text":69376},"Q1. Which statement correctly distinguishes localStorage from sessionStorage?",{"id":67308,"depth":296,"text":69378},"Q2. A team stores a JWT auth token in a cookie versus localStorage. Which behavior is unique to cookies (not localStorage)?",{"id":67399,"depth":296,"text":67400},{"id":67547,"depth":296,"text":69381},"Q4. When does the storage event fire on the window object?",{"id":67627,"depth":296,"text":69383},"Q5. What does fetch() return?",{"id":67719,"depth":296,"text":69385},"Q6. A developer writes the following and is confused why the catch block never runs for a 404 response:",{"id":67885,"depth":296,"text":69387},"Q7. What is the key advantage of structuredClone(obj) over JSON.parse(JSON.stringify(obj)) for deep-copying data?",{"id":67990,"depth":296,"text":69389},"Q8. A page stores several megabytes of data over time via repeated localStorage.setItem calls until the origin's quota (commonly ~5–10MB depending on browser) is exceeded. What happens on the call that exceeds it?",{"id":68069,"depth":296,"text":69391},"Q9. Why is heavy, repeated use of localStorage inside a hot code path (e.g., on every scroll or mousemove event) considered a performance anti-pattern?",{"id":68142,"depth":296,"text":69393},"Q10. A user opens the same web app in two separate tabs. They interact with Tab A, which writes to sessionStorage. What does Tab B see?",{"id":68216,"depth":296,"text":68217},{"id":68274,"depth":296,"text":69396},"Q12. What happens when you call structuredClone() on an object that contains a function property?",{"id":68419,"depth":296,"text":69398},"Q13. A developer writes JSON.stringify on an object with a self-reference:",{"id":68549,"depth":296,"text":69400},"Q14. A response body has already been consumed once via .json(). What happens on a second call to .json() or .text() on the same Response object?",{"id":68704,"depth":296,"text":68705},{"id":68768,"depth":296,"text":69403},"Q16. For storing a sensitive authentication token, why do security-conscious teams generally prefer an HttpOnly, Secure, SameSite cookie over localStorage?",{"id":68858,"depth":296,"text":69405},"Q17. What is the idiomatic way to handle a non-2xx HTTP response with fetch, given that it doesn't reject the promise?",{"id":69063,"depth":296,"text":69064},{"id":69124,"depth":296,"text":69408},"Q19. A search-as-you-type feature fires a new fetch request on every keystroke. Why should the code use an AbortController to cancel the previous in-flight request when a new one starts?",{"id":69302,"depth":296,"text":69410},"Q20. Setting a cookie with Set-Cookie: session=abc123; SameSite=Strict; Secure; HttpOnly primarily helps mitigate which class of attack?",{},"\u002Fjs\u002F21-web-storage-and-apis",{"title":67206,"description":264},"js\u002F21-web-storage-and-apis","_QtEE28wmf2NU-DWn4sbFqhiduQVBXeK13a23vyId4o",{"id":69417,"title":69418,"body":69419,"description":264,"extension":2144,"meta":71579,"navigation":35,"path":71580,"seo":71581,"stem":71582,"__hash__":71583},"content\u002Fjs\u002F22-timers-and-scheduling.md","22 — Timers & Scheduling",{"type":8,"value":69420,"toc":71542},[69421,69424,69503,69644,69712,69810,69880,70015,70074,70213,70272,70435,70511,70619,70686,70753,70892,71061,71268,71353,71481,71540],[11,69422,69418],{"id":69423},"_22-timers-scheduling",[15,69425,69426,69434,69478],{},[18,69427,69429,69430,69433],{"id":69428},"q1-what-does-the-second-argument-to-settimeoutfn-delay-actually-guarantee","Q1. What does the second argument to ",[39,69431,69432],{},"setTimeout(fn, delay)"," actually guarantee?",[23,69435,69437,69448,69459,69470],{"className":69436},[26],[28,69438,69440,355,69442,69444,69445,69447],{"className":69439},[31],[33,69441],{"disabled":35,"type":36},[39,69443,37837],{}," will run exactly ",[39,69446,40755],{}," milliseconds later, to the millisecond",[28,69449,69451,355,69453,69455,69456,69458],{"className":69450},[31],[33,69452],{"disabled":35,"type":36},[39,69454,37837],{}," will run no earlier than ",[39,69457,40755],{}," milliseconds later — the actual delay may be longer",[28,69460,69462,355,69464,69466,69467,69469],{"className":69461},[31],[33,69463],{"disabled":35,"type":36},[39,69465,37837],{}," will run before ",[39,69468,40755],{}," milliseconds have passed",[28,69471,69473,355,69475,69477],{"className":69472},[31],[33,69474],{"disabled":35,"type":36},[39,69476,40755],{}," is ignored in all modern browsers",[66,69479,69480,69482,69490],{},[69,69481,71],{},[73,69483,69484,1727,69486,69455,69488,69458],{},[76,69485,78],{},[39,69487,37837],{},[39,69489,40755],{},[73,69491,69492,355,69494,358,69496,69499,69500,69502],{},[76,69493,84],{},[39,69495,40755],{},[104,69497,69498],{},"minimum"," wait time, not a scheduling guarantee. The callback is only queued as a macrotask once ",[39,69501,40755],{}," elapses; it still has to wait for the call stack to be empty and for any tasks already ahead of it in the queue to finish, so a busy main thread (long synchronous work, other pending callbacks) pushes the actual execution later. Option A is the common misconception that timers behave like a real-time scheduler. Option C is backwards. Option D is false — the delay still matters as a floor.",[15,69504,69505,69512,69565,69602],{"language":247},[18,69506,69508,69509,1685],{"id":69507},"q2-what-happens-when-you-call-settimeoutfn-0","Q2. What happens when you call ",[39,69510,69511],{},"setTimeout(fn, 0)",[257,69513,69514],{"language":247},[260,69515,69517],{"className":262,"code":69516,"language":247,"meta":264,"style":264},"console.log(\"1\");\nsetTimeout(() => console.log(\"2\"), 0);\nconsole.log(\"3\");\n",[39,69518,69519,69531,69553],{"__ignoreMap":264},[268,69520,69521,69523,69525,69527,69529],{"class":270,"line":271},[268,69522,1353],{"class":282},[268,69524,1356],{"class":278},[268,69526,622],{"class":282},[268,69528,3387],{"class":289},[268,69530,628],{"class":282},[268,69532,69533,69535,69537,69539,69541,69543,69545,69547,69549,69551],{"class":270,"line":286},[268,69534,9578],{"class":278},[268,69536,9411],{"class":282},[268,69538,9414],{"class":274},[268,69540,9417],{"class":282},[268,69542,1356],{"class":278},[268,69544,622],{"class":282},[268,69546,9269],{"class":289},[268,69548,33111],{"class":282},[268,69550,3307],{"class":305},[268,69552,628],{"class":282},[268,69554,69555,69557,69559,69561,69563],{"class":270,"line":296},[268,69556,1353],{"class":282},[268,69558,1356],{"class":278},[268,69560,622],{"class":282},[268,69562,50483],{"class":289},[268,69564,628],{"class":282},[23,69566,69568,69576,69587,69593],{"className":69567},[26],[28,69569,69571,3578,69573,69575],{"className":69570},[31],[33,69572],{"disabled":35,"type":36},[39,69574,23888],{}," — the timeout runs immediately since delay is 0",[28,69577,69579,3578,69581,3990,69584,69586],{"className":69578},[31],[33,69580],{"disabled":35,"type":36},[39,69582,69583],{},"1, 3, 2",[39,69585,37837],{}," is still deferred to a macrotask that runs after the current synchronous code finishes",[28,69588,69590,69592],{"className":69589},[31],[33,69591],{"disabled":35,"type":36}," Throws an error, since 0 is not a valid delay",[28,69594,69596,3578,69598,69601],{"className":69595},[31],[33,69597],{"disabled":35,"type":36},[39,69599,69600],{},"2, 1, 3"," — zero-delay timers jump the queue",[66,69603,69604,69606,69614],{},[69,69605,71],{},[73,69607,69608,2450,69610,3990,69612,69586],{},[76,69609,78],{},[39,69611,69583],{},[39,69613,37837],{},[73,69615,69616,69618,69619,69621,69622,69624,69625,69628,69629,1133,69632,69634,69635,69637,69638,69640,69641,69643],{},[76,69617,84],{}," Even with a ",[39,69620,3307],{},"ms delay, ",[39,69623,9578],{}," always schedules its callback as a macrotask for a ",[104,69626,69627],{},"future"," iteration of the event loop — it never runs synchronously inline, no matter how small the delay. The current call stack (",[39,69630,69631],{},"console.log(\"1\")",[39,69633,57518],{},") always finishes executing first. Option A is the classic beginner assumption that ",[39,69636,3307],{}," means \"right now.\" This also means a zero-delay timer runs ",[104,69639,1747],{}," any pending microtasks (like resolved Promise ",[39,69642,47423],{}," callbacks), which is a related, frequently-tested ordering gotcha.",[15,69645,69646,69656,69686],{},[18,69647,23672,69649,69652,69653,69655],{"id":69648},"q3-what-does-cleartimeoutid-do-if-id-refers-to-a-timer-that-has-already-fired",[39,69650,69651],{},"clearTimeout(id)"," do if ",[39,69654,14610],{}," refers to a timer that has already fired?",[23,69657,69659,69666,69672,69678],{"className":69658},[26],[28,69660,69662,1271,69664],{"className":69661},[31],[33,69663],{"disabled":35,"type":36},[39,69665,815],{},[28,69667,69669,69671],{"className":69668},[31],[33,69670],{"disabled":35,"type":36}," It does nothing — calling it on an already-fired (or invalid\u002Fnonexistent) id is a silent no-op",[28,69673,69675,69677],{"className":69674},[31],[33,69676],{"disabled":35,"type":36}," It re-schedules the callback to run again",[28,69679,69681,1271,69683,69685],{"className":69680},[31],[33,69682],{"disabled":35,"type":36},[39,69684,827],{}," because the timer is no longer active",[66,69687,69688,69690,69695],{},[69,69689,71],{},[73,69691,69692,69694],{},[76,69693,78],{}," B — It does nothing — calling it on an already-fired (or invalid\u002Fnonexistent) id is a silent no-op",[73,69696,69697,355,69699,446,69702,69705,69706,69708,69709,69711],{},[76,69698,84],{},[39,69700,69701],{},"clearTimeout",[39,69703,69704],{},"clearInterval"," are deliberately forgiving: passing an id that already fired, was already cleared, or was never valid at all simply does nothing and never throws. This makes it safe to call ",[39,69707,69701],{}," defensively (e.g., in cleanup code that isn't sure whether the timer already ran) without needing to guard it in a ",[39,69710,2081],{},". Options A, C, and D invent error\u002Fre-trigger behavior that the spec explicitly avoids for ergonomic reasons.",[15,69713,69714,69724,69767],{},[18,69715,69717,69718,69721,69722,1685],{"id":69716},"q4-what-is-the-defining-behavior-of-setintervalfn-delay-compared-to-a-single-settimeout","Q4. What is the defining behavior of ",[39,69719,69720],{},"setInterval(fn, delay)"," compared to a single ",[39,69723,9578],{},[23,69725,69727,69739,69753,69761],{"className":69726},[26],[28,69728,69730,69732,69733,69735,69736,69738],{"className":69729},[31],[33,69731],{"disabled":35,"type":36}," It runs ",[39,69734,37837],{}," once after ",[39,69737,40755],{},", then automatically clears itself",[28,69740,69742,69744,69745,69747,69748,69750,69751],{"className":69741},[31],[33,69743],{"disabled":35,"type":36}," It repeatedly schedules ",[39,69746,37837],{}," to run roughly every ",[39,69749,40755],{}," milliseconds until explicitly cleared with ",[39,69752,69704],{},[28,69754,69756,69732,69758,69760],{"className":69755},[31],[33,69757],{"disabled":35,"type":36},[39,69759,37837],{}," synchronously and blocks the thread until cleared",[28,69762,69764,69766],{"className":69763},[31],[33,69765],{"disabled":35,"type":36}," It only works for functions with no arguments",[66,69768,69769,69771,69782],{},[69,69770,71],{},[73,69772,69773,69775,69776,69747,69778,69750,69780],{},[76,69774,78],{}," B — It repeatedly schedules ",[39,69777,37837],{},[39,69779,40755],{},[39,69781,69704],{},[73,69783,69784,355,69786,69788,69789,69791,69792,69794,69795,69797,69798,69801,69802,69804,69805,186,69807,69809],{},[76,69785,84],{},[39,69787,47386],{}," is the repeating counterpart to ",[39,69790,9578],{},": after the initial ",[39,69793,40755],{},", it keeps re-queuing ",[39,69796,37837],{}," at that interval indefinitely, and only ",[39,69799,69800],{},"clearInterval(id)"," stops it — it will otherwise keep firing for the lifetime of the page. Option A describes ",[39,69803,9578],{},"'s one-shot behavior instead. Option C is false since all timer callbacks run asynchronously on the event loop, never blocking synchronously. Option D is fabricated — you can pass extra arguments to both ",[39,69806,9578],{},[39,69808,47386],{}," as trailing parameters after the delay.",[15,69811,69812,69824,69853],{},[18,69813,69815,69816,69818,69819,446,69821,69823],{"id":69814},"q5-why-is-requestanimationframe-raf-preferred-over-settimeoutsetinterval-for-javascript-driven-animations","Q5. Why is ",[39,69817,62893],{}," (rAF) preferred over ",[39,69820,9578],{},[39,69822,47386],{}," for JavaScript-driven animations?",[23,69825,69827,69833,69839,69845],{"className":69826},[26],[28,69828,69830,69832],{"className":69829},[31],[33,69831],{"disabled":35,"type":36}," rAF runs animations on a separate thread, avoiding the main thread entirely",[28,69834,69836,69838],{"className":69835},[31],[33,69837],{"disabled":35,"type":36}," rAF schedules the callback to run right before the browser's next repaint, syncing animation updates to the display's actual refresh rate",[28,69840,69842,69844],{"className":69841},[31],[33,69843],{"disabled":35,"type":36}," rAF guarantees exactly 60 callbacks per second on every device",[28,69846,69848,69850,69851],{"className":69847},[31],[33,69849],{"disabled":35,"type":36}," rAF has no minimum delay, so it always fires faster than ",[39,69852,69511],{},[66,69854,69855,69857,69862],{},[69,69856,71],{},[73,69858,69859,69861],{},[76,69860,78],{}," B — rAF schedules the callback to run right before the browser's next repaint, syncing animation updates to the display's actual refresh rate",[73,69863,69864,355,69866,355,69868,69870,69871,446,69873,69875,69876,69879],{},[76,69865,84],{},[76,69867,438],{},[39,69869,62893],{}," ties its callback to the browser's paint cycle, so updates happen exactly once per frame with no wasted work (no updates when the tab isn't visible) and no risk of scheduling a visual update at a moment the browser is about to throw it away before the next paint. ",[39,69872,9578],{},[39,69874,47386],{}," have no awareness of paint timing, so an interval like ",[39,69877,69878],{},"16.67ms"," can easily drift out of sync with the actual refresh rate, causing jank. Option C is wrong because refresh rate varies (90Hz, 120Hz, etc.) and rAF adapts to the actual display, not a fixed 60. Option A is false — rAF still runs on the main thread.",[15,69881,69882,69886,69960,69997],{"language":247},[18,69883,69885],{"id":69884},"q6-what-does-this-code-log-and-why","Q6. What does this code log, and why?",[257,69887,69888],{"language":247},[260,69889,69891],{"className":262,"code":69890,"language":247,"meta":264,"style":264},"function tick(n) {\n  console.log(n);\n  if (n \u003C 3) setTimeout(() => tick(n + 1), 0);\n}\ntick(0);\n",[39,69892,69893,69906,69914,69946,69950],{"__ignoreMap":264},[268,69894,69895,69897,69900,69902,69904],{"class":270,"line":271},[268,69896,275],{"class":274},[268,69898,69899],{"class":278}," tick",[268,69901,622],{"class":282},[268,69903,4599],{"class":1222},[268,69905,1235],{"class":282},[268,69907,69908,69910,69912],{"class":270,"line":286},[268,69909,5556],{"class":282},[268,69911,1356],{"class":278},[268,69913,37888],{"class":282},[268,69915,69916,69918,69920,69922,69924,69926,69928,69930,69932,69934,69936,69938,69940,69942,69944],{"class":270,"line":296},[268,69917,9863],{"class":274},[268,69919,13562],{"class":282},[268,69921,1076],{"class":274},[268,69923,3396],{"class":305},[268,69925,6131],{"class":282},[268,69927,9578],{"class":278},[268,69929,9411],{"class":282},[268,69931,9414],{"class":274},[268,69933,69899],{"class":278},[268,69935,13376],{"class":282},[268,69937,1246],{"class":274},[268,69939,2199],{"class":305},[268,69941,33111],{"class":282},[268,69943,3307],{"class":305},[268,69945,628],{"class":282},[268,69947,69948],{"class":270,"line":311},[268,69949,314],{"class":282},[268,69951,69952,69954,69956,69958],{"class":270,"line":788},[268,69953,35156],{"class":278},[268,69955,622],{"class":282},[268,69957,3307],{"class":305},[268,69959,628],{"class":282},[23,69961,69963,69972,69980,69991],{"className":69962},[26],[28,69964,69966,355,69968,69971],{"className":69965},[31],[33,69967],{"disabled":35,"type":36},[39,69969,69970],{},"0, 1, 2, 3",", each firing essentially instantly since delay is 0",[28,69973,69975,355,69977,69979],{"className":69974},[31],[33,69976],{"disabled":35,"type":36},[39,69978,69970],{},", but after 5+ levels of nesting the HTML spec clamps timeouts to a minimum of ~4ms — irrelevant here since nesting is shallow",[28,69981,69983,50010,69985,69987,69988,69990],{"className":69982},[31],[33,69984],{"disabled":35,"type":36},[39,69986,3307],{}," is logged; the recursive ",[39,69989,9578],{}," calls never fire",[28,69992,69994,69996],{"className":69993},[31],[33,69995],{"disabled":35,"type":36}," It causes a stack overflow due to unbounded recursion",[66,69998,69999,70001,70007],{},[69,70000,71],{},[73,70002,70003,1727,70005,69979],{},[76,70004,78],{},[39,70006,69970],{},[73,70008,70009,70011,70012,70014],{},[76,70010,84],{}," Each call logs its number, then schedules the next tick as a macrotask, so all four values print in order across separate event-loop turns. The clamping rule (relevant background, not the trigger here) is that once ",[39,70013,9578],{}," calls are nested more than 5 levels deep, browsers enforce a minimum delay of about 4ms regardless of the requested delay, specifically to prevent runaway zero-delay recursive loops from starving the event loop. With only 4 total levels of nesting, this clamp never actually kicks in for this snippet, which is why A is tempting but imprecise — it's not \"no clamp exists,\" it's that the threshold isn't reached. Option D is wrong because each recursive call happens in a fresh, unwound stack (a new macrotask), not synchronous recursion, so there's no stack growth.",[15,70016,70017,70021,70053],{},[18,70018,70020],{"id":70019},"q7-what-is-the-core-conceptual-difference-between-debouncing-and-throttling-a-function","Q7. What is the core conceptual difference between debouncing and throttling a function?",[23,70022,70024,70030,70036,70042],{"className":70023},[26],[28,70025,70027,70029],{"className":70026},[31],[33,70028],{"disabled":35,"type":36}," They are the same technique with different names",[28,70031,70033,70035],{"className":70032},[31],[33,70034],{"disabled":35,"type":36}," Debounce delays execution until a pause in calls; throttle guarantees execution at most once per fixed time window, even during continuous calls",[28,70037,70039,70041],{"className":70038},[31],[33,70040],{"disabled":35,"type":36}," Debounce runs the function on a background thread; throttle runs it on the main thread",[28,70043,70045,70047,70048,70050,70051],{"className":70044},[31],[33,70046],{"disabled":35,"type":36}," Throttle only works with ",[39,70049,47386],{},"; debounce only works with ",[39,70052,9578],{},[66,70054,70055,70057,70062],{},[69,70056,71],{},[73,70058,70059,70061],{},[76,70060,78],{}," B — Debounce delays execution until a pause in calls; throttle guarantees execution at most once per fixed time window, even during continuous calls",[73,70063,70064,70066,70067,70070,70071,70073],{},[76,70065,84],{}," Debounce resets a timer on every call and only fires once the calls ",[104,70068,70069],{},"stop"," for the configured wait period — ideal for \"wait until the user stops typing.\" Throttle instead enforces a rate ceiling, letting the function run at regular intervals ",[104,70072,11160],{}," calls keep coming — ideal for \"update at most every 200ms while scrolling.\" They solve related but distinct problems, so treating them as interchangeable (option A) is a common but incorrect simplification that leads to picking the wrong one for a given UI interaction.",[15,70075,70076,70080,70145,70154,70188],{"language":247},[18,70077,70079],{"id":70078},"q8-a-naive-polling-interval-assumes-each-tick-fires-exactly-on-schedule","Q8. A naive polling interval assumes each tick fires exactly on schedule:",[257,70081,70082],{"language":247},[260,70083,70085],{"className":262,"code":70084,"language":247,"meta":264,"style":264},"setInterval(() => {\n  const start = Date.now();\n  doExpensiveWork();\n  console.log(Date.now() - start);\n}, 100);\n",[39,70086,70087,70097,70112,70119,70137],{"__ignoreMap":264},[268,70088,70089,70091,70093,70095],{"class":270,"line":271},[268,70090,47386],{"class":278},[268,70092,9411],{"class":282},[268,70094,9414],{"class":274},[268,70096,9914],{"class":282},[268,70098,70099,70101,70104,70106,70108,70110],{"class":270,"line":286},[268,70100,12441],{"class":274},[268,70102,70103],{"class":305}," start",[268,70105,616],{"class":274},[268,70107,49122],{"class":282},[268,70109,49125],{"class":278},[268,70111,794],{"class":282},[268,70113,70114,70117],{"class":270,"line":296},[268,70115,70116],{"class":278},"  doExpensiveWork",[268,70118,794],{"class":282},[268,70120,70121,70123,70125,70128,70130,70132,70134],{"class":270,"line":311},[268,70122,5556],{"class":282},[268,70124,1356],{"class":278},[268,70126,70127],{"class":282},"(Date.",[268,70129,49125],{"class":278},[268,70131,16182],{"class":282},[268,70133,6244],{"class":274},[268,70135,70136],{"class":282}," start);\n",[268,70138,70139,70141,70143],{"class":270,"line":788},[268,70140,50490],{"class":282},[268,70142,13912],{"class":305},[268,70144,628],{"class":282},[73,70146,70147,70148,70151,70152,38654],{},"If ",[39,70149,70150],{},"doExpensiveWork()"," occasionally takes 150ms, what is the practical consequence of using ",[39,70153,47386],{},[23,70155,70157,70165,70174,70182],{"className":70156},[26],[28,70158,70160,355,70162,70164],{"className":70159},[31],[33,70161],{"disabled":35,"type":36},[39,70163,47386],{}," automatically skips the next tick to compensate, keeping long-run timing perfectly accurate",[28,70166,70168,70170,70171,70173],{"className":70167},[31],[33,70169],{"disabled":35,"type":36}," Ticks can effectively overlap or fire back-to-back with no gap once the callback finally returns, since the browser only queues the ",[104,70172,16949],{}," invocation and doesn't wait for slow callbacks to \"catch up\" gracefully — leading to drift and, if the callback consistently runs long, calls stacking up as fast as the engine can process them",[28,70175,70177,355,70179,70181],{"className":70176},[31],[33,70178],{"disabled":35,"type":36},[39,70180,47386],{}," throws an error once a callback exceeds the interval duration",[28,70183,70185,70187],{"className":70184},[31],[33,70186],{"disabled":35,"type":36}," The interval pauses entirely until the slow callback completes, then resumes exactly on the original 100ms grid",[66,70189,70190,70192,70197],{},[69,70191,71],{},[73,70193,70194,70196],{},[76,70195,78],{}," B — Ticks can effectively overlap or fire back-to-back with no gap once the callback finally returns, since the browser only queues the next invocation and doesn't wait for slow callbacks to catch up gracefully — leading to drift and, if the callback consistently runs long, calls stacking up as fast as the engine can process them",[73,70198,70199,355,70201,70203,70204,70206,70207,70209,70210,70212],{},[76,70200,84],{},[39,70202,47386],{}," doesn't run callbacks concurrently (JS is single-threaded), but it also doesn't intelligently reschedule around slow callbacks — if a tick takes longer than the interval, the ",[104,70205,16949],{}," tick is still just queued as soon as possible once the thread is free, meaning back-to-back execution with no actual pause, and the wall-clock spacing between ticks silently drifts away from the requested ",[39,70208,49225],{},". Over many iterations with an unreliable callback duration, this compounds into meaningful timing drift, which is why polling loops susceptible to variable-duration work are usually rewritten with self-rescheduling ",[39,70211,9578],{}," (see Q15) instead. Option A and D describe smart compensation the API doesn't actually implement.",[15,70214,70215,70222,70249],{},[18,70216,70218,70219,70221],{"id":70217},"q9-a-setinterval-is-running-to-poll-a-server-every-5-seconds-the-user-switches-to-a-different-browser-tab-for-10-minutes-what-commonly-happens-to-the-timers-firing-rate-in-most-modern-browsers","Q9. A ",[39,70220,47386],{}," is running to poll a server every 5 seconds. The user switches to a different browser tab for 10 minutes. What commonly happens to the timer's firing rate in most modern browsers?",[23,70223,70225,70231,70237,70243],{"className":70224},[26],[28,70226,70228,70230],{"className":70227},[31],[33,70229],{"disabled":35,"type":36}," It continues firing exactly every 5 seconds, unaffected by tab visibility",[28,70232,70234,70236],{"className":70233},[31],[33,70235],{"disabled":35,"type":36}," It stops firing completely and never resumes, even after the tab becomes visible again",[28,70238,70240,70242],{"className":70239},[31],[33,70241],{"disabled":35,"type":36}," Browsers throttle timers in background\u002Finactive tabs (often to no more than once per second, and more aggressively for long-backgrounded tabs) to save power and CPU",[28,70244,70246,70248],{"className":70245},[31],[33,70247],{"disabled":35,"type":36}," The interval speeds up to \"catch up\" once the tab regains focus",[66,70250,70251,70253,70258],{},[69,70252,71],{},[73,70254,70255,70257],{},[76,70256,78],{}," C — Browsers throttle timers in background\u002Finactive tabs (often to no more than once per second, and more aggressively for long-backgrounded tabs) to save power and CPU",[73,70259,70260,355,70262,70264,70265,70267,70268,70271],{},[76,70261,84],{},[76,70263,438],{}," modern browsers deliberately deprioritize timers in inactive tabs — a 5-second interval might slow to firing once per second or even less frequently the longer the tab stays backgrounded, and mobile browsers can throttle even more aggressively. This is intentional battery\u002FCPU conservation, not a bug, but it surprises developers who assume timers are exact and can cause \"why did polling stop working\" bug reports. ",[76,70266,182],{}," the exact throttling thresholds are browser-specific and not standardized, so code with hard real-time requirements shouldn't rely on background timer precision at all — visibility-aware logic (",[39,70269,70270],{},"document.visibilityState",") or server push (WebSockets) is more appropriate. Option A ignores this well-documented throttling; option B and D describe behaviors that don't match how throttling actually works (it slows, it doesn't stop or \"catch up\").",[15,70273,70274,70278,70332,70382],{"language":247},[18,70275,70277],{"id":70276},"q10-what-does-this-loop-log-and-why","Q10. What does this loop log, and why?",[257,70279,70280],{"language":247},[260,70281,70282],{"className":262,"code":37579,"language":247,"meta":264,"style":264},[39,70283,70284,70310,70328],{"__ignoreMap":264},[268,70285,70286,70288,70290,70292,70294,70296,70298,70300,70302,70304,70306,70308],{"class":270,"line":271},[268,70287,6926],{"class":274},[268,70289,2182],{"class":282},[268,70291,1440],{"class":274},[268,70293,9384],{"class":282},[268,70295,302],{"class":274},[268,70297,5728],{"class":305},[268,70299,9391],{"class":282},[268,70301,1076],{"class":274},[268,70303,3396],{"class":305},[268,70305,9398],{"class":282},[268,70307,9401],{"class":274},[268,70309,1235],{"class":282},[268,70311,70312,70314,70316,70318,70320,70322,70324,70326],{"class":270,"line":286},[268,70313,9408],{"class":278},[268,70315,9411],{"class":282},[268,70317,9414],{"class":274},[268,70319,9417],{"class":282},[268,70321,1356],{"class":278},[268,70323,9422],{"class":282},[268,70325,3307],{"class":305},[268,70327,628],{"class":282},[268,70329,70330],{"class":270,"line":296},[268,70331,314],{"class":282},[23,70333,70335,70346,70360,70372],{"className":70334},[26],[28,70336,70338,355,70340,70342,70343,70345],{"className":70337},[31],[33,70339],{"disabled":35,"type":36},[39,70341,9494],{}," — each callback closes over the value of ",[39,70344,9509],{}," at the time it was scheduled",[28,70347,70349,355,70351,70353,70354,70356,70357,70359],{"className":70348},[31],[33,70350],{"disabled":35,"type":36},[39,70352,9505],{}," — all three callbacks share the same ",[39,70355,9568],{},", which has finished looping to ",[39,70358,3423],{}," by the time any of them run",[28,70361,70363,355,70365,70368,70369,70371],{"className":70362},[31],[33,70364],{"disabled":35,"type":36},[39,70366,70367],{},"0, 0, 0"," — each closure captures ",[39,70370,9509],{}," as it was on the first iteration",[28,70373,70375,1271,70377,183,70379,70381],{"className":70374},[31],[33,70376],{"disabled":35,"type":36},[39,70378,815],{},[39,70380,9509],{}," is out of scope in the callback",[66,70383,70384,70386,70396],{},[69,70385,71],{},[73,70387,70388,1727,70390,70353,70392,70356,70394,70359],{},[76,70389,78],{},[39,70391,9505],{},[39,70393,9568],{},[39,70395,3423],{},[73,70397,70398,355,70400,70402,70403,355,70405,70407,70408,70410,70411,5425,70413,70415,70416,70419,70420,2029,70422,70424,70425,70428,70429,70431,70432,70434],{},[76,70399,84],{},[39,70401,1440],{}," is function-scoped, not block-scoped, so there is only ",[104,70404,9572],{},[39,70406,9509],{}," binding shared by the loop and all three closures. Since ",[39,70409,9578],{}," always defers execution to a later macrotask (per Q2), the loop finishes completely — incrementing ",[39,70412,9509],{},[39,70414,3423],{}," and failing the ",[39,70417,70418],{},"i \u003C 3"," check — before any of the callbacks actually run, so every closure reads the same final value. This is one of the most famous JavaScript interview gotchas; the fix is replacing ",[39,70421,1440],{},[39,70423,240],{},", which creates a fresh binding per iteration, making option A the ",[104,70426,70427],{},"correct"," behavior for a ",[39,70430,240],{},"-based loop but not for this ",[39,70433,1440],{},"-based one.",[15,70436,70437,70447,70484],{},[18,70438,70440,70441,99,70444,65680],{"id":70439},"q11-what-does-settimeoutfn-100-or-settimeoutfn-abc-do","Q11. What does ",[39,70442,70443],{},"setTimeout(fn, -100)",[39,70445,70446],{},"setTimeout(fn, \"abc\")",[23,70448,70450,70459,70470,70476],{"className":70449},[26],[28,70451,70453,70455,70456,70458],{"className":70452},[31],[33,70454],{"disabled":35,"type":36}," Both throw a ",[39,70457,827],{}," immediately",[28,70460,70462,70464,70465,3990,70467,70469],{"className":70461},[31],[33,70463],{"disabled":35,"type":36}," A negative or non-numeric (NaN-producing) delay is treated as ",[39,70466,3307],{},[39,70468,37837],{}," is still scheduled as a macrotask on the next available tick",[28,70471,70473,70475],{"className":70472},[31],[33,70474],{"disabled":35,"type":36}," Negative delays run the function immediately and synchronously, before the current line finishes",[28,70477,70479,70481,70482,52174],{"className":70478},[31],[33,70480],{"disabled":35,"type":36}," The call is silently ignored and ",[39,70483,37837],{},[66,70485,70486,70488,70497],{},[69,70487,71],{},[73,70489,70490,70492,70493,3990,70495,70469],{},[76,70491,78],{}," B — A negative or non-numeric (NaN-producing) delay is treated as ",[39,70494,3307],{},[39,70496,37837],{},[73,70498,70499,70501,70502,70504,70505,70507,70508,70510],{},[76,70500,84],{}," Per the HTML timer spec, an invalid delay (negative, ",[39,70503,3040],{},", or omitted) is clamped to the minimum allowed value, effectively ",[39,70506,3307],{}," — it does not throw and does not run synchronously. This still goes through the normal macrotask-queuing behavior from Q2, so ",[39,70509,37837],{}," runs after the current synchronous code completes, not immediately inline. Option C is the tempting trap of assuming a negative number somehow means \"run before now,\" which isn't possible in an event-loop model. Option D and A both invent stricter failure behavior than what actually happens.",[15,70512,70513,70520,70562,70594],{"language":247},[18,70514,70516,70517,70519],{"id":70515},"q12-a-component-sets-up-an-interval-on-mount-and-stores-the-id-but-a-bug-elsewhere-in-the-app-accidentally-calls-clearinterval-twice-with-the-same-id-once-in-a-cleanup-function-once-in-an-unrelated-handler-what-happens-on-the-second-call","Q12. A component sets up an interval on mount and stores the id, but a bug elsewhere in the app accidentally calls ",[39,70518,69704],{}," twice with the same id (once in a cleanup function, once in an unrelated handler). What happens on the second call?",[257,70521,70522],{"language":247},[260,70523,70525],{"className":262,"code":70524,"language":247,"meta":264,"style":264},"const id = setInterval(poll, 1000);\nclearInterval(id);\nclearInterval(id); \u002F\u002F called again elsewhere\n",[39,70526,70527,70546,70552],{"__ignoreMap":264},[268,70528,70529,70531,70533,70535,70538,70541,70544],{"class":270,"line":271},[268,70530,243],{"class":274},[268,70532,4632],{"class":305},[268,70534,616],{"class":274},[268,70536,70537],{"class":278}," setInterval",[268,70539,70540],{"class":282},"(poll, ",[268,70542,70543],{"class":305},"1000",[268,70545,628],{"class":282},[268,70547,70548,70550],{"class":270,"line":286},[268,70549,69704],{"class":278},[268,70551,12284],{"class":282},[268,70553,70554,70556,70559],{"class":270,"line":296},[268,70555,69704],{"class":278},[268,70557,70558],{"class":282},"(id); ",[268,70560,70561],{"class":29390},"\u002F\u002F called again elsewhere\n",[23,70563,70565,70571,70582,70588],{"className":70564},[26],[28,70566,70568,70570],{"className":70567},[31],[33,70569],{"disabled":35,"type":36}," The second call throws because the interval is already cleared",[28,70572,70574,70576,70577,446,70579,70581],{"className":70573},[31],[33,70575],{"disabled":35,"type":36}," The second call is a harmless no-op, consistent with ",[39,70578,69701],{},[39,70580,69704],{}," accepting any id (valid, stale, or already-cleared) without error",[28,70583,70585,70587],{"className":70584},[31],[33,70586],{"disabled":35,"type":36}," The second call restarts the interval",[28,70589,70591,70593],{"className":70590},[31],[33,70592],{"disabled":35,"type":36}," The second call clears a different, unrelated timer due to id reuse",[66,70595,70596,70598,70607],{},[69,70597,71],{},[73,70599,70600,70602,70603,446,70605,70581],{},[76,70601,78],{}," B — The second call is a harmless no-op, consistent with ",[39,70604,69701],{},[39,70606,69704],{},[73,70608,70609,70611,70612,70615,70616,70618],{},[76,70610,84],{}," As established in Q3, clearing an already-cleared (or otherwise invalid) id is always safe and silent — there's no double-clear error to worry about. The subtler real risk here isn't the double-clear itself, it's option D's premise: timer ids ",[104,70613,70614],{},"are"," recycled by the engine once freed, so in a codebase with sloppy id bookkeeping, holding onto a stale id and clearing it \"late\" could — in a pathological, contrived case — coincide with an id reused for a newer, unrelated timer. In practice this requires mismanaging ids across unrelated code paths and is a code-hygiene problem, not something ",[39,70617,69704],{}," itself does wrong; keeping id ownership local to the code that created the timer avoids it entirely.",[15,70620,70621,70631,70661],{},[18,70622,70624,70625,70627,70628,70630],{"id":70623},"q13-unlike-setinterval-what-happens-to-a-pending-requestanimationframe-callback-when-its-tab-is-backgrounded-not-visible","Q13. Unlike ",[39,70626,47386],{},", what happens to a pending ",[39,70629,62893],{}," callback when its tab is backgrounded (not visible)?",[23,70632,70634,70640,70646,70652],{"className":70633},[26],[28,70635,70637,70639],{"className":70636},[31],[33,70638],{"disabled":35,"type":36}," It fires at the same rate regardless of visibility, since rAF is not subject to browser throttling",[28,70641,70643,70645],{"className":70642},[31],[33,70644],{"disabled":35,"type":36}," Browsers pause rAF callbacks entirely for hidden\u002Finactive tabs (no repaint needed), only resuming once the tab becomes visible again",[28,70647,70649,70651],{"className":70648},[31],[33,70650],{"disabled":35,"type":36}," rAF throws an error if called while the tab is hidden",[28,70653,70655,70657,70658,70660],{"className":70654},[31],[33,70656],{"disabled":35,"type":36}," rAF automatically converts itself into a ",[39,70659,47386],{}," while hidden",[66,70662,70663,70665,70670],{},[69,70664,71],{},[73,70666,70667,70669],{},[76,70668,78],{}," B — Browsers pause rAF callbacks entirely for hidden\u002Finactive tabs (no repaint needed), only resuming once the tab becomes visible again",[73,70671,70672,355,70674,5887,70676,70678,70679,70682,70683,70685],{},[76,70673,84],{},[76,70675,438],{},[39,70677,62893],{},"'s entire purpose is to sync with the next paint, and hidden tabs don't paint, browsers simply stop invoking rAF callbacks while a tab is not visible — this is actually a ",[104,70680,70681],{},"feature",", not a limitation, since it means animation loops using rAF automatically pause and save CPU\u002Fbattery without any extra code. This is a meaningful practical difference from ",[39,70684,47386],{},"-driven \"animations,\" which keep running (heavily throttled per Q9, but not fully paused) in the background, silently wasting resources on work nobody will see. Code with logic that must keep running regardless of visibility (e.g., a countdown timer) should not rely on rAF for that reason.",[15,70687,70688,70698,70727],{},[18,70689,70691,70692,26924,70694,70697],{"id":70690},"q14-if-a-callback-registered-with-setinterval-takes-longer-than-the-interval-every-single-time-eg-a-500ms-interval-running-an-800ms-task-for-an-extended-period-what-is-the-realistic-outcome-as-opposed-to-a-naive-mental-model-of-queued-calls-piling-up-infinitely","Q14. If a callback registered with ",[39,70693,47386],{},[104,70695,70696],{},"longer"," than the interval every single time (e.g., a 500ms interval running an 800ms task) for an extended period, what is the realistic outcome, as opposed to a naive mental model of \"queued calls piling up infinitely\"?",[23,70699,70701,70707,70713,70721],{"className":70700},[26],[28,70702,70704,70706],{"className":70703},[31],[33,70705],{"disabled":35,"type":36}," The engine queues every missed tick and eventually executes a huge backlog all at once",[28,70708,70710,70712],{"className":70709},[31],[33,70711],{"disabled":35,"type":36}," The browser effectively runs the callback back-to-back as fast as the thread allows (since only one pending invocation is queued at a time), so the interval behaves closer to \"run continuously\" than \"run every 500ms,\" and the requested cadence is lost",[28,70714,70716,355,70718,70720],{"className":70715},[31],[33,70717],{"disabled":35,"type":36},[39,70719,47386],{}," automatically cancels itself after 3 consecutive overruns",[28,70722,70724,70726],{"className":70723},[31],[33,70725],{"disabled":35,"type":36}," The browser spawns a new thread per overrun to keep up with the schedule",[66,70728,70729,70731,70736],{},[69,70730,71],{},[73,70732,70733,70735],{},[76,70734,78],{}," B — The browser effectively runs the callback back-to-back as fast as the thread allows (since only one pending invocation is queued at a time), so the interval behaves closer to \"run continuously\" than \"run every 500ms,\" and the requested cadence is lost",[73,70737,70738,70740,70741,70743,70744,70746,70747,70749,70750,70752],{},[76,70739,84],{}," Browsers do not queue unlimited backlog invocations of a ",[39,70742,47386],{}," callback (option A is a common but incorrect assumption) — implementations generally avoid stacking up multiple pending calls for the same interval, so a persistently-overrunning callback effectively degrades into running immediately after the previous call finishes, with no actual idle gap. This is the practical, worse cousin of the drift problem in Q8: not just imprecise timing, but the interval's requested cadence becoming meaningless. ",[76,70745,930],{}," the standard fix is a self-rescheduling ",[39,70748,9578],{}," that only queues the ",[104,70751,16949],{}," call after the current one finishes, so the true gap is always at least the intended delay (see Q15).",[15,70754,70755,70765,70812,70856],{"language":247},[18,70756,70758,70759,70761,70762,70764],{"id":70757},"q15-why-do-experienced-engineers-often-replace-setintervalfn-delay-with-a-recursive-settimeout-for-polling-loops","Q15. Why do experienced engineers often replace ",[39,70760,69720],{}," with a recursive ",[39,70763,9578],{}," for polling loops?",[257,70766,70767],{"language":247},[260,70768,70770],{"className":262,"code":70769,"language":247,"meta":264,"style":264},"function poll() {\n  doWork();\n  setTimeout(poll, 1000);\n}\nsetTimeout(poll, 1000);\n",[39,70771,70772,70781,70788,70798,70802],{"__ignoreMap":264},[268,70773,70774,70776,70779],{"class":270,"line":271},[268,70775,275],{"class":274},[268,70777,70778],{"class":278}," poll",[268,70780,283],{"class":282},[268,70782,70783,70786],{"class":270,"line":286},[268,70784,70785],{"class":278},"  doWork",[268,70787,794],{"class":282},[268,70789,70790,70792,70794,70796],{"class":270,"line":296},[268,70791,9408],{"class":278},[268,70793,70540],{"class":282},[268,70795,70543],{"class":305},[268,70797,628],{"class":282},[268,70799,70800],{"class":270,"line":311},[268,70801,314],{"class":282},[268,70803,70804,70806,70808,70810],{"class":270,"line":788},[268,70805,9578],{"class":278},[268,70807,70540],{"class":282},[268,70809,70543],{"class":305},[268,70811,628],{"class":282},[23,70813,70815,70827,70842,70850],{"className":70814},[26],[28,70816,70818,70820,70821,70823,70824,70826],{"className":70817},[31],[33,70819],{"disabled":35,"type":36}," Recursive ",[39,70822,9578],{}," runs faster than ",[39,70825,47386],{}," in every engine",[28,70828,70830,70832,70833,70835,70836,70838,70839,70841],{"className":70829},[31],[33,70831],{"disabled":35,"type":36}," It guarantees a minimum gap between the ",[104,70834,13951],{}," of one call and the ",[104,70837,13946],{}," of the next, avoiding the overlap\u002Fback-to-back execution risk that ",[39,70840,47386],{}," has when a callback runs long",[28,70843,70845,355,70847,70849],{"className":70844},[31],[33,70846],{"disabled":35,"type":36},[39,70848,47386],{}," is deprecated in modern JavaScript",[28,70851,70853,70855],{"className":70852},[31],[33,70854],{"disabled":35,"type":36}," It's purely stylistic; there's no functional difference",[66,70857,70858,70860,70867],{},[69,70859,71],{},[73,70861,70862,70864,70865,70841],{},[76,70863,78],{}," B — It guarantees a minimum gap between the end of one call and the start of the next, avoiding the overlap\u002Fback-to-back execution risk that ",[39,70866,47386],{},[73,70868,70869,355,70871,70873,70874,70876,70877,355,70879,70882,70883,70885,70886,70888,70889,70891],{},[76,70870,84],{},[76,70872,930],{}," because the next ",[39,70875,9578],{}," is only scheduled ",[104,70878,1747],{},[39,70880,70881],{},"doWork()"," finishes, the interval between invocations always includes both the requested delay and however long the previous call took — there's no risk of the pile-up behavior described in Q14, since a new timer is never queued until the current work is fully done. This makes recursive ",[39,70884,9578],{}," the safer default for polling\u002Fretry loops with variable-duration work. ",[39,70887,47386],{}," remains perfectly fine for short, reliably-fast, fixed-duration callbacks. Option C is false — ",[39,70890,47386],{}," isn't deprecated, just less safe for this specific case.",[15,70893,70894,70908,70991,71027],{"language":247},[18,70895,70897,70898,70900,70901,70904,70905,70907],{"id":70896},"q16-which-implementation-correctly-debounces-fn-so-it-only-runs-once-wait-ms-after-the-last-call","Q16. Which implementation correctly debounces ",[39,70899,37837],{}," so it only runs once, ",[39,70902,70903],{},"wait"," ms after the ",[104,70906,6891],{}," call?",[257,70909,70910],{"language":247},[260,70911,70913],{"className":262,"code":70912,"language":247,"meta":264,"style":264},"function debounce(fn, wait) {\n  let timer;\n  return function (...args) {\n    clearTimeout(timer);\n    timer = setTimeout(() => fn.apply(this, args), wait);\n  };\n}\n",[39,70914,70915,70931,70938,70952,70959,70983,70987],{"__ignoreMap":264},[268,70916,70917,70919,70921,70923,70925,70927,70929],{"class":270,"line":271},[268,70918,275],{"class":274},[268,70920,40746],{"class":278},[268,70922,622],{"class":282},[268,70924,37837],{"class":1222},[268,70926,42],{"class":282},[268,70928,70903],{"class":1222},[268,70930,1235],{"class":282},[268,70932,70933,70935],{"class":270,"line":286},[268,70934,2206],{"class":274},[268,70936,70937],{"class":282}," timer;\n",[268,70939,70940,70942,70944,70946,70948,70950],{"class":270,"line":296},[268,70941,1240],{"class":274},[268,70943,12080],{"class":274},[268,70945,2182],{"class":282},[268,70947,15329],{"class":274},[268,70949,40270],{"class":1222},[268,70951,1235],{"class":282},[268,70953,70954,70956],{"class":270,"line":311},[268,70955,40783],{"class":278},[268,70957,70958],{"class":282},"(timer);\n",[268,70960,70961,70964,70966,70968,70970,70972,70974,70976,70978,70980],{"class":270,"line":788},[268,70962,70963],{"class":282},"    timer ",[268,70965,302],{"class":274},[268,70967,40796],{"class":278},[268,70969,9411],{"class":282},[268,70971,9414],{"class":274},[268,70973,40288],{"class":282},[268,70975,34637],{"class":278},[268,70977,622],{"class":282},[268,70979,950],{"class":305},[268,70981,70982],{"class":282},", args), wait);\n",[268,70984,70985],{"class":270,"line":1951},[268,70986,15185],{"class":282},[268,70988,70989],{"class":270,"line":8955},[268,70990,314],{"class":282},[23,70992,70994,71006,71012,71021],{"className":70993},[26],[28,70995,70997,70999,71000,71002,71003,71005],{"className":70996},[31],[33,70998],{"disabled":35,"type":36}," This is broken — it needs to call ",[39,71001,37837],{}," immediately, then block further calls for ",[39,71004,70903],{}," ms",[28,71007,71009,71011],{"className":71008},[31],[33,71010],{"disabled":35,"type":36}," This is correct — clearing the previous timer on every call means only the last call's scheduled invocation ever actually fires",[28,71013,71015,71017,71018,71020],{"className":71014},[31],[33,71016],{"disabled":35,"type":36}," This is broken — ",[39,71019,69701],{}," inside the returned function causes an infinite loop",[28,71022,71024,71026],{"className":71023},[31],[33,71025],{"disabled":35,"type":36}," This is correct, but only works for functions that take no arguments",[66,71028,71029,71031,71036],{},[69,71030,71],{},[73,71032,71033,71035],{},[76,71034,78],{}," B — This is correct — clearing the previous timer on every call means only the last call's scheduled invocation ever actually fires",[73,71037,71038,71040,71041,71044,71045,71047,71048,71050,71051,71053,71054,71057,71058,71060],{},[76,71039,84],{}," Each invocation cancels whatever timer the ",[104,71042,71043],{},"previous"," call had queued (a harmless no-op per Q3 if it already fired) and starts a fresh one; as long as calls keep arriving faster than ",[39,71046,70903],{},", no scheduled ",[39,71049,37837],{}," call ever survives long enough to execute, so only the final call — the one with no subsequent call to cancel it — actually runs, ",[39,71052,70903],{}," ms after that last call. Option A describes throttle-with-leading-edge behavior, a different (also valid) pattern, but not what \"debounce\" means. Option D is wrong — ",[39,71055,71056],{},"fn.apply(this, args)"," correctly forwards whatever arguments and ",[39,71059,950],{}," context the wrapped call received.",[15,71062,71063,71073,71191,71230],{"language":247},[18,71064,71066,71067,71069,71070,71072],{"id":71065},"q17-which-implementation-correctly-throttles-fn-to-run-at-most-once-every-wait-ms-even-under-continuous-calls","Q17. Which implementation correctly throttles ",[39,71068,37837],{}," to run at most once every ",[39,71071,70903],{}," ms, even under continuous calls?",[257,71074,71075],{"language":247},[260,71076,71078],{"className":262,"code":71077,"language":247,"meta":264,"style":264},"function throttle(fn, wait) {\n  let lastCall = 0;\n  return function (...args) {\n    const now = Date.now();\n    if (now - lastCall >= wait) {\n      lastCall = now;\n      fn.apply(this, args);\n    }\n  };\n}\n",[39,71079,71080,71097,71110,71124,71139,71155,71165,71179,71183,71187],{"__ignoreMap":264},[268,71081,71082,71084,71087,71089,71091,71093,71095],{"class":270,"line":271},[268,71083,275],{"class":274},[268,71085,71086],{"class":278}," throttle",[268,71088,622],{"class":282},[268,71090,37837],{"class":1222},[268,71092,42],{"class":282},[268,71094,70903],{"class":1222},[268,71096,1235],{"class":282},[268,71098,71099,71101,71104,71106,71108],{"class":270,"line":286},[268,71100,2206],{"class":274},[268,71102,71103],{"class":282}," lastCall ",[268,71105,302],{"class":274},[268,71107,5728],{"class":305},[268,71109,293],{"class":282},[268,71111,71112,71114,71116,71118,71120,71122],{"class":270,"line":296},[268,71113,1240],{"class":274},[268,71115,12080],{"class":274},[268,71117,2182],{"class":282},[268,71119,15329],{"class":274},[268,71121,40270],{"class":1222},[268,71123,1235],{"class":282},[268,71125,71126,71128,71131,71133,71135,71137],{"class":270,"line":311},[268,71127,37893],{"class":274},[268,71129,71130],{"class":305}," now",[268,71132,616],{"class":274},[268,71134,49122],{"class":282},[268,71136,49125],{"class":278},[268,71138,794],{"class":282},[268,71140,71141,71143,71146,71148,71150,71152],{"class":270,"line":788},[268,71142,9686],{"class":274},[268,71144,71145],{"class":282}," (now ",[268,71147,6244],{"class":274},[268,71149,71103],{"class":282},[268,71151,6779],{"class":274},[268,71153,71154],{"class":282}," wait) {\n",[268,71156,71157,71160,71162],{"class":270,"line":1951},[268,71158,71159],{"class":282},"      lastCall ",[268,71161,302],{"class":274},[268,71163,71164],{"class":282}," now;\n",[268,71166,71167,71170,71172,71174,71176],{"class":270,"line":8955},[268,71168,71169],{"class":282},"      fn.",[268,71171,34637],{"class":278},[268,71173,622],{"class":282},[268,71175,950],{"class":305},[268,71177,71178],{"class":282},", args);\n",[268,71180,71181],{"class":270,"line":8966},[268,71182,11972],{"class":282},[268,71184,71185],{"class":270,"line":8974},[268,71186,15185],{"class":282},[268,71188,71189],{"class":270,"line":8985},[268,71190,314],{"class":282},[23,71192,71194,71203,71215,71224],{"className":71193},[26],[28,71195,71197,71199,71200,71202],{"className":71196},[31],[33,71198],{"disabled":35,"type":36}," This is broken — it never calls ",[39,71201,37837],{}," more than once, ever",[28,71204,71206,71208,71209,71211,71212,71214],{"className":71205},[31],[33,71207],{"disabled":35,"type":36}," This is correct — it only invokes ",[39,71210,37837],{}," when at least ",[39,71213,70903],{}," ms have passed since the last actual invocation, allowing calls at a steady rate rather than resetting on every call like debounce",[28,71216,71218,71017,71220,71223],{"className":71217},[31],[33,71219],{"disabled":35,"type":36},[39,71221,71222],{},"Date.now()"," cannot be used for timing comparisons",[28,71225,71227,71229],{"className":71226},[31],[33,71228],{"disabled":35,"type":36}," This is identical to the debounce implementation in Q16, just renamed",[66,71231,71232,71234,71243],{},[69,71233,71],{},[73,71235,71236,71238,71239,71211,71241,71214],{},[76,71237,78],{}," B — This is correct — it only invokes ",[39,71240,37837],{},[39,71242,70903],{},[73,71244,71245,71247,71248,71250,71251,71253,71254,71256,71257,446,71259,71261,71262,71264,71265,71267],{},[76,71246,84],{}," Unlike debounce (which cancels and restarts a timer on every call, so continuous calls can starve execution indefinitely), this throttle checks elapsed time on every call and lets ",[39,71249,37837],{}," fire as soon as the window has passed, then immediately starts a new window — so during a sustained burst (e.g., a ",[39,71252,62345],{}," handler), ",[39,71255,37837],{}," still executes periodically instead of waiting for a pause. Option D is a common conflation, but the two implementations are meaningfully different: debounce uses ",[39,71258,9578],{},[39,71260,69701],{}," and fires ",[104,71263,1747],{}," activity stops, while this throttle uses a timestamp comparison and fires ",[104,71266,47814],{}," continuous activity, at most once per window.",[15,71269,71270,71281,71318],{},[18,71271,71273,71274,71276,71277,71280],{"id":71272},"q18-a-developer-builds-a-drag-to-reposition-ui-feature-and-updates-the-elements-position-inside-a-mousemove-handler-using-settimeoutupdate-16-scheduled-repeatedly-aiming-for-60fps-whats-the-more-idiomatic-approach","Q18. A developer builds a drag-to-reposition UI feature and updates the element's position inside a ",[39,71275,66817],{}," handler using ",[39,71278,71279],{},"setTimeout(update, 16)"," scheduled repeatedly, aiming for ~60fps. What's the more idiomatic approach?",[23,71282,71284,71290,71298,71307],{"className":71283},[26],[28,71285,71287,71289],{"className":71286},[31],[33,71288],{"disabled":35,"type":36}," This is already correct — 16ms is exactly one frame at 60fps",[28,71291,71293,4353,71295,71297],{"className":71292},[31],[33,71294],{"disabled":35,"type":36},[39,71296,62893],{}," instead, since it syncs the visual update to the actual paint cycle rather than an approximate, drift-prone timer interval, and automatically pauses when the tab is hidden",[28,71299,71301,71303,71304,71306],{"className":71300},[31],[33,71302],{"disabled":35,"type":36}," Reduce the delay to ",[39,71305,3307],{}," for maximum responsiveness",[28,71308,71310,4353,71312,71315,71316],{"className":71309},[31],[33,71311],{"disabled":35,"type":36},[39,71313,71314],{},"setInterval(update, 16)"," instead, since intervals are more precise than repeated ",[39,71317,9578],{},[66,71319,71320,71322,71328],{},[69,71321,71],{},[73,71323,71324,4409,71326,71297],{},[76,71325,78],{},[39,71327,62893],{},[73,71329,71330,355,71332,355,71334,71337,71338,71341,71342,446,71344,71346,71347,71349,71350,71352],{},[76,71331,84],{},[76,71333,930],{},[39,71335,71336],{},"16ms"," is only an ",[104,71339,71340],{},"approximation"," of one frame at exactly 60Hz — actual refresh rates vary (90Hz, 120Hz, or throttled displays), and timer-based scheduling has no knowledge of the browser's actual paint schedule, so visual updates driven by ",[39,71343,9578],{},[39,71345,47386],{}," can land at the wrong moment relative to a repaint, causing visible jank or wasted work. ",[39,71348,62893],{}," (from Q5) is purpose-built to solve exactly this, and as a bonus pauses automatically in hidden tabs (Q13), unlike option D's ",[39,71351,47386],{},", which keeps running (throttled) in the background for no visual benefit.",[15,71354,71355,71362,71416,71454],{"language":247},[18,71356,71358,71359,71361],{"id":71357},"q19-a-component-adds-a-setinterval-for-auto-refreshing-data-when-it-mounts-what-is-the-idiomatic-cleanup-requirement-and-what-bug-results-if-its-skipped","Q19. A component adds a ",[39,71360,47386],{}," for auto-refreshing data when it mounts. What is the idiomatic cleanup requirement, and what bug results if it's skipped?",[257,71363,71364],{"language":247},[260,71365,71367],{"className":262,"code":71366,"language":247,"meta":264,"style":264},"useEffect(() => {\n  const id = setInterval(fetchLatest, 5000);\n  return () => clearInterval(id);\n}, []);\n",[39,71368,71369,71380,71398,71411],{"__ignoreMap":264},[268,71370,71371,71374,71376,71378],{"class":270,"line":271},[268,71372,71373],{"class":278},"useEffect",[268,71375,9411],{"class":282},[268,71377,9414],{"class":274},[268,71379,9914],{"class":282},[268,71381,71382,71384,71386,71388,71390,71393,71396],{"class":270,"line":286},[268,71383,12441],{"class":274},[268,71385,4632],{"class":305},[268,71387,616],{"class":274},[268,71389,70537],{"class":278},[268,71391,71392],{"class":282},"(fetchLatest, ",[268,71394,71395],{"class":305},"5000",[268,71397,628],{"class":282},[268,71399,71400,71402,71404,71406,71409],{"class":270,"line":296},[268,71401,1240],{"class":274},[268,71403,15158],{"class":282},[268,71405,9414],{"class":274},[268,71407,71408],{"class":278}," clearInterval",[268,71410,12284],{"class":282},[268,71412,71413],{"class":270,"line":311},[268,71414,71415],{"class":282},"}, []);\n",[23,71417,71419,71428,71438,71446],{"className":71418},[26],[28,71420,71422,4396,71424,71427],{"className":71421},[31],[33,71423],{"disabled":35,"type":36},[39,71425,71426],{},"return () => clearInterval(id)"," line is unnecessary boilerplate and can be removed safely",[28,71429,71431,71433,71434,71437],{"className":71430},[31],[33,71432],{"disabled":35,"type":36}," Skipping the cleanup leaks the interval — it keeps firing after the component unmounts, potentially calling ",[39,71435,71436],{},"fetchLatest"," (and any state updates it triggers) against a component that no longer exists, wasting resources or throwing warnings",[28,71439,71441,355,71443,71445],{"className":71440},[31],[33,71442],{"disabled":35,"type":36},[39,71444,69704],{}," must be called synchronously, not inside a cleanup function",[28,71447,71449,355,71451,71453],{"className":71448},[31],[33,71450],{"disabled":35,"type":36},[39,71452,47386],{}," automatically stops itself when the component unmounts, without explicit cleanup",[66,71455,71456,71458,71465],{},[69,71457,71],{},[73,71459,71460,71462,71463,71437],{},[76,71461,78],{}," B — Skipping the cleanup leaks the interval — it keeps firing after the component unmounts, potentially calling ",[39,71464,71436],{},[73,71466,71467,355,71469,71471,71472,71474,71475,71477,71478,71480],{},[76,71468,84],{},[76,71470,930],{}," timers are entirely independent of any UI framework's component lifecycle — nothing automatically stops a ",[39,71473,47386],{}," just because the component that created it was removed from the tree (option D is false). Without the cleanup function calling ",[39,71476,69800],{}," on unmount, the interval keeps running indefinitely, continuing to invoke ",[39,71479,71436],{}," and any state-setting logic inside it, which is a classic source of memory leaks and \"can't update state on an unmounted component\" warnings in UI frameworks. This is a specific case of the general rule: any subscription-like resource (timers, event listeners, observers) needs matching teardown.",[15,71482,71483,71487,71514],{},[18,71484,71486],{"id":71485},"q20-a-search-box-needs-to-hit-an-autocomplete-api-as-the-user-types-and-a-separate-feature-needs-to-update-a-scroll-progress-indicator-as-the-user-scrolls-the-page-which-combination-is-the-idiomatic-choice","Q20. A search box needs to hit an autocomplete API as the user types, and a separate feature needs to update a \"scroll progress\" indicator as the user scrolls the page. Which combination is the idiomatic choice?",[23,71488,71490,71496,71502,71508],{"className":71489},[26],[28,71491,71493,71495],{"className":71492},[31],[33,71494],{"disabled":35,"type":36}," Debounce both — waiting for a pause makes sense for both features",[28,71497,71499,71501],{"className":71498},[31],[33,71500],{"disabled":35,"type":36}," Throttle both — a steady rate limit is correct for both features",[28,71503,71505,71507],{"className":71504},[31],[33,71506],{"disabled":35,"type":36}," Debounce the search input (fire the API call after typing pauses); throttle the scroll handler (update the indicator at a steady rate during continuous scrolling)",[28,71509,71511,71513],{"className":71510},[31],[33,71512],{"disabled":35,"type":36}," Neither needs rate-limiting — modern browsers handle this automatically",[66,71515,71516,71518,71523],{},[69,71517,71],{},[73,71519,71520,71522],{},[76,71521,78],{}," C — Debounce the search input (fire the API call after typing pauses); throttle the scroll handler (update the indicator at a steady rate during continuous scrolling)",[73,71524,71525,355,71527,71529,71530,71532,71533,71535,71536,71539],{},[76,71526,84],{},[76,71528,930],{}," these are the textbook use cases for each technique, precisely because of the semantic difference established in Q7 and Q16\u002FQ17. Search-as-you-type benefits from ",[104,71531,49236],{}," until the user pauses — firing an API request after every keystroke wastes bandwidth and creates race conditions between in-flight requests (see Q19 in the Web Storage & APIs quiz on ",[39,71534,39934],{},"), so debounce is correct. A scroll progress indicator, by contrast, needs to visibly ",[104,71537,71538],{},"keep updating"," throughout continuous scrolling rather than going silent until scrolling stops — using debounce there would make the UI look frozen during the scroll and only \"catch up\" once the user stops, which is the wrong feel; throttle keeps it responsive at a bounded, performance-friendly update rate instead.",[2107,71541,50703],{},{"title":264,"searchDepth":286,"depth":286,"links":71543},[71544,71546,71548,71550,71552,71554,71555,71556,71557,71559,71560,71562,71564,71566,71568,71570,71572,71574,71576,71578],{"id":69428,"depth":296,"text":71545},"Q1. What does the second argument to setTimeout(fn, delay) actually guarantee?",{"id":69507,"depth":296,"text":71547},"Q2. What happens when you call setTimeout(fn, 0)?",{"id":69648,"depth":296,"text":71549},"Q3. What does clearTimeout(id) do if id refers to a timer that has already fired?",{"id":69716,"depth":296,"text":71551},"Q4. What is the defining behavior of setInterval(fn, delay) compared to a single setTimeout?",{"id":69814,"depth":296,"text":71553},"Q5. Why is requestAnimationFrame (rAF) preferred over setTimeout\u002FsetInterval for JavaScript-driven animations?",{"id":69884,"depth":296,"text":69885},{"id":70019,"depth":296,"text":70020},{"id":70078,"depth":296,"text":70079},{"id":70217,"depth":296,"text":71558},"Q9. A setInterval is running to poll a server every 5 seconds. The user switches to a different browser tab for 10 minutes. What commonly happens to the timer's firing rate in most modern browsers?",{"id":70276,"depth":296,"text":70277},{"id":70439,"depth":296,"text":71561},"Q11. What does setTimeout(fn, -100) or setTimeout(fn, \"abc\") do?",{"id":70515,"depth":296,"text":71563},"Q12. A component sets up an interval on mount and stores the id, but a bug elsewhere in the app accidentally calls clearInterval twice with the same id (once in a cleanup function, once in an unrelated handler). What happens on the second call?",{"id":70623,"depth":296,"text":71565},"Q13. Unlike setInterval, what happens to a pending requestAnimationFrame callback when its tab is backgrounded (not visible)?",{"id":70690,"depth":296,"text":71567},"Q14. If a callback registered with setInterval takes longer than the interval every single time (e.g., a 500ms interval running an 800ms task) for an extended period, what is the realistic outcome, as opposed to a naive mental model of \"queued calls piling up infinitely\"?",{"id":70757,"depth":296,"text":71569},"Q15. Why do experienced engineers often replace setInterval(fn, delay) with a recursive setTimeout for polling loops?",{"id":70896,"depth":296,"text":71571},"Q16. Which implementation correctly debounces fn so it only runs once, wait ms after the last call?",{"id":71065,"depth":296,"text":71573},"Q17. Which implementation correctly throttles fn to run at most once every wait ms, even under continuous calls?",{"id":71272,"depth":296,"text":71575},"Q18. A developer builds a drag-to-reposition UI feature and updates the element's position inside a mousemove handler using setTimeout(update, 16) scheduled repeatedly, aiming for ~60fps. What's the more idiomatic approach?",{"id":71357,"depth":296,"text":71577},"Q19. A component adds a setInterval for auto-refreshing data when it mounts. What is the idiomatic cleanup requirement, and what bug results if it's skipped?",{"id":71485,"depth":296,"text":71486},{},"\u002Fjs\u002F22-timers-and-scheduling",{"title":69418,"description":264},"js\u002F22-timers-and-scheduling","xekT5WQneVovVKQdGCLjZFUcHZRq2avthVei9GZ0xZg",{"id":71585,"title":71586,"body":71587,"description":264,"extension":2144,"meta":75448,"navigation":35,"path":75449,"seo":75450,"stem":75451,"__hash__":75452},"content\u002Fjs\u002F23-functional-programming.md","23 — Functional Programming",{"type":8,"value":71588,"toc":75418},[71589,71592,71765,71877,71995,72172,72425,72637,72799,72961,73199,73502,73830,73955,74113,74344,74575,74739,74898,75116,75261,75415],[11,71590,71586],{"id":71591},"_23-functional-programming",[15,71593,71594,71601,71698,71731],{"language":247},[18,71595,71597,71598,1685],{"id":71596},"q1-which-function-below-is-a-pure-function","Q1. Which function below is a ",[76,71599,71600],{},"pure function",[257,71602,71603],{"language":247},[260,71604,71606],{"className":262,"code":71605,"language":247,"meta":264,"style":264},"let taxRate = 0.08;\n\nfunction priceWithTaxA(price) {\n  return price + price * taxRate;\n}\n\nfunction priceWithTaxB(price, rate) {\n  return price + price * rate;\n}\n",[39,71607,71608,71622,71626,71639,71654,71658,71662,71679,71694],{"__ignoreMap":264},[268,71609,71610,71612,71615,71617,71620],{"class":270,"line":271},[268,71611,240],{"class":274},[268,71613,71614],{"class":282}," taxRate ",[268,71616,302],{"class":274},[268,71618,71619],{"class":305}," 0.08",[268,71621,293],{"class":282},[268,71623,71624],{"class":270,"line":286},[268,71625,5033],{"emptyLinePlaceholder":35},[268,71627,71628,71630,71633,71635,71637],{"class":270,"line":296},[268,71629,275],{"class":274},[268,71631,71632],{"class":278}," priceWithTaxA",[268,71634,622],{"class":282},[268,71636,17225],{"class":1222},[268,71638,1235],{"class":282},[268,71640,71641,71643,71645,71647,71649,71651],{"class":270,"line":311},[268,71642,1240],{"class":274},[268,71644,36880],{"class":282},[268,71646,1246],{"class":274},[268,71648,36880],{"class":282},[268,71650,6134],{"class":274},[268,71652,71653],{"class":282}," taxRate;\n",[268,71655,71656],{"class":270,"line":788},[268,71657,314],{"class":282},[268,71659,71660],{"class":270,"line":1951},[268,71661,5033],{"emptyLinePlaceholder":35},[268,71663,71664,71666,71669,71671,71673,71675,71677],{"class":270,"line":8955},[268,71665,275],{"class":274},[268,71667,71668],{"class":278}," priceWithTaxB",[268,71670,622],{"class":282},[268,71672,17225],{"class":1222},[268,71674,42],{"class":282},[268,71676,36871],{"class":1222},[268,71678,1235],{"class":282},[268,71680,71681,71683,71685,71687,71689,71691],{"class":270,"line":8966},[268,71682,1240],{"class":274},[268,71684,36880],{"class":282},[268,71686,1246],{"class":274},[268,71688,36880],{"class":282},[268,71690,6134],{"class":274},[268,71692,71693],{"class":282}," rate;\n",[268,71695,71696],{"class":270,"line":8974},[268,71697,314],{"class":282},[23,71699,71701,71710,71719,71725],{"className":71700},[26],[28,71702,71704,355,71706,71709],{"className":71703},[31],[33,71705],{"disabled":35,"type":36},[39,71707,71708],{},"priceWithTaxA",", because it performs a calculation",[28,71711,71713,355,71715,71718],{"className":71712},[31],[33,71714],{"disabled":35,"type":36},[39,71716,71717],{},"priceWithTaxB",", because its output depends only on its arguments and it causes no observable side effects",[28,71720,71722,71724],{"className":71721},[31],[33,71723],{"disabled":35,"type":36}," Both are pure, since neither mutates its input",[28,71726,71728,71730],{"className":71727},[31],[33,71729],{"disabled":35,"type":36}," Neither is pure, since both perform arithmetic",[66,71732,71733,71735,71741],{},[69,71734,71],{},[73,71736,71737,1727,71739,71718],{},[76,71738,78],{},[39,71740,71717],{},[73,71742,71743,71745,71746,71748,71749,71751,71752,71755,71756,71758,71759,71761,71762,71764],{},[76,71744,84],{}," A pure function's return value must depend ",[104,71747,3117],{}," on its input parameters, with no reads of external mutable state and no side effects. ",[39,71750,71708],{}," reads the outer ",[39,71753,71754],{},"taxRate"," variable — if that variable changes between calls, the same ",[39,71757,17225],{}," argument produces a different result, which violates purity even though the function never mutates anything itself. ",[39,71760,71717],{}," closes over nothing external; every input it needs is passed explicitly, so it's deterministic and pure. This distinction matters in practice: ",[39,71763,71708],{}," is harder to test (you must control global state) and harder to reason about in concurrent\u002Fasync code.",[15,71766,71767,71774,71815,71848],{"language":247},[18,71768,71770,71771,71773],{"id":71769},"q2-why-is-the-following-function-considered-impure-beyond-just-it-uses-push","Q2. Why is the following function considered impure, beyond just \"it uses ",[39,71772,12499],{},"\"?",[257,71775,71776],{"language":247},[260,71777,71779],{"className":262,"code":71778,"language":247,"meta":264,"style":264},"function addItem(cart, item) {\n  cart.push(item);\n  return cart;\n}\n",[39,71780,71781,71797,71805,71811],{"__ignoreMap":264},[268,71782,71783,71785,71787,71789,71791,71793,71795],{"class":270,"line":271},[268,71784,275],{"class":274},[268,71786,14788],{"class":278},[268,71788,622],{"class":282},[268,71790,8318],{"class":1222},[268,71792,42],{"class":282},[268,71794,14793],{"class":1222},[268,71796,1235],{"class":282},[268,71798,71799,71801,71803],{"class":270,"line":286},[268,71800,14807],{"class":282},[268,71802,12499],{"class":278},[268,71804,11808],{"class":282},[268,71806,71807,71809],{"class":270,"line":296},[268,71808,1240],{"class":274},[268,71810,14818],{"class":282},[268,71812,71813],{"class":270,"line":311},[268,71814,314],{"class":282},[23,71816,71818,71824,71833,71839],{"className":71817},[26],[28,71819,71821,71823],{"className":71820},[31],[33,71822],{"disabled":35,"type":36}," It's not impure — returning a value makes any function pure",[28,71825,71827,71829,71830,71832],{"className":71826},[31],[33,71828],{"disabled":35,"type":36}," It mutates the ",[39,71831,8318],{}," array argument in place, producing a side effect visible to any other code holding a reference to that same array",[28,71834,71836,71838],{"className":71835},[31],[33,71837],{"disabled":35,"type":36}," It's impure only because it takes two arguments instead of one",[28,71840,71842,71844,71845,71847],{"className":71841},[31],[33,71843],{"disabled":35,"type":36}," It's impure because ",[39,71846,12499],{}," is asynchronous",[66,71849,71850,71852,71859],{},[69,71851,71],{},[73,71853,71854,71856,71857,71832],{},[76,71855,78],{}," B — It mutates the ",[39,71858,8318],{},[73,71860,71861,71863,71864,71867,71868,71870,71871,71873,71874,462],{},[76,71862,84],{}," Purity isn't just about avoiding ",[104,71865,71866],{},"global"," state — mutating an argument that was passed in by reference (arrays and objects are reference types in JS) is itself a side effect, because any other part of the program holding a reference to that same ",[39,71869,8318],{}," array sees the change too, even though this function never touched a variable outside its own scope. Option A is the common misconception that \"has a return value\" automatically implies purity; a function can return something ",[104,71872,31781],{}," still mutate its inputs, which is precisely the trap here. The pure version would return a new array: ",[39,71875,71876],{},"return [...cart, item]",[15,71878,71879,71883,71909,71944],{"language":247},[18,71880,71882],{"id":71881},"q3-what-is-the-idiomatic-immutable-way-to-add-a-property-to-an-object-without-mutating-the-original","Q3. What is the idiomatic, immutable way to add a property to an object without mutating the original?",[257,71884,71885],{"language":247},[260,71886,71888],{"className":262,"code":71887,"language":247,"meta":264,"style":264},"const user = { name: \"Priya\", role: \"admin\" };\n",[39,71889,71890],{"__ignoreMap":264},[268,71891,71892,71894,71896,71898,71900,71903,71905,71907],{"class":270,"line":271},[268,71893,243],{"class":274},[268,71895,4071],{"class":305},[268,71897,616],{"class":274},[268,71899,4076],{"class":282},[268,71901,71902],{"class":289},"\"Priya\"",[268,71904,27781],{"class":282},[268,71906,19778],{"class":289},[268,71908,2790],{"class":282},[23,71910,71912,71920,71928,71936],{"className":71911},[26],[28,71913,71915,355,71917],{"className":71914},[31],[33,71916],{"disabled":35,"type":36},[39,71918,71919],{},"user.active = true;",[28,71921,71923,355,71925],{"className":71922},[31],[33,71924],{"disabled":35,"type":36},[39,71926,71927],{},"Object.assign(user, { active: true });",[28,71929,71931,355,71933],{"className":71930},[31],[33,71932],{"disabled":35,"type":36},[39,71934,71935],{},"const updated = { ...user, active: true };",[28,71937,71939,355,71941],{"className":71938},[31],[33,71940],{"disabled":35,"type":36},[39,71942,71943],{},"user[\"active\"] = true; return user;",[66,71945,71946,71948,71954],{},[69,71947,71],{},[73,71949,71950,1004,71952],{},[76,71951,78],{},[39,71953,71935],{},[73,71955,71956,71958,71959,71961,71962,71964,71965,71967,71968,71970,71971,71973,71974,71977,71978,71980,71981,71983,71984,71987,71988,71990,71991,71994],{},[76,71957,84],{}," The spread operator creates a ",[104,71960,2689],{}," object, copying all of ",[39,71963,4155],{},"'s own enumerable properties into it and then overwriting\u002Fadding ",[39,71966,27420],{},", leaving the original ",[39,71969,4155],{}," completely untouched. Options A and D directly mutate ",[39,71972,4155],{}," in place. Option B is the sneaky trap: ",[39,71975,71976],{},"Object.assign(target, source)"," mutates ",[39,71979,65414],{}," (the first argument) — passing ",[39,71982,4155],{}," as the target still mutates it, even though ",[39,71985,71986],{},"Object.assign"," is often reached for as an \"immutable-looking\" utility; producing a new object with ",[39,71989,71986],{}," requires ",[39,71992,71993],{},"Object.assign({}, user, { active: true })",", with an empty object literal as the target.",[15,71996,71997,72001,72097,72127],{"language":247},[18,71998,72000],{"id":71999},"q4-what-does-currying-a-function-mean","Q4. What does \"currying\" a function mean?",[257,72002,72003],{"language":247},[260,72004,72006],{"className":262,"code":72005,"language":247,"meta":264,"style":264},"function add(a, b, c) {\n  return a + b + c;\n}\n\nfunction curriedAdd(a) {\n  return (b) => (c) => a + b + c;\n}\n",[39,72007,72008,72028,72042,72046,72050,72063,72093],{"__ignoreMap":264},[268,72009,72010,72012,72014,72016,72018,72020,72022,72024,72026],{"class":270,"line":271},[268,72011,275],{"class":274},[268,72013,1217],{"class":278},[268,72015,622],{"class":282},[268,72017,1223],{"class":1222},[268,72019,42],{"class":282},[268,72021,1232],{"class":1222},[268,72023,42],{"class":282},[268,72025,16484],{"class":1222},[268,72027,1235],{"class":282},[268,72029,72030,72032,72034,72036,72038,72040],{"class":270,"line":286},[268,72031,1240],{"class":274},[268,72033,1243],{"class":282},[268,72035,1246],{"class":274},[268,72037,2209],{"class":282},[268,72039,1246],{"class":274},[268,72041,28498],{"class":282},[268,72043,72044],{"class":270,"line":296},[268,72045,314],{"class":282},[268,72047,72048],{"class":270,"line":311},[268,72049,5033],{"emptyLinePlaceholder":35},[268,72051,72052,72054,72057,72059,72061],{"class":270,"line":788},[268,72053,275],{"class":274},[268,72055,72056],{"class":278}," curriedAdd",[268,72058,622],{"class":282},[268,72060,1223],{"class":1222},[268,72062,1235],{"class":282},[268,72064,72065,72067,72069,72071,72073,72075,72077,72079,72081,72083,72085,72087,72089,72091],{"class":270,"line":1951},[268,72066,1240],{"class":274},[268,72068,2182],{"class":282},[268,72070,1232],{"class":1222},[268,72072,6131],{"class":282},[268,72074,9414],{"class":274},[268,72076,2182],{"class":282},[268,72078,16484],{"class":1222},[268,72080,6131],{"class":282},[268,72082,9414],{"class":274},[268,72084,1243],{"class":282},[268,72086,1246],{"class":274},[268,72088,2209],{"class":282},[268,72090,1246],{"class":274},[268,72092,28498],{"class":282},[268,72094,72095],{"class":270,"line":8955},[268,72096,314],{"class":282},[23,72098,72100,72106,72112,72118],{"className":72099},[26],[28,72101,72103,72105],{"className":72102},[31],[33,72104],{"disabled":35,"type":36}," Transforming a function so it can accept its arguments one at a time, each call returning a new function until all arguments are supplied",[28,72107,72109,72111],{"className":72108},[31],[33,72110],{"disabled":35,"type":36}," Making a function run faster by caching its results",[28,72113,72115,72117],{"className":72114},[31],[33,72116],{"disabled":35,"type":36}," Converting a function to accept an array of arguments instead of separate parameters",[28,72119,72121,72123,72124,72126],{"className":72120},[31],[33,72122],{"disabled":35,"type":36}," Binding a function's ",[39,72125,950],{}," value permanently",[66,72128,72129,72131,72136],{},[69,72130,71],{},[73,72132,72133,72135],{},[76,72134,78],{}," A — Transforming a function so it can accept its arguments one at a time, each call returning a new function until all arguments are supplied",[73,72137,72138,355,72140,72143,72144,12867,72146,2029,72148,72143,72150,72152,72153,72156,72157,72159,72160,72162,72163,72165,72166,9057,72169,72171],{},[76,72139,84],{},[39,72141,72142],{},"curriedAdd(1)"," returns a function waiting for ",[39,72145,1232],{},[104,72147,7690],{},[39,72149,2258],{},[39,72151,16484],{}," — only ",[39,72154,72155],{},"curriedAdd(1)(2)(3)"," produces the final sum ",[39,72158,13663],{},". This enables partial application: ",[39,72161,72142],{}," can be saved and reused as a specialized function that always adds ",[39,72164,2255],{}," to whatever comes next. Option B describes memoization, a related but distinct technique (see Q17). Option C describes a different pattern sometimes called \"argument spreading\" or using a single options object, not currying. Option D describes ",[39,72167,72168],{},"Function.prototype.bind",[39,72170,950],{},"-binding behavior, unrelated to currying's argument-splitting purpose.",[15,72173,72174,72182,72315,72374],{"language":247},[18,72175,72177,72178,72181],{"id":72176},"q5-what-does-function-composition-compose-typically-achieve","Q5. What does function composition (",[39,72179,72180],{},"compose",") typically achieve?",[257,72183,72184],{"language":247},[260,72185,72187],{"className":262,"code":72186,"language":247,"meta":264,"style":264},"const compose = (f, g) => (x) => f(g(x));\n\nconst shout = (s) => s.toUpperCase() + \"!\";\nconst exclaim = (s) => s + \"!!!\";\n\nconst shoutExclaim = compose(exclaim, shout);\nshoutExclaim(\"hello\");\n",[39,72188,72189,72227,72231,72259,72286,72290,72304],{"__ignoreMap":264},[268,72190,72191,72193,72196,72198,72200,72202,72204,72206,72208,72210,72212,72214,72216,72218,72220,72222,72224],{"class":270,"line":271},[268,72192,243],{"class":274},[268,72194,72195],{"class":278}," compose",[268,72197,616],{"class":274},[268,72199,2182],{"class":282},[268,72201,35286],{"class":1222},[268,72203,42],{"class":282},[268,72205,18287],{"class":1222},[268,72207,6131],{"class":282},[268,72209,9414],{"class":274},[268,72211,2182],{"class":282},[268,72213,2403],{"class":1222},[268,72215,6131],{"class":282},[268,72217,9414],{"class":274},[268,72219,35259],{"class":278},[268,72221,622],{"class":282},[268,72223,18287],{"class":278},[268,72225,72226],{"class":282},"(x));\n",[268,72228,72229],{"class":270,"line":286},[268,72230,5033],{"emptyLinePlaceholder":35},[268,72232,72233,72235,72237,72239,72241,72243,72245,72247,72249,72251,72253,72255,72257],{"class":270,"line":296},[268,72234,243],{"class":274},[268,72236,16162],{"class":278},[268,72238,616],{"class":274},[268,72240,2182],{"class":282},[268,72242,25393],{"class":1222},[268,72244,6131],{"class":282},[268,72246,9414],{"class":274},[268,72248,25398],{"class":282},[268,72250,16179],{"class":278},[268,72252,16182],{"class":282},[268,72254,1246],{"class":274},[268,72256,16187],{"class":289},[268,72258,293],{"class":282},[268,72260,72261,72263,72266,72268,72270,72272,72274,72276,72279,72281,72284],{"class":270,"line":311},[268,72262,243],{"class":274},[268,72264,72265],{"class":278}," exclaim",[268,72267,616],{"class":274},[268,72269,2182],{"class":282},[268,72271,25393],{"class":1222},[268,72273,6131],{"class":282},[268,72275,9414],{"class":274},[268,72277,72278],{"class":282}," s ",[268,72280,1246],{"class":274},[268,72282,72283],{"class":289}," \"!!!\"",[268,72285,293],{"class":282},[268,72287,72288],{"class":270,"line":788},[268,72289,5033],{"emptyLinePlaceholder":35},[268,72291,72292,72294,72297,72299,72301],{"class":270,"line":1951},[268,72293,243],{"class":274},[268,72295,72296],{"class":305}," shoutExclaim",[268,72298,616],{"class":274},[268,72300,72195],{"class":278},[268,72302,72303],{"class":282},"(exclaim, shout);\n",[268,72305,72306,72309,72311,72313],{"class":270,"line":8955},[268,72307,72308],{"class":278},"shoutExclaim",[268,72310,622],{"class":282},[268,72312,4436],{"class":289},[268,72314,628],{"class":282},[23,72316,72318,72340,72349,72359],{"className":72317},[26],[28,72319,72321,355,72323,3990,72326,2182,72328,72330,72331,2182,72333,72336,72337,72339],{"className":72320},[31],[33,72322],{"disabled":35,"type":36},[39,72324,72325],{},"\"HELLO!!!!!\"",[39,72327,18287],{},[39,72329,16226],{},") runs first on the input, then ",[39,72332,35286],{},[39,72334,72335],{},"exclaim",") runs on ",[39,72338,18287],{},"'s result",[28,72341,72343,355,72345,72348],{"className":72342},[31],[33,72344],{"disabled":35,"type":36},[39,72346,72347],{},"\"hello!!!\""," then uppercased separately",[28,72350,72352,1271,72354,183,72356,72358],{"className":72351},[31],[33,72353],{"disabled":35,"type":36},[39,72355,827],{},[39,72357,72180],{}," only accepts one function",[28,72360,72362,355,72364,2182,72366,72368,72369,2182,72371,72373],{"className":72361},[31],[33,72363],{"disabled":35,"type":36},[39,72365,35286],{},[39,72367,72335],{},") runs first, then ",[39,72370,18287],{},[39,72372,16226],{},") runs on its result",[66,72375,72376,72378,72394],{},[69,72377,71],{},[73,72379,72380,3459,72382,3990,72384,2182,72386,72330,72388,2182,72390,72336,72392,72339],{},[76,72381,78],{},[39,72383,72325],{},[39,72385,18287],{},[39,72387,16226],{},[39,72389,35286],{},[39,72391,72335],{},[39,72393,18287],{},[73,72395,72396,72398,72399,72402,72403,53650,72406,72409,72410,7159,72413,137,72416,7159,72419,72421,72422,72424],{},[76,72397,84],{}," By convention, ",[39,72400,72401],{},"compose(f, g)(x)"," evaluates as ",[39,72404,72405],{},"f(g(x))",[104,72407,72408],{},"rightmost"," function runs first, and results flow right-to-left through the chain, mirroring mathematical function composition notation. Here ",[39,72411,72412],{},"shout(\"hello\")",[39,72414,72415],{},"\"HELLO!\"",[39,72417,72418],{},"exclaim(\"HELLO!\")",[39,72420,72325],{},". This right-to-left order is a frequent point of confusion (option D reverses it), which is exactly why many functional libraries also offer a ",[39,72423,43741],{}," helper that runs left-to-right instead, matching the order functions are visually listed — see Q11 for the mixup this causes.",[15,72426,72427,72431,72561,72596],{"language":247},[18,72428,72430],{"id":72429},"q6-which-snippet-demonstrates-point-free-tacit-style","Q6. Which snippet demonstrates \"point-free\" (tacit) style?",[257,72432,72433],{"language":247},[260,72434,72436],{"className":262,"code":72435,"language":247,"meta":264,"style":264},"const names = [\"ravi\", \"priya\", \"sam\"];\n\nconst a = names.map((name) => name.toUpperCase());\nconst b = names.map(String.prototype.toUpperCase.call.bind(String.prototype.toUpperCase));\nconst c = names.map((name) => name.trim().toUpperCase());\n",[39,72437,72438,72463,72467,72495,72531],{"__ignoreMap":264},[268,72439,72440,72442,72444,72446,72448,72451,72453,72456,72458,72461],{"class":270,"line":271},[268,72441,243],{"class":274},[268,72443,41263],{"class":305},[268,72445,616],{"class":274},[268,72447,8710],{"class":282},[268,72449,72450],{"class":289},"\"ravi\"",[268,72452,42],{"class":282},[268,72454,72455],{"class":289},"\"priya\"",[268,72457,42],{"class":282},[268,72459,72460],{"class":289},"\"sam\"",[268,72462,8737],{"class":282},[268,72464,72465],{"class":270,"line":286},[268,72466,5033],{"emptyLinePlaceholder":35},[268,72468,72469,72471,72473,72475,72478,72480,72482,72484,72486,72488,72491,72493],{"class":270,"line":296},[268,72470,243],{"class":274},[268,72472,7203],{"class":305},[268,72474,616],{"class":274},[268,72476,72477],{"class":282}," names.",[268,72479,23950],{"class":278},[268,72481,6122],{"class":282},[268,72483,14605],{"class":1222},[268,72485,6131],{"class":282},[268,72487,9414],{"class":274},[268,72489,72490],{"class":282}," name.",[268,72492,16179],{"class":278},[268,72494,8174],{"class":282},[268,72496,72497,72499,72501,72503,72505,72507,72509,72511,72513,72515,72518,72520,72522,72524,72526,72528],{"class":270,"line":311},[268,72498,243],{"class":274},[268,72500,16372],{"class":305},[268,72502,616],{"class":274},[268,72504,72477],{"class":282},[268,72506,23950],{"class":278},[268,72508,622],{"class":282},[268,72510,16721],{"class":305},[268,72512,462],{"class":282},[268,72514,12070],{"class":305},[268,72516,72517],{"class":282},".toUpperCase.call.",[268,72519,34786],{"class":278},[268,72521,622],{"class":282},[268,72523,16721],{"class":305},[268,72525,462],{"class":282},[268,72527,12070],{"class":305},[268,72529,72530],{"class":282},".toUpperCase));\n",[268,72532,72533,72535,72537,72539,72541,72543,72545,72547,72549,72551,72553,72555,72557,72559],{"class":270,"line":788},[268,72534,243],{"class":274},[268,72536,16389],{"class":305},[268,72538,616],{"class":274},[268,72540,72477],{"class":282},[268,72542,23950],{"class":278},[268,72544,6122],{"class":282},[268,72546,14605],{"class":1222},[268,72548,6131],{"class":282},[268,72550,9414],{"class":274},[268,72552,72490],{"class":282},[268,72554,18832],{"class":278},[268,72556,19341],{"class":282},[268,72558,16179],{"class":278},[268,72560,8174],{"class":282},[23,72562,72564,72572,72582,72590],{"className":72563},[26],[28,72565,72567,355,72569,72571],{"className":72566},[31],[33,72568],{"disabled":35,"type":36},[39,72570,1223],{},", because it uses an arrow function",[28,72573,72575,355,72577,72579,72580,2690],{"className":72574},[31],[33,72576],{"disabled":35,"type":36},[39,72578,1232],{},", because the mapping function is referenced directly without explicitly naming or wrapping the data it operates on (no intermediate named argument like ",[39,72581,14605],{},[28,72583,72585,355,72587,72589],{"className":72584},[31],[33,72586],{"disabled":35,"type":36},[39,72588,16484],{},", because it chains two methods",[28,72591,72593,72595],{"className":72592},[31],[33,72594],{"disabled":35,"type":36}," None of these are point-free",[66,72597,72598,72600,72608],{},[69,72599,71],{},[73,72601,72602,1727,72604,72579,72606,2690],{},[76,72603,78],{},[39,72605,1232],{},[39,72607,14605],{},[73,72609,72610,72612,72613,3277,72616,186,72618,72620,72621,72623,72624,72626,72627,4977,72630,72633,72634,462],{},[76,72611,84],{}," Point-free style means defining a function without mentioning the arguments (\"points\") it operates on — you compose existing functions directly rather than writing ",[39,72614,72615],{},"(x) => f(x)",[39,72617,1223],{},[39,72619,16484],{}," both explicitly name ",[39,72622,14605],{}," as an intermediate variable, which is the opposite of point-free. ",[39,72625,1232],{}," (admittedly contrived and hard to read here, which illustrates a real trade-off) passes a function reference derived purely from existing methods, with no named parameter appearing in the mapping logic itself. In practice, simpler point-free examples look like ",[39,72628,72629],{},"names.map(s => s.toUpperCase())",[39,72631,72632],{},"names.map(String.prototype.toUpperCase.call, String.prototype)"," style tricks, or more commonly just passing a named utility function directly: ",[39,72635,72636],{},"names.map(toUpperCase)",[15,72638,72639,72643,72725,72763],{"language":247},[18,72640,72642],{"id":72641},"q7-why-is-shared-mutable-state-considered-risky-in-a-codebase-especially-with-async-code","Q7. Why is shared mutable state considered risky in a codebase, especially with async code?",[257,72644,72645],{"language":247},[260,72646,72648],{"className":262,"code":72647,"language":247,"meta":264,"style":264},"let requestCount = 0;\n\nasync function handleRequest(req) {\n  requestCount++;\n  const result = await process(req);\n  requestCount--;\n  return result;\n}\n",[39,72649,72650,72663,72667,72682,72691,72706,72715,72721],{"__ignoreMap":264},[268,72651,72652,72654,72657,72659,72661],{"class":270,"line":271},[268,72653,240],{"class":274},[268,72655,72656],{"class":282}," requestCount ",[268,72658,302],{"class":274},[268,72660,5728],{"class":305},[268,72662,293],{"class":282},[268,72664,72665],{"class":270,"line":286},[268,72666,5033],{"emptyLinePlaceholder":35},[268,72668,72669,72671,72673,72675,72677,72680],{"class":270,"line":296},[268,72670,379],{"class":274},[268,72672,12080],{"class":274},[268,72674,59371],{"class":278},[268,72676,622],{"class":282},[268,72678,72679],{"class":1222},"req",[268,72681,1235],{"class":282},[268,72683,72684,72687,72689],{"class":270,"line":311},[268,72685,72686],{"class":282},"  requestCount",[268,72688,9401],{"class":274},[268,72690,293],{"class":282},[268,72692,72693,72695,72697,72699,72701,72703],{"class":270,"line":788},[268,72694,12441],{"class":274},[268,72696,5583],{"class":305},[268,72698,616],{"class":274},[268,72700,52502],{"class":274},[268,72702,10851],{"class":278},[268,72704,72705],{"class":282},"(req);\n",[268,72707,72708,72710,72713],{"class":270,"line":1951},[268,72709,72686],{"class":282},[268,72711,72712],{"class":274},"--",[268,72714,293],{"class":282},[268,72716,72717,72719],{"class":270,"line":8955},[268,72718,1240],{"class":274},[268,72720,10895],{"class":282},[268,72722,72723],{"class":270,"line":8966},[268,72724,314],{"class":282},[23,72726,72728,72737,72747,72755],{"className":72727},[26],[28,72729,72731,72733,72734,72736],{"className":72730},[31],[33,72732],{"disabled":35,"type":36}," It isn't risky — ",[39,72735,240],{}," variables are always safe to share",[28,72738,72740,72742,72743,72746],{"className":72739},[31],[33,72741],{"disabled":35,"type":36}," Multiple concurrent calls all read and write the same ",[39,72744,72745],{},"requestCount"," variable, so their increments\u002Fdecrements interleave in ways that are hard to trace, and any bug in one call path can corrupt state visible to every other call",[28,72748,72750,355,72752,72754],{"className":72749},[31],[33,72751],{"disabled":35,"type":36},[39,72753,72745],{}," will overflow after 2^53 requests, causing incorrect counts",[28,72756,72758,355,72760,72762],{"className":72757},[31],[33,72759],{"disabled":35,"type":36},[39,72761,379],{}," functions cannot access variables declared outside their own body",[66,72764,72765,72767,72774],{},[69,72766,71],{},[73,72768,72769,72771,72772,72746],{},[76,72770,78],{}," B — Multiple concurrent calls all read and write the same ",[39,72773,72745],{},[73,72775,72776,72778,72779,446,72782,72785,72786,72789,72790,72792,72793,72795,72796,72798],{},[76,72777,84],{}," Even though JavaScript is single-threaded and each individual ",[39,72780,72781],{},"requestCount++",[39,72783,72784],{},"requestCount--"," is atomic, the ",[104,72787,72788],{},"sequence"," of operations across many concurrent ",[39,72791,59298],{}," calls (each suspended and resumed at different ",[39,72794,12304],{}," points) means the shared counter's value at any given moment depends on unpredictable interleaving — an early return, a thrown error skipping the decrement, or a bug in one request handler can leave ",[39,72797,72745],{}," permanently wrong for the entire process, affecting every other concurrent request. Isolating state per-call (e.g., not sharing a mutable counter at all, or using request-scoped state) avoids this entire category of bug, which is the core motivation behind functional programming's emphasis on avoiding shared mutable state.",[15,72800,72801,72807,72869,72916],{"language":247},[18,72802,55624,72804,72806],{"id":72803},"q8-objectfreeze-is-often-used-for-immutability-whats-the-gotcha-with-the-following-code",[39,72805,20133],{}," is often used for immutability. What's the gotcha with the following code?",[257,72808,72809],{"language":247},[260,72810,72812],{"className":262,"code":72811,"language":247,"meta":264,"style":264},"const config = Object.freeze({\n  api: { retries: 3, timeout: 5000 },\n});\n\nconfig.api.retries = 10;\nconsole.log(config.api.retries);\n",[39,72813,72814,72828,72841,72845,72849,72860],{"__ignoreMap":264},[268,72815,72816,72818,72820,72822,72824,72826],{"class":270,"line":271},[268,72817,243],{"class":274},[268,72819,8029],{"class":305},[268,72821,616],{"class":274},[268,72823,20017],{"class":282},[268,72825,20020],{"class":278},[268,72827,20023],{"class":282},[268,72829,72830,72833,72835,72837,72839],{"class":270,"line":286},[268,72831,72832],{"class":282},"  api: { retries: ",[268,72834,3423],{"class":305},[268,72836,21235],{"class":282},[268,72838,71395],{"class":305},[268,72840,20042],{"class":282},[268,72842,72843],{"class":270,"line":296},[268,72844,20047],{"class":282},[268,72846,72847],{"class":270,"line":311},[268,72848,5033],{"emptyLinePlaceholder":35},[268,72850,72851,72854,72856,72858],{"class":270,"line":788},[268,72852,72853],{"class":282},"config.api.retries ",[268,72855,302],{"class":274},[268,72857,306],{"class":305},[268,72859,293],{"class":282},[268,72861,72862,72864,72866],{"class":270,"line":1951},[268,72863,1353],{"class":282},[268,72865,1356],{"class":278},[268,72867,72868],{"class":282},"(config.api.retries);\n",[23,72870,72872,72883,72897,72908],{"className":72871},[26],[28,72873,72875,1271,72877,72879,72880,72882],{"className":72874},[31],[33,72876],{"disabled":35,"type":36},[39,72878,827],{}," in strict mode because ",[39,72881,8109],{}," is frozen",[28,72884,72886,30037,72888,3990,72890,72892,72893,72896],{"className":72885},[31],[33,72887],{"disabled":35,"type":36},[39,72889,5825],{},[39,72891,20133],{}," is shallow, so nested objects (",[39,72894,72895],{},"config.api",") remain fully mutable",[28,72898,72900,30037,72902,72904,72905,72907],{"className":72899},[31],[33,72901],{"disabled":35,"type":36},[39,72903,3423],{}," — the mutation silently fails because ",[39,72906,20133],{}," is deep by default",[28,72909,72911,355,72913,72915],{"className":72910},[31],[33,72912],{"disabled":35,"type":36},[39,72914,20133],{}," only works on arrays, not plain objects",[66,72917,72918,72920,72931],{},[69,72919,71],{},[73,72921,72922,72924,72925,3990,72927,72892,72929,72896],{},[76,72923,78],{}," B — It logs ",[39,72926,5825],{},[39,72928,20133],{},[39,72930,72895],{},[73,72932,72933,355,72935,355,72937,72939,72940,72943,72944,72946,72947,72950,72951,72953,72954,72957,72958,72960],{},[76,72934,84],{},[76,72936,582],{},[39,72938,20133],{}," only locks the ",[104,72941,72942],{},"direct"," properties of the object it's called on — it prevents reassigning ",[39,72945,72895],{}," itself to a different object, but the nested ",[39,72948,72949],{},"api"," object was never frozen, so its own properties remain fully writable. This is one of the most common ",[39,72952,20133],{}," gotchas: developers assume \"frozen\" means \"deeply immutable,\" write ",[39,72955,72956],{},"config.api.retries = 10",", and are surprised it silently succeeds (in non-strict contexts) or throws only for the ",[104,72959,72942],{}," level. Achieving true deep immutability requires recursively freezing every nested object, or using a library\u002Futility that does so.",[15,72962,72963,72971,73091,73134],{"language":247},[18,72964,72966,72967,72970],{"id":72965},"q9-what-is-the-surprising-problem-with-using-arrayprototypesort-inside-code-thats-meant-to-follow-functional-immutable-patterns","Q9. What is the surprising problem with using ",[39,72968,72969],{},"Array.prototype.sort"," inside code that's meant to follow functional, immutable patterns?",[257,72972,72973],{"language":247},[260,72974,72976],{"className":262,"code":72975,"language":247,"meta":264,"style":264},"function topScores(scores) {\n  return scores.sort((a, b) => b - a).slice(0, 3);\n}\n\nconst original = [5, 2, 9, 1, 7];\nconst top3 = topScores(original);\nconsole.log(original);\n",[39,72977,72978,72992,73032,73036,73040,73070,73083],{"__ignoreMap":264},[268,72979,72980,72982,72985,72987,72990],{"class":270,"line":271},[268,72981,275],{"class":274},[268,72983,72984],{"class":278}," topScores",[268,72986,622],{"class":282},[268,72988,72989],{"class":1222},"scores",[268,72991,1235],{"class":282},[268,72993,72994,72996,72999,73001,73003,73005,73007,73009,73011,73013,73015,73017,73020,73022,73024,73026,73028,73030],{"class":270,"line":286},[268,72995,1240],{"class":274},[268,72997,72998],{"class":282}," scores.",[268,73000,19029],{"class":278},[268,73002,6122],{"class":282},[268,73004,1223],{"class":1222},[268,73006,42],{"class":282},[268,73008,1232],{"class":1222},[268,73010,6131],{"class":282},[268,73012,9414],{"class":274},[268,73014,2209],{"class":282},[268,73016,6244],{"class":274},[268,73018,73019],{"class":282}," a).",[268,73021,25821],{"class":278},[268,73023,622],{"class":282},[268,73025,3307],{"class":305},[268,73027,42],{"class":282},[268,73029,3423],{"class":305},[268,73031,628],{"class":282},[268,73033,73034],{"class":270,"line":296},[268,73035,314],{"class":282},[268,73037,73038],{"class":270,"line":311},[268,73039,5033],{"emptyLinePlaceholder":35},[268,73041,73042,73044,73046,73048,73050,73052,73054,73056,73058,73060,73062,73064,73066,73068],{"class":270,"line":788},[268,73043,243],{"class":274},[268,73045,20173],{"class":305},[268,73047,616],{"class":274},[268,73049,8710],{"class":282},[268,73051,2429],{"class":305},[268,73053,42],{"class":282},[268,73055,2258],{"class":305},[268,73057,42],{"class":282},[268,73059,6360],{"class":305},[268,73061,42],{"class":282},[268,73063,2255],{"class":305},[268,73065,42],{"class":282},[268,73067,26963],{"class":305},[268,73069,8737],{"class":282},[268,73071,73072,73074,73077,73079,73081],{"class":270,"line":1951},[268,73073,243],{"class":274},[268,73075,73076],{"class":305}," top3",[268,73078,616],{"class":274},[268,73080,72984],{"class":278},[268,73082,22300],{"class":282},[268,73084,73085,73087,73089],{"class":270,"line":8955},[268,73086,1353],{"class":282},[268,73088,1356],{"class":278},[268,73090,22300],{"class":282},[23,73092,73094,73105,73116,73124],{"className":73093},[26],[28,73095,73097,355,73099,73101,73102,73104],{"className":73096},[31],[33,73098],{"disabled":35,"type":36},[39,73100,19029],{}," returns a new array, so ",[39,73103,22772],{}," is unaffected — this code is already pure",[28,73106,73108,355,73110,73112,73113,73115],{"className":73107},[31],[33,73109],{"disabled":35,"type":36},[39,73111,19029],{}," mutates the array in place and also returns it, so ",[39,73114,22772],{}," itself ends up reordered as a side effect, even though the function \"looks\" like it just derives a new value",[28,73117,73119,355,73121,73123],{"className":73118},[31],[33,73120],{"disabled":35,"type":36},[39,73122,19029],{}," throws an error when used with a custom comparator",[28,73125,73127,355,73129,71977,73131,73133],{"className":73126},[31],[33,73128],{"disabled":35,"type":36},[39,73130,25821],{},[39,73132,22772],{}," by removing the first three elements",[66,73135,73136,73138,73146],{},[69,73137,71],{},[73,73139,73140,1727,73142,73112,73144,73115],{},[76,73141,78],{},[39,73143,19029],{},[39,73145,22772],{},[73,73147,73148,355,73150,2338,73152,42,73154,42,73156,42,73158,73161,73162,73165,73166,73168,73169,73172,73173,73175,73176,73178,73179,73181,73182,446,73184,446,73186,73188,73189,73191,73192,99,73195,73198],{},[76,73149,84],{},[39,73151,72969],{},[39,73153,19338],{},[39,73155,25974],{},[39,73157,38693],{},[39,73159,73160],{},"copyWithin",") sorts the array ",[104,73163,73164],{},"in place"," and returns the same reference — it does not create a new array. Chaining ",[39,73167,16076],{}," afterward returns a fresh array for ",[39,73170,73171],{},"top3",", which masks the fact that ",[39,73174,22772],{}," was already silently reordered by the time ",[39,73177,19029],{}," ran. This is a classic trap for functional-style code, since ",[39,73180,19029],{}," sits right next to genuinely non-mutating array methods like ",[39,73183,23950],{},[39,73185,14962],{},[39,73187,25821],{}," and is easy to assume behaves the same way. ",[76,73190,930],{}," the fix is to copy first — ",[39,73193,73194],{},"[...scores].sort(...)",[39,73196,73197],{},"scores.toSorted(...)"," (the newer, non-mutating ES2023 method) — before sorting.",[15,73200,73201,73208,73391,73445],{"language":247},[18,73202,73204,73205,73207],{"id":73203},"q10-a-curried-function-is-built-using-functionprototypelength-to-determine-when-enough-arguments-have-been-collected-whats-the-pitfall-with-this-specific-implementation","Q10. A curried function is built using ",[39,73206,15622],{}," to determine when enough arguments have been collected. What's the pitfall with this specific implementation?",[257,73209,73210],{"language":247},[260,73211,73213],{"className":262,"code":73212,"language":247,"meta":264,"style":264},"function curry(fn) {\n  return function curried(...args) {\n    if (args.length >= fn.length) return fn(...args);\n    return (...more) => curried(...args, ...more);\n  };\n}\n\nfunction sum(a, b, ...rest) {\n  return a + b + rest.reduce((x, y) => x + y, 0);\n}\n\nconst curriedSum = curry(sum);\n",[39,73214,73215,73227,73243,73269,73295,73299,73303,73307,73329,73369,73373,73377],{"__ignoreMap":264},[268,73216,73217,73219,73221,73223,73225],{"class":270,"line":271},[268,73218,275],{"class":274},[268,73220,40257],{"class":278},[268,73222,622],{"class":282},[268,73224,37837],{"class":1222},[268,73226,1235],{"class":282},[268,73228,73229,73231,73233,73235,73237,73239,73241],{"class":270,"line":286},[268,73230,1240],{"class":274},[268,73232,12080],{"class":274},[268,73234,40382],{"class":278},[268,73236,622],{"class":282},[268,73238,15329],{"class":274},[268,73240,40270],{"class":1222},[268,73242,1235],{"class":282},[268,73244,73245,73247,73249,73251,73253,73255,73257,73259,73261,73263,73265,73267],{"class":270,"line":296},[268,73246,9686],{"class":274},[268,73248,42823],{"class":282},[268,73250,3567],{"class":305},[268,73252,40285],{"class":274},[268,73254,40288],{"class":282},[268,73256,3567],{"class":305},[268,73258,6131],{"class":282},[268,73260,9151],{"class":274},[268,73262,37900],{"class":278},[268,73264,622],{"class":282},[268,73266,15329],{"class":274},[268,73268,42844],{"class":282},[268,73270,73271,73273,73275,73277,73279,73281,73283,73285,73287,73289,73291,73293],{"class":270,"line":311},[268,73272,9871],{"class":274},[268,73274,2182],{"class":282},[268,73276,15329],{"class":274},[268,73278,40317],{"class":1222},[268,73280,6131],{"class":282},[268,73282,9414],{"class":274},[268,73284,40382],{"class":278},[268,73286,622],{"class":282},[268,73288,15329],{"class":274},[268,73290,40331],{"class":282},[268,73292,15329],{"class":274},[268,73294,40336],{"class":282},[268,73296,73297],{"class":270,"line":788},[268,73298,15185],{"class":282},[268,73300,73301],{"class":270,"line":1951},[268,73302,314],{"class":282},[268,73304,73305],{"class":270,"line":8955},[268,73306,5033],{"emptyLinePlaceholder":35},[268,73308,73309,73311,73313,73315,73317,73319,73321,73323,73325,73327],{"class":270,"line":8966},[268,73310,275],{"class":274},[268,73312,28469],{"class":278},[268,73314,622],{"class":282},[268,73316,1223],{"class":1222},[268,73318,42],{"class":282},[268,73320,1232],{"class":1222},[268,73322,42],{"class":282},[268,73324,15329],{"class":274},[268,73326,22677],{"class":1222},[268,73328,1235],{"class":282},[268,73330,73331,73333,73335,73337,73339,73341,73344,73346,73348,73350,73352,73354,73356,73358,73360,73362,73365,73367],{"class":270,"line":8974},[268,73332,1240],{"class":274},[268,73334,1243],{"class":282},[268,73336,1246],{"class":274},[268,73338,2209],{"class":282},[268,73340,1246],{"class":274},[268,73342,73343],{"class":282}," rest.",[268,73345,14980],{"class":278},[268,73347,6122],{"class":282},[268,73349,2403],{"class":1222},[268,73351,42],{"class":282},[268,73353,2909],{"class":1222},[268,73355,6131],{"class":282},[268,73357,9414],{"class":274},[268,73359,2382],{"class":282},[268,73361,1246],{"class":274},[268,73363,73364],{"class":282}," y, ",[268,73366,3307],{"class":305},[268,73368,628],{"class":282},[268,73370,73371],{"class":270,"line":8985},[268,73372,314],{"class":282},[268,73374,73375],{"class":270,"line":8990},[268,73376,5033],{"emptyLinePlaceholder":35},[268,73378,73379,73381,73384,73386,73388],{"class":270,"line":8997},[268,73380,243],{"class":274},[268,73382,73383],{"class":305}," curriedSum",[268,73385,616],{"class":274},[268,73387,40257],{"class":278},[268,73389,73390],{"class":282},"(sum);\n",[23,73392,73394,73402,73424,73437],{"className":73393},[26],[28,73395,73397,73399,73400],{"className":73396},[31],[33,73398],{"disabled":35,"type":36}," It works perfectly for any function, including variadic ones like ",[39,73401,28535],{},[28,73403,73405,355,73407,73409,73410,830,73413,3990,73415,73418,73419,73421,73422,8705],{"className":73404},[31],[33,73406],{"disabled":35,"type":36},[39,73408,40500],{}," does not count rest parameters (or parameters after the first default-valued one), so ",[39,73411,73412],{},"sum.length",[39,73414,2258],{},[39,73416,73417],{},"curriedSum"," will call ",[39,73420,28535],{}," as soon as 2 arguments arrive, silently ignoring the ability to curry in any of the ",[39,73423,22677],{},[28,73425,73427,355,73429,2278,73431,73433,73434,73436],{"className":73426},[31],[33,73428],{"disabled":35,"type":36},[39,73430,43032],{},[39,73432,827],{}," immediately because ",[39,73435,28535],{}," uses rest parameters",[28,73438,73440,355,73442,73444],{"className":73439},[31],[33,73441],{"disabled":35,"type":36},[39,73443,40500],{}," always equals the number of arguments actually passed at call time, so this is safe",[66,73446,73447,73449,73464],{},[69,73448,71],{},[73,73450,73451,1727,73453,73409,73455,830,73457,3990,73459,73418,73461,73463],{},[76,73452,78],{},[39,73454,40500],{},[39,73456,73412],{},[39,73458,2258],{},[39,73460,73417],{},[39,73462,28535],{}," as soon as 2 arguments arrive, silently ignoring the ability to curry in any of the rest values",[73,73465,73466,355,73468,73470,73471,73473,73474,42,73477,830,73479,73481,73482,73484,73485,73487,73488,73491,73492,73494,73495,73498,73499,73501],{},[76,73467,84],{},[39,73469,15622],{}," reports only the count of parameters ",[104,73472,11314],{}," the first default-valued or rest parameter — it's a static count of the function's declared signature, not a runtime count of anything. For ",[39,73475,73476],{},"sum(a, b, ...rest)",[39,73478,73412],{},[39,73480,2258],{},", so a ",[39,73483,3567],{},"-based ",[39,73486,43032],{}," implementation will invoke ",[39,73489,73490],{},"sum(a, b)"," the moment two arguments are collected, never giving the caller a chance to curry in additional values that ",[39,73493,22677],{}," was designed to accept. This is a real, easy-to-miss limitation of naive curry implementations, and is why production-grade curry utilities usually require an explicit arity argument (",[39,73496,73497],{},"curry(fn, arity)",") instead of trusting ",[39,73500,40500],{}," for any function that isn't a plain fixed-arity function.",[15,73503,73504,73513,73703,73710,73772],{"language":247},[18,73505,73507,73508,186,73510,73512],{"id":73506},"q11-a-developer-mixes-up-compose-and-pipe-and-gets-an-unexpected-result-given","Q11. A developer mixes up ",[39,73509,72180],{},[39,73511,43741],{}," and gets an unexpected result. Given:",[257,73514,73515],{"language":247},[260,73516,73518],{"className":262,"code":73517,"language":247,"meta":264,"style":264},"const compose = (...fns) => (x) => fns.reduceRight((acc, fn) => fn(acc), x);\nconst pipe = (...fns) => (x) => fns.reduce((acc, fn) => fn(acc), x);\n\nconst double = (n) => n * 2;\nconst addOne = (n) => n + 1;\n\nconst a = compose(double, addOne)(5);\nconst b = pipe(double, addOne)(5);\n",[39,73519,73520,73567,73613,73617,73641,73666,73670,73687],{"__ignoreMap":264},[268,73521,73522,73524,73526,73528,73530,73532,73534,73536,73538,73540,73542,73544,73546,73548,73551,73553,73555,73557,73559,73561,73563,73565],{"class":270,"line":271},[268,73523,243],{"class":274},[268,73525,72195],{"class":278},[268,73527,616],{"class":274},[268,73529,2182],{"class":282},[268,73531,15329],{"class":274},[268,73533,43584],{"class":1222},[268,73535,6131],{"class":282},[268,73537,9414],{"class":274},[268,73539,2182],{"class":282},[268,73541,2403],{"class":1222},[268,73543,6131],{"class":282},[268,73545,9414],{"class":274},[268,73547,43595],{"class":282},[268,73549,73550],{"class":278},"reduceRight",[268,73552,6122],{"class":282},[268,73554,24160],{"class":1222},[268,73556,42],{"class":282},[268,73558,37837],{"class":1222},[268,73560,6131],{"class":282},[268,73562,9414],{"class":274},[268,73564,37900],{"class":278},[268,73566,43614],{"class":282},[268,73568,73569,73571,73573,73575,73577,73579,73581,73583,73585,73587,73589,73591,73593,73595,73597,73599,73601,73603,73605,73607,73609,73611],{"class":270,"line":286},[268,73570,243],{"class":274},[268,73572,43575],{"class":278},[268,73574,616],{"class":274},[268,73576,2182],{"class":282},[268,73578,15329],{"class":274},[268,73580,43584],{"class":1222},[268,73582,6131],{"class":282},[268,73584,9414],{"class":274},[268,73586,2182],{"class":282},[268,73588,2403],{"class":1222},[268,73590,6131],{"class":282},[268,73592,9414],{"class":274},[268,73594,43595],{"class":282},[268,73596,14980],{"class":278},[268,73598,6122],{"class":282},[268,73600,24160],{"class":1222},[268,73602,42],{"class":282},[268,73604,37837],{"class":1222},[268,73606,6131],{"class":282},[268,73608,9414],{"class":274},[268,73610,37900],{"class":278},[268,73612,43614],{"class":282},[268,73614,73615],{"class":270,"line":296},[268,73616,5033],{"emptyLinePlaceholder":35},[268,73618,73619,73621,73623,73625,73627,73629,73631,73633,73635,73637,73639],{"class":270,"line":311},[268,73620,243],{"class":274},[268,73622,41156],{"class":278},[268,73624,616],{"class":274},[268,73626,2182],{"class":282},[268,73628,4599],{"class":1222},[268,73630,6131],{"class":282},[268,73632,9414],{"class":274},[268,73634,13355],{"class":282},[268,73636,6134],{"class":274},[268,73638,2214],{"class":305},[268,73640,293],{"class":282},[268,73642,73643,73645,73648,73650,73652,73654,73656,73658,73660,73662,73664],{"class":270,"line":788},[268,73644,243],{"class":274},[268,73646,73647],{"class":278}," addOne",[268,73649,616],{"class":274},[268,73651,2182],{"class":282},[268,73653,4599],{"class":1222},[268,73655,6131],{"class":282},[268,73657,9414],{"class":274},[268,73659,13355],{"class":282},[268,73661,1246],{"class":274},[268,73663,2199],{"class":305},[268,73665,293],{"class":282},[268,73667,73668],{"class":270,"line":1951},[268,73669,5033],{"emptyLinePlaceholder":35},[268,73671,73672,73674,73676,73678,73680,73683,73685],{"class":270,"line":8955},[268,73673,243],{"class":274},[268,73675,7203],{"class":305},[268,73677,616],{"class":274},[268,73679,72195],{"class":278},[268,73681,73682],{"class":282},"(double, addOne)(",[268,73684,2429],{"class":305},[268,73686,628],{"class":282},[268,73688,73689,73691,73693,73695,73697,73699,73701],{"class":270,"line":8966},[268,73690,243],{"class":274},[268,73692,16372],{"class":305},[268,73694,616],{"class":274},[268,73696,43575],{"class":278},[268,73698,73682],{"class":282},[268,73700,2429],{"class":305},[268,73702,628],{"class":282},[73,73704,73705,73706,186,73708,1685],{},"What are ",[39,73707,1223],{},[39,73709,1232],{},[23,73711,73713,73725,73752,73763],{"className":73712},[26],[28,73714,73716,355,73718,42,73721,73724],{"className":73715},[31],[33,73717],{"disabled":35,"type":36},[39,73719,73720],{},"a = 11",[39,73722,73723],{},"b = 11"," — order doesn't matter for these particular functions",[28,73726,73728,355,73730,42,73733,3990,73735,73737,73738,73741,73742,73744,73745,73737,73747,73741,73749,73751],{"className":73727},[31],[33,73729],{"disabled":35,"type":36},[39,73731,73732],{},"a = 12",[39,73734,73723],{},[39,73736,72180],{}," applies ",[39,73739,73740],{},"addOne"," first then ",[39,73743,41177],{}," (right-to-left); ",[39,73746,43741],{},[39,73748,41177],{},[39,73750,73740],{}," (left-to-right)",[28,73753,73755,355,73757,42,73759,73762],{"className":73754},[31],[33,73756],{"disabled":35,"type":36},[39,73758,73720],{},[39,73760,73761],{},"b = 12"," — the reverse of the above",[28,73764,73766,73768,73769,73771],{"className":73765},[31],[33,73767],{"disabled":35,"type":36}," Both throw an error because ",[39,73770,73550],{}," cannot be used with functions",[66,73773,73774,73776,73796],{},[69,73775,71],{},[73,73777,73778,1727,73780,42,73782,3990,73784,73737,73786,73741,73788,73744,73790,73737,73792,73741,73794,73751],{},[76,73779,78],{},[39,73781,73732],{},[39,73783,73723],{},[39,73785,72180],{},[39,73787,73740],{},[39,73789,41177],{},[39,73791,43741],{},[39,73793,41177],{},[39,73795,73740],{},[73,73797,73798,355,73800,73803,73804,3493,73807,6345,73810,3277,73812,73815,73816,3493,73819,6345,73822,73824,73825,446,73827,73829],{},[76,73799,84],{},[39,73801,73802],{},"compose(double, addOne)"," runs right-to-left (per Q5): ",[39,73805,73806],{},"addOne(5) = 6",[39,73808,73809],{},"double(6) = 12",[39,73811,73732],{},[39,73813,73814],{},"pipe(double, addOne)"," runs left-to-right: ",[39,73817,73818],{},"double(5) = 10",[39,73820,73821],{},"addOne(10) = 11",[39,73823,73723],{},". This mismatch — same function list, same input, different results purely because of which combinator was used — is exactly the gotcha that makes ",[39,73826,72180],{},[39,73828,43741],{}," mixups a real production bug source: swapping one for the other with the same argument order silently changes execution order rather than throwing an error, so the bug can slip past casual testing if the functions happen to be commutative for some inputs but not others.",[15,73831,73832,73836,73888,73924],{"language":247},[18,73833,73835],{"id":73834},"q12-is-the-following-function-pure","Q12. Is the following function pure?",[257,73837,73838],{"language":247},[260,73839,73841],{"className":262,"code":73840,"language":247,"meta":264,"style":264},"function createSession(userId) {\n  return { userId, createdAt: Date.now(), token: Math.random().toString(36) };\n}\n",[39,73842,73843,73857,73884],{"__ignoreMap":264},[268,73844,73845,73847,73850,73852,73855],{"class":270,"line":271},[268,73846,275],{"class":274},[268,73848,73849],{"class":278}," createSession",[268,73851,622],{"class":282},[268,73853,73854],{"class":1222},"userId",[268,73856,1235],{"class":282},[268,73858,73859,73861,73864,73866,73869,73872,73874,73876,73878,73881],{"class":270,"line":286},[268,73860,1240],{"class":274},[268,73862,73863],{"class":282}," { userId, createdAt: Date.",[268,73865,49125],{"class":278},[268,73867,73868],{"class":282},"(), token: Math.",[268,73870,73871],{"class":278},"random",[268,73873,19341],{"class":282},[268,73875,22604],{"class":278},[268,73877,622],{"class":282},[268,73879,73880],{"class":305},"36",[268,73882,73883],{"class":282},") };\n",[268,73885,73886],{"class":270,"line":296},[268,73887,314],{"class":282},[23,73889,73891,73897,73912,73918],{"className":73890},[26],[28,73892,73894,73896],{"className":73893},[31],[33,73895],{"disabled":35,"type":36}," Yes — it doesn't read or mutate any external variable",[28,73898,73900,73902,73903,186,73905,73908,73909,73911],{"className":73899},[31],[33,73901],{"disabled":35,"type":36}," No — even though it never touches external variables, ",[39,73904,71222],{},[39,73906,73907],{},"Math.random()"," make its output non-deterministic: the same ",[39,73910,73854],{}," input produces a different result on every call",[28,73913,73915,73917],{"className":73914},[31],[33,73916],{"disabled":35,"type":36}," Yes — purity only requires the absence of argument mutation, which this function satisfies",[28,73919,73921,73923],{"className":73920},[31],[33,73922],{"disabled":35,"type":36}," No — it's impure because it returns an object instead of a primitive",[66,73925,73926,73928,73939],{},[69,73927,71],{},[73,73929,73930,73932,73933,186,73935,73908,73937,73911],{},[76,73931,78],{}," B — No — even though it never touches external variables, ",[39,73934,71222],{},[39,73936,73907],{},[39,73938,73854],{},[73,73940,73941,73943,73944,73946,73947,186,73949,73951,73952,462],{},[76,73942,84],{}," Purity requires that calling the function with the same arguments ",[104,73945,940],{}," produces the same result — determinism is just as essential as \"no side effects.\" ",[39,73948,71222],{},[39,73950,73907],{}," both read genuinely external, constantly-changing state (the system clock, the engine's PRNG state), so even though this function never mutates anything or reads a module-level variable, it's still impure by the \"same input → same output\" definition. This is a subtle gotcha: developers often equate purity purely with \"doesn't mutate things\" (option C), missing the determinism requirement entirely. Functions needing timestamps\u002Frandomness for testability are usually made pure by accepting them as injected parameters instead: ",[39,73953,73954],{},"createSession(userId, now, randomToken)",[15,73956,73957,73964,74017,74068],{"language":247},[18,73958,73960,73961,73963],{"id":73959},"q13-whats-the-gotcha-in-this-code-given-that-const-is-often-incorrectly-equated-with-immutable","Q13. What's the gotcha in this code, given that ",[39,73962,243],{}," is often (incorrectly) equated with \"immutable\"?",[257,73965,73966],{"language":247},[260,73967,73969],{"className":262,"code":73968,"language":247,"meta":264,"style":264},"const cart = [];\ncart.push(\"item-1\");\ncart.push(\"item-2\");\nconsole.log(cart);\n",[39,73970,73971,73981,73995,74008],{"__ignoreMap":264},[268,73972,73973,73975,73977,73979],{"class":270,"line":271},[268,73974,243],{"class":274},[268,73976,41499],{"class":305},[268,73978,616],{"class":274},[268,73980,12449],{"class":282},[268,73982,73983,73986,73988,73990,73993],{"class":270,"line":286},[268,73984,73985],{"class":282},"cart.",[268,73987,12499],{"class":278},[268,73989,622],{"class":282},[268,73991,73992],{"class":289},"\"item-1\"",[268,73994,628],{"class":282},[268,73996,73997,73999,74001,74003,74006],{"class":270,"line":296},[268,73998,73985],{"class":282},[268,74000,12499],{"class":278},[268,74002,622],{"class":282},[268,74004,74005],{"class":289},"\"item-2\"",[268,74007,628],{"class":282},[268,74009,74010,74012,74014],{"class":270,"line":311},[268,74011,1353],{"class":282},[268,74013,1356],{"class":278},[268,74015,74016],{"class":282},"(cart);\n",[23,74018,74020,74032,74048,74059],{"className":74019},[26],[28,74021,74023,2398,74025,183,74027,74029,74030],{"className":74022},[31],[33,74024],{"disabled":35,"type":36},[39,74026,827],{},[39,74028,8318],{}," is declared ",[39,74031,243],{},[28,74033,74035,74037,74038,3990,74041,21595,74043,21599,74045,74047],{"className":74034},[31],[33,74036],{"disabled":35,"type":36}," This works fine and logs ",[39,74039,74040],{},"[\"item-1\", \"item-2\"]",[39,74042,243],{},[104,74044,21598],{},[39,74046,8318],{}," binding to a different value, it does nothing to prevent mutating the object\u002Farray that binding currently points to",[28,74049,74051,355,74053,74055,74056,74058],{"className":74050},[31],[33,74052],{"disabled":35,"type":36},[39,74054,243],{}," arrays are automatically frozen, so ",[39,74057,12499],{}," is a no-op",[28,74060,74062,74064,74065,74067],{"className":74061},[31],[33,74063],{"disabled":35,"type":36}," This is a syntax error since ",[39,74066,243],{}," variables cannot call methods",[66,74069,74070,74072,74084],{},[69,74071,71],{},[73,74073,74074,74076,74077,3990,74079,74081,74082,74047],{},[76,74075,78],{}," B — This works fine and logs ",[39,74078,74040],{},[39,74080,243],{}," only prevents reassigning the ",[39,74083,8318],{},[73,74085,74086,355,74088,74090,74091,74093,74094,74097,74098,42,74100,74103,74104,74106,74107,74109,74110,74112],{},[76,74087,84],{},[39,74089,243],{}," creates an immutable ",[104,74092,4175],{}," (you can't do ",[39,74095,74096],{},"cart = []"," again later), but it says nothing about the mutability of the value the binding refers to — arrays and objects remain fully mutable through their own methods (",[39,74099,12499],{},[39,74101,74102],{},"pop",", direct property assignment) regardless of how the variable holding them was declared. This is a persistent beginner misconception (",[39,74105,243],{}," = \"constant value\") that leads to real bugs when someone assumes a ",[39,74108,243],{},"-declared array or object is safe from mutation elsewhere in the code. True immutability requires ",[39,74111,20133],{}," (with the shallow caveat from Q8) or disciplined use of non-mutating operations like spread.",[15,74114,74115,74119,74252,74309],{"language":247},[18,74116,74118],{"id":74117},"q14-what-bug-does-this-counter-factory-have-and-why","Q14. What bug does this counter factory have, and why?",[257,74120,74121],{"language":247},[260,74122,74124],{"className":262,"code":74123,"language":247,"meta":264,"style":264},"function makeCounter() {\n  let count = 0;\n  return {\n    increment: () => count++,\n    reset: () => (count = 0),\n  };\n}\n\nconst counterA = makeCounter();\nconst counterB = makeCounter();\ncounterA.increment();\ncounterA.increment();\nconsole.log(counterB.increment());\n",[39,74125,74126,74134,74146,74152,74167,74184,74188,74192,74196,74209,74222,74231,74239],{"__ignoreMap":264},[268,74127,74128,74130,74132],{"class":270,"line":271},[268,74129,275],{"class":274},[268,74131,37290],{"class":278},[268,74133,283],{"class":282},[268,74135,74136,74138,74140,74142,74144],{"class":270,"line":286},[268,74137,2206],{"class":274},[268,74139,10091],{"class":282},[268,74141,302],{"class":274},[268,74143,5728],{"class":305},[268,74145,293],{"class":282},[268,74147,74148,74150],{"class":270,"line":296},[268,74149,1240],{"class":274},[268,74151,9914],{"class":282},[268,74153,74154,74157,74159,74161,74163,74165],{"class":270,"line":311},[268,74155,74156],{"class":278},"    increment",[268,74158,34921],{"class":282},[268,74160,9414],{"class":274},[268,74162,5723],{"class":282},[268,74164,9401],{"class":274},[268,74166,1789],{"class":282},[268,74168,74169,74172,74174,74176,74178,74180,74182],{"class":270,"line":788},[268,74170,74171],{"class":278},"    reset",[268,74173,34921],{"class":282},[268,74175,9414],{"class":274},[268,74177,10134],{"class":282},[268,74179,302],{"class":274},[268,74181,5728],{"class":305},[268,74183,17159],{"class":282},[268,74185,74186],{"class":270,"line":1951},[268,74187,15185],{"class":282},[268,74189,74190],{"class":270,"line":8955},[268,74191,314],{"class":282},[268,74193,74194],{"class":270,"line":8966},[268,74195,5033],{"emptyLinePlaceholder":35},[268,74197,74198,74200,74203,74205,74207],{"class":270,"line":8974},[268,74199,243],{"class":274},[268,74201,74202],{"class":305}," counterA",[268,74204,616],{"class":274},[268,74206,37290],{"class":278},[268,74208,794],{"class":282},[268,74210,74211,74213,74216,74218,74220],{"class":270,"line":8985},[268,74212,243],{"class":274},[268,74214,74215],{"class":305}," counterB",[268,74217,616],{"class":274},[268,74219,37290],{"class":278},[268,74221,794],{"class":282},[268,74223,74224,74227,74229],{"class":270,"line":8990},[268,74225,74226],{"class":282},"counterA.",[268,74228,34969],{"class":278},[268,74230,794],{"class":282},[268,74232,74233,74235,74237],{"class":270,"line":8997},[268,74234,74226],{"class":282},[268,74236,34969],{"class":278},[268,74238,794],{"class":282},[268,74240,74241,74243,74245,74248,74250],{"class":270,"line":9002},[268,74242,1353],{"class":282},[268,74244,1356],{"class":278},[268,74246,74247],{"class":282},"(counterB.",[268,74249,34969],{"class":278},[268,74251,8174],{"class":282},[23,74253,74255,74269,74285,74297],{"className":74254},[26],[28,74256,74258,355,74260,2269,74263,74265,74266,74268],{"className":74257},[31],[33,74259],{"disabled":35,"type":36},[39,74261,74262],{},"counterB.increment()",[39,74264,2258],{},", since both counters share the same closed-over ",[39,74267,10191],{}," variable",[28,74270,74272,355,74274,2269,74276,74278,74279,74281,74282,74284],{"className":74271},[31],[33,74273],{"disabled":35,"type":36},[39,74275,74262],{},[39,74277,3307],{},", because each call to ",[39,74280,37441],{}," creates a fresh closure with its own independent ",[39,74283,10191],{}," variable — there's no bug here, this is correctly isolated state",[28,74286,74288,2398,74290,183,74292,74294,74295],{"className":74287},[31],[33,74289],{"disabled":35,"type":36},[39,74291,815],{},[39,74293,10191],{}," is not accessible outside ",[39,74296,37428],{},[28,74298,74300,355,74302,186,74305,74308],{"className":74299},[31],[33,74301],{"disabled":35,"type":36},[39,74303,74304],{},"counterA",[39,74306,74307],{},"counterB"," are the same object reference, so both counters are actually identical",[66,74310,74311,74313,74325],{},[69,74312,71],{},[73,74314,74315,1727,74317,2269,74319,74278,74321,74281,74323,74284],{},[76,74316,78],{},[39,74318,74262],{},[39,74320,3307],{},[39,74322,37441],{},[39,74324,10191],{},[73,74326,74327,74329,74330,44798,74333,74335,74336,74338,74339,186,74341,74343],{},[76,74328,84],{}," This question flips the expected gotcha: many developers assume closures created from the same factory function share state (confusing this with the module-scoped shared-state problem from Q7), but each ",[104,74331,74332],{},"invocation",[39,74334,37441],{}," creates a brand-new ",[39,74337,10191],{}," variable and a brand-new pair of closures over it — ",[39,74340,74304],{},[39,74342,74307],{}," are fully independent, so incrementing one has zero effect on the other. This pattern (closures for private, per-instance state) is a deliberately safe alternative to the shared-mutable-module-variable trap from Q7, precisely because each call gets its own isolated scope rather than reading from one shared location.",[15,74345,74346,74350,74482,74532],{"language":247},[18,74347,74349],{"id":74348},"q15-which-style-is-more-idiomatic-functional-javascript-for-transforming-an-array-of-order-objects-into-a-total","Q15. Which style is more idiomatic functional JavaScript for transforming an array of order objects into a total?",[257,74351,74352],{"language":247},[260,74353,74355],{"className":262,"code":74354,"language":247,"meta":264,"style":264},"const orders = [{ amount: 20 }, { amount: 35 }, { amount: 10 }];\n\nlet totalA = 0;\nfor (let i = 0; i \u003C orders.length; i++) {\n  totalA += orders[i].amount;\n}\n\nconst totalB = orders.reduce((sum, order) => sum + order.amount, 0);\n",[39,74356,74357,74382,74386,74399,74428,74438,74442,74446],{"__ignoreMap":264},[268,74358,74359,74361,74363,74365,74368,74370,74373,74376,74378,74380],{"class":270,"line":271},[268,74360,243],{"class":274},[268,74362,41629],{"class":305},[268,74364,616],{"class":274},[268,74366,74367],{"class":282}," [{ amount: ",[268,74369,6149],{"class":305},[268,74371,74372],{"class":282}," }, { amount: ",[268,74374,74375],{"class":305},"35",[268,74377,74372],{"class":282},[268,74379,5825],{"class":305},[268,74381,26654],{"class":282},[268,74383,74384],{"class":270,"line":286},[268,74385,5033],{"emptyLinePlaceholder":35},[268,74387,74388,74390,74393,74395,74397],{"class":270,"line":296},[268,74389,240],{"class":274},[268,74391,74392],{"class":282}," totalA ",[268,74394,302],{"class":274},[268,74396,5728],{"class":305},[268,74398,293],{"class":282},[268,74400,74401,74403,74405,74407,74409,74411,74413,74415,74417,74420,74422,74424,74426],{"class":270,"line":311},[268,74402,6926],{"class":274},[268,74404,2182],{"class":282},[268,74406,240],{"class":274},[268,74408,9384],{"class":282},[268,74410,302],{"class":274},[268,74412,5728],{"class":305},[268,74414,9391],{"class":282},[268,74416,1076],{"class":274},[268,74418,74419],{"class":282}," orders.",[268,74421,3567],{"class":305},[268,74423,9398],{"class":282},[268,74425,9401],{"class":274},[268,74427,1235],{"class":282},[268,74429,74430,74433,74435],{"class":270,"line":788},[268,74431,74432],{"class":282},"  totalA ",[268,74434,14575],{"class":274},[268,74436,74437],{"class":282}," orders[i].amount;\n",[268,74439,74440],{"class":270,"line":1951},[268,74441,314],{"class":282},[268,74443,74444],{"class":270,"line":8955},[268,74445,5033],{"emptyLinePlaceholder":35},[268,74447,74448,74450,74453,74455,74457,74459,74461,74463,74465,74467,74469,74471,74473,74475,74478,74480],{"class":270,"line":8966},[268,74449,243],{"class":274},[268,74451,74452],{"class":305}," totalB",[268,74454,616],{"class":274},[268,74456,74419],{"class":282},[268,74458,14980],{"class":278},[268,74460,6122],{"class":282},[268,74462,28535],{"class":1222},[268,74464,42],{"class":282},[268,74466,11927],{"class":1222},[268,74468,6131],{"class":282},[268,74470,9414],{"class":274},[268,74472,41543],{"class":282},[268,74474,1246],{"class":274},[268,74476,74477],{"class":282}," order.amount, ",[268,74479,3307],{"class":305},[268,74481,628],{"class":282},[23,74483,74485,74494,74517,74523],{"className":74484},[26],[28,74486,74488,355,74490,74493],{"className":74487},[31],[33,74489],{"disabled":35,"type":36},[39,74491,74492],{},"totalA","'s imperative loop, because it's more performant in all cases",[28,74495,74497,355,74499,9057,74502,74504,74505,74508,74509,74512,74513,446,74515,8067],{"className":74496},[31],[33,74498],{"disabled":35,"type":36},[39,74500,74501],{},"totalB",[39,74503,14980],{},", because it declares ",[104,74506,74507],{},"what"," is being computed rather than ",[104,74510,74511],{},"how"," to iterate, avoids a mutable accumulator variable in the surrounding scope, and composes naturally with ",[39,74514,23950],{},[39,74516,14962],{},[28,74518,74520,74522],{"className":74519},[31],[33,74521],{"disabled":35,"type":36}," Both are equally idiomatic; functional style has no preference here",[28,74524,74526,74528,74529],{"className":74525},[31],[33,74527],{"disabled":35,"type":36}," Neither — the idiomatic approach is ",[39,74530,74531],{},"orders.map(o => o.amount).sum()",[66,74533,74534,74536,74549],{},[69,74535,71],{},[73,74537,74538,1727,74540,9057,74542,74544,74545,446,74547,8067],{},[76,74539,78],{},[39,74541,74501],{},[39,74543,14980],{},", because it declares what is being computed rather than how to iterate, avoids a mutable accumulator variable in the surrounding scope, and composes naturally with ",[39,74546,23950],{},[39,74548,14962],{},[73,74550,74551,355,74553,355,74555,26754,74557,446,74559,74561,74562,74564,74565,74568,74569,74571,74572,74574],{},[76,74552,84],{},[76,74554,930],{},[39,74556,14980],{},[39,74558,23950],{},[39,74560,14962],{},") expresses the transformation declaratively and keeps the accumulator scoped entirely inside the call rather than as a mutable ",[39,74563,240],{}," variable in the enclosing function, which reduces the surface area for bugs (accidental reuse, forgetting to reset, off-by-one loop errors) and reads closer to \"sum the amounts\" than \"manage an index and a running total.\" Option D is a tempting-looking but invalid API — plain arrays have no built-in ",[39,74566,74567],{},".sum()"," method in JavaScript. Performance (option A) is not the deciding factor here; a simple ",[39,74570,14980],{}," over a modest array is not meaningfully slower than a ",[39,74573,6926],{}," loop in practice, and clarity\u002Fcomposability is the actual reason functional style is favored for this kind of transformation.",[15,74576,74577,74581,74659,74701],{"language":247},[18,74578,74580],{"id":74579},"q16-in-a-redux-style-state-management-pattern-why-is-the-following-reducer-considered-buggy","Q16. In a Redux-style state management pattern, why is the following reducer considered buggy?",[257,74582,74583],{"language":247},[260,74584,74586],{"className":262,"code":74585,"language":247,"meta":264,"style":264},"function cartReducer(state, action) {\n  switch (action.type) {\n    case \"ADD_ITEM\":\n      state.items.push(action.item);\n      return state;\n    default:\n      return state;\n  }\n}\n",[39,74587,74588,74606,74613,74622,74632,74639,74645,74651,74655],{"__ignoreMap":264},[268,74589,74590,74592,74595,74597,74599,74601,74604],{"class":270,"line":271},[268,74591,275],{"class":274},[268,74593,74594],{"class":278}," cartReducer",[268,74596,622],{"class":282},[268,74598,21602],{"class":1222},[268,74600,42],{"class":282},[268,74602,74603],{"class":1222},"action",[268,74605,1235],{"class":282},[268,74607,74608,74610],{"class":270,"line":286},[268,74609,8917],{"class":274},[268,74611,74612],{"class":282}," (action.type) {\n",[268,74614,74615,74617,74620],{"class":270,"line":296},[268,74616,8925],{"class":274},[268,74618,74619],{"class":289}," \"ADD_ITEM\"",[268,74621,8931],{"class":282},[268,74623,74624,74627,74629],{"class":270,"line":311},[268,74625,74626],{"class":282},"      state.items.",[268,74628,12499],{"class":278},[268,74630,74631],{"class":282},"(action.item);\n",[268,74633,74634,74636],{"class":270,"line":788},[268,74635,10451],{"class":274},[268,74637,74638],{"class":282}," state;\n",[268,74640,74641,74643],{"class":270,"line":1951},[268,74642,8969],{"class":274},[268,74644,8931],{"class":282},[268,74646,74647,74649],{"class":270,"line":8955},[268,74648,10451],{"class":274},[268,74650,74638],{"class":282},[268,74652,74653],{"class":270,"line":8966},[268,74654,1948],{"class":282},[268,74656,74657],{"class":270,"line":8974},[268,74658,314],{"class":282},[23,74660,74662,74670,74680,74689],{"className":74661},[26],[28,74663,74665,355,74667,74669],{"className":74664},[31],[33,74666],{"disabled":35,"type":36},[39,74668,8884],{}," statements aren't allowed in reducers",[28,74671,74673,74675,74676,74679],{"className":74672},[31],[33,74674],{"disabled":35,"type":36}," It mutates ",[39,74677,74678],{},"state.items"," directly instead of returning a new state object\u002Farray, which breaks reference-equality checks that UI frameworks rely on to detect changes and re-render",[28,74681,74683,355,74685,74688],{"className":74682},[31],[33,74684],{"disabled":35,"type":36},[39,74686,74687],{},"action.item"," must be destructured before use",[28,74690,74692,74694,74695,74697,74698,74700],{"className":74691},[31],[33,74693],{"disabled":35,"type":36}," Reducers cannot return the same ",[39,74696,21602],{}," reference under any circumstance, including the ",[39,74699,9046],{}," case",[66,74702,74703,74705,74712],{},[69,74704,71],{},[73,74706,74707,74709,74710,74679],{},[76,74708,78],{}," B — It mutates ",[39,74711,74678],{},[73,74713,74714,355,74716,74718,74719,74722,74723,74725,74726,74728,74729,74732,74733,74735,74736,74738],{},[76,74715,84],{},[76,74717,930],{}," state management libraries typically detect changes with a cheap ",[39,74720,74721],{},"oldState !== newState"," reference comparison rather than a deep-equality check, for performance reasons. Mutating ",[39,74724,74678],{}," in place means ",[39,74727,21602],{}," (the object reference) never actually changes, so that comparison reports \"nothing changed\" even though the data did — this manifests as a UI that silently fails to re-render after an action that logically should have updated it. The fix follows the immutable-update pattern from Q3: ",[39,74730,74731],{},"return { ...state, items: [...state.items, action.item] }",", creating new references at every level of the update path. Option D is a false generalization — returning the ",[104,74734,22779],{}," reference for ",[39,74737,9046],{}," (an unhandled\u002Fno-op action) is correct and expected, since nothing changed there.",[15,74740,74741,74745,74848,74875],{"language":247},[18,74742,74744],{"id":74743},"q17-what-performance-technique-commonly-pairs-with-pure-functions-and-why-does-purity-make-it-safe","Q17. What performance technique commonly pairs with pure functions, and why does purity make it safe?",[257,74746,74747],{"language":247},[260,74748,74750],{"className":262,"code":74749,"language":247,"meta":264,"style":264},"function memoize(fn) {\n  const cache = new Map();\n  return (arg) => {\n    if (cache.has(arg)) return cache.get(arg);\n    const result = fn(arg);\n    cache.set(arg, result);\n    return result;\n  };\n}\n",[39,74751,74752,74764,74778,74793,74813,74825,74834,74840,74844],{"__ignoreMap":264},[268,74753,74754,74756,74758,74760,74762],{"class":270,"line":271},[268,74755,275],{"class":274},[268,74757,37832],{"class":278},[268,74759,622],{"class":282},[268,74761,37837],{"class":1222},[268,74763,1235],{"class":282},[268,74765,74766,74768,74770,74772,74774,74776],{"class":270,"line":286},[268,74767,12441],{"class":274},[268,74769,15807],{"class":305},[268,74771,616],{"class":274},[268,74773,11370],{"class":274},[268,74775,11373],{"class":278},[268,74777,794],{"class":282},[268,74779,74780,74782,74784,74787,74789,74791],{"class":270,"line":296},[268,74781,1240],{"class":274},[268,74783,2182],{"class":282},[268,74785,74786],{"class":1222},"arg",[268,74788,6131],{"class":282},[268,74790,9414],{"class":274},[268,74792,9914],{"class":282},[268,74794,74795,74797,74799,74801,74804,74806,74808,74810],{"class":270,"line":311},[268,74796,9686],{"class":274},[268,74798,37872],{"class":282},[268,74800,37875],{"class":278},[268,74802,74803],{"class":282},"(arg)) ",[268,74805,9151],{"class":274},[268,74807,37883],{"class":282},[268,74809,32437],{"class":278},[268,74811,74812],{"class":282},"(arg);\n",[268,74814,74815,74817,74819,74821,74823],{"class":270,"line":788},[268,74816,37893],{"class":274},[268,74818,5583],{"class":305},[268,74820,616],{"class":274},[268,74822,37900],{"class":278},[268,74824,74812],{"class":282},[268,74826,74827,74829,74831],{"class":270,"line":1951},[268,74828,37907],{"class":282},[268,74830,37910],{"class":278},[268,74832,74833],{"class":282},"(arg, result);\n",[268,74835,74836,74838],{"class":270,"line":8955},[268,74837,9871],{"class":274},[268,74839,10895],{"class":282},[268,74841,74842],{"class":270,"line":8966},[268,74843,15185],{"class":282},[268,74845,74846],{"class":270,"line":8974},[268,74847,314],{"class":282},[23,74849,74851,74857,74863,74869],{"className":74850},[26],[28,74852,74854,74856],{"className":74853},[31],[33,74855],{"disabled":35,"type":36}," Debouncing — pure functions are always slow, so debouncing their calls is necessary",[28,74858,74860,74862],{"className":74859},[31],[33,74861],{"disabled":35,"type":36}," Memoization — because a pure function always returns the same output for the same input, caching results by argument is safe and never returns a stale\u002Fincorrect value",[28,74864,74866,74868],{"className":74865},[31],[33,74867],{"disabled":35,"type":36}," Throttling — pure functions must be rate-limited to avoid excessive CPU use",[28,74870,74872,74874],{"className":74871},[31],[33,74873],{"disabled":35,"type":36}," Currying — memoization only works on curried functions",[66,74876,74877,74879,74884],{},[69,74878,71],{},[73,74880,74881,74883],{},[76,74882,78],{}," B — Memoization — because a pure function always returns the same output for the same input, caching results by argument is safe and never returns a stale\u002Fincorrect value",[73,74885,74886,355,74888,74890,74891,74893,74894,74897],{},[76,74887,84],{},[76,74889,438],{}," memoization trades memory for time by caching a function's output keyed by its input, but this is only ",[104,74892,70427],{}," to do when the function is pure — an impure function (like the ",[39,74895,74896],{},"createSession"," example from Q12, which depends on the current time\u002Frandomness) would return a stale, wrong cached value for a later call with the same argument, since its \"true\" output legitimately changes between calls. This is why memoization utilities are typically documented as safe only for pure functions, and why introducing impurity into a previously-pure function that's already memoized somewhere is a subtle way to introduce a correctness bug.",[15,74899,74900,74904,75061,75088],{"language":247},[18,74901,74903],{"id":74902},"q18-why-do-teams-favor-composing-several-small-pure-functions-over-one-large-function-that-does-everything-from-a-testingmaintenance-standpoint","Q18. Why do teams favor composing several small pure functions over one large function that does everything, from a testing\u002Fmaintenance standpoint?",[257,74905,74906],{"language":247},[260,74907,74909],{"className":262,"code":74908,"language":247,"meta":264,"style":264},"const applyDiscount = (rate) => (price) => price - price * rate;\nconst applyTax = (rate) => (price) => price + price * rate;\nconst round2 = (price) => Math.round(price * 100) \u002F 100;\n\nconst finalPrice = (price) => round2(applyTax(0.08)(applyDiscount(0.1)(price)));\n",[39,74910,74911,74945,74980,75017,75021],{"__ignoreMap":264},[268,74912,74913,74915,74917,74919,74921,74923,74925,74927,74929,74931,74933,74935,74937,74939,74941,74943],{"class":270,"line":271},[268,74914,243],{"class":274},[268,74916,36819],{"class":278},[268,74918,616],{"class":274},[268,74920,2182],{"class":282},[268,74922,36871],{"class":1222},[268,74924,6131],{"class":282},[268,74926,9414],{"class":274},[268,74928,2182],{"class":282},[268,74930,17225],{"class":1222},[268,74932,6131],{"class":282},[268,74934,9414],{"class":274},[268,74936,36880],{"class":282},[268,74938,6244],{"class":274},[268,74940,36880],{"class":282},[268,74942,6134],{"class":274},[268,74944,71693],{"class":282},[268,74946,74947,74949,74952,74954,74956,74958,74960,74962,74964,74966,74968,74970,74972,74974,74976,74978],{"class":270,"line":286},[268,74948,243],{"class":274},[268,74950,74951],{"class":278}," applyTax",[268,74953,616],{"class":274},[268,74955,2182],{"class":282},[268,74957,36871],{"class":1222},[268,74959,6131],{"class":282},[268,74961,9414],{"class":274},[268,74963,2182],{"class":282},[268,74965,17225],{"class":1222},[268,74967,6131],{"class":282},[268,74969,9414],{"class":274},[268,74971,36880],{"class":282},[268,74973,1246],{"class":274},[268,74975,36880],{"class":282},[268,74977,6134],{"class":274},[268,74979,71693],{"class":282},[268,74981,74982,74984,74987,74989,74991,74993,74995,74997,74999,75002,75005,75007,75009,75011,75013,75015],{"class":270,"line":296},[268,74983,243],{"class":274},[268,74985,74986],{"class":278}," round2",[268,74988,616],{"class":274},[268,74990,2182],{"class":282},[268,74992,17225],{"class":1222},[268,74994,6131],{"class":282},[268,74996,9414],{"class":274},[268,74998,30188],{"class":282},[268,75000,75001],{"class":278},"round",[268,75003,75004],{"class":282},"(price ",[268,75006,6134],{"class":274},[268,75008,13821],{"class":305},[268,75010,6131],{"class":282},[268,75012,446],{"class":274},[268,75014,13821],{"class":305},[268,75016,293],{"class":282},[268,75018,75019],{"class":270,"line":311},[268,75020,5033],{"emptyLinePlaceholder":35},[268,75022,75023,75025,75028,75030,75032,75034,75036,75038,75040,75042,75045,75047,75050,75052,75054,75056,75058],{"class":270,"line":788},[268,75024,243],{"class":274},[268,75026,75027],{"class":278}," finalPrice",[268,75029,616],{"class":274},[268,75031,2182],{"class":282},[268,75033,17225],{"class":1222},[268,75035,6131],{"class":282},[268,75037,9414],{"class":274},[268,75039,74986],{"class":278},[268,75041,622],{"class":282},[268,75043,75044],{"class":278},"applyTax",[268,75046,622],{"class":282},[268,75048,75049],{"class":305},"0.08",[268,75051,40411],{"class":282},[268,75053,41065],{"class":278},[268,75055,622],{"class":282},[268,75057,3832],{"class":305},[268,75059,75060],{"class":282},")(price)));\n",[23,75062,75064,75070,75076,75082],{"className":75063},[26],[28,75065,75067,75069],{"className":75066},[31],[33,75068],{"disabled":35,"type":36}," Small functions are always faster to execute than one large function",[28,75071,75073,75075],{"className":75072},[31],[33,75074],{"disabled":35,"type":36}," Each small function can be tested and reasoned about independently with trivial input\u002Foutput assertions, and bugs are easier to isolate to a single stage of the pipeline rather than buried inside one large, tangled function",[28,75077,75079,75081],{"className":75078},[31],[33,75080],{"disabled":35,"type":36}," JavaScript engines require functions to be under a certain line count to JIT-compile them",[28,75083,75085,75087],{"className":75084},[31],[33,75086],{"disabled":35,"type":36}," Composing small functions eliminates the need for any testing at all",[66,75089,75090,75092,75097],{},[69,75091,71],{},[73,75093,75094,75096],{},[76,75095,78],{}," B — Each small function can be tested and reasoned about independently with trivial input\u002Foutput assertions, and bugs are easier to isolate to a single stage of the pipeline rather than buried inside one large, tangled function",[73,75098,75099,355,75101,75103,75104,42,75106,137,75108,75111,75112,75115],{},[76,75100,84],{},[76,75102,930],{}," because each of ",[39,75105,41065],{},[39,75107,75044],{},[39,75109,75110],{},"round2"," is pure and does exactly one thing, each can be unit-tested with a handful of direct input\u002Foutput examples with no setup or mocking required, and if ",[39,75113,75114],{},"finalPrice"," produces a wrong result, the bug can be isolated by checking each stage's output in the pipeline rather than debugging one monolithic calculation. This composability is one of the primary practical benefits of functional style in production codebases, independent of any specific execution-speed claim (option A is a fabricated, generally false performance claim — composing functions typically has function-call overhead, not a speed benefit).",[15,75117,75118,75122,75194,75226],{"language":247},[18,75119,75121],{"id":75120},"q19-a-codebase-rewrites-this-straightforward-function-into-point-free-style-is-this-a-good-idea","Q19. A codebase rewrites this straightforward function into \"point-free\" style. Is this a good idea?",[257,75123,75124],{"language":247},[260,75125,75127],{"className":262,"code":75126,"language":247,"meta":264,"style":264},"const isAdult = (person) => person.age >= 18;\n\nconst isAdultPointFree = compose(gte(18), prop(\"age\"));\n",[39,75128,75129,75157,75161],{"__ignoreMap":264},[268,75130,75131,75133,75136,75138,75140,75143,75145,75147,75150,75152,75155],{"class":270,"line":271},[268,75132,243],{"class":274},[268,75134,75135],{"class":278}," isAdult",[268,75137,616],{"class":274},[268,75139,2182],{"class":282},[268,75141,75142],{"class":1222},"person",[268,75144,6131],{"class":282},[268,75146,9414],{"class":274},[268,75148,75149],{"class":282}," person.age ",[268,75151,6779],{"class":274},[268,75153,75154],{"class":305}," 18",[268,75156,293],{"class":282},[268,75158,75159],{"class":270,"line":286},[268,75160,5033],{"emptyLinePlaceholder":35},[268,75162,75163,75165,75168,75170,75172,75174,75177,75179,75182,75184,75187,75189,75192],{"class":270,"line":296},[268,75164,243],{"class":274},[268,75166,75167],{"class":305}," isAdultPointFree",[268,75169,616],{"class":274},[268,75171,72195],{"class":278},[268,75173,622],{"class":282},[268,75175,75176],{"class":278},"gte",[268,75178,622],{"class":282},[268,75180,75181],{"class":305},"18",[268,75183,33111],{"class":282},[268,75185,75186],{"class":278},"prop",[268,75188,622],{"class":282},[268,75190,75191],{"class":289},"\"age\"",[268,75193,4818],{"class":282},[23,75195,75197,75203,75214,75220],{"className":75196},[26],[28,75198,75200,75202],{"className":75199},[31],[33,75201],{"disabled":35,"type":36}," Always — point-free style is strictly superior and should be used everywhere possible",[28,75204,75206,75208,75209,446,75211,75213],{"className":75205},[31],[33,75207],{"disabled":35,"type":36}," It depends — point-free style can be elegant for simple, well-named transformations, but overusing it (especially with unfamiliar helper functions like ",[39,75210,75176],{},[39,75212,75186],{},") can hurt readability, making code harder to scan and debug compared to a plain, explicit arrow function",[28,75215,75217,75219],{"className":75216},[31],[33,75218],{"disabled":35,"type":36}," Never — point-free style is always harder to read than named-parameter style",[28,75221,75223,75225],{"className":75222},[31],[33,75224],{"disabled":35,"type":36}," It doesn't matter — both versions are byte-for-byte identical after minification, so there's no practical difference",[66,75227,75228,75230,75239],{},[69,75229,71],{},[73,75231,75232,75234,75235,446,75237,75213],{},[76,75233,78],{}," B — It depends — point-free style can be elegant for simple, well-named transformations, but overusing it (especially with unfamiliar helper functions like ",[39,75236,75176],{},[39,75238,75186],{},[73,75240,75241,355,75243,75245,75246,42,75248,75251,75252,42,75254,75256,75257,75260],{},[76,75242,84],{},[76,75244,930],{}," point-free style trades an explicit, named parameter (",[39,75247,75142],{},[39,75249,75250],{},"person.age",") for implicit data flow through composed helper functions — readable to someone fluent in the specific utility library's vocabulary (",[39,75253,75176],{},[39,75255,75186],{}," are common in libraries like Ramda), but opaque to someone who isn't, and notably harder to debug since there's no intermediate named value to inspect in a debugger or log statement. The original ",[39,75258,75259],{},"isAdult"," is immediately clear to any JavaScript developer regardless of functional-programming background. Neither extreme (option A \"always\" or option C \"never\") reflects real engineering judgment — the right call depends on team familiarity, the complexity of the transformation, and whether the point-free version actually reads more clearly than the explicit one.",[15,75262,75263,75267,75329,75371],{"language":247},[18,75264,75266],{"id":75265},"q20-a-module-exports-a-shared-configuration-object-that-multiple-other-modules-import-and-occasionally-mutate-directly-what-is-the-idiomatic-functional-programming-fix-for-this-shared-mutable-state-hazard","Q20. A module exports a shared configuration object that multiple other modules import and occasionally mutate directly. What is the idiomatic functional-programming fix for this shared-mutable-state hazard?",[257,75268,75269],{"language":247},[260,75270,75272],{"className":262,"code":75271,"language":247,"meta":264,"style":264},"export const appConfig = { retries: 3, timeout: 5000 };\n\n\u002F\u002F elsewhere, in an unrelated module:\nimport { appConfig } from \".\u002Fconfig.js\";\nappConfig.retries = 10;\n",[39,75273,75274,75295,75299,75304,75318],{"__ignoreMap":264},[268,75275,75276,75278,75280,75283,75285,75287,75289,75291,75293],{"class":270,"line":271},[268,75277,665],{"class":274},[268,75279,44357],{"class":274},[268,75281,75282],{"class":305}," appConfig",[268,75284,616],{"class":274},[268,75286,21225],{"class":282},[268,75288,3423],{"class":305},[268,75290,21235],{"class":282},[268,75292,71395],{"class":305},[268,75294,2790],{"class":282},[268,75296,75297],{"class":270,"line":286},[268,75298,5033],{"emptyLinePlaceholder":35},[268,75300,75301],{"class":270,"line":296},[268,75302,75303],{"class":29390},"\u002F\u002F elsewhere, in an unrelated module:\n",[268,75305,75306,75308,75311,75313,75316],{"class":270,"line":311},[268,75307,662],{"class":274},[268,75309,75310],{"class":282}," { appConfig } ",[268,75312,44539],{"class":274},[268,75314,75315],{"class":289}," \".\u002Fconfig.js\"",[268,75317,293],{"class":282},[268,75319,75320,75323,75325,75327],{"class":270,"line":788},[268,75321,75322],{"class":282},"appConfig.retries ",[268,75324,302],{"class":274},[268,75326,306],{"class":305},[268,75328,293],{"class":282},[23,75330,75332,75338,75351,75363],{"className":75331},[26],[28,75333,75335,75337],{"className":75334},[31],[33,75336],{"disabled":35,"type":36}," Nothing needs to change — ES module bindings are read-only by default, so this mutation already fails silently",[28,75339,75341,75343,75344,75346,75347,75350],{"className":75340},[31],[33,75342],{"disabled":35,"type":36}," Freeze the exported object with ",[39,75345,20133],{}," (deeply, if it has nested data) so accidental mutation throws (in strict mode) or silently no-ops instead of corrupting shared state, and provide an explicit function like ",[39,75348,75349],{},"updateConfig(patch)"," that returns a new merged object for legitimate updates",[28,75352,75354,75356,75357,8574,75360,75362],{"className":75353},[31],[33,75355],{"disabled":35,"type":36}," Export a ",[39,75358,75359],{},"let appConfig",[39,75361,243],{}," so reassignment is explicitly allowed",[28,75364,75366,75368,75369],{"className":75365},[31],[33,75367],{"disabled":35,"type":36}," Wrap every property access across the codebase in a ",[39,75370,2081],{},[66,75372,75373,75375,75384],{},[69,75374,71],{},[73,75376,75377,75379,75380,75346,75382,75350],{},[76,75378,78],{}," B — Freeze the exported object with ",[39,75381,20133],{},[39,75383,75349],{},[73,75385,75386,355,75388,75390,75391,2182,75394,75397,75398,75400,75401,75404,75405,75407,75408,75410,75411,75414],{},[76,75387,84],{},[76,75389,930],{}," ES module bindings only make the ",[104,75392,75393],{},"binding itself",[39,75395,75396],{},"appConfig"," as a name) immutable from an importing module's perspective — you can't reassign what ",[39,75399,75396],{}," refers to from outside the exporting module — but that says nothing about mutating the ",[104,75402,75403],{},"object's properties",", which remain fully writable by default (option A's premise is false, echoing the ",[39,75406,243],{}," gotcha from Q13, just at module scope instead of function scope). ",[39,75409,20133],{}," closes that hole directly, and pairing it with an explicit, controlled update function keeps all legitimate state changes traceable to one place instead of scattered ",[39,75412,75413],{},"appConfig.x = y"," mutations anywhere in the codebase, directly addressing the shared-mutable-state risk described in Q7.",[2107,75416,75417],{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}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 .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}",{"title":264,"searchDepth":286,"depth":286,"links":75419},[75420,75422,75424,75425,75426,75428,75429,75430,75432,75434,75436,75438,75439,75441,75442,75443,75444,75445,75446,75447],{"id":71596,"depth":296,"text":75421},"Q1. Which function below is a pure function?",{"id":71769,"depth":296,"text":75423},"Q2. Why is the following function considered impure, beyond just \"it uses push\"?",{"id":71881,"depth":296,"text":71882},{"id":71999,"depth":296,"text":72000},{"id":72176,"depth":296,"text":75427},"Q5. What does function composition (compose) typically achieve?",{"id":72429,"depth":296,"text":72430},{"id":72641,"depth":296,"text":72642},{"id":72803,"depth":296,"text":75431},"Q8. Object.freeze is often used for immutability. What's the gotcha with the following code?",{"id":72965,"depth":296,"text":75433},"Q9. What is the surprising problem with using Array.prototype.sort inside code that's meant to follow functional, immutable patterns?",{"id":73203,"depth":296,"text":75435},"Q10. A curried function is built using Function.prototype.length to determine when enough arguments have been collected. What's the pitfall with this specific implementation?",{"id":73506,"depth":296,"text":75437},"Q11. A developer mixes up compose and pipe and gets an unexpected result. Given:",{"id":73834,"depth":296,"text":73835},{"id":73959,"depth":296,"text":75440},"Q13. What's the gotcha in this code, given that const is often (incorrectly) equated with \"immutable\"?",{"id":74117,"depth":296,"text":74118},{"id":74348,"depth":296,"text":74349},{"id":74579,"depth":296,"text":74580},{"id":74743,"depth":296,"text":74744},{"id":74902,"depth":296,"text":74903},{"id":75120,"depth":296,"text":75121},{"id":75265,"depth":296,"text":75266},{},"\u002Fjs\u002F23-functional-programming",{"title":71586,"description":264},"js\u002F23-functional-programming","D_d2ER0Vy-RW0lgiZRfgf0xhA5dpWOgjaCJPB7jxMBI",{"id":75454,"title":75455,"body":75456,"description":264,"extension":2144,"meta":78957,"navigation":35,"path":78958,"seo":78959,"stem":78960,"__hash__":78961},"content\u002Fjs\u002F25-testing.md","25 — Testing",{"type":8,"value":75457,"toc":78928},[75458,75461,75508,75710,75773,75917,76090,76311,76458,76642,76773,76824,77066,77331,77636,77867,78138,78335,78386,78601,78648,78925],[11,75459,75455],{"id":75460},"_25-testing",[15,75462,75463,75467,75494],{"language":247},[18,75464,75466],{"id":75465},"q1-what-best-characterizes-the-difference-between-unit-integration-and-end-to-end-e2e-tests","Q1. What best characterizes the difference between unit, integration, and end-to-end (E2E) tests?",[23,75468,75470,75476,75482,75488],{"className":75469},[26],[28,75471,75473,75475],{"className":75472},[31],[33,75474],{"disabled":35,"type":36}," Unit tests exercise the whole app through the UI, so they give the highest confidence but run slowest",[28,75477,75479,75481],{"className":75478},[31],[33,75480],{"disabled":35,"type":36}," Unit tests verify a single function\u002Fmodule in isolation and run fastest; integration tests verify multiple units working together; end-to-end tests drive the real app like a user and give the highest confidence but are slowest and most brittle",[28,75483,75485,75487],{"className":75484},[31],[33,75486],{"disabled":35,"type":36}," Integration tests are always slower than end-to-end tests, because they spin up a full browser",[28,75489,75491,75493],{"className":75490},[31],[33,75492],{"disabled":35,"type":36}," End-to-end tests replace the need for unit tests once a project has enough of them",[66,75495,75496,75498,75503],{},[69,75497,71],{},[73,75499,75500,75502],{},[76,75501,78],{}," B — Unit tests verify a single function\u002Fmodule in isolation and run fastest; integration tests verify multiple units working together; end-to-end tests drive the real app like a user and give the highest confidence but are slowest and most brittle",[73,75504,75505,75507],{},[76,75506,84],{}," This is the classic testing pyramid tradeoff: isolation and speed decrease as confidence increases. Unit tests are cheap and fast because they touch no real collaborators; E2E tests are expensive and slow because they exercise the real browser, network, and database, but they catch integration bugs unit tests structurally cannot see. Option A reverses the definitions — unit tests never touch the UI. Option C gets the ordering backwards; E2E is typically the slowest tier because it pays for a real browser and real I\u002FO, with integration tests in between. Option D is wrong because the pyramid recommends many unit tests, fewer integration tests, and the fewest E2E tests as complements, not replacements — E2E tests alone are too slow and flaky to run on every change.",[15,75509,75510,75534,75653,75692],{"language":247},[18,75511,75513,75514,75517,75518,19439,75521,75524,75525,75527,75528,830,75530,75533],{"id":75512},"q2-you-have-processordercart-paymentgateway-which-totals-a-cart-and-charges-a-payment-gateway-a-test-constructs-an-in-memory-inmemorycart-and-a-fakepaymentgateway-calls-processorder-and-asserts-the-resulting-orders-status-is-paid-what-kind-of-test-is-this","Q2. You have ",[39,75515,75516],{},"processOrder(cart, paymentGateway)",", which totals a cart and charges a payment gateway. A test constructs an in-memory ",[39,75519,75520],{},"InMemoryCart",[39,75522,75523],{},"FakePaymentGateway",", calls ",[39,75526,59476],{},", and asserts the resulting order's ",[39,75529,13305],{},[39,75531,75532],{},"\"paid\"",". What kind of test is this?",[257,75535,75536],{"language":247},[260,75537,75539],{"className":262,"code":75538,"language":247,"meta":264,"style":264},"test(\"processOrder marks the order as paid\", async () => {\n  const cart = new InMemoryCart([{ sku: \"A1\", price: 20 }]);\n  const gateway = new FakePaymentGateway({ willSucceed: true });\n\n  const order = await processOrder(cart, gateway);\n\n  expect(order.status).toBe(\"paid\");\n});\n",[39,75540,75541,75560,75587,75608,75612,75628,75632,75649],{"__ignoreMap":264},[268,75542,75543,75545,75547,75550,75552,75554,75556,75558],{"class":270,"line":271},[268,75544,57434],{"class":278},[268,75546,622],{"class":282},[268,75548,75549],{"class":289},"\"processOrder marks the order as paid\"",[268,75551,42],{"class":282},[268,75553,379],{"class":274},[268,75555,15158],{"class":282},[268,75557,9414],{"class":274},[268,75559,9914],{"class":282},[268,75561,75562,75564,75566,75568,75570,75573,75576,75579,75582,75584],{"class":270,"line":286},[268,75563,12441],{"class":274},[268,75565,41499],{"class":305},[268,75567,616],{"class":274},[268,75569,11370],{"class":274},[268,75571,75572],{"class":278}," InMemoryCart",[268,75574,75575],{"class":282},"([{ sku: ",[268,75577,75578],{"class":289},"\"A1\"",[268,75580,75581],{"class":282},", price: ",[268,75583,6149],{"class":305},[268,75585,75586],{"class":282}," }]);\n",[268,75588,75589,75591,75594,75596,75598,75601,75604,75606],{"class":270,"line":296},[268,75590,12441],{"class":274},[268,75592,75593],{"class":305}," gateway",[268,75595,616],{"class":274},[268,75597,11370],{"class":274},[268,75599,75600],{"class":278}," FakePaymentGateway",[268,75602,75603],{"class":282},"({ willSucceed: ",[268,75605,2185],{"class":305},[268,75607,36080],{"class":282},[268,75609,75610],{"class":270,"line":311},[268,75611,5033],{"emptyLinePlaceholder":35},[268,75613,75614,75616,75619,75621,75623,75625],{"class":270,"line":788},[268,75615,12441],{"class":274},[268,75617,75618],{"class":305}," order",[268,75620,616],{"class":274},[268,75622,52502],{"class":274},[268,75624,11922],{"class":278},[268,75626,75627],{"class":282},"(cart, gateway);\n",[268,75629,75630],{"class":270,"line":1951},[268,75631,5033],{"emptyLinePlaceholder":35},[268,75633,75634,75637,75640,75643,75645,75647],{"class":270,"line":8955},[268,75635,75636],{"class":278},"  expect",[268,75638,75639],{"class":282},"(order.status).",[268,75641,75642],{"class":278},"toBe",[268,75644,622],{"class":282},[268,75646,75532],{"class":289},[268,75648,628],{"class":282},[268,75650,75651],{"class":270,"line":8966},[268,75652,20047],{"class":282},[23,75654,75656,75662,75671,75683],{"className":75655},[26],[28,75657,75659,75661],{"className":75658},[31],[33,75660],{"disabled":35,"type":36}," End-to-end test — it exercises the full application exactly the way a real user would, including the actual UI and a live payment gateway",[28,75663,75665,75667,75668,75670],{"className":75664},[31],[33,75666],{"disabled":35,"type":36}," Unit test — because ",[39,75669,59476],{}," is a single function, calling it in a test always makes the test a unit test regardless of what it depends on",[28,75672,75674,75676,75677,75679,75680,75682],{"className":75673},[31],[33,75675],{"disabled":35,"type":36}," Integration test — it exercises ",[39,75678,59476],{}," together with its collaborators (the cart and the payment gateway, even though the gateway is a fake), verifying that these pieces work correctly together rather than testing ",[39,75681,59476],{}," in full isolation or driving the app through a real UI",[28,75684,75686,75688,75689,75691],{"className":75685},[31],[33,75687],{"disabled":35,"type":36}," Snapshot test — because the assertion checks the resulting ",[39,75690,11927],{}," object's shape",[66,75693,75694,75696,75705],{},[69,75695,71],{},[73,75697,75698,75700,75701,75679,75703,75682],{},[76,75699,78],{}," C — Integration test — it exercises ",[39,75702,59476],{},[39,75704,59476],{},[73,75706,75707,75709],{},[76,75708,84],{}," What makes this an integration test is that the assertion depends on the correct interaction between multiple collaborating pieces (cart totaling, order state transitions, gateway charging), even though the gateway is faked rather than real. Option A is wrong because there's no browser, UI, or live network call involved — using fakes instead of the real UI is exactly what keeps this out of E2E territory. Option B is the common misconception that \"one function call\" automatically means \"unit test\"; what matters is whether the collaborators are isolated out (unit) or exercised together (integration), not how many function calls appear in the test body. Option D confuses this with snapshot testing, which serializes and diffs output rather than asserting on a specific field.",[15,75711,75712,75716,75743],{},[18,75713,75715],{"id":75714},"q3-which-statement-accurately-distinguishes-a-spy-a-stub-and-a-mock","Q3. Which statement accurately distinguishes a spy, a stub, and a mock?",[23,75717,75719,75725,75731,75737],{"className":75718},[26],[28,75720,75722,75724],{"className":75721},[31],[33,75723],{"disabled":35,"type":36}," A spy wraps a real function, recording calls (arguments, call count) while still invoking the original implementation; a stub replaces a function with fixed, canned behavior; a mock is a stub that also has built-in expectations\u002Fassertions about how it should be called",[28,75726,75728,75730],{"className":75727},[31],[33,75729],{"disabled":35,"type":36}," A stub wraps a real function and records how it was called while still invoking the original implementation",[28,75732,75734,75736],{"className":75733},[31],[33,75735],{"disabled":35,"type":36}," A mock always requires a real network connection to verify calls",[28,75738,75740,75742],{"className":75739},[31],[33,75741],{"disabled":35,"type":36}," Spies, stubs, and mocks are interchangeable terms with no meaningful difference between testing libraries",[66,75744,75745,75747,75752],{},[69,75746,71],{},[73,75748,75749,75751],{},[76,75750,78],{}," A — A spy wraps a real function, recording calls (arguments, call count) while still invoking the original implementation; a stub replaces a function with fixed, canned behavior; a mock is a stub that also has built-in expectations\u002Fassertions about how it should be called",[73,75753,75754,355,75756,75758,75759,446,75762,75765,75766,446,75769,75772],{},[76,75755,84],{},[76,75757,930],{}," these three terms describe increasing levels of replacement and assertion, and the distinction is universal test-double terminology, not specific to any one framework — Jest's ",[39,75760,75761],{},"jest.fn()",[39,75763,75764],{},"jest.spyOn()"," and Vitest's ",[39,75767,75768],{},"vi.fn()",[39,75770,75771],{},"vi.spyOn()"," are just two libraries' names for building spies, stubs, and mocks. A spy observes without necessarily replacing behavior; a stub replaces behavior with something canned so the test controls the return value; a mock goes further by encoding expectations about the calls themselves (e.g. \"was called exactly once with these arguments\") as part of the double. Option B swaps the spy\u002Fstub definitions. Option C and D are simply false — none of these concepts require real network access, and the distinctions materially affect how a test reads and what it actually proves.",[15,75774,75775,75786,75843,75881],{"language":247},[18,75776,44471,75778,75781,75782,75785],{"id":75777},"q4-jestspyonconsole-error-is-called-with-no-mockimplementation-chained-after-it-what-happens-when-the-spied-method-is-invoked-during-the-test",[39,75779,75780],{},"jest.spyOn(console, \"error\")"," is called with no ",[39,75783,75784],{},".mockImplementation(...)"," chained after it. What happens when the spied method is invoked during the test?",[257,75787,75788],{"language":247},[260,75789,75791],{"className":262,"code":75790,"language":247,"meta":264,"style":264},"const spy = jest.spyOn(console, \"error\");\n\ndoSomethingThatLogsAnError();\n\nexpect(spy).toHaveBeenCalled();\n",[39,75792,75793,75815,75819,75826,75830],{"__ignoreMap":264},[268,75794,75795,75797,75800,75802,75805,75808,75811,75813],{"class":270,"line":271},[268,75796,243],{"class":274},[268,75798,75799],{"class":305}," spy",[268,75801,616],{"class":274},[268,75803,75804],{"class":282}," jest.",[268,75806,75807],{"class":278},"spyOn",[268,75809,75810],{"class":282},"(console, ",[268,75812,18255],{"class":289},[268,75814,628],{"class":282},[268,75816,75817],{"class":270,"line":286},[268,75818,5033],{"emptyLinePlaceholder":35},[268,75820,75821,75824],{"class":270,"line":296},[268,75822,75823],{"class":278},"doSomethingThatLogsAnError",[268,75825,794],{"class":282},[268,75827,75828],{"class":270,"line":311},[268,75829,5033],{"emptyLinePlaceholder":35},[268,75831,75832,75835,75838,75841],{"class":270,"line":788},[268,75833,75834],{"class":278},"expect",[268,75836,75837],{"class":282},"(spy).",[268,75839,75840],{"class":278},"toHaveBeenCalled",[268,75842,794],{"class":282},[23,75844,75846,75854,75866,75872],{"className":75845},[26],[28,75847,75849,355,75851,75853],{"className":75848},[31],[33,75850],{"disabled":35,"type":36},[39,75852,58817],{}," is completely silenced; nothing is printed to the console",[28,75855,75857,355,75859,75862,75863,75865],{"className":75856},[31],[33,75858],{"disabled":35,"type":36},[39,75860,75861],{},"jest.spyOn"," throws because ",[39,75864,58817],{}," cannot be spied on",[28,75867,75869,75871],{"className":75868},[31],[33,75870],{"disabled":35,"type":36}," The test fails immediately, because spies cannot wrap built-in global methods",[28,75873,75875,75877,75878,75880],{"className":75874},[31],[33,75876],{"disabled":35,"type":36}," The spy records the call for the assertion, but ",[39,75879,58817],{}," still executes its real implementation, so the error is still printed to the console",[66,75882,75883,75885,75892],{},[69,75884,71],{},[73,75886,75887,75889,75890,75880],{},[76,75888,78],{}," D — The spy records the call for the assertion, but ",[39,75891,58817],{},[73,75893,75894,355,75896,75898,75899,75902,75903,75905,75906,75909,75910,75912,75913,75916],{},[76,75895,84],{},[76,75897,365],{}," a bare ",[39,75900,75901],{},"jest.spyOn(obj, \"method\")"," call, by default, calls through to the real implementation — it only adds tracking of calls, arguments, and return values on top. To also replace the behavior (e.g. to silence noisy ",[39,75904,58817],{}," output in a test), you must explicitly chain ",[39,75907,75908],{},".mockImplementation(() => {})",". Option A is the mistake many people make: assuming spying automatically suppresses output, when in fact suppression requires an explicit mock implementation. Options B and C are false — ",[39,75911,75861],{}," works on object methods including built-ins like ",[39,75914,75915],{},"console",", as long as the property is configurable.",[15,75918,75919,75923,75993,76042],{"language":247},[18,75920,75922],{"id":75921},"q5-what-is-the-problem-with-this-test","Q5. What is the problem with this test?",[257,75924,75925],{"language":247},[260,75926,75928],{"className":262,"code":75927,"language":247,"meta":264,"style":264},"test(\"fetchUser resolves with the right name\", () => {\n  fetchUser(1).then((user) => {\n    expect(user.name).toBe(\"Ada\");\n  });\n});\n",[39,75929,75930,75945,75968,75985,75989],{"__ignoreMap":264},[268,75931,75932,75934,75936,75939,75941,75943],{"class":270,"line":271},[268,75933,57434],{"class":278},[268,75935,622],{"class":282},[268,75937,75938],{"class":289},"\"fetchUser resolves with the right name\"",[268,75940,35745],{"class":282},[268,75942,9414],{"class":274},[268,75944,9914],{"class":282},[268,75946,75947,75950,75952,75954,75956,75958,75960,75962,75964,75966],{"class":270,"line":286},[268,75948,75949],{"class":278},"  fetchUser",[268,75951,622],{"class":282},[268,75953,2255],{"class":305},[268,75955,6232],{"class":282},[268,75957,47505],{"class":278},[268,75959,6122],{"class":282},[268,75961,4155],{"class":1222},[268,75963,6131],{"class":282},[268,75965,9414],{"class":274},[268,75967,9914],{"class":282},[268,75969,75970,75973,75976,75978,75980,75983],{"class":270,"line":296},[268,75971,75972],{"class":278},"    expect",[268,75974,75975],{"class":282},"(user.name).",[268,75977,75642],{"class":278},[268,75979,622],{"class":282},[268,75981,75982],{"class":289},"\"Ada\"",[268,75984,628],{"class":282},[268,75986,75987],{"class":270,"line":311},[268,75988,39914],{"class":282},[268,75990,75991],{"class":270,"line":788},[268,75992,20047],{"class":282},[23,75994,75996,76005,76026,76036],{"className":75995},[26],[28,75997,75999,76001,76002,76004],{"className":75998},[31],[33,76000],{"disabled":35,"type":36}," This test always fails, because ",[39,76003,47058],{}," returns a promise instead of a value",[28,76006,76008,76010,76011,76013,76014,76016,76017,76019,76020,76022,76023,76025],{"className":76007},[31],[33,76009],{"disabled":35,"type":36}," This test can report as passing even if ",[39,76012,22787],{}," is not ",[39,76015,75982],{},", because the test function returns ",[39,76018,833],{}," synchronously and the test runner considers the test done before the ",[39,76021,46149],{}," callback — and its ",[39,76024,75834],{}," — ever runs",[28,76027,76029,76031,76032,12305,76034,47378],{"className":76028},[31],[33,76030],{"disabled":35,"type":36}," This test throws a syntax error, because ",[39,76033,46149],{},[39,76035,57512],{},[28,76037,76039,76041],{"className":76038},[31],[33,76040],{"disabled":35,"type":36}," This test correctly verifies the resolved value; the test runner automatically waits for any promise created inside a test",[66,76043,76044,76046,76061],{},[69,76045,71],{},[73,76047,76048,76050,76051,76013,76053,76016,76055,76019,76057,76022,76059,76025],{},[76,76049,78],{}," B — This test can report as passing even if ",[39,76052,22787],{},[39,76054,75982],{},[39,76056,833],{},[39,76058,46149],{},[39,76060,75834],{},[73,76062,76063,355,76065,76067,76068,76070,76071,76073,76074,76076,76077,76079,76080,76082,76083,76086,76087,462],{},[76,76064,84],{},[76,76066,365],{}," this is one of the most common silent-false-positive bugs in async testing. The test callback here is a plain synchronous function that returns ",[39,76069,833],{}," immediately; Jest and Vitest both mark a test complete as soon as its callback returns (unless it returns a promise or uses a ",[39,76072,55154],{}," parameter). The ",[39,76075,46149],{}," callback is scheduled as a microtask that runs ",[104,76078,1747],{}," the synchronous test function has already returned, so if the ",[39,76081,75834],{}," inside it fails, that failure either gets reported as an unhandled rejection after the test has already \"passed,\" or is missed entirely depending on runner configuration. The fix is to ",[39,76084,76085],{},"return fetchUser(1).then(...)"," or, more idiomatically, use ",[39,76088,76089],{},"async () => { const user = await fetchUser(1); expect(user.name).toBe(\"Ada\"); }",[15,76091,76092,76096,76207,76262],{"language":247},[18,76093,76095],{"id":76094},"q6-what-is-wrong-with-this-test","Q6. What is wrong with this test?",[257,76097,76098],{"language":247},[260,76099,76101],{"className":262,"code":76100,"language":247,"meta":264,"style":264},"test(\"all users are validated\", async () => {\n  const ids = [1, 2, 3];\n\n  ids.forEach(async (id) => {\n    const user = await fetchUser(id);\n    expect(user.isValid).toBe(true);\n  });\n});\n",[39,76102,76103,76122,76145,76149,76170,76184,76199,76203],{"__ignoreMap":264},[268,76104,76105,76107,76109,76112,76114,76116,76118,76120],{"class":270,"line":271},[268,76106,57434],{"class":278},[268,76108,622],{"class":282},[268,76110,76111],{"class":289},"\"all users are validated\"",[268,76113,42],{"class":282},[268,76115,379],{"class":274},[268,76117,15158],{"class":282},[268,76119,9414],{"class":274},[268,76121,9914],{"class":282},[268,76123,76124,76126,76129,76131,76133,76135,76137,76139,76141,76143],{"class":270,"line":286},[268,76125,12441],{"class":274},[268,76127,76128],{"class":305}," ids",[268,76130,616],{"class":274},[268,76132,8710],{"class":282},[268,76134,2255],{"class":305},[268,76136,42],{"class":282},[268,76138,2258],{"class":305},[268,76140,42],{"class":282},[268,76142,3423],{"class":305},[268,76144,8737],{"class":282},[268,76146,76147],{"class":270,"line":296},[268,76148,5033],{"emptyLinePlaceholder":35},[268,76150,76151,76154,76156,76158,76160,76162,76164,76166,76168],{"class":270,"line":311},[268,76152,76153],{"class":282},"  ids.",[268,76155,12330],{"class":278},[268,76157,622],{"class":282},[268,76159,379],{"class":274},[268,76161,2182],{"class":282},[268,76163,14610],{"class":1222},[268,76165,6131],{"class":282},[268,76167,9414],{"class":274},[268,76169,9914],{"class":282},[268,76171,76172,76174,76176,76178,76180,76182],{"class":270,"line":788},[268,76173,37893],{"class":274},[268,76175,4071],{"class":305},[268,76177,616],{"class":274},[268,76179,52502],{"class":274},[268,76181,54856],{"class":278},[268,76183,12284],{"class":282},[268,76185,76186,76188,76191,76193,76195,76197],{"class":270,"line":1951},[268,76187,75972],{"class":278},[268,76189,76190],{"class":282},"(user.isValid).",[268,76192,75642],{"class":278},[268,76194,622],{"class":282},[268,76196,2185],{"class":305},[268,76198,628],{"class":282},[268,76200,76201],{"class":270,"line":8955},[268,76202,39914],{"class":282},[268,76204,76205],{"class":270,"line":8966},[268,76206,20047],{"class":282},[23,76208,76210,76224,76241,76251],{"className":76209},[26],[28,76211,76213,355,76215,76217,76218,76220,76221,76223],{"className":76212},[31],[33,76214],{"disabled":35,"type":36},[39,76216,12384],{}," does not await the async callbacks it's given, so the outer test function returns (and the test is marked done) before any of the ",[39,76219,47058],{}," calls resolve or their ",[39,76222,75834],{}," calls actually run",[28,76225,76227,76229,76230,23506,76232,76234,76235,76237,76238,76240],{"className":76226},[31],[33,76228],{"disabled":35,"type":36}," This is correct — ",[39,76231,379],{},[39,76233,12330],{}," makes the whole loop asynchronous, and ",[39,76236,12304],{}," on the outer ",[39,76239,57434],{}," waits for every iteration to finish before the test completes",[28,76242,76244,2398,76246,2833,76248,76250],{"className":76243},[31],[33,76245],{"disabled":35,"type":36},[39,76247,827],{},[39,76249,12330],{}," cannot accept an async function",[28,76252,76254,76256,76257,2029,76259,76261],{"className":76253},[31],[33,76255],{"disabled":35,"type":36}," This is equivalent to using ",[39,76258,52467],{},[39,76260,23950],{},", so all assertions are guaranteed to run before the test finishes",[66,76263,76264,76266,76276],{},[69,76265,71],{},[73,76267,76268,3459,76270,76217,76272,76220,76274,76223],{},[76,76269,78],{},[39,76271,12384],{},[39,76273,47058],{},[39,76275,75834],{},[73,76277,76278,355,76280,355,76282,76284,76285,76288,76289,76291,76292,76294,76295,76297,76298,76300,76301,76303,76304,383,76307,76310],{},[76,76279,84],{},[76,76281,365],{},[39,76283,12330],{}," invokes its callback for each element and completely ignores any value — including a promise — that the callback returns; it does not chain or await them. Each ",[39,76286,76287],{},"async (id) => {...}"," call kicks off a promise and ",[39,76290,12330],{}," immediately moves to the next element without waiting, so the outer ",[39,76293,57434],{}," function's ",[39,76296,12304],{},"-free body returns right after the loop, and the test is considered finished before any ",[39,76299,47058],{}," resolves. This makes every ",[39,76302,75834],{}," inside the loop a fire-and-forget check that may never be seen by the test runner. The fix is ",[39,76305,76306],{},"for (const id of ids) { const user = await fetchUser(id); expect(user.isValid).toBe(true); }",[39,76308,76309],{},"await Promise.all(ids.map(async (id) => { ... }))",". Option D specifically names the correct fix pattern but wrongly claims it describes the code as written.",[15,76312,76313,76317,76380,76415],{"language":247},[18,76314,76316],{"id":76315},"q7-given-this-function-which-is-the-most-correct-way-to-test-that-it-rejects-for-an-invalid-amount","Q7. Given this function, which is the most correct way to test that it rejects for an invalid amount?",[257,76318,76319],{"language":247},[260,76320,76322],{"className":262,"code":76321,"language":247,"meta":264,"style":264},"async function chargeCard(amount) {\n  if (amount \u003C= 0) throw new Error(\"Invalid amount\");\n  return gateway.charge(amount);\n}\n",[39,76323,76324,76338,76363,76376],{"__ignoreMap":264},[268,76325,76326,76328,76330,76332,76334,76336],{"class":270,"line":271},[268,76327,379],{"class":274},[268,76329,12080],{"class":274},[268,76331,54215],{"class":278},[268,76333,622],{"class":282},[268,76335,31848],{"class":1222},[268,76337,1235],{"class":282},[268,76339,76340,76342,76344,76346,76348,76350,76352,76354,76356,76358,76361],{"class":270,"line":286},[268,76341,9863],{"class":274},[268,76343,54250],{"class":282},[268,76345,6776],{"class":274},[268,76347,5728],{"class":305},[268,76349,6131],{"class":282},[268,76351,48836],{"class":274},[268,76353,11370],{"class":274},[268,76355,11593],{"class":278},[268,76357,622],{"class":282},[268,76359,76360],{"class":289},"\"Invalid amount\"",[268,76362,628],{"class":282},[268,76364,76365,76367,76370,76373],{"class":270,"line":296},[268,76366,1240],{"class":274},[268,76368,76369],{"class":282}," gateway.",[268,76371,76372],{"class":278},"charge",[268,76374,76375],{"class":282},"(amount);\n",[268,76377,76378],{"class":270,"line":311},[268,76379,314],{"class":282},[23,76381,76383,76391,76399,76407],{"className":76382},[26],[28,76384,76386,355,76388],{"className":76385},[31],[33,76387],{"disabled":35,"type":36},[39,76389,76390],{},"expect(chargeCard(-5)).toThrow(\"Invalid amount\");",[28,76392,76394,355,76396],{"className":76393},[31],[33,76395],{"disabled":35,"type":36},[39,76397,76398],{},"const result = chargeCard(-5); expect(result).toBe(undefined);",[28,76400,76402,355,76404],{"className":76401},[31],[33,76403],{"disabled":35,"type":36},[39,76405,76406],{},"chargeCard(-5).catch((e) => console.log(e));",[28,76408,76410,355,76412],{"className":76409},[31],[33,76411],{"disabled":35,"type":36},[39,76413,76414],{},"await expect(chargeCard(-5)).rejects.toThrow(\"Invalid amount\");",[66,76416,76417,76419,76425],{},[69,76418,71],{},[73,76420,76421,6901,76423],{},[76,76422,78],{},[39,76424,76414],{},[73,76426,76427,355,76429,355,76431,76434,76435,76438,76439,446,76442,76444,76445,76448,76449,76451,76452,76454,76455,76457],{},[76,76428,84],{},[76,76430,930],{},[39,76432,76433],{},".rejects"," unwraps the promise's rejection so the matcher can assert on the thrown error, and awaiting the whole ",[39,76436,76437],{},"expect(...)"," call ensures the test runner actually waits for that assertion to run before the test is marked complete. (",[39,76440,76441],{},"rejects",[39,76443,51690],{}," are Jest and Vitest matcher-naming conventions specifically — other runners use different syntax, but the underlying need to both await and assert on the rejection is universal.) Option A is wrong because ",[39,76446,76447],{},"toThrow"," expects a synchronously-throwing function, not a promise — an async function's ",[39,76450,48836],{}," becomes a rejection, not a synchronous exception, so this assertion doesn't correctly observe it. Option B never awaits anything and doesn't test failure at all. Option C swallows the rejection with a ",[39,76453,5627],{}," and asserts nothing — if ",[39,76456,54317],{}," unexpectedly resolved instead of rejecting, this \"test\" would still report as passing.",[15,76459,76460,76464,76541,76593],{"language":247},[18,76461,76463],{"id":76462},"q8-what-is-the-risk-in-this-test","Q8. What is the risk in this test?",[257,76465,76466],{"language":247},[260,76467,76469],{"className":262,"code":76468,"language":247,"meta":264,"style":264},"test(\"chargeCard rejects for invalid amount\", async () => {\n  try {\n    await chargeCard(-5);\n  } catch (err) {\n    expect(err.message).toBe(\"Invalid amount\");\n  }\n});\n",[39,76470,76471,76490,76496,76510,76518,76533,76537],{"__ignoreMap":264},[268,76472,76473,76475,76477,76480,76482,76484,76486,76488],{"class":270,"line":271},[268,76474,57434],{"class":278},[268,76476,622],{"class":282},[268,76478,76479],{"class":289},"\"chargeCard rejects for invalid amount\"",[268,76481,42],{"class":282},[268,76483,379],{"class":274},[268,76485,15158],{"class":282},[268,76487,9414],{"class":274},[268,76489,9914],{"class":282},[268,76491,76492,76494],{"class":270,"line":286},[268,76493,54867],{"class":274},[268,76495,9914],{"class":282},[268,76497,76498,76500,76502,76504,76506,76508],{"class":270,"line":296},[268,76499,12278],{"class":274},[268,76501,54215],{"class":278},[268,76503,622],{"class":282},[268,76505,6244],{"class":274},[268,76507,2429],{"class":305},[268,76509,628],{"class":282},[268,76511,76512,76514,76516],{"class":270,"line":311},[268,76513,9881],{"class":282},[268,76515,12488],{"class":274},[268,76517,12491],{"class":282},[268,76519,76520,76522,76525,76527,76529,76531],{"class":270,"line":788},[268,76521,75972],{"class":278},[268,76523,76524],{"class":282},"(err.message).",[268,76526,75642],{"class":278},[268,76528,622],{"class":282},[268,76530,76360],{"class":289},[268,76532,628],{"class":282},[268,76534,76535],{"class":270,"line":1951},[268,76536,1948],{"class":282},[268,76538,76539],{"class":270,"line":8955},[268,76540,20047],{"class":282},[23,76542,76544,76553,76564,76579],{"className":76543},[26],[28,76545,76547,76549,76550],{"className":76546},[31],[33,76548],{"disabled":35,"type":36}," This is the recommended pattern for testing rejections; it is equivalent in safety to ",[39,76551,76552],{},"rejects.toThrow",[28,76554,76556,76558,76559,76561,76562,11115],{"className":76555},[31],[33,76557],{"disabled":35,"type":36}," This throws a syntax error, because ",[39,76560,75834],{}," cannot be called inside a ",[39,76563,12488],{},[28,76565,76567,76569,76570,76572,76573,76575,76576,76578],{"className":76566},[31],[33,76568],{"disabled":35,"type":36}," This test can give a false positive: if ",[39,76571,54456],{}," unexpectedly resolves instead of rejecting, the ",[39,76574,12488],{}," block — and its ",[39,76577,75834],{}," — never runs, and the test passes having executed zero assertions",[28,76580,76582,76001,76584,446,76586,76588,76589,446,76591],{"className":76581},[31],[33,76583],{"disabled":35,"type":36},[39,76585,23142],{},[39,76587,12488],{}," cannot be combined with ",[39,76590,379],{},[39,76592,12304],{},[66,76594,76595,76597,76608],{},[69,76596,71],{},[73,76598,76599,76601,76602,76572,76604,76575,76606,76578],{},[76,76600,78],{}," C — This test can give a false positive: if ",[39,76603,54456],{},[39,76605,12488],{},[39,76607,75834],{},[73,76609,76610,355,76612,76614,76615,446,76617,76619,76620,446,76622,76624,76625,76627,76628,76630,76631,76633,76634,76637,76638,76641],{},[76,76611,84],{},[76,76613,365],{}," this is the same silent-false-positive family as the missing-",[39,76616,12304],{},[39,76618,46149],{}," bug, just wearing a ",[39,76621,23142],{},[39,76623,12488],{}," disguise. If a future change accidentally makes ",[39,76626,54317],{}," resolve for negative amounts instead of throwing, the ",[39,76629,12488],{}," block simply never executes, no ",[39,76632,75834],{}," ever runs, and the test still reports green — precisely when it should be failing loudest. The safer pattern is ",[39,76635,76636],{},"await expect(chargeCard(-5)).rejects.toThrow(\"Invalid amount\")",", where the absence of a rejection itself causes the assertion to fail; alternatively, guard the try\u002Fcatch version with ",[39,76639,76640],{},"expect.assertions(1)"," at the top of the test so the runner fails the test if the expected number of assertions never ran.",[15,76643,76644,76648,76719,76746],{"language":247},[18,76645,76647],{"id":76646},"q9-what-tradeoff-does-snapshot-testing-introduce","Q9. What tradeoff does snapshot testing introduce?",[257,76649,76650],{"language":247},[260,76651,76653],{"className":262,"code":76652,"language":247,"meta":264,"style":264},"test(\"renders the user card\", () => {\n  const tree = renderer.create(\u003CUserCard name=\"Ada\" \u002F>).toJSON();\n  expect(tree).toMatchSnapshot();\n});\n",[39,76654,76655,76670,76703,76715],{"__ignoreMap":264},[268,76656,76657,76659,76661,76664,76666,76668],{"class":270,"line":271},[268,76658,57434],{"class":278},[268,76660,622],{"class":282},[268,76662,76663],{"class":289},"\"renders the user card\"",[268,76665,35745],{"class":282},[268,76667,9414],{"class":274},[268,76669,9914],{"class":282},[268,76671,76672,76674,76677,76679,76682,76684,76687,76690,76692,76694,76696,76699,76701],{"class":270,"line":286},[268,76673,12441],{"class":274},[268,76675,76676],{"class":305}," tree",[268,76678,616],{"class":274},[268,76680,76681],{"class":282}," renderer.",[268,76683,20628],{"class":278},[268,76685,76686],{"class":282},"(\u003C",[268,76688,76689],{"class":305},"UserCard",[268,76691,16204],{"class":278},[268,76693,302],{"class":274},[268,76695,75982],{"class":289},[268,76697,76698],{"class":282}," \u002F>).",[268,76700,22419],{"class":278},[268,76702,794],{"class":282},[268,76704,76705,76707,76710,76713],{"class":270,"line":296},[268,76706,75636],{"class":278},[268,76708,76709],{"class":282},"(tree).",[268,76711,76712],{"class":278},"toMatchSnapshot",[268,76714,794],{"class":282},[268,76716,76717],{"class":270,"line":311},[268,76718,20047],{"class":282},[23,76720,76722,76728,76734,76740],{"className":76721},[26],[28,76723,76725,76727],{"className":76724},[31],[33,76726],{"disabled":35,"type":36}," Snapshot tests replace the need for any other assertions, because they capture the entire output automatically",[28,76729,76731,76733],{"className":76730},[31],[33,76732],{"disabled":35,"type":36}," Snapshot tests are useful for catching unintended changes to output, but they carry a real risk: when a snapshot fails, it's easy to reflexively run the \"update snapshot\" command without actually reviewing the diff, which can silently bake a real regression into the new snapshot as the new \"expected\" output",[28,76735,76737,76739],{"className":76736},[31],[33,76738],{"disabled":35,"type":36}," Snapshots can only be used with React components, never with plain JSON or string output",[28,76741,76743,76745],{"className":76742},[31],[33,76744],{"disabled":35,"type":36}," A snapshot test fails only if the component throws an error during render",[66,76747,76748,76750,76755],{},[69,76749,71],{},[73,76751,76752,76754],{},[76,76753,78],{}," B — Snapshot tests are useful for catching unintended changes to output, but they carry a real risk: when a snapshot fails, it's easy to reflexively run the \"update snapshot\" command without actually reviewing the diff, which can silently bake a real regression into the new snapshot as the new \"expected\" output",[73,76756,76757,76759,76760,76762,76763,2758,76766,76769,76770,76772],{},[76,76758,84],{}," Snapshot testing is good at flagging ",[104,76761,7690],{}," output changed, but says nothing about whether the change is correct — that judgment call is left entirely to whoever reviews the failing diff. In practice, a failing snapshot in a busy CI run often gets \"fixed\" by blindly re-running the updater, which overwrites the stored snapshot with whatever the (possibly buggy) code now produces, turning a real regression into the new passing baseline. Option A overstates what snapshots verify — they detect ",[104,76764,76765],{},"change",[104,76767,76768],{},"correctness",". Option C is false; ",[39,76771,76712],{}," works on any serializable value, including plain objects and strings. Option D is false; a snapshot test fails whenever the serialized output differs from the stored snapshot, render errors aside.",[15,76774,76775,76779,76806],{},[18,76776,76778],{"id":76777},"q10-following-on-from-snapshot-testing-what-is-the-correct-discipline-for-handling-a-failing-snapshot","Q10. Following on from snapshot testing: what is the correct discipline for handling a failing snapshot?",[23,76780,76782,76788,76794,76800],{"className":76781},[26],[28,76783,76785,76787],{"className":76784},[31],[33,76786],{"disabled":35,"type":36}," Snapshots should be reviewed like a code diff on every failure — treating an unreviewed \"update snapshot\" run as automatically correct defeats the purpose of the test, since it just captures whatever the code currently outputs as the new \"truth\"",[28,76789,76791,76793],{"className":76790},[31],[33,76792],{"disabled":35,"type":36}," It is always safe to run the snapshot-update command in CI on every failing build, to keep the suite green",[28,76795,76797,76799],{"className":76796},[31],[33,76798],{"disabled":35,"type":36}," Snapshots should be committed as binary files, so they cannot be diffed or reviewed at all",[28,76801,76803,76805],{"className":76802},[31],[33,76804],{"disabled":35,"type":36}," A growing snapshot file is a sign the test suite has too much coverage, and snapshots should be deleted regularly",[66,76807,76808,76810,76815],{},[69,76809,71],{},[73,76811,76812,76814],{},[76,76813,78],{}," A — Snapshots should be reviewed like a code diff on every failure — treating an unreviewed \"update snapshot\" run as automatically correct defeats the purpose of the test, since it just captures whatever the code currently outputs as the new \"truth\"",[73,76816,76817,76819,76820,76823],{},[76,76818,84],{}," A snapshot is only as trustworthy as the review it received when it was captured or updated; the entire value of the test collapses if updates are applied reflexively rather than read as a diff. Option B describes the exact anti-pattern that turns a regression detector into rubber-stamping machinery — automatically updating snapshots in CI removes the human review step that gives the test any signal at all. Option C is counterproductive; snapshots are stored as plain, diffable text (e.g. ",[39,76821,76822],{},".snap"," files) specifically so they can be reviewed in pull requests. Option D confuses volume with quality — a large snapshot file isn't inherently a problem, but unreviewed updates are.",[15,76825,76826,76830,76977,77017],{"language":247},[18,76827,76829],{"id":76828},"q11-what-is-the-problem-with-this-pair-of-tests","Q11. What is the problem with this pair of tests?",[257,76831,76832],{"language":247},[260,76833,76835],{"className":262,"code":76834,"language":247,"meta":264,"style":264},"let cache = [];\n\nfunction addItem(item) {\n  cache.push(item);\n  return cache.length;\n}\n\ntest(\"adds first item\", () => {\n  expect(addItem(\"a\")).toBe(1);\n});\n\ntest(\"adds second item\", () => {\n  expect(addItem(\"b\")).toBe(1);\n});\n",[39,76836,76837,76848,76852,76864,76872,76882,76886,76890,76905,76928,76932,76936,76951,76973],{"__ignoreMap":264},[268,76838,76839,76841,76844,76846],{"class":270,"line":271},[268,76840,240],{"class":274},[268,76842,76843],{"class":282}," cache ",[268,76845,302],{"class":274},[268,76847,12449],{"class":282},[268,76849,76850],{"class":270,"line":286},[268,76851,5033],{"emptyLinePlaceholder":35},[268,76853,76854,76856,76858,76860,76862],{"class":270,"line":296},[268,76855,275],{"class":274},[268,76857,14788],{"class":278},[268,76859,622],{"class":282},[268,76861,14793],{"class":1222},[268,76863,1235],{"class":282},[268,76865,76866,76868,76870],{"class":270,"line":311},[268,76867,15846],{"class":282},[268,76869,12499],{"class":278},[268,76871,11808],{"class":282},[268,76873,76874,76876,76878,76880],{"class":270,"line":788},[268,76875,1240],{"class":274},[268,76877,37883],{"class":282},[268,76879,3567],{"class":305},[268,76881,293],{"class":282},[268,76883,76884],{"class":270,"line":1951},[268,76885,314],{"class":282},[268,76887,76888],{"class":270,"line":8955},[268,76889,5033],{"emptyLinePlaceholder":35},[268,76891,76892,76894,76896,76899,76901,76903],{"class":270,"line":8966},[268,76893,57434],{"class":278},[268,76895,622],{"class":282},[268,76897,76898],{"class":289},"\"adds first item\"",[268,76900,35745],{"class":282},[268,76902,9414],{"class":274},[268,76904,9914],{"class":282},[268,76906,76907,76909,76911,76913,76915,76917,76920,76922,76924,76926],{"class":270,"line":8974},[268,76908,75636],{"class":278},[268,76910,622],{"class":282},[268,76912,14837],{"class":278},[268,76914,622],{"class":282},[268,76916,7582],{"class":289},[268,76918,76919],{"class":282},")).",[268,76921,75642],{"class":278},[268,76923,622],{"class":282},[268,76925,2255],{"class":305},[268,76927,628],{"class":282},[268,76929,76930],{"class":270,"line":8985},[268,76931,20047],{"class":282},[268,76933,76934],{"class":270,"line":8990},[268,76935,5033],{"emptyLinePlaceholder":35},[268,76937,76938,76940,76942,76945,76947,76949],{"class":270,"line":8997},[268,76939,57434],{"class":278},[268,76941,622],{"class":282},[268,76943,76944],{"class":289},"\"adds second item\"",[268,76946,35745],{"class":282},[268,76948,9414],{"class":274},[268,76950,9914],{"class":282},[268,76952,76953,76955,76957,76959,76961,76963,76965,76967,76969,76971],{"class":270,"line":9002},[268,76954,75636],{"class":278},[268,76956,622],{"class":282},[268,76958,14837],{"class":278},[268,76960,622],{"class":282},[268,76962,9188],{"class":289},[268,76964,76919],{"class":282},[268,76966,75642],{"class":278},[268,76968,622],{"class":282},[268,76970,2255],{"class":305},[268,76972,628],{"class":282},[268,76974,76975],{"class":270,"line":14676},[268,76976,20047],{"class":282},[23,76978,76980,76986,76995,77008],{"className":76979},[26],[28,76981,76983,76985],{"className":76982},[31],[33,76984],{"disabled":35,"type":36}," Both tests pass reliably regardless of run order, because the test runner resets all module-level variables before each test",[28,76987,76989,76991,76992,76994],{"className":76988},[31],[33,76990],{"disabled":35,"type":36}," This code cannot run at all, because top-level ",[39,76993,240],{}," declarations are forbidden in test files",[28,76996,76998,77000,77001,2833,77003,77005,77006],{"className":76997},[31],[33,76999],{"disabled":35,"type":36}," The second test always fails with a ",[39,77002,827],{},[39,77004,15925],{}," is undefined inside ",[39,77007,14837],{},[28,77009,77011,77013,77014,77016],{"className":77010},[31],[33,77012],{"disabled":35,"type":36}," The second test is order-dependent and will fail (or pass) unpredictably depending on execution order, because ",[39,77015,15925],{}," is module-level shared state that isn't reset between tests — a classic source of flaky, order-dependent failures",[66,77018,77019,77021,77028],{},[69,77020,71],{},[73,77022,77023,77025,77026,77016],{},[76,77024,78],{}," D — The second test is order-dependent and will fail (or pass) unpredictably depending on execution order, because ",[39,77027,15925],{},[73,77029,77030,77032,77033,77035,77036,77039,77040,77042,77043,4912,77046,2758,77048,77050,77051,77054,77055,77058,77059,50319,77062,77065],{},[76,77031,84],{}," Test isolation means each test should start from a known, independent state. Here, ",[39,77034,15925],{}," lives outside any test and outside any setup hook, so it accumulates across the whole file: after the first test runs, ",[39,77037,77038],{},"cache.length"," is already ",[39,77041,2255],{},", so the second test's ",[39,77044,77045],{},"addItem(\"b\")",[39,77047,2258],{},[39,77049,2255],{},", and the assertion fails — but only if the tests run in that order. If a test runner or ",[39,77052,77053],{},"--shuffle"," flag reorders tests, or a test is run in isolation with ",[39,77056,77057],{},".only",", the outcome flips unpredictably. The fix is to reset ",[39,77060,77061],{},"cache = []",[39,77063,77064],{},"beforeEach",", or avoid module-level mutable state entirely by scoping it inside each test. Option A describes behavior no mainstream test runner provides by default — module state persists across tests in the same file unless explicitly reset.",[15,77067,77068,77078,77217,77275],{"language":247},[18,77069,77071,77072,186,77074,77077],{"id":77070},"q12-what-do-beforeeach-and-aftereach-accomplish-in-this-test-file","Q12. What do ",[39,77073,77064],{},[39,77075,77076],{},"afterEach"," accomplish in this test file?",[257,77079,77080],{"language":247},[260,77081,77083],{"className":262,"code":77082,"language":247,"meta":264,"style":264},"describe(\"UserRepository\", () => {\n  let repo;\n\n  beforeEach(() => {\n    repo = new UserRepository();\n  });\n\n  afterEach(() => {\n    repo.close();\n  });\n\n  test(\"starts empty\", () => {\n    expect(repo.count()).toBe(0);\n  });\n});\n",[39,77084,77085,77100,77107,77111,77122,77136,77140,77144,77155,77165,77169,77173,77189,77209,77213],{"__ignoreMap":264},[268,77086,77087,77089,77091,77094,77096,77098],{"class":270,"line":271},[268,77088,9942],{"class":278},[268,77090,622],{"class":282},[268,77092,77093],{"class":289},"\"UserRepository\"",[268,77095,35745],{"class":282},[268,77097,9414],{"class":274},[268,77099,9914],{"class":282},[268,77101,77102,77104],{"class":270,"line":286},[268,77103,2206],{"class":274},[268,77105,77106],{"class":282}," repo;\n",[268,77108,77109],{"class":270,"line":296},[268,77110,5033],{"emptyLinePlaceholder":35},[268,77112,77113,77116,77118,77120],{"class":270,"line":311},[268,77114,77115],{"class":278},"  beforeEach",[268,77117,9411],{"class":282},[268,77119,9414],{"class":274},[268,77121,9914],{"class":282},[268,77123,77124,77127,77129,77131,77134],{"class":270,"line":788},[268,77125,77126],{"class":282},"    repo ",[268,77128,302],{"class":274},[268,77130,11370],{"class":274},[268,77132,77133],{"class":278}," UserRepository",[268,77135,794],{"class":282},[268,77137,77138],{"class":270,"line":1951},[268,77139,39914],{"class":282},[268,77141,77142],{"class":270,"line":8955},[268,77143,5033],{"emptyLinePlaceholder":35},[268,77145,77146,77149,77151,77153],{"class":270,"line":8966},[268,77147,77148],{"class":278},"  afterEach",[268,77150,9411],{"class":282},[268,77152,9414],{"class":274},[268,77154,9914],{"class":282},[268,77156,77157,77160,77163],{"class":270,"line":8974},[268,77158,77159],{"class":282},"    repo.",[268,77161,77162],{"class":278},"close",[268,77164,794],{"class":282},[268,77166,77167],{"class":270,"line":8985},[268,77168,39914],{"class":282},[268,77170,77171],{"class":270,"line":8990},[268,77172,5033],{"emptyLinePlaceholder":35},[268,77174,77175,77178,77180,77183,77185,77187],{"class":270,"line":8997},[268,77176,77177],{"class":278},"  test",[268,77179,622],{"class":282},[268,77181,77182],{"class":289},"\"starts empty\"",[268,77184,35745],{"class":282},[268,77186,9414],{"class":274},[268,77188,9914],{"class":282},[268,77190,77191,77193,77196,77198,77201,77203,77205,77207],{"class":270,"line":9002},[268,77192,75972],{"class":278},[268,77194,77195],{"class":282},"(repo.",[268,77197,10191],{"class":278},[268,77199,77200],{"class":282},"()).",[268,77202,75642],{"class":278},[268,77204,622],{"class":282},[268,77206,3307],{"class":305},[268,77208,628],{"class":282},[268,77210,77211],{"class":270,"line":14676},[268,77212,39914],{"class":282},[268,77214,77215],{"class":270,"line":14681},[268,77216,20047],{"class":282},[23,77218,77220,77233,77247,77261],{"className":77219},[26],[28,77221,77223,355,77225,446,77227,77229,77230,77232],{"className":77222},[31],[33,77224],{"disabled":35,"type":36},[39,77226,77064],{},[39,77228,77076],{}," run once total for the whole ",[39,77231,9942],{}," block, before\u002Fafter all its tests combined",[28,77234,77236,355,77238,51262,77240,77242,77243,77246],{"className":77235},[31],[33,77237],{"disabled":35,"type":36},[39,77239,77076],{},[39,77241,77064],{}," on every test, so ",[39,77244,77245],{},"repo"," is closed before it's even created",[28,77248,77250,355,77252,77254,77255,77257,77258,77260],{"className":77249},[31],[33,77251],{"disabled":35,"type":36},[39,77253,77064],{}," creates a fresh ",[39,77256,77245],{}," before every test in the block and ",[39,77259,77076],{}," tears it down after every test, giving each test an isolated, known starting state instead of leaking state between tests",[28,77262,77264,12848,77266,77268,77269,77271,77272,67669],{"className":77263},[31],[33,77265],{"disabled":35,"type":36},[39,77267,77245],{}," is declared with ",[39,77270,240],{}," outside the hooks, every test shares the exact same ",[39,77273,77274],{},"UserRepository",[66,77276,77277,77279,77289],{},[69,77278,71],{},[73,77280,77281,1004,77283,77254,77285,77257,77287,77260],{},[76,77282,78],{},[39,77284,77064],{},[39,77286,77245],{},[39,77288,77076],{},[73,77290,77291,355,77293,446,77295,77297,77298,355,77301,446,77303,77306,77307,77309,77310,446,77313,77316,77317,77319,77320,77322,77323,355,77325,355,77328,77330],{},[76,77292,84],{},[39,77294,77064],{},[39,77296,77076],{}," run around ",[104,77299,77300],{},"every individual",[39,77302,57434],{},[39,77304,77305],{},"it"," in their scope, not once for the whole ",[39,77308,9942],{}," block — that's what ",[39,77311,77312],{},"beforeAll",[39,77314,77315],{},"afterAll"," do instead, which is the mistake option A describes. Each test therefore gets a brand-new ",[39,77318,77274],{}," assigned to the shared ",[39,77321,77245],{}," variable, and the previous instance is closed afterward, preventing the kind of cross-test state leakage seen in Q11. Option B reverses the actual execution order — setup always runs before the test, teardown after. Option D is wrong precisely because ",[39,77324,77064],{},[104,77326,77327],{},"reassigns",[39,77329,77245],{}," to a new instance before each test, so the reference changes even though the variable binding itself is declared once.",[15,77332,77333,77349,77476,77555],{"language":247},[18,77334,45860,77336,77338,77339,77341,77342,77344,77345,77348],{"id":77335},"q13-save-is-a-mock-with-a-canned-return-value-the-first-test-passes-the-second-fails-because-save-has-already-been-called-once-by-the-time-it-runs-which-fix-resets-the-call-count-between-tests-without-discarding-the-mockreturnvaluetrue-behavior",[39,77337,60710],{}," is a mock with a canned return value. The first test passes; the second fails because ",[39,77340,60710],{}," has already been called once by the time it runs. Which fix resets the call count between tests ",[104,77343,28448],{}," discarding the ",[39,77346,77347],{},"mockReturnValue(true)"," behavior?",[257,77350,77351],{"language":247},[260,77352,77354],{"className":262,"code":77353,"language":247,"meta":264,"style":264},"const save = jest.fn().mockReturnValue(true);\n\ntest(\"first call\", () => {\n  save(\"a\");\n  expect(save).toHaveBeenCalledTimes(1);\n});\n\ntest(\"second call\", () => {\n  save(\"b\");\n  expect(save).toHaveBeenCalledTimes(1);\n});\n",[39,77355,77356,77379,77383,77398,77409,77425,77429,77433,77448,77458,77472],{"__ignoreMap":264},[268,77357,77358,77360,77362,77364,77366,77368,77370,77373,77375,77377],{"class":270,"line":271},[268,77359,243],{"class":274},[268,77361,60603],{"class":305},[268,77363,616],{"class":274},[268,77365,75804],{"class":282},[268,77367,37837],{"class":278},[268,77369,19341],{"class":282},[268,77371,77372],{"class":278},"mockReturnValue",[268,77374,622],{"class":282},[268,77376,2185],{"class":305},[268,77378,628],{"class":282},[268,77380,77381],{"class":270,"line":286},[268,77382,5033],{"emptyLinePlaceholder":35},[268,77384,77385,77387,77389,77392,77394,77396],{"class":270,"line":296},[268,77386,57434],{"class":278},[268,77388,622],{"class":282},[268,77390,77391],{"class":289},"\"first call\"",[268,77393,35745],{"class":282},[268,77395,9414],{"class":274},[268,77397,9914],{"class":282},[268,77399,77400,77403,77405,77407],{"class":270,"line":311},[268,77401,77402],{"class":278},"  save",[268,77404,622],{"class":282},[268,77406,7582],{"class":289},[268,77408,628],{"class":282},[268,77410,77411,77413,77416,77419,77421,77423],{"class":270,"line":788},[268,77412,75636],{"class":278},[268,77414,77415],{"class":282},"(save).",[268,77417,77418],{"class":278},"toHaveBeenCalledTimes",[268,77420,622],{"class":282},[268,77422,2255],{"class":305},[268,77424,628],{"class":282},[268,77426,77427],{"class":270,"line":1951},[268,77428,20047],{"class":282},[268,77430,77431],{"class":270,"line":8955},[268,77432,5033],{"emptyLinePlaceholder":35},[268,77434,77435,77437,77439,77442,77444,77446],{"class":270,"line":8966},[268,77436,57434],{"class":278},[268,77438,622],{"class":282},[268,77440,77441],{"class":289},"\"second call\"",[268,77443,35745],{"class":282},[268,77445,9414],{"class":274},[268,77447,9914],{"class":282},[268,77449,77450,77452,77454,77456],{"class":270,"line":8974},[268,77451,77402],{"class":278},[268,77453,622],{"class":282},[268,77455,9188],{"class":289},[268,77457,628],{"class":282},[268,77459,77460,77462,77464,77466,77468,77470],{"class":270,"line":8985},[268,77461,75636],{"class":278},[268,77463,77415],{"class":282},[268,77465,77418],{"class":278},[268,77467,622],{"class":282},[268,77469,2255],{"class":305},[268,77471,628],{"class":282},[268,77473,77474],{"class":270,"line":8990},[268,77475,20047],{"class":282},[23,77477,77479,77500,77521,77549],{"className":77478},[26],[28,77480,77482,77484,77485,77488,77489,77491,77492,77494,77495,77497,77498],{"className":77481},[31],[33,77483],{"disabled":35,"type":36}," Add ",[39,77486,77487],{},"jest.restoreAllMocks()"," in an ",[39,77490,77076],{}," — it only affects mocks created with ",[39,77493,75861],{},", restoring their original (non-mocked) implementation, so it wouldn't touch a plain ",[39,77496,75761],{}," like ",[39,77499,60710],{},[28,77501,77503,77484,77505,77488,77508,77510,77511,446,77514,77517,77518,77520],{"className":77502},[31],[33,77504],{"disabled":35,"type":36},[39,77506,77507],{},"jest.clearAllMocks()",[39,77509,77076],{}," — it resets ",[39,77512,77513],{},"mock.calls",[39,77515,77516],{},"mock.instances"," (so the recorded call count starts fresh before each test) but leaves the configured ",[39,77519,77347],{}," implementation intact",[28,77522,77524,77484,77526,77488,77529,77531,77532,446,77534,77537,77538,77540,77541,1179,77543,77546,77547],{"className":77523},[31],[33,77525],{"disabled":35,"type":36},[39,77527,77528],{},"jest.resetAllMocks()",[39,77530,77076],{}," — it clears call history AND removes any configured ",[39,77533,77372],{},[39,77535,77536],{},"mockImplementation",", resetting ",[39,77539,60710],{}," to a plain mock that returns ",[39,77542,833],{},[39,77544,77545],{},"save(\"b\")"," would no longer return ",[39,77548,2185],{},[28,77550,77552,77554],{"className":77551},[31],[33,77553],{"disabled":35,"type":36}," Do nothing — the test runner automatically clears mock call counts between tests by default in every configuration",[66,77556,77557,77559,77574],{},[69,77558,71],{},[73,77560,77561,77563,77564,77488,77566,77510,77568,446,77570,77517,77572,77520],{},[76,77562,78],{}," B — Add ",[39,77565,77507],{},[39,77567,77076],{},[39,77569,77513],{},[39,77571,77516],{},[39,77573,77347],{},[73,77575,77576,355,77578,355,77580,77583,77584,77586,77587,446,77590,77592,77593,77595,77596,77598,77599,3277,77601,446,77604,77606,77607,77609,77610,77612,77613,77615,77616,446,77619,446,77622,77625,77626,446,77629,446,77632,77635],{},[76,77577,84],{},[76,77579,930],{},[39,77581,77582],{},"mockClear()"," (and its bulk form ",[39,77585,77507],{},") only wipes recorded call history — arguments, call count, results — leaving any configured implementation untouched, which is exactly what's needed here. ",[39,77588,77589],{},"mockReset()",[39,77591,77528],{}," goes further and also strips the mocked implementation, which is why option C's ",[39,77594,60710],{}," would start returning ",[39,77597,833],{},", breaking any test relying on ",[39,77600,2185],{},[39,77602,77603],{},"mockRestore()",[39,77605,77487],{}," goes furthest, restoring the ",[104,77608,22772],{}," un-mocked implementation, but that only applies to mocks created via ",[39,77611,75861],{}," on a real method — a bare ",[39,77614,75761],{}," has no \"original\" to restore to, so option A wouldn't fix anything. (",[39,77617,77618],{},"clearAllMocks",[39,77620,77621],{},"resetAllMocks",[39,77623,77624],{},"restoreAllMocks"," are Jest's specific method names; Vitest mirrors them as ",[39,77627,77628],{},"vi.clearAllMocks()",[39,77630,77631],{},"vi.resetAllMocks()",[39,77633,77634],{},"vi.restoreAllMocks()"," — the underlying three-tier distinction is the part worth remembering.) Option D is false; leftover mock state across tests is a common, real cause of flakiness, not something runners fix automatically.",[15,77637,77638,77642,77770,77823],{"language":247},[18,77639,77641],{"id":77640},"q14-why-does-this-test-complete-instantly-instead-of-taking-5-real-seconds","Q14. Why does this test complete instantly instead of taking 5 real seconds?",[257,77643,77644],{"language":247},[260,77645,77647],{"className":262,"code":77646,"language":247,"meta":264,"style":264},"function scheduleReminder(cb) {\n  setTimeout(cb, 5000);\n}\n\ntest(\"calls the callback after 5 seconds\", () => {\n  jest.useFakeTimers();\n  const cb = jest.fn();\n  scheduleReminder(cb);\n\n  jest.advanceTimersByTime(5000);\n\n  expect(cb).toHaveBeenCalledTimes(1);\n});\n",[39,77648,77649,77663,77674,77678,77682,77697,77707,77722,77730,77734,77747,77751,77766],{"__ignoreMap":264},[268,77650,77651,77653,77656,77658,77661],{"class":270,"line":271},[268,77652,275],{"class":274},[268,77654,77655],{"class":278}," scheduleReminder",[268,77657,622],{"class":282},[268,77659,77660],{"class":1222},"cb",[268,77662,1235],{"class":282},[268,77664,77665,77667,77670,77672],{"class":270,"line":286},[268,77666,9408],{"class":278},[268,77668,77669],{"class":282},"(cb, ",[268,77671,71395],{"class":305},[268,77673,628],{"class":282},[268,77675,77676],{"class":270,"line":296},[268,77677,314],{"class":282},[268,77679,77680],{"class":270,"line":311},[268,77681,5033],{"emptyLinePlaceholder":35},[268,77683,77684,77686,77688,77691,77693,77695],{"class":270,"line":788},[268,77685,57434],{"class":278},[268,77687,622],{"class":282},[268,77689,77690],{"class":289},"\"calls the callback after 5 seconds\"",[268,77692,35745],{"class":282},[268,77694,9414],{"class":274},[268,77696,9914],{"class":282},[268,77698,77699,77702,77705],{"class":270,"line":1951},[268,77700,77701],{"class":282},"  jest.",[268,77703,77704],{"class":278},"useFakeTimers",[268,77706,794],{"class":282},[268,77708,77709,77711,77714,77716,77718,77720],{"class":270,"line":8955},[268,77710,12441],{"class":274},[268,77712,77713],{"class":305}," cb",[268,77715,616],{"class":274},[268,77717,75804],{"class":282},[268,77719,37837],{"class":278},[268,77721,794],{"class":282},[268,77723,77724,77727],{"class":270,"line":8966},[268,77725,77726],{"class":278},"  scheduleReminder",[268,77728,77729],{"class":282},"(cb);\n",[268,77731,77732],{"class":270,"line":8974},[268,77733,5033],{"emptyLinePlaceholder":35},[268,77735,77736,77738,77741,77743,77745],{"class":270,"line":8985},[268,77737,77701],{"class":282},[268,77739,77740],{"class":278},"advanceTimersByTime",[268,77742,622],{"class":282},[268,77744,71395],{"class":305},[268,77746,628],{"class":282},[268,77748,77749],{"class":270,"line":8990},[268,77750,5033],{"emptyLinePlaceholder":35},[268,77752,77753,77755,77758,77760,77762,77764],{"class":270,"line":8997},[268,77754,75636],{"class":278},[268,77756,77757],{"class":282},"(cb).",[268,77759,77418],{"class":278},[268,77761,622],{"class":282},[268,77763,2255],{"class":305},[268,77765,628],{"class":282},[268,77767,77768],{"class":270,"line":9002},[268,77769,20047],{"class":282},[23,77771,77773,77786,77799,77814],{"className":77772},[26],[28,77774,77776,355,77778,77781,77782,77785],{"className":77775},[31],[33,77777],{"disabled":35,"type":36},[39,77779,77780],{},"jest.useFakeTimers()"," replaces the global timer functions with mock versions; ",[39,77783,77784],{},"jest.advanceTimersByTime(5000)"," then synchronously fast-forwards the mocked clock and fires any callbacks scheduled at or before that point — no real waiting occurs, so the test runs instantly",[28,77787,77789,77791,77792,77794,77795,2758,77797],{"className":77788},[31],[33,77790],{"disabled":35,"type":36}," This test actually waits 5 real seconds; ",[39,77793,77740],{}," only affects ",[39,77796,71222],{},[39,77798,9578],{},[28,77800,77802,355,77804,77806,77807,2758,77809,1179,77811,77813],{"className":77801},[31],[33,77803],{"disabled":35,"type":36},[39,77805,77780],{}," only works with ",[39,77808,47386],{},[39,77810,9578],{},[39,77812,77660],{}," is never called",[28,77815,77817,355,77819,77822],{"className":77816},[31],[33,77818],{"disabled":35,"type":36},[39,77820,77821],{},"advanceTimersByTime(5000)"," schedules the callback to run 5000 real milliseconds from now, instead of running it immediately",[66,77824,77825,77827,77835],{},[69,77826,71],{},[73,77828,77829,3459,77831,77781,77833,77785],{},[76,77830,78],{},[39,77832,77780],{},[39,77834,77784],{},[73,77836,77837,77839,77840,446,77842,446,77844,77846,77847,77850,77851,77854,77855,77857,77858,77861,77862,186,77864,77866],{},[76,77838,84],{}," Fake timers swap out ",[39,77841,9578],{},[39,77843,47386],{},[39,77845,2669],{}," (depending on configuration) with mock implementations that track scheduled callbacks against a fake internal clock instead of the real system clock. ",[39,77848,77849],{},"advanceTimersByTime(ms)"," moves that fake clock forward by ",[39,77852,77853],{},"ms"," and synchronously invokes any callbacks whose delay has now elapsed, letting time-based code be tested in milliseconds of real wall-clock time instead of actually waiting. (",[39,77856,77780],{}," is Jest's API name; Vitest's equivalent is ",[39,77859,77860],{},"vi.useFakeTimers()"," — the fake-clock concept itself is universal.) Options B and C misdescribe what fake timers intercept — they replace the timer functions themselves, working for both ",[39,77863,9578],{},[39,77865,47386],{},". Option D inverts what \"advance\" means; it moves the clock forward through the scheduled point, not away from it.",[15,77868,77869,77878,78030,78087],{"language":247},[18,77870,77872,77873,446,77875,77877],{"id":77871},"q15-this-test-combines-fake-timers-with-a-real-asyncawait-chain-what-subtlety-can-trip-it-up","Q15. This test combines fake timers with a real ",[39,77874,379],{},[39,77876,12304],{}," chain. What subtlety can trip it up?",[257,77879,77880],{"language":247},[260,77881,77883],{"className":262,"code":77882,"language":247,"meta":264,"style":264},"async function delayedFetch(id) {\n  await new Promise((resolve) => setTimeout(resolve, 1000));\n  return fetch(`\u002Fusers\u002F${id}`);\n}\n\ntest(\"resolves after the delay\", async () => {\n  jest.useFakeTimers();\n  const promise = delayedFetch(1);\n\n  jest.advanceTimersByTime(1000);\n\n  await expect(promise).resolves.toBeDefined();\n});\n",[39,77884,77885,77900,77924,77940,77944,77948,77967,77975,77991,77995,78007,78011,78026],{"__ignoreMap":264},[268,77886,77887,77889,77891,77894,77896,77898],{"class":270,"line":271},[268,77888,379],{"class":274},[268,77890,12080],{"class":274},[268,77892,77893],{"class":278}," delayedFetch",[268,77895,622],{"class":282},[268,77897,14610],{"class":1222},[268,77899,1235],{"class":282},[268,77901,77902,77904,77906,77908,77910,77912,77914,77916,77918,77920,77922],{"class":270,"line":286},[268,77903,54703],{"class":274},[268,77905,11370],{"class":274},[268,77907,50116],{"class":305},[268,77909,6122],{"class":282},[268,77911,47500],{"class":1222},[268,77913,6131],{"class":282},[268,77915,9414],{"class":274},[268,77917,40796],{"class":278},[268,77919,54718],{"class":282},[268,77921,70543],{"class":305},[268,77923,4818],{"class":282},[268,77925,77926,77928,77930,77932,77934,77936,77938],{"class":270,"line":296},[268,77927,1240],{"class":274},[268,77929,53875],{"class":278},[268,77931,622],{"class":282},[268,77933,59569],{"class":289},[268,77935,14610],{"class":282},[268,77937,11603],{"class":289},[268,77939,628],{"class":282},[268,77941,77942],{"class":270,"line":311},[268,77943,314],{"class":282},[268,77945,77946],{"class":270,"line":788},[268,77947,5033],{"emptyLinePlaceholder":35},[268,77949,77950,77952,77954,77957,77959,77961,77963,77965],{"class":270,"line":1951},[268,77951,57434],{"class":278},[268,77953,622],{"class":282},[268,77955,77956],{"class":289},"\"resolves after the delay\"",[268,77958,42],{"class":282},[268,77960,379],{"class":274},[268,77962,15158],{"class":282},[268,77964,9414],{"class":274},[268,77966,9914],{"class":282},[268,77968,77969,77971,77973],{"class":270,"line":8955},[268,77970,77701],{"class":282},[268,77972,77704],{"class":278},[268,77974,794],{"class":282},[268,77976,77977,77979,77981,77983,77985,77987,77989],{"class":270,"line":8966},[268,77978,12441],{"class":274},[268,77980,55652],{"class":305},[268,77982,616],{"class":274},[268,77984,77893],{"class":278},[268,77986,622],{"class":282},[268,77988,2255],{"class":305},[268,77990,628],{"class":282},[268,77992,77993],{"class":270,"line":8974},[268,77994,5033],{"emptyLinePlaceholder":35},[268,77996,77997,77999,78001,78003,78005],{"class":270,"line":8985},[268,77998,77701],{"class":282},[268,78000,77740],{"class":278},[268,78002,622],{"class":282},[268,78004,70543],{"class":305},[268,78006,628],{"class":282},[268,78008,78009],{"class":270,"line":8990},[268,78010,5033],{"emptyLinePlaceholder":35},[268,78012,78013,78015,78018,78021,78024],{"class":270,"line":8997},[268,78014,54703],{"class":274},[268,78016,78017],{"class":278}," expect",[268,78019,78020],{"class":282},"(promise).resolves.",[268,78022,78023],{"class":278},"toBeDefined",[268,78025,794],{"class":282},[268,78027,78028],{"class":270,"line":9002},[268,78029,20047],{"class":282},[23,78031,78033,78042,78057,78071],{"className":78032},[26],[28,78034,78036,78038,78039,78041],{"className":78035},[31],[33,78037],{"disabled":35,"type":36}," This is completely safe — ",[39,78040,77740],{}," always resolves every pending promise in the same synchronous call, so no extra step is ever needed",[28,78043,78045,355,78047,78049,78050,446,78052,78054,78055],{"className":78044},[31],[33,78046],{"disabled":35,"type":36},[39,78048,77780],{}," disables ",[39,78051,379],{},[39,78053,12304],{}," entirely, so this test throws a ",[39,78056,1274],{},[28,78058,78060,355,78062,78064,78065,78067,78068,78070],{"className":78059},[31],[33,78061],{"disabled":35,"type":36},[39,78063,47324],{}," cannot be called inside a function that uses ",[39,78066,9578],{},", so this test always throws a ",[39,78069,815],{}," regardless of timers",[28,78072,78074,78076,78077,23506,78079,78082,78083,78086],{"className":78073},[31],[33,78075],{"disabled":35,"type":36}," Advancing fake timers fires the timer callback synchronously, but resuming the ",[39,78078,12304],{},[39,78080,78081],{},"delayedFetch"," still requires a separate microtask tick — advancing timers doesn't automatically flush pending microtasks from real Promises, so mixing fake timers with async code can need an extra ",[39,78084,78085],{},"await Promise.resolve()"," (or an async-aware timer-advance helper) before the promise actually settles",[66,78088,78089,78091,78102],{},[69,78090,71],{},[73,78092,78093,78095,78096,23506,78098,78082,78100,78086],{},[76,78094,78],{}," D — Advancing fake timers fires the timer callback synchronously, but resuming the ",[39,78097,12304],{},[39,78099,78081],{},[39,78101,78085],{},[73,78103,78104,355,78106,355,78108,78110,78111,78113,78114,78117,78118,78120,78121,78124,78125,8828,78128,78131,78132,446,78134,78137],{},[76,78105,84],{},[76,78107,365],{},[39,78109,77740],{}," operates on the macrotask\u002Ftimer queue — it synchronously invokes the ",[39,78112,9578],{}," callback (which calls ",[39,78115,78116],{},"resolve()","), but resuming execution after an ",[39,78119,12304],{}," happens on the microtask queue, on the next tick. If the mock-timer implementation doesn't also flush pending microtasks, the outer ",[39,78122,78123],{},"await expect(promise).resolves..."," can end up racing the still-pending microtask, leading to flaky or hanging assertions in some setups. Modern Jest\u002FVitest offer async-aware helpers (e.g. ",[39,78126,78127],{},"jest.advanceTimersByTimeAsync",[39,78129,78130],{},"vi.advanceTimersByTimeAsync",", or awaiting a ",[39,78133,53482],{},[39,78135,78136],{},"flushPromises()"," tick) specifically to bridge this gap. Options B and C describe failures that don't occur — fake timers don't disable async\u002Fawait or forbid calling other functions inside a timer-based one; option A overstates the guarantee and is the assumption that causes real intermittent failures in test suites mixing fake timers with real promise chains.",[15,78139,78140,78144,78252,78306],{"language":247},[18,78141,78143],{"id":78142},"q16-what-is-wrong-with-testing-this-function-by-asserting-on-a-hardcoded-expected-output","Q16. What is wrong with testing this function by asserting on a hardcoded expected output?",[257,78145,78146],{"language":247},[260,78147,78149],{"className":262,"code":78148,"language":247,"meta":264,"style":264},"function generateOrderId() {\n  return `ORD-${Date.now()}-${Math.floor(Math.random() * 1000)}`;\n}\n\ntest(\"generateOrderId returns a predictable id\", () => {\n  expect(generateOrderId()).toBe(\"ORD-1700000000000-42\");\n});\n",[39,78150,78151,78160,78205,78209,78213,78228,78248],{"__ignoreMap":264},[268,78152,78153,78155,78158],{"class":270,"line":271},[268,78154,275],{"class":274},[268,78156,78157],{"class":278}," generateOrderId",[268,78159,283],{"class":282},[268,78161,78162,78164,78167,78169,78171,78173,78175,78177,78180,78182,78185,78187,78189,78191,78193,78195,78197,78199,78201,78203],{"class":270,"line":286},[268,78163,1240],{"class":274},[268,78165,78166],{"class":289}," `ORD-${",[268,78168,2669],{"class":282},[268,78170,462],{"class":289},[268,78172,49125],{"class":278},[268,78174,16952],{"class":289},[268,78176,16955],{"class":289},[268,78178,78179],{"class":282},"Math",[268,78181,462],{"class":289},[268,78183,78184],{"class":278},"floor",[268,78186,622],{"class":289},[268,78188,78179],{"class":282},[268,78190,462],{"class":289},[268,78192,73871],{"class":278},[268,78194,16182],{"class":289},[268,78196,6134],{"class":274},[268,78198,62793],{"class":305},[268,78200,2690],{"class":289},[268,78202,11603],{"class":289},[268,78204,293],{"class":282},[268,78206,78207],{"class":270,"line":296},[268,78208,314],{"class":282},[268,78210,78211],{"class":270,"line":311},[268,78212,5033],{"emptyLinePlaceholder":35},[268,78214,78215,78217,78219,78222,78224,78226],{"class":270,"line":788},[268,78216,57434],{"class":278},[268,78218,622],{"class":282},[268,78220,78221],{"class":289},"\"generateOrderId returns a predictable id\"",[268,78223,35745],{"class":282},[268,78225,9414],{"class":274},[268,78227,9914],{"class":282},[268,78229,78230,78232,78234,78237,78239,78241,78243,78246],{"class":270,"line":1951},[268,78231,75636],{"class":278},[268,78233,622],{"class":282},[268,78235,78236],{"class":278},"generateOrderId",[268,78238,77200],{"class":282},[268,78240,75642],{"class":278},[268,78242,622],{"class":282},[268,78244,78245],{"class":289},"\"ORD-1700000000000-42\"",[268,78247,628],{"class":282},[268,78249,78250],{"class":270,"line":8955},[268,78251,20047],{"class":282},[23,78253,78255,78267,78278,78297],{"className":78254},[26],[28,78256,78258,78260,78261,78263,78264,78266],{"className":78257},[31],[33,78259],{"disabled":35,"type":36}," This test is fine, because the test runner automatically freezes ",[39,78262,71222],{}," and seeds ",[39,78265,73907],{}," for every test run",[28,78268,78270,355,78272,78274,78275,78277],{"className":78269},[31],[33,78271],{"disabled":35,"type":36},[39,78273,73907],{}," always returns the same value within a single test file, so only ",[39,78276,71222],{}," needs mocking",[28,78279,78281,78283,78284,186,78286,78288,78289,78292,78293,78296],{"className":78280},[31],[33,78282],{"disabled":35,"type":36}," This test is inherently flaky, because ",[39,78285,71222],{},[39,78287,73907],{}," produce different real values on every run; to make it deterministic you need to mock them (e.g. ",[39,78290,78291],{},"jest.spyOn(Date, \"now\").mockReturnValue(...)"," and mock ",[39,78294,78295],{},"Math.random",") or inject a clock\u002FRNG dependency so the test controls their output",[28,78298,78300,78302,78303,78305],{"className":78299},[31],[33,78301],{"disabled":35,"type":36}," This will pass consistently as long as the test runs on the same machine, because ",[39,78304,71222],{}," is deterministic per machine",[66,78307,78308,78310,78323],{},[69,78309,71],{},[73,78311,78312,78314,78315,186,78317,78288,78319,78292,78321,78296],{},[76,78313,78],{}," C — This test is inherently flaky, because ",[39,78316,71222],{},[39,78318,73907],{},[39,78320,78291],{},[39,78322,78295],{},[73,78324,78325,78327,78328,42,78331,78334],{},[76,78326,84],{}," Any function whose output depends on wall-clock time or randomness cannot be asserted against a fixed literal — the exact same code will produce a different string on every single run, so this test is guaranteed to fail almost immediately after being written (or on any machine other than the one that generated the literal). The fix is either to mock the nondeterministic sources directly (",[39,78329,78330],{},"jest.spyOn(Date, \"now\").mockReturnValue(1700000000000)",[39,78332,78333],{},"jest.spyOn(Math, \"random\").mockReturnValue(0.042)","), or better, to inject a clock and RNG as parameters\u002Fdependencies so the test can supply deterministic fakes without needing to patch globals. Options A, B, and D each invent a guarantee that doesn't exist in JavaScript or any mainstream test runner.",[15,78336,78337,78341,78368],{},[18,78338,78340],{"id":78339},"q17-a-function-under-test-has-five-collaborators-and-the-test-mocks-all-five-then-asserts-only-that-each-mock-was-called-with-the-expected-arguments-in-the-expected-order-what-risk-does-this-pattern-introduce","Q17. A function under test has five collaborators, and the test mocks all five, then asserts only that each mock was called with the expected arguments in the expected order. What risk does this pattern introduce?",[23,78342,78344,78350,78356,78362],{"className":78343},[26],[28,78345,78347,78349],{"className":78346},[31],[33,78348],{"disabled":35,"type":36}," Mocking more dependencies always makes a test suite more reliable, since fewer real code paths can fail",[28,78351,78353,78355],{"className":78352},[31],[33,78354],{"disabled":35,"type":36}," Mocking so many of a function's collaborators that the test only verifies the mocks were called in the expected sequence — rather than exercising any real logic — can create false confidence: the test passes even if the real integration between those pieces is broken, because none of the real code paths actually ran",[28,78357,78359,78361],{"className":78358},[31],[33,78360],{"disabled":35,"type":36}," Over-mocking is only a concern in end-to-end tests, never in unit tests",[28,78363,78365,78367],{"className":78364},[31],[33,78366],{"disabled":35,"type":36}," A test with heavy mocking runs slower than one with no mocks, because mock setup always requires real I\u002FO",[66,78369,78370,78372,78377],{},[69,78371,71],{},[73,78373,78374,78376],{},[76,78375,78],{}," B — Mocking so many of a function's collaborators that the test only verifies the mocks were called in the expected sequence — rather than exercising any real logic — can create false confidence: the test passes even if the real integration between those pieces is broken, because none of the real code paths actually ran",[73,78378,78379,78381,78382,78385],{},[76,78380,84],{}," When every collaborator is replaced with a mock, the \"system under test\" shrinks down to just the glue code wiring those mocks together — the test proves that glue code calls things in the right order, but proves nothing about whether the real implementations actually work together correctly. This is a genuine, common trap: a suite can be full of green tests like this while a refactor that changes real interaction contracts (argument shapes, error handling) sails through undetected, because nothing in the test exercised real behavior. Option A inverts the actual risk — more mocking generally means less real code is verified, not more reliability. Option C is false; over-mocking is very much a unit-test problem, arguably its most common failure mode. Option D confuses mock setup cost with I\u002FO cost; mocks specifically avoid real I\u002FO and are typically ",[104,78383,78384],{},"faster",", not slower.",[15,78387,78388,78396,78498,78552],{"language":247},[18,78389,78391,78392,78395],{"id":78390},"q18-this-test-achieves-100-line-coverage-of-divide-what-is-still-missing","Q18. This test achieves 100% line coverage of ",[39,78393,78394],{},"divide",". What is still missing?",[257,78397,78398],{"language":247},[260,78399,78401],{"className":262,"code":78400,"language":247,"meta":264,"style":264},"function divide(a, b) {\n  if (b === 0) throw new Error(\"Cannot divide by zero\");\n  return a \u002F b;\n}\n\ntest(\"divide runs without crashing\", () => {\n  divide(10, 2);\n});\n",[39,78402,78403,78420,78446,78456,78460,78464,78479,78494],{"__ignoreMap":264},[268,78404,78405,78407,78410,78412,78414,78416,78418],{"class":270,"line":271},[268,78406,275],{"class":274},[268,78408,78409],{"class":278}," divide",[268,78411,622],{"class":282},[268,78413,1223],{"class":1222},[268,78415,42],{"class":282},[268,78417,1232],{"class":1222},[268,78419,1235],{"class":282},[268,78421,78422,78424,78427,78429,78431,78433,78435,78437,78439,78441,78444],{"class":270,"line":286},[268,78423,9863],{"class":274},[268,78425,78426],{"class":282}," (b ",[268,78428,3280],{"class":274},[268,78430,5728],{"class":305},[268,78432,6131],{"class":282},[268,78434,48836],{"class":274},[268,78436,11370],{"class":274},[268,78438,11593],{"class":278},[268,78440,622],{"class":282},[268,78442,78443],{"class":289},"\"Cannot divide by zero\"",[268,78445,628],{"class":282},[268,78447,78448,78450,78452,78454],{"class":270,"line":296},[268,78449,1240],{"class":274},[268,78451,1243],{"class":282},[268,78453,446],{"class":274},[268,78455,1249],{"class":282},[268,78457,78458],{"class":270,"line":311},[268,78459,314],{"class":282},[268,78461,78462],{"class":270,"line":788},[268,78463,5033],{"emptyLinePlaceholder":35},[268,78465,78466,78468,78470,78473,78475,78477],{"class":270,"line":1951},[268,78467,57434],{"class":278},[268,78469,622],{"class":282},[268,78471,78472],{"class":289},"\"divide runs without crashing\"",[268,78474,35745],{"class":282},[268,78476,9414],{"class":274},[268,78478,9914],{"class":282},[268,78480,78481,78484,78486,78488,78490,78492],{"class":270,"line":8955},[268,78482,78483],{"class":278},"  divide",[268,78485,622],{"class":282},[268,78487,5825],{"class":305},[268,78489,42],{"class":282},[268,78491,2258],{"class":305},[268,78493,628],{"class":282},[268,78495,78496],{"class":270,"line":8966},[268,78497,20047],{"class":282},[23,78499,78501,78521,78531,78543],{"className":78500},[26],[28,78502,78504,78506,78507,78509,78510,78512,78513,78515,78516,7255,78518,78520],{"className":78503},[31],[33,78505],{"disabled":35,"type":36}," This test can contribute to 100% line coverage for ",[39,78508,78394],{}," while asserting nothing about its behavior — it never checks that the returned value is actually ",[39,78511,2429],{},", so a bug that made ",[39,78514,78394],{}," always return ",[39,78517,3307],{},[39,78519,3040],{},") would still leave this test green. High coverage measures which lines executed, not whether the output was verified",[28,78522,78524,78526,78527,78530],{"className":78523},[31],[33,78525],{"disabled":35,"type":36}," This test is equivalent to ",[39,78528,78529],{},"expect(divide(10, 2)).toBe(5)",", because the test runner automatically asserts on the return value of the last expression in a test",[28,78532,78534,78536,78537,78539,78540,13454],{"className":78533},[31],[33,78535],{"disabled":35,"type":36}," This test fails automatically, because a ",[39,78538,57512],{}," block must contain at least one ",[39,78541,78542],{},"expect()",[28,78544,78546,78548,78549,78551],{"className":78545},[31],[33,78547],{"disabled":35,"type":36}," Line coverage tools report this line as uncovered because no ",[39,78550,78542],{}," was used, so the false sense of confidence described doesn't apply here",[66,78553,78554,78556,78571],{},[69,78555,71],{},[73,78557,78558,78560,78561,78509,78563,78512,78565,78515,78567,7255,78569,78520],{},[76,78559,78],{}," A — This test can contribute to 100% line coverage for ",[39,78562,78394],{},[39,78564,2429],{},[39,78566,78394],{},[39,78568,3307],{},[39,78570,3040],{},[73,78572,78573,78575,78576,78579,78580,78583,78584,78587,78588,78590,78591,78593,78594,78597,78598,78600],{},[76,78574,84],{}," Line\u002Fbranch coverage is purely a measure of which code ",[104,78577,78578],{},"ran"," during the test suite, not whether the test made any meaningful claim about correctness. Calling ",[39,78581,78582],{},"divide(10, 2)"," executes the ",[39,78585,78586],{},"return a \u002F b"," line, satisfying coverage tooling, but with zero ",[39,78589,78542],{}," calls the test can never fail no matter how wrong the computed value is — coverage percentage and correctness confidence are two different axes that can diverge sharply. Option B invents a behavior no mainstream test runner has; nothing is asserted automatically. Option C is false — most runners do not require an ",[39,78592,78542],{}," per test by default (some can be configured with ",[39,78595,78596],{},"expect.assertions()"," to enforce it, but that's opt-in, not automatic). Option D is wrong for the reason stated in the correct answer: the line ",[104,78599,10043],{}," count as covered by execution alone, regardless of whether it was asserted on.",[15,78602,78603,78607,78634],{},[18,78604,78606],{"id":78605},"q19-a-test-suite-occasionally-fails-because-a-test-makes-a-real-http-call-to-a-third-party-api-which-is-sometimes-slow-or-briefly-unavailable-what-is-the-best-practice-fix","Q19. A test suite occasionally fails because a test makes a real HTTP call to a third-party API, which is sometimes slow or briefly unavailable. What is the best-practice fix?",[23,78608,78610,78616,78622,78628],{"className":78609},[26],[28,78611,78613,78615],{"className":78612},[31],[33,78614],{"disabled":35,"type":36}," Add a retry mechanism so the test simply reruns until it passes",[28,78617,78619,78621],{"className":78618},[31],[33,78620],{"disabled":35,"type":36}," Keep the real network call, since network-dependent tests are considered best practice — they prove the code works against the real production API",[28,78623,78625,78627],{"className":78624},[31],[33,78626],{"disabled":35,"type":36}," Increase the test timeout, since that addresses the root cause of network-related flakiness",[28,78629,78631,78633],{"className":78630},[31],[33,78632],{"disabled":35,"type":36}," A test that calls a real external API introduces flakiness from network latency, rate limits, and outages that have nothing to do with whether the code under test is correct; the best practice is to isolate the unit by mocking the network layer (or using a recorded fixture\u002Ffake server) so the test's pass\u002Ffail depends only on the code being tested",[66,78635,78636,78638,78643],{},[69,78637,71],{},[73,78639,78640,78642],{},[76,78641,78],{}," D — A test that calls a real external API introduces flakiness from network latency, rate limits, and outages that have nothing to do with whether the code under test is correct; the best practice is to isolate the unit by mocking the network layer (or using a recorded fixture\u002Ffake server) so the test's pass\u002Ffail depends only on the code being tested",[73,78644,78645,78647],{},[76,78646,84],{}," A test's job is to give a reliable, repeatable signal about the code under test; anything that ties its outcome to an external system's availability, latency, or rate limits undermines that signal, because the test can now fail for reasons that have nothing to do with a real bug. The standard fix is to isolate the unit from the network entirely — mocking the HTTP client, stubbing the fetch call, or replaying a recorded fixture — so the test exercises the code's logic deterministically, with a separate (typically smaller, explicitly-labeled) suite of true integration\u002FE2E tests reserved for verifying the real network integration occasionally. Option A papers over the symptom without fixing the underlying nondeterminism, and can hide a real regression behind eventual retries. Option B mistakes an E2E concern for a unit-test virtue — real-API calls belong in a deliberately separate, smaller test tier, not scattered through the main suite. Option C doesn't address rate limits or outright outages, and just makes a slow, flaky test slower.",[15,78649,78650,78665,78849,78889],{"language":247},[18,78651,78653,78654,78656,78657,78660,78661,78664],{"id":78652},"q20-two-tests-check-the-same-increment-behavior-on-a-counter-class-that-uses-a-real-count-private-field-which-approach-is-the-better-practice-and-why","Q20. Two tests check the same ",[39,78655,34969],{}," behavior on a ",[39,78658,78659],{},"Counter"," class that uses a real ",[39,78662,78663],{},"#count"," private field. Which approach is the better practice, and why?",[257,78666,78667],{"language":247},[260,78668,78670],{"className":262,"code":78669,"language":247,"meta":264,"style":264},"class Counter {\n  #count = 0;\n  increment() {\n    this.#count += 1;\n    return this.#count;\n  }\n}\n\ntest(\"increment increases the count (implementation-coupled)\", () => {\n  const c = new Counter();\n  c.increment();\n  expect(c[\"#count\"]).toBe(1);\n});\n\ntest(\"increment increases the count (behavior-based)\", () => {\n  const c = new Counter();\n  expect(c.increment()).toBe(1);\n});\n",[39,78671,78672,78680,78691,78697,78710,78719,78723,78727,78731,78746,78760,78769,78789,78793,78797,78812,78826,78845],{"__ignoreMap":264},[268,78673,78674,78676,78678],{"class":270,"line":271},[268,78675,1468],{"class":274},[268,78677,32656],{"class":278},[268,78679,9914],{"class":282},[268,78681,78682,78685,78687,78689],{"class":270,"line":286},[268,78683,78684],{"class":1222},"  #count",[268,78686,616],{"class":274},[268,78688,5728],{"class":305},[268,78690,293],{"class":282},[268,78692,78693,78695],{"class":270,"line":296},[268,78694,34918],{"class":278},[268,78696,283],{"class":282},[268,78698,78699,78701,78704,78706,78708],{"class":270,"line":311},[268,78700,22057],{"class":305},[268,78702,78703],{"class":282},".#count ",[268,78705,14575],{"class":274},[268,78707,2199],{"class":305},[268,78709,293],{"class":282},[268,78711,78712,78714,78716],{"class":270,"line":788},[268,78713,9871],{"class":274},[268,78715,30206],{"class":305},[268,78717,78718],{"class":282},".#count;\n",[268,78720,78721],{"class":270,"line":1951},[268,78722,1948],{"class":282},[268,78724,78725],{"class":270,"line":8955},[268,78726,314],{"class":282},[268,78728,78729],{"class":270,"line":8966},[268,78730,5033],{"emptyLinePlaceholder":35},[268,78732,78733,78735,78737,78740,78742,78744],{"class":270,"line":8974},[268,78734,57434],{"class":278},[268,78736,622],{"class":282},[268,78738,78739],{"class":289},"\"increment increases the count (implementation-coupled)\"",[268,78741,35745],{"class":282},[268,78743,9414],{"class":274},[268,78745,9914],{"class":282},[268,78747,78748,78750,78752,78754,78756,78758],{"class":270,"line":8985},[268,78749,12441],{"class":274},[268,78751,16389],{"class":305},[268,78753,616],{"class":274},[268,78755,11370],{"class":274},[268,78757,32656],{"class":278},[268,78759,794],{"class":282},[268,78761,78762,78765,78767],{"class":270,"line":8990},[268,78763,78764],{"class":282},"  c.",[268,78766,34969],{"class":278},[268,78768,794],{"class":282},[268,78770,78771,78773,78776,78779,78781,78783,78785,78787],{"class":270,"line":8997},[268,78772,75636],{"class":278},[268,78774,78775],{"class":282},"(c[",[268,78777,78778],{"class":289},"\"#count\"",[268,78780,53255],{"class":282},[268,78782,75642],{"class":278},[268,78784,622],{"class":282},[268,78786,2255],{"class":305},[268,78788,628],{"class":282},[268,78790,78791],{"class":270,"line":9002},[268,78792,20047],{"class":282},[268,78794,78795],{"class":270,"line":14676},[268,78796,5033],{"emptyLinePlaceholder":35},[268,78798,78799,78801,78803,78806,78808,78810],{"class":270,"line":14681},[268,78800,57434],{"class":278},[268,78802,622],{"class":282},[268,78804,78805],{"class":289},"\"increment increases the count (behavior-based)\"",[268,78807,35745],{"class":282},[268,78809,9414],{"class":274},[268,78811,9914],{"class":282},[268,78813,78814,78816,78818,78820,78822,78824],{"class":270,"line":31051},[268,78815,12441],{"class":274},[268,78817,16389],{"class":305},[268,78819,616],{"class":274},[268,78821,11370],{"class":274},[268,78823,32656],{"class":278},[268,78825,794],{"class":282},[268,78827,78828,78830,78833,78835,78837,78839,78841,78843],{"class":270,"line":31071},[268,78829,75636],{"class":278},[268,78831,78832],{"class":282},"(c.",[268,78834,34969],{"class":278},[268,78836,77200],{"class":282},[268,78838,75642],{"class":278},[268,78840,622],{"class":282},[268,78842,2255],{"class":305},[268,78844,628],{"class":282},[268,78846,78847],{"class":270,"line":33819},[268,78848,20047],{"class":282},[23,78850,78852,78861,78867,78880],{"className":78851},[26],[28,78853,78855,78857,78858,78860],{"className":78854},[31],[33,78856],{"disabled":35,"type":36}," Both tests are equally good, because they both call ",[39,78859,78542],{}," on the counter's state",[28,78862,78864,78866],{"className":78863},[31],[33,78865],{"disabled":35,"type":36}," The first test is preferred, because it verifies the internal field directly, which is more precise than checking the return value",[28,78868,78870,78872,78873,78875,78876,78879],{"className":78869},[31],[33,78871],{"disabled":35,"type":36}," The second test is the better practice: it asserts on the public, observable output (the return value) that consumers actually depend on, so refactoring ",[39,78874,78659],{},"'s internals won't break it. The first test reaches for a private field by bracket-string key, which doesn't actually work with real ",[39,78877,78878],{},"#","-syntax private fields and couples the test to implementation details that can change independently of behavior",[28,78881,78883,78885,78886,78888],{"className":78882},[31],[33,78884],{"disabled":35,"type":36}," Neither test is valid, because private ",[39,78887,78878],{}," fields cannot be tested at all, even indirectly",[66,78890,78891,78893,78902],{},[69,78892,71],{},[73,78894,78895,78897,78898,78875,78900,78879],{},[76,78896,78],{}," C — The second test is the better practice: it asserts on the public, observable output (the return value) that consumers actually depend on, so refactoring ",[39,78899,78659],{},[39,78901,78878],{},[73,78903,78904,78906,78907,78909,78910,78912,78913,3801,78915,78918,78919,78921,78922,78924],{},[76,78905,84],{}," Good tests verify a contract — given these inputs, what output or observable behavior should result — rather than reaching into how that output is produced internally. The second test does exactly that: it only relies on ",[39,78908,44633],{},"'s public return value, so if ",[39,78911,78659],{}," is later refactored to store its count differently, the test keeps passing as long as the behavior is unchanged. The first test tries to peek at ",[39,78914,78663],{},[39,78916,78917],{},"c[\"#count\"]",", which is not how JavaScript's true private class fields (",[39,78920,78878],{},"-prefixed) work at all — they are not accessible via bracket\u002Fstring property access from outside the class, so this line either reads ",[39,78923,833],{}," or throws, depending on engine and strict-mode context, making the test broken independent of the design critique. Even a syntactically-valid version of implementation-coupled testing is still the worse practice, because it makes tests brittle against safe refactors that don't change behavior.",[2107,78926,78927],{},"html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}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 .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}",{"title":264,"searchDepth":286,"depth":286,"links":78929},[78930,78931,78933,78934,78936,78937,78938,78939,78940,78941,78942,78943,78945,78947,78948,78950,78951,78952,78954,78955],{"id":75465,"depth":296,"text":75466},{"id":75512,"depth":296,"text":78932},"Q2. You have processOrder(cart, paymentGateway), which totals a cart and charges a payment gateway. A test constructs an in-memory InMemoryCart and a FakePaymentGateway, calls processOrder, and asserts the resulting order's status is \"paid\". What kind of test is this?",{"id":75714,"depth":296,"text":75715},{"id":75777,"depth":296,"text":78935},"Q4. jest.spyOn(console, \"error\") is called with no .mockImplementation(...) chained after it. What happens when the spied method is invoked during the test?",{"id":75921,"depth":296,"text":75922},{"id":76094,"depth":296,"text":76095},{"id":76315,"depth":296,"text":76316},{"id":76462,"depth":296,"text":76463},{"id":76646,"depth":296,"text":76647},{"id":76777,"depth":296,"text":76778},{"id":76828,"depth":296,"text":76829},{"id":77070,"depth":296,"text":78944},"Q12. What do beforeEach and afterEach accomplish in this test file?",{"id":77335,"depth":296,"text":78946},"Q13. save is a mock with a canned return value. The first test passes; the second fails because save has already been called once by the time it runs. Which fix resets the call count between tests without discarding the mockReturnValue(true) behavior?",{"id":77640,"depth":296,"text":77641},{"id":77871,"depth":296,"text":78949},"Q15. This test combines fake timers with a real async\u002Fawait chain. What subtlety can trip it up?",{"id":78142,"depth":296,"text":78143},{"id":78339,"depth":296,"text":78340},{"id":78390,"depth":296,"text":78953},"Q18. This test achieves 100% line coverage of divide. What is still missing?",{"id":78605,"depth":296,"text":78606},{"id":78652,"depth":296,"text":78956},"Q20. Two tests check the same increment behavior on a Counter class that uses a real #count private field. Which approach is the better practice, and why?",{},"\u002Fjs\u002F25-testing",{"title":75455,"description":264},"js\u002F25-testing","Cds1rki2tKGnL20phu-XkinEgkgR9yHVuoLjdTY2DgI",{"id":78963,"title":78964,"body":78965,"description":264,"extension":2144,"meta":81873,"navigation":35,"path":81874,"seo":81875,"stem":81876,"__hash__":81877},"content\u002Fjs\u002F26-performance-and-optimization.md","26 — Performance & Optimization",{"type":8,"value":78966,"toc":81840},[78967,78970,79175,79351,79500,79555,79613,79869,80058,80203,80315,80455,80677,80760,81043,81105,81177,81315,81392,81576,81760,81837],[11,78968,78964],{"id":78969},"_26-performance-optimization",[15,78971,78972,78976,79092,79135],{"language":247},[18,78973,78975],{"id":78974},"q1-after-the-code-below-runs-is-the-removed-button-eligible-for-garbage-collection","Q1. After the code below runs, is the removed button eligible for garbage collection?",[257,78977,78978],{"language":247},[260,78979,78981],{"className":262,"code":78980,"language":247,"meta":264,"style":264},"function attachHandler() {\n  const btn = document.getElementById(\"submit\");\n  let clickCount = 0;\n  btn.addEventListener(\"click\", () => {\n    clickCount++;\n    console.log(clickCount);\n  });\n}\nattachHandler();\ndocument.getElementById(\"submit\").remove();\n",[39,78982,78983,78992,79013,79026,79043,79052,79061,79065,79069,79076],{"__ignoreMap":264},[268,78984,78985,78987,78990],{"class":270,"line":271},[268,78986,275],{"class":274},[268,78988,78989],{"class":278}," attachHandler",[268,78991,283],{"class":282},[268,78993,78994,78996,78999,79001,79003,79006,79008,79011],{"class":270,"line":286},[268,78995,12441],{"class":274},[268,78997,78998],{"class":305}," btn",[268,79000,616],{"class":274},[268,79002,25659],{"class":282},[268,79004,79005],{"class":278},"getElementById",[268,79007,622],{"class":282},[268,79009,79010],{"class":289},"\"submit\"",[268,79012,628],{"class":282},[268,79014,79015,79017,79020,79022,79024],{"class":270,"line":296},[268,79016,2206],{"class":274},[268,79018,79019],{"class":282}," clickCount ",[268,79021,302],{"class":274},[268,79023,5728],{"class":305},[268,79025,293],{"class":282},[268,79027,79028,79031,79033,79035,79037,79039,79041],{"class":270,"line":311},[268,79029,79030],{"class":282},"  btn.",[268,79032,35737],{"class":278},[268,79034,622],{"class":282},[268,79036,64737],{"class":289},[268,79038,35745],{"class":282},[268,79040,9414],{"class":274},[268,79042,9914],{"class":282},[268,79044,79045,79048,79050],{"class":270,"line":788},[268,79046,79047],{"class":282},"    clickCount",[268,79049,9401],{"class":274},[268,79051,293],{"class":282},[268,79053,79054,79056,79058],{"class":270,"line":1951},[268,79055,9707],{"class":282},[268,79057,1356],{"class":278},[268,79059,79060],{"class":282},"(clickCount);\n",[268,79062,79063],{"class":270,"line":8955},[268,79064,39914],{"class":282},[268,79066,79067],{"class":270,"line":8966},[268,79068,314],{"class":282},[268,79070,79071,79074],{"class":270,"line":8974},[268,79072,79073],{"class":278},"attachHandler",[268,79075,794],{"class":282},[268,79077,79078,79080,79082,79084,79086,79088,79090],{"class":270,"line":8985},[268,79079,61438],{"class":282},[268,79081,79005],{"class":278},[268,79083,622],{"class":282},[268,79085,79010],{"class":289},[268,79087,6232],{"class":282},[268,79089,61848],{"class":278},[268,79091,794],{"class":282},[23,79093,79095,79111,79117,79126],{"className":79094},[26],[28,79096,79098,79100,79101,79103,79104,2338,79107,79110],{"className":79097},[31],[33,79099],{"disabled":35,"type":36}," No — the closure passed to ",[39,79102,35737],{}," still holds a reference to ",[39,79105,79106],{},"btn",[39,79108,79109],{},"clickCount","), keeping the detached node alive until the listener is removed or the reference is released",[28,79112,79114,79116],{"className":79113},[31],[33,79115],{"disabled":35,"type":36}," Yes, once removed from the DOM it's eligible immediately regardless of listeners",[28,79118,79120,79122,79123,79125],{"className":79119},[31],[33,79121],{"disabled":35,"type":36}," Yes, because ",[39,79124,79109],{}," is a primitive and doesn't affect garbage collection",[28,79127,79129,79131,79132,79134],{"className":79128},[31],[33,79130],{"disabled":35,"type":36}," No, because ",[39,79133,79005],{}," caches all elements internally forever",[66,79136,79137,79139,79150],{},[69,79138,71],{},[73,79140,79141,79143,79144,79103,79146,2338,79148,79110],{},[76,79142,78],{}," A — No — the closure passed to ",[39,79145,35737],{},[39,79147,79106],{},[39,79149,79109],{},[73,79151,79152,355,79154,79156,79157,79159,79160,79162,79163,79165,79166,79168,79169,39931,79172,79174],{},[76,79153,84],{},[76,79155,365],{}," Removing an element from the DOM tree does not remove any event listeners attached to it, and the closure created inside ",[39,79158,79073],{}," still captures ",[39,79161,79106],{}," in its scope for as long as the listener function itself is reachable — which it is, since the DOM's internal listener registry keeps a reference to it. This is the classic \"detached DOM node\" leak: the node is invisible on the page but still resident in memory. Option B is the common misconception that DOM removal alone triggers collection. Option C is irrelevant — a captured primitive doesn't change how ",[39,79164,79106],{}," is retained. Option D fabricates caching behavior ",[39,79167,79005],{}," doesn't have. The fix is to call ",[39,79170,79171],{},"btn.removeEventListener(...)",[39,79173,39934],{}," signal) before\u002Fwhen discarding the node.",[15,79176,79177,79185,79283,79320],{"language":247},[18,79178,79180,79181,79184],{"id":79179},"q2-whats-the-memorybehavior-consequence-of-removing-clockel-without-clearing-the-interval","Q2. What's the memory\u002Fbehavior consequence of removing ",[39,79182,79183],{},"clockEl"," without clearing the interval?",[257,79186,79187],{"language":247},[260,79188,79190],{"className":262,"code":79189,"language":247,"meta":264,"style":264},"function startPolling(el) {\n  setInterval(() => {\n    el.textContent = new Date().toLocaleTimeString();\n  }, 1000);\n}\nconst clockEl = document.getElementById(\"clock\");\nstartPolling(clockEl);\nclockEl.remove();\n",[39,79191,79192,79205,79216,79234,79242,79246,79266,79274],{"__ignoreMap":264},[268,79193,79194,79196,79199,79201,79203],{"class":270,"line":271},[268,79195,275],{"class":274},[268,79197,79198],{"class":278}," startPolling",[268,79200,622],{"class":282},[268,79202,25687],{"class":1222},[268,79204,1235],{"class":282},[268,79206,79207,79210,79212,79214],{"class":270,"line":286},[268,79208,79209],{"class":278},"  setInterval",[268,79211,9411],{"class":282},[268,79213,9414],{"class":274},[268,79215,9914],{"class":282},[268,79217,79218,79221,79223,79225,79227,79229,79232],{"class":270,"line":296},[268,79219,79220],{"class":282},"    el.textContent ",[268,79222,302],{"class":274},[268,79224,11370],{"class":274},[268,79226,22208],{"class":278},[268,79228,19341],{"class":282},[268,79230,79231],{"class":278},"toLocaleTimeString",[268,79233,794],{"class":282},[268,79235,79236,79238,79240],{"class":270,"line":311},[268,79237,48721],{"class":282},[268,79239,70543],{"class":305},[268,79241,628],{"class":282},[268,79243,79244],{"class":270,"line":788},[268,79245,314],{"class":282},[268,79247,79248,79250,79253,79255,79257,79259,79261,79264],{"class":270,"line":1951},[268,79249,243],{"class":274},[268,79251,79252],{"class":305}," clockEl",[268,79254,616],{"class":274},[268,79256,25659],{"class":282},[268,79258,79005],{"class":278},[268,79260,622],{"class":282},[268,79262,79263],{"class":289},"\"clock\"",[268,79265,628],{"class":282},[268,79267,79268,79271],{"class":270,"line":8955},[268,79269,79270],{"class":278},"startPolling",[268,79272,79273],{"class":282},"(clockEl);\n",[268,79275,79276,79279,79281],{"class":270,"line":8966},[268,79277,79278],{"class":282},"clockEl.",[268,79280,61848],{"class":278},[268,79282,794],{"class":282},[23,79284,79286,79292,79301,79309],{"className":79285},[26],[28,79287,79289,79291],{"className":79288},[31],[33,79290],{"disabled":35,"type":36}," The interval automatically stops once its target element is detached from the DOM",[28,79293,79295,79297,79298,79300],{"className":79294},[31],[33,79296],{"disabled":35,"type":36}," The interval keeps firing forever, and its closure keeps a live reference to ",[39,79299,79183],{},", preventing the detached node from ever being garbage collected — a classic leak",[28,79302,79304,355,79306,79308],{"className":79303},[31],[33,79305],{"disabled":35,"type":36},[39,79307,79183],{}," becomes eligible for garbage collection immediately since it no longer has a parent",[28,79310,79312,355,79314,79316,79317,79319],{"className":79311},[31],[33,79313],{"disabled":35,"type":36},[39,79315,47386],{}," throws once ",[39,79318,25687],{}," is detached, alerting you to the leak",[66,79321,79322,79324,79331],{},[69,79323,71],{},[73,79325,79326,79328,79329,79300],{},[76,79327,78],{}," B — The interval keeps firing forever, and its closure keeps a live reference to ",[39,79330,79183],{},[73,79332,79333,355,79335,355,79337,79339,79340,79342,79343,15479,79345,79347,79348,79350],{},[76,79334,84],{},[76,79336,365],{},[39,79338,47386],{}," has no awareness of the DOM — it keeps invoking its callback on schedule until ",[39,79341,69704],{}," is explicitly called, regardless of whether the elements it touches are still attached. The arrow function's closure over ",[39,79344,25687],{},[39,79346,79183],{}," reachable forever, so the detached node (and everything it references) leaks for the lifetime of the page. Option A and D invent automatic cleanup\u002Ferror behavior that doesn't exist. Option C ignores that the interval's closure is still a live reference even after DOM removal. The fix is to store the interval id and call ",[39,79349,69800],{}," whenever the element is torn down (e.g., in a component's cleanup\u002Funmount logic).",[15,79352,79353,79357,79441,79479],{"language":247},[18,79354,79356],{"id":79355},"q3-over-a-long-running-session-with-thousands-of-unique-ids-whats-the-risk-with-this-cache-and-how-should-it-be-fixed","Q3. Over a long-running session with thousands of unique ids, what's the risk with this cache, and how should it be fixed?",[257,79358,79359],{"language":247},[260,79360,79362],{"className":262,"code":79361,"language":247,"meta":264,"style":264},"const cache = new Map();\nfunction getUser(id) {\n  if (cache.has(id)) return cache.get(id);\n  const user = fetchUserSync(id);\n  cache.set(id, user);\n  return user;\n}\n",[39,79363,79364,79378,79390,79409,79422,79431,79437],{"__ignoreMap":264},[268,79365,79366,79368,79370,79372,79374,79376],{"class":270,"line":271},[268,79367,243],{"class":274},[268,79369,15807],{"class":305},[268,79371,616],{"class":274},[268,79373,11370],{"class":274},[268,79375,11373],{"class":278},[268,79377,794],{"class":282},[268,79379,79380,79382,79384,79386,79388],{"class":270,"line":286},[268,79381,275],{"class":274},[268,79383,51115],{"class":278},[268,79385,622],{"class":282},[268,79387,14610],{"class":1222},[268,79389,1235],{"class":282},[268,79391,79392,79394,79396,79398,79401,79403,79405,79407],{"class":270,"line":296},[268,79393,9863],{"class":274},[268,79395,37872],{"class":282},[268,79397,37875],{"class":278},[268,79399,79400],{"class":282},"(id)) ",[268,79402,9151],{"class":274},[268,79404,37883],{"class":282},[268,79406,32437],{"class":278},[268,79408,12284],{"class":282},[268,79410,79411,79413,79415,79417,79420],{"class":270,"line":311},[268,79412,12441],{"class":274},[268,79414,4071],{"class":305},[268,79416,616],{"class":274},[268,79418,79419],{"class":278}," fetchUserSync",[268,79421,12284],{"class":282},[268,79423,79424,79426,79428],{"class":270,"line":788},[268,79425,15846],{"class":282},[268,79427,37910],{"class":278},[268,79429,79430],{"class":282},"(id, user);\n",[268,79432,79433,79435],{"class":270,"line":1951},[268,79434,1240],{"class":274},[268,79436,26989],{"class":282},[268,79438,79439],{"class":270,"line":8955},[268,79440,314],{"class":282},[23,79442,79444,79453,79462,79471],{"className":79443},[26],[28,79445,79447,79449,79450,79452],{"className":79446},[31],[33,79448],{"disabled":35,"type":36}," None — ",[39,79451,2672],{}," automatically evicts old entries once memory pressure is detected",[28,79454,79456,79458,79459,79461],{"className":79455},[31],[33,79457],{"disabled":35,"type":36}," This can never leak because ",[39,79460,14610],{}," is typically a primitive number",[28,79463,79465,79467,79468,79470],{"className":79464},[31],[33,79466],{"disabled":35,"type":36}," The cache grows unbounded since entries are never removed, steadily increasing memory use; fix by adding an eviction policy (LRU, TTL, or a max-size cap) — a ",[39,79469,40238],{}," would not help here since the keys are primitive ids, not objects being tracked elsewhere",[28,79472,79474,355,79476,79478],{"className":79473},[31],[33,79475],{"disabled":35,"type":36},[39,79477,2672],{}," keys are always garbage collected once the function returns, so this is safe",[66,79480,79481,79483,79490],{},[69,79482,71],{},[73,79484,79485,79487,79488,79470],{},[76,79486,78],{}," C — The cache grows unbounded since entries are never removed, steadily increasing memory use; fix by adding an eviction policy (LRU, TTL, or a max-size cap) — a ",[39,79489,40238],{},[73,79491,79492,812,79494,79496,79497,79499],{},[76,79493,84],{},[39,79495,2672],{}," never evicts entries on its own — it holds a strong reference to every key and value for as long as the entry exists, so an ever-growing set of unique ids means an ever-growing cache with no upper bound. Option A invents automatic eviction that ",[39,79498,2672],{}," does not provide. Option B and D wrongly assume primitive keys are somehow exempt from retention — primitives are stored and retained just like any other value. The real fix is bounding growth explicitly (an LRU cache, a TTL-based expiry, or a max-entry cap that evicts the oldest\u002Fleast-used entry).",[15,79501,79502,79506,79536],{},[18,79503,79505],{"id":79504},"q4-youre-implementing-search-as-you-type-autocomplete-that-should-fire-an-api-request-only-once-the-user-pauses-typing-for-300ms-not-on-every-keystroke-which-technique-fits-and-why","Q4. You're implementing search-as-you-type autocomplete that should fire an API request only once the user pauses typing for 300ms, not on every keystroke. Which technique fits, and why?",[23,79507,79509,79515,79521,79527],{"className":79508},[26],[28,79510,79512,79514],{"className":79511},[31],[33,79513],{"disabled":35,"type":36}," Throttle — it guarantees the function runs at least once every 300ms even during continuous typing",[28,79516,79518,79520],{"className":79517},[31],[33,79519],{"disabled":35,"type":36}," Throttle — it runs the function immediately on the first keystroke and ignores the rest",[28,79522,79524,79526],{"className":79523},[31],[33,79525],{"disabled":35,"type":36}," Debounce — it runs the function on every keystroke but batches the results",[28,79528,79530,79532,79533,79535],{"className":79529},[31],[33,79531],{"disabled":35,"type":36}," Debounce — it delays execution until 300ms have passed with no new keystrokes, so an idle pause is what finally triggers the call; throttle would still fire repeatedly at intervals ",[104,79534,11160],{}," the user keeps typing, which isn't what's wanted here",[66,79537,79538,79540,79547],{},[69,79539,71],{},[73,79541,79542,79544,79545,79535],{},[76,79543,78],{}," D — Debounce — it delays execution until 300ms have passed with no new keystrokes, so an idle pause is what finally triggers the call; throttle would still fire repeatedly at intervals ",[104,79546,11160],{},[73,79548,79549,79551,79552,79554],{},[76,79550,84],{}," Debounce resets its timer on every call and only fires once the calls stop for the configured wait — exactly what \"wait until the user pauses\" needs. Throttle (options A and B) instead guarantees execution on a steady cadence ",[104,79553,47814],{}," continuous activity, which would fire requests mid-typing rather than waiting for a pause — the two are frequently confused because both \"limit\" how often a function runs, but they solve opposite problems. Option C misdescribes debounce as running on every keystroke, which defeats its entire purpose.",[15,79556,79557,79561,79590],{},[18,79558,79560],{"id":79559},"q5-a-scroll-handler-recalculates-a-sticky-headers-position-and-needs-to-run-at-most-once-every-100ms-while-the-user-is-actively-scrolling-not-only-after-scrolling-stops-which-is-correct","Q5. A scroll handler recalculates a sticky header's position and needs to run at most once every 100ms while the user is actively scrolling, not only after scrolling stops. Which is correct?",[23,79562,79564,79570,79576,79584],{"className":79563},[26],[28,79565,79567,79569],{"className":79566},[31],[33,79568],{"disabled":35,"type":36}," Throttle with a 100ms interval — the handler executes on a steady cadence during continuous scrolling instead of only after it stops, keeping the header visually in sync while scrolling happens",[28,79571,79573,79575],{"className":79572},[31],[33,79574],{"disabled":35,"type":36}," Debounce with a 100ms wait — ensures the handler only runs after scrolling stops",[28,79577,79579,355,79581,79583],{"className":79578},[31],[33,79580],{"disabled":35,"type":36},[39,79582,65735],{}," — runs the handler only when the browser is completely idle",[28,79585,79587,79589],{"className":79586},[31],[33,79588],{"disabled":35,"type":36}," Neither — scroll handlers should never be rate-limited since browsers already throttle them to the display refresh rate automatically",[66,79591,79592,79594,79599],{},[69,79593,71],{},[73,79595,79596,79598],{},[76,79597,78],{}," A — Throttle with a 100ms interval — the handler executes on a steady cadence during continuous scrolling instead of only after it stops, keeping the header visually in sync while scrolling happens",[73,79600,79601,79603,79604,79606,79607,79609,79610,79612],{},[76,79602,84],{}," Throttle guarantees the function runs at a capped rate ",[104,79605,11160],{}," events keep firing, which is exactly what a sticky header needs — visual updates during the scroll, not just at the end. Option B (debounce) would make the header appear frozen until scrolling fully stops, which looks broken for a \"stays in sync\" requirement. Option C is wrong because ",[39,79608,65735],{}," only runs during idle gaps and offers no guarantee of running during continuous scrolling at all. Option D is a myth — native ",[39,79611,62345],{}," events can fire far more often than needed for visual updates, and manual rate-limiting is standard practice, not redundant.",[15,79614,79615,79619,79782,79823],{"language":247},[18,79616,79618],{"id":79617},"q6-what-gets-logged-and-at-roughly-what-time","Q6. What gets logged, and at roughly what time?",[257,79620,79621],{"language":247},[260,79622,79624],{"className":262,"code":79623,"language":247,"meta":264,"style":264},"function debounce(fn, wait) {\n  let timer;\n  return (...args) => {\n    clearTimeout(timer);\n    timer = setTimeout(() => fn(...args), wait);\n  };\n}\n\nconst log = debounce((x) => console.log(x), 200);\nlog(\"a\");\nsetTimeout(() => log(\"b\"), 100);\nsetTimeout(() => log(\"c\"), 250);\n",[39,79625,79626,79642,79648,79664,79670,79691,79695,79699,79703,79732,79742,79762],{"__ignoreMap":264},[268,79627,79628,79630,79632,79634,79636,79638,79640],{"class":270,"line":271},[268,79629,275],{"class":274},[268,79631,40746],{"class":278},[268,79633,622],{"class":282},[268,79635,37837],{"class":1222},[268,79637,42],{"class":282},[268,79639,70903],{"class":1222},[268,79641,1235],{"class":282},[268,79643,79644,79646],{"class":270,"line":286},[268,79645,2206],{"class":274},[268,79647,70937],{"class":282},[268,79649,79650,79652,79654,79656,79658,79660,79662],{"class":270,"line":296},[268,79651,1240],{"class":274},[268,79653,2182],{"class":282},[268,79655,15329],{"class":274},[268,79657,40270],{"class":1222},[268,79659,6131],{"class":282},[268,79661,9414],{"class":274},[268,79663,9914],{"class":282},[268,79665,79666,79668],{"class":270,"line":311},[268,79667,40783],{"class":278},[268,79669,70958],{"class":282},[268,79671,79672,79674,79676,79678,79680,79682,79684,79686,79688],{"class":270,"line":788},[268,79673,70963],{"class":282},[268,79675,302],{"class":274},[268,79677,40796],{"class":278},[268,79679,9411],{"class":282},[268,79681,9414],{"class":274},[268,79683,37900],{"class":278},[268,79685,622],{"class":282},[268,79687,15329],{"class":274},[268,79689,79690],{"class":282},"args), wait);\n",[268,79692,79693],{"class":270,"line":1951},[268,79694,15185],{"class":282},[268,79696,79697],{"class":270,"line":8955},[268,79698,314],{"class":282},[268,79700,79701],{"class":270,"line":8966},[268,79702,5033],{"emptyLinePlaceholder":35},[268,79704,79705,79707,79709,79711,79713,79715,79717,79719,79721,79723,79725,79728,79730],{"class":270,"line":8974},[268,79706,243],{"class":274},[268,79708,16942],{"class":305},[268,79710,616],{"class":274},[268,79712,40746],{"class":278},[268,79714,6122],{"class":282},[268,79716,2403],{"class":1222},[268,79718,6131],{"class":282},[268,79720,9414],{"class":274},[268,79722,9417],{"class":282},[268,79724,1356],{"class":278},[268,79726,79727],{"class":282},"(x), ",[268,79729,40987],{"class":305},[268,79731,628],{"class":282},[268,79733,79734,79736,79738,79740],{"class":270,"line":8985},[268,79735,1356],{"class":278},[268,79737,622],{"class":282},[268,79739,7582],{"class":289},[268,79741,628],{"class":282},[268,79743,79744,79746,79748,79750,79752,79754,79756,79758,79760],{"class":270,"line":8990},[268,79745,9578],{"class":278},[268,79747,9411],{"class":282},[268,79749,9414],{"class":274},[268,79751,16942],{"class":278},[268,79753,622],{"class":282},[268,79755,9188],{"class":289},[268,79757,33111],{"class":282},[268,79759,13912],{"class":305},[268,79761,628],{"class":282},[268,79763,79764,79766,79768,79770,79772,79774,79776,79778,79780],{"class":270,"line":8997},[268,79765,9578],{"class":278},[268,79767,9411],{"class":282},[268,79769,9414],{"class":274},[268,79771,16942],{"class":278},[268,79773,622],{"class":282},[268,79775,9193],{"class":289},[268,79777,33111],{"class":282},[268,79779,22166],{"class":305},[268,79781,628],{"class":282},[23,79783,79785,79797,79805,79813],{"className":79784},[26],[28,79786,79788,355,79790,42,79792,137,79794,79796],{"className":79787},[31],[33,79789],{"disabled":35,"type":36},[39,79791,1223],{},[39,79793,1232],{},[39,79795,16484],{}," all log, at 200ms, 300ms, and 450ms respectively — since each call schedules its own timer independently",[28,79798,79800,50010,79802,79804],{"className":79799},[31],[33,79801],{"disabled":35,"type":36},[39,79803,16484],{}," logs, at ~450ms — each new call clears the still-pending timer from the previous call before it can fire, and since no further call arrives within 200ms of the last one, only its timer survives to completion",[28,79806,79808,50010,79810,79812],{"className":79807},[31],[33,79809],{"disabled":35,"type":36},[39,79811,1223],{}," logs, at 200ms — later calls are ignored once a timer is already pending",[28,79814,79816,355,79818,186,79820,79822],{"className":79815},[31],[33,79817],{"disabled":35,"type":36},[39,79819,1232],{},[39,79821,16484],{}," both log, at 300ms and 450ms — only the very first call's timer gets cancelled",[66,79824,79825,79827,79834],{},[69,79826,71],{},[73,79828,79829,79831,79832,79804],{},[76,79830,78],{}," B — Only ",[39,79833,16484],{},[73,79835,79836,355,79838,79840,79841,79844,79845,79848,79849,79851,79852,79854,79855,79858,79859,79861,79862,79865,79866,79868],{},[76,79837,84],{},[76,79839,365],{}," Trace it: ",[39,79842,79843],{},"log(\"a\")"," at t=0 schedules a fire at t=200. ",[39,79846,79847],{},"log(\"b\")"," at t=100 calls ",[39,79850,69701],{}," on that pending timer (cancelling ",[39,79853,1223],{}," before it ever fires) and schedules its own fire at t=300. ",[39,79856,79857],{},"log(\"c\")"," at t=250 again clears the still-pending timer (cancelling ",[39,79860,1232],{},", since 250 \u003C 300) and schedules its own fire at t=450. No further call arrives before t=450, so ",[39,79863,79864],{},"fn(\"c\")"," finally runs — nothing else does. Option A ignores that ",[39,79867,69701],{}," cancels the previous pending call entirely rather than letting each accumulate. Option C stops tracing too early. Option D misidentifies which timer survives.",[15,79870,79871,79880,79983,80022],{"language":247},[18,79872,79874,79875,186,79877,79879],{"id":79873},"q7-what-perf-benefit-does-v8-get-from-a-and-b-being-built-with-the-same-property-order-and-types","Q7. What perf benefit does V8 get from ",[39,79876,1223],{},[39,79878,1232],{}," being built with the same property order and types?",[257,79881,79882],{"language":247},[260,79883,79885],{"className":262,"code":79884,"language":247,"meta":264,"style":264},"function makePoint(x, y) {\n  const p = {};\n  p.x = x;\n  p.y = y;\n  return p;\n}\nconst a = makePoint(1, 2);\nconst b = makePoint(3, 4);\n",[39,79886,79887,79904,79914,79923,79932,79939,79943,79963],{"__ignoreMap":264},[268,79888,79889,79891,79894,79896,79898,79900,79902],{"class":270,"line":271},[268,79890,275],{"class":274},[268,79892,79893],{"class":278}," makePoint",[268,79895,622],{"class":282},[268,79897,2403],{"class":1222},[268,79899,42],{"class":282},[268,79901,2909],{"class":1222},[268,79903,1235],{"class":282},[268,79905,79906,79908,79910,79912],{"class":270,"line":286},[268,79907,12441],{"class":274},[268,79909,29927],{"class":305},[268,79911,616],{"class":274},[268,79913,15812],{"class":282},[268,79915,79916,79919,79921],{"class":270,"line":296},[268,79917,79918],{"class":282},"  p.x ",[268,79920,302],{"class":274},[268,79922,3547],{"class":282},[268,79924,79925,79928,79930],{"class":270,"line":311},[268,79926,79927],{"class":282},"  p.y ",[268,79929,302],{"class":274},[268,79931,30002],{"class":282},[268,79933,79934,79936],{"class":270,"line":788},[268,79935,1240],{"class":274},[268,79937,79938],{"class":282}," p;\n",[268,79940,79941],{"class":270,"line":1951},[268,79942,314],{"class":282},[268,79944,79945,79947,79949,79951,79953,79955,79957,79959,79961],{"class":270,"line":8955},[268,79946,243],{"class":274},[268,79948,7203],{"class":305},[268,79950,616],{"class":274},[268,79952,79893],{"class":278},[268,79954,622],{"class":282},[268,79956,2255],{"class":305},[268,79958,42],{"class":282},[268,79960,2258],{"class":305},[268,79962,628],{"class":282},[268,79964,79965,79967,79969,79971,79973,79975,79977,79979,79981],{"class":270,"line":8966},[268,79966,243],{"class":274},[268,79968,16372],{"class":305},[268,79970,616],{"class":274},[268,79972,79893],{"class":278},[268,79974,622],{"class":282},[268,79976,3423],{"class":305},[268,79978,42],{"class":282},[268,79980,15049],{"class":305},[268,79982,628],{"class":282},[23,79984,79986,79992,80003,80013],{"className":79985},[26],[28,79987,79989,79991],{"className":79988},[31],[33,79990],{"disabled":35,"type":36}," Nothing — V8 treats every object as a fully dynamic hash map regardless of creation pattern",[28,79993,79995,79997,79998,186,80000,80002],{"className":79994},[31],[33,79996],{"disabled":35,"type":36}," V8 merges ",[39,79999,1223],{},[39,80001,1232],{}," into a single object in memory to save space",[28,80004,80006,355,80008,186,80010,80012],{"className":80005},[31],[33,80007],{"disabled":35,"type":36},[39,80009,1223],{},[39,80011,1232],{}," end up sharing the same underlying \"hidden class\" (shape), letting V8 use fast, offset-based property access instead of a slower dictionary lookup for both objects",[28,80014,80016,80018,80019,80021],{"className":80015},[31],[33,80017],{"disabled":35,"type":36}," Hidden classes only apply to objects created with ",[39,80020,1468],{}," syntax, not object literals",[66,80023,80024,80026,80034],{},[69,80025,71],{},[73,80027,80028,1004,80030,186,80032,80012],{},[76,80029,78],{},[39,80031,1223],{},[39,80033,1232],{},[73,80035,80036,355,80038,80040,80041,80044,80045,1133,80047,80049,80050,186,80052,80054,80055,80057],{},[76,80037,84],{},[76,80039,438],{}," V8 assigns objects an internal \"hidden class\" (a.k.a. \"shape\" or \"map\") that describes their property layout. Because ",[39,80042,80043],{},"makePoint"," always adds ",[39,80046,2403],{},[39,80048,2909],{},", in that order, with consistent value types, both ",[39,80051,1223],{},[39,80053,1232],{}," transition through the exact same sequence of hidden classes and end up sharing one — letting V8 compile property access as a fixed memory offset instead of a hash-map lookup. Option A describes the slow, generic fallback path that hidden classes exist to avoid. Option B fabricates object merging. Option D is false — hidden classes apply to any object, ",[39,80056,1468],{},"-based or not.",[15,80059,80060,80064,80108,80158],{"language":247},[18,80061,80063],{"id":80062},"q8-building-on-the-previous-scenario-what-happens-to-the-shared-hidden-class-optimization-once-this-runs","Q8. Building on the previous scenario, what happens to the shared hidden-class optimization once this runs?",[257,80065,80066],{"language":247},[260,80067,80069],{"className":262,"code":80068,"language":247,"meta":264,"style":264},"b.z = 99;\nif (Math.random() > 0.9) a.y = \"surprise\";\n",[39,80070,80071,80082],{"__ignoreMap":264},[268,80072,80073,80076,80078,80080],{"class":270,"line":271},[268,80074,80075],{"class":282},"b.z ",[268,80077,302],{"class":274},[268,80079,2811],{"class":305},[268,80081,293],{"class":282},[268,80083,80084,80086,80089,80091,80093,80095,80098,80101,80103,80106],{"class":270,"line":286},[268,80085,2179],{"class":274},[268,80087,80088],{"class":282}," (Math.",[268,80090,73871],{"class":278},[268,80092,16182],{"class":282},[268,80094,6435],{"class":274},[268,80096,80097],{"class":305}," 0.9",[268,80099,80100],{"class":282},") a.y ",[268,80102,302],{"class":274},[268,80104,80105],{"class":289}," \"surprise\"",[268,80107,293],{"class":282},[23,80109,80111,80117,80129,80135],{"className":80110},[26],[28,80112,80114,80116],{"className":80113},[31],[33,80115],{"disabled":35,"type":36}," Nothing changes — hidden classes are assigned once at creation and never affected by later mutation",[28,80118,80120,80122,80123,80125,80126,80128],{"className":80119},[31],[33,80121],{"disabled":35,"type":36}," V8 automatically adds a ",[39,80124,28015],{}," property to ",[39,80127,1223],{}," as well to keep the shapes in sync",[28,80130,80132,80134],{"className":80131},[31],[33,80133],{"disabled":35,"type":36}," This only matters for arrays, not plain objects",[28,80136,80138,28423,80140,80142,80143,2906,80145,80147,80148,80150,80151,80154,80155,80157],{"className":80137},[31],[33,80139],{"disabled":35,"type":36},[39,80141,28015],{}," only to ",[39,80144,1232],{},[39,80146,1232],{}," a different hidden-class transition than ",[39,80149,1223],{},", and changing ",[39,80152,80153],{},"a.y"," from a number to a string can force V8 to fall back to a slower representation for ",[39,80156,1223],{}," — both objects lose the shared fast shape, and functions operating on both become polymorphic",[66,80159,80160,80162,80179],{},[69,80161,71],{},[73,80163,80164,80166,80167,80142,80169,2906,80171,80147,80173,80150,80175,80154,80177,80157],{},[76,80165,78],{}," D — Adding ",[39,80168,28015],{},[39,80170,1232],{},[39,80172,1232],{},[39,80174,1223],{},[39,80176,80153],{},[39,80178,1223],{},[73,80180,80181,355,80183,80185,80186,80142,80188,80190,80191,80193,80194,80196,80197,80199,80200,80202],{},[76,80182,84],{},[76,80184,438],{}," Hidden classes are dynamic, not frozen at creation — every property addition or type change is itself a transition to a (possibly new) hidden class. Adding ",[39,80187,28015],{},[39,80189,1232],{}," diverges ",[39,80192,1232],{},"'s shape from ",[39,80195,1223],{},"'s; changing ",[39,80198,80153],{},"'s type mid-flight can force V8 out of the fast tracked-shape path entirely for ",[39,80201,1223],{},". Any function that previously saw only one shared shape now sees two different shapes, becoming polymorphic and losing its fast inline-cached path. Option A is false — mutation absolutely affects hidden-class assignment. Option B invents synchronization behavior V8 doesn't perform. Option C is wrong — this applies to any plain object, not just arrays.",[15,80204,80205,80221,80257,80287],{"language":247},[18,80206,80208,80209,80212,80213,80216,80217,80220],{"id":80207},"q9-getareashape-reads-shapewidth-shapeheight-and-runs-thousands-of-times-per-frame-why-is-it-faster-when-every-shape-has-the-same-property-layout-than-when-shapes-vary","Q9. ",[39,80210,80211],{},"getArea(shape)"," reads ",[39,80214,80215],{},"shape.width * shape.height"," and runs thousands of times per frame. Why is it faster when every ",[39,80218,80219],{},"shape"," has the same property layout than when shapes vary?",[257,80222,80223],{"language":247},[260,80224,80226],{"className":262,"code":80225,"language":247,"meta":264,"style":264},"function getArea(shape) {\n  return shape.width * shape.height;\n}\n",[39,80227,80228,80241,80253],{"__ignoreMap":264},[268,80229,80230,80232,80235,80237,80239],{"class":270,"line":271},[268,80231,275],{"class":274},[268,80233,80234],{"class":278}," getArea",[268,80236,622],{"class":282},[268,80238,80219],{"class":1222},[268,80240,1235],{"class":282},[268,80242,80243,80245,80248,80250],{"class":270,"line":286},[268,80244,1240],{"class":274},[268,80246,80247],{"class":282}," shape.width ",[268,80249,6134],{"class":274},[268,80251,80252],{"class":282}," shape.height;\n",[268,80254,80255],{"class":270,"line":296},[268,80256,314],{"class":282},[23,80258,80260,80266,80272,80281],{"className":80259},[26],[28,80261,80263,80265],{"className":80262},[31],[33,80264],{"disabled":35,"type":36}," Consistent shapes make the call site monomorphic (one hidden class seen), letting the JIT inline a fast, specialized path; varying shapes make it polymorphic\u002Fmegamorphic, forcing V8 to fall back to slower generic property lookups and inline-cache misses",[28,80267,80269,80271],{"className":80268},[31],[33,80270],{"disabled":35,"type":36}," It doesn't matter — the JIT re-optimizes on every call regardless of shape",[28,80273,80275,50010,80277,80280],{"className":80274},[31],[33,80276],{"disabled":35,"type":36},[39,80278,80279],{},"TypedArray","s benefit from consistent shapes; plain objects are unaffected",[28,80282,80284,80286],{"className":80283},[31],[33,80285],{"disabled":35,"type":36}," Polymorphic call sites are always faster because V8 can choose the best strategy per call",[66,80288,80289,80291,80296],{},[69,80290,71],{},[73,80292,80293,80295],{},[76,80294,78],{}," A — Consistent shapes make the call site monomorphic (one hidden class seen), letting the JIT inline a fast, specialized path; varying shapes make it polymorphic\u002Fmegamorphic, forcing V8 to fall back to slower generic property lookups and inline-cache misses",[73,80297,80298,355,80300,80302,80303,80305,80306,80309,80310,446,80312,80314],{},[76,80299,84],{},[76,80301,438],{}," V8's inline caches record which hidden class(es) a call site has seen for ",[39,80304,80219],{},". If it's always the same shape (monomorphic), the JIT can specialize ",[39,80307,80308],{},"getArea"," to read ",[39,80311,32233],{},[39,80313,32238],{}," at fixed offsets directly. Once the call site sees several distinct shapes (polymorphic) or too many (megamorphic), V8 gives up on a specialized fast path and falls back to a generic, slower lookup on every call. Option B and D contradict how inline caches actually behave — variety is a cost, not a benefit. Option C is false; this optimization applies broadly to plain objects, not just typed arrays.",[15,80316,80317,80325,80383,80427],{"language":247},[18,80318,80320,80321,80324],{"id":80319},"q10-in-a-hot-path-whats-the-perf-concern-with-delete-cfgdebug-and-whats-the-preferred-alternative","Q10. In a hot path, what's the perf concern with ",[39,80322,80323],{},"delete cfg.debug",", and what's the preferred alternative?",[257,80326,80327],{"language":247},[260,80328,80330],{"className":262,"code":80329,"language":247,"meta":264,"style":264},"const config = { debug: true, retries: 3, timeout: 500 };\nfunction disableDebug(cfg) {\n  delete cfg.debug;\n}\n",[39,80331,80332,80357,80371,80379],{"__ignoreMap":264},[268,80333,80334,80336,80338,80340,80343,80345,80348,80350,80352,80355],{"class":270,"line":271},[268,80335,243],{"class":274},[268,80337,8029],{"class":305},[268,80339,616],{"class":274},[268,80341,80342],{"class":282}," { debug: ",[268,80344,2185],{"class":305},[268,80346,80347],{"class":282},", retries: ",[268,80349,3423],{"class":305},[268,80351,21235],{"class":282},[268,80353,80354],{"class":305},"500",[268,80356,2790],{"class":282},[268,80358,80359,80361,80364,80366,80369],{"class":270,"line":286},[268,80360,275],{"class":274},[268,80362,80363],{"class":278}," disableDebug",[268,80365,622],{"class":282},[268,80367,80368],{"class":1222},"cfg",[268,80370,1235],{"class":282},[268,80372,80373,80376],{"class":270,"line":296},[268,80374,80375],{"class":274},"  delete",[268,80377,80378],{"class":282}," cfg.debug;\n",[268,80380,80381],{"class":270,"line":311},[268,80382,314],{"class":282},[23,80384,80386,80394,80406,80417],{"className":80385},[26],[28,80387,80389,355,80391,80393],{"className":80388},[31],[33,80390],{"disabled":35,"type":36},[39,80392,21490],{}," is always fastest since it fully frees the property's memory immediately",[28,80395,80397,355,80399,80401,80402,80405],{"className":80396},[31],[33,80398],{"disabled":35,"type":36},[39,80400,21490],{}," changes the object's hidden class (creating a new, often \"dictionary mode\" shape), which can deoptimize property access for that object; setting ",[39,80403,80404],{},"cfg.debug = undefined"," (or restructuring so the property was never conditionally needed) preserves the original shape and avoids the transition",[28,80407,80409,80411,80412,80414,80415],{"className":80408},[31],[33,80410],{"disabled":35,"type":36}," There's no concern — ",[39,80413,21490],{}," behaves identically to setting a property to ",[39,80416,833],{},[28,80418,80420,355,80422,80424,80425],{"className":80419},[31],[33,80421],{"disabled":35,"type":36},[39,80423,21490],{}," is disallowed in strict mode, so this code throws a ",[39,80426,1274],{},[66,80428,80429,80431,80439],{},[69,80430,71],{},[73,80432,80433,1727,80435,80401,80437,80405],{},[76,80434,78],{},[39,80436,21490],{},[39,80438,80404],{},[73,80440,80441,355,80443,80445,80446,80448,80449,80451,80452,80454],{},[76,80442,84],{},[76,80444,438],{}," Unlike simply overwriting a value, ",[39,80447,21490],{}," removes a property slot entirely, which forces a hidden-class transition and can push the object into a slower, dictionary-mode (hash-map-like) representation that loses the fast offset-based access other objects of the \"same\" original shape still enjoy. ",[39,80450,80404],{}," keeps the property (and the object's shape) intact — only the value changes — so it avoids the deopt. Option A gets the performance direction backwards. Option C ignores the shape-transition cost that makes the two meaningfully different. Option D is fabricated — ",[39,80453,21490],{}," on a configurable own property is valid in strict mode.",[15,80456,80457,80471,80593,80638],{"language":247},[18,80458,80460,80461,80464,80465,99,80468,1685],{"id":80459},"q11-why-can-iteratingsumming-dense-be-significantly-faster-than-doing-the-same-over-sparse-or-alsosparse","Q11. Why can iterating\u002Fsumming ",[39,80462,80463],{},"dense"," be significantly faster than doing the same over ",[39,80466,80467],{},"sparse",[39,80469,80470],{},"alsoSparse",[257,80472,80473],{"language":247},[260,80474,80476],{"className":262,"code":80475,"language":247,"meta":264,"style":264},"const dense = [1, 2, 3, 4, 5];\n\nconst sparse = [1, 2, 3, 4, 5];\ndelete sparse[2];\n\nconst alsoSparse = new Array(5);\nalsoSparse[0] = \"x\";\n",[39,80477,80478,80509,80513,80543,80554,80558,80577],{"__ignoreMap":264},[268,80479,80480,80482,80485,80487,80489,80491,80493,80495,80497,80499,80501,80503,80505,80507],{"class":270,"line":271},[268,80481,243],{"class":274},[268,80483,80484],{"class":305}," dense",[268,80486,616],{"class":274},[268,80488,8710],{"class":282},[268,80490,2255],{"class":305},[268,80492,42],{"class":282},[268,80494,2258],{"class":305},[268,80496,42],{"class":282},[268,80498,3423],{"class":305},[268,80500,42],{"class":282},[268,80502,15049],{"class":305},[268,80504,42],{"class":282},[268,80506,2429],{"class":305},[268,80508,8737],{"class":282},[268,80510,80511],{"class":270,"line":286},[268,80512,5033],{"emptyLinePlaceholder":35},[268,80514,80515,80517,80519,80521,80523,80525,80527,80529,80531,80533,80535,80537,80539,80541],{"class":270,"line":296},[268,80516,243],{"class":274},[268,80518,24453],{"class":305},[268,80520,616],{"class":274},[268,80522,8710],{"class":282},[268,80524,2255],{"class":305},[268,80526,42],{"class":282},[268,80528,2258],{"class":305},[268,80530,42],{"class":282},[268,80532,3423],{"class":305},[268,80534,42],{"class":282},[268,80536,15049],{"class":305},[268,80538,42],{"class":282},[268,80540,2429],{"class":305},[268,80542,8737],{"class":282},[268,80544,80545,80547,80550,80552],{"class":270,"line":311},[268,80546,21490],{"class":274},[268,80548,80549],{"class":282}," sparse[",[268,80551,2258],{"class":305},[268,80553,8737],{"class":282},[268,80555,80556],{"class":270,"line":788},[268,80557,5033],{"emptyLinePlaceholder":35},[268,80559,80560,80562,80565,80567,80569,80571,80573,80575],{"class":270,"line":1951},[268,80561,243],{"class":274},[268,80563,80564],{"class":305}," alsoSparse",[268,80566,616],{"class":274},[268,80568,11370],{"class":274},[268,80570,24460],{"class":278},[268,80572,622],{"class":282},[268,80574,2429],{"class":305},[268,80576,628],{"class":282},[268,80578,80579,80582,80584,80586,80588,80591],{"class":270,"line":8955},[268,80580,80581],{"class":282},"alsoSparse[",[268,80583,3307],{"class":305},[268,80585,19897],{"class":282},[268,80587,302],{"class":274},[268,80589,80590],{"class":289}," \"x\"",[268,80592,293],{"class":282},[23,80594,80596,80602,80612,80626],{"className":80595},[26],[28,80597,80599,80601],{"className":80598},[31],[33,80600],{"disabled":35,"type":36}," There is no difference — all three are stored identically as contiguous memory blocks",[28,80603,80605,355,80607,186,80609,80611],{"className":80604},[31],[33,80606],{"disabled":35,"type":36},[39,80608,80467],{},[39,80610,80470],{}," are actually faster because V8 pre-allocates extra memory for them",[28,80613,80615,355,80617,80619,80620,99,80622,80625],{"className":80614},[31],[33,80616],{"disabled":35,"type":36},[39,80618,80463],{}," stays on V8's fast, packed \"elements kind\" (contiguous backing store); creating holes with ",[39,80621,21490],{},[39,80623,80624],{},"new Array(n)"," transitions the array to a slower \"holey\"\u002Fdictionary-like representation, since engines must now check for and skip missing indices on every access",[28,80627,80629,355,80631,80634,80635,80637],{"className":80628},[31],[33,80630],{"disabled":35,"type":36},[39,80632,80633],{},"delete sparse[2]"," shrinks the array's ",[39,80636,3567],{}," by one, making it faster to iterate",[66,80639,80640,80642,80652],{},[69,80641,71],{},[73,80643,80644,1004,80646,80619,80648,99,80650,80625],{},[76,80645,78],{},[39,80647,80463],{},[39,80649,21490],{},[39,80651,80624],{},[73,80653,80654,355,80656,80658,80659,80661,80662,80664,80665,80667,80668,80671,80672,80674,80675,462],{},[76,80655,84],{},[76,80657,438],{}," V8 tracks an array's \"elements kind\" internally. A fully packed array like ",[39,80660,80463],{}," can use a tight, contiguous fast path. ",[39,80663,80633],{}," doesn't shrink the array or fill the gap — it leaves an actual hole at index 2 (the array's ",[39,80666,3567],{}," stays 5), which downgrades it to a \"holey\" representation that must check for missing slots on every access. ",[39,80669,80670],{},"new Array(5)"," starts out entirely holey by construction, for the same reason. Option A and B invert the real cost. Option D is a common misconception — ",[39,80673,21490],{}," on an array index never changes ",[39,80676,3567],{},[15,80678,80679,80689,80727],{},[18,80680,80682,80683,8574,80685,80688],{"id":80681},"q12-an-animation-loop-uses-setintervalupdate-16-instead-of-requestanimationframeupdate-beyond-potential-drift-from-the-displays-refresh-rate-whats-another-concrete-downside-in-production","Q12. An animation loop uses ",[39,80684,71314],{},[39,80686,80687],{},"requestAnimationFrame(update)",". Beyond potential drift from the display's refresh rate, what's another concrete downside in production?",[23,80690,80692,80700,80708,80716],{"className":80691},[26],[28,80693,80695,355,80697,80699],{"className":80694},[31],[33,80696],{"disabled":35,"type":36},[39,80698,47386],{}," cannot be cleared once started, so the animation runs forever even after the component unmounts",[28,80701,80703,355,80705,80707],{"className":80702},[31],[33,80704],{"disabled":35,"type":36},[39,80706,47386],{}," runs on a separate thread, causing race conditions with the DOM",[28,80709,80711,355,80713,80715],{"className":80710},[31],[33,80712],{"disabled":35,"type":36},[39,80714,47386],{}," cannot accept a callback that touches the DOM",[28,80717,80719,355,80721,80723,80724,80726],{"className":80718},[31],[33,80720],{"disabled":35,"type":36},[39,80722,47386],{}," keeps firing at roughly the same rate even when the tab is backgrounded\u002Fhidden, wasting CPU and battery on invisible work, whereas ",[39,80725,62893],{}," callbacks are automatically throttled\u002Fpaused by the browser for hidden tabs",[66,80728,80729,80731,80739],{},[69,80730,71],{},[73,80732,80733,6901,80735,80723,80737,80726],{},[76,80734,78],{},[39,80736,47386],{},[39,80738,62893],{},[73,80740,80741,355,80743,80745,80746,80748,80749,80751,80752,80754,80755,80757,80758,462],{},[76,80742,84],{},[76,80744,438],{}," Browsers specifically de-prioritize ",[39,80747,62893],{}," for hidden\u002Fbackground tabs (heavily throttling or pausing it entirely, since there's nothing to paint), which saves CPU and battery for work the user can't even see. ",[39,80750,47386],{}," has no such built-in awareness of visibility and keeps ticking at roughly its configured rate regardless, silently burning resources in the background. Option A is false — ",[39,80753,69704],{}," works identically to clearing any interval. Options B and C invent thread and DOM-access restrictions that don't exist; ",[39,80756,47386],{}," runs on the main thread just like ",[39,80759,62893],{},[15,80761,80762,80766,80975,81011],{"language":247},[18,80763,80765],{"id":80764},"q13-running-this-synchronous-computation-in-a-click-handler-freezes-the-ui-for-its-duration-whats-the-correct-fix-and-why","Q13. Running this synchronous computation in a click handler freezes the UI for its duration. What's the correct fix, and why?",[257,80767,80768],{"language":247},[260,80769,80771],{"className":262,"code":80770,"language":247,"meta":264,"style":264},"function findPrimesUpTo(n) {\n  const primes = [];\n  for (let i = 2; i \u003C= n; i++) {\n    let isPrime = true;\n    for (let j = 2; j * j \u003C= i; j++) {\n      if (i % j === 0) { isPrime = false; break; }\n    }\n    if (isPrime) primes.push(i);\n  }\n  return primes;\n}\ndocument.getElementById(\"go\").addEventListener(\"click\", () => {\n  const result = findPrimesUpTo(5_000_000);\n  render(result);\n});\n",[39,80772,80773,80786,80797,80822,80836,80866,80893,80897,80908,80912,80919,80923,80948,80965,80971],{"__ignoreMap":264},[268,80774,80775,80777,80780,80782,80784],{"class":270,"line":271},[268,80776,275],{"class":274},[268,80778,80779],{"class":278}," findPrimesUpTo",[268,80781,622],{"class":282},[268,80783,4599],{"class":1222},[268,80785,1235],{"class":282},[268,80787,80788,80790,80793,80795],{"class":270,"line":286},[268,80789,12441],{"class":274},[268,80791,80792],{"class":305}," primes",[268,80794,616],{"class":274},[268,80796,12449],{"class":282},[268,80798,80799,80801,80803,80805,80807,80809,80811,80813,80815,80818,80820],{"class":270,"line":296},[268,80800,9659],{"class":274},[268,80802,2182],{"class":282},[268,80804,240],{"class":274},[268,80806,9384],{"class":282},[268,80808,302],{"class":274},[268,80810,2214],{"class":305},[268,80812,9391],{"class":282},[268,80814,6776],{"class":274},[268,80816,80817],{"class":282}," n; i",[268,80819,9401],{"class":274},[268,80821,1235],{"class":282},[268,80823,80824,80827,80830,80832,80834],{"class":270,"line":311},[268,80825,80826],{"class":274},"    let",[268,80828,80829],{"class":282}," isPrime ",[268,80831,302],{"class":274},[268,80833,7905],{"class":305},[268,80835,293],{"class":282},[268,80837,80838,80841,80843,80845,80847,80849,80851,80853,80855,80857,80859,80862,80864],{"class":270,"line":788},[268,80839,80840],{"class":274},"    for",[268,80842,2182],{"class":282},[268,80844,240],{"class":274},[268,80846,9441],{"class":282},[268,80848,302],{"class":274},[268,80850,2214],{"class":305},[268,80852,9448],{"class":282},[268,80854,6134],{"class":274},[268,80856,9441],{"class":282},[268,80858,6776],{"class":274},[268,80860,80861],{"class":282}," i; j",[268,80863,9401],{"class":274},[268,80865,1235],{"class":282},[268,80867,80868,80870,80872,80874,80876,80878,80880,80883,80885,80887,80889,80891],{"class":270,"line":1951},[268,80869,11948],{"class":274},[268,80871,11240],{"class":282},[268,80873,26178],{"class":274},[268,80875,9441],{"class":282},[268,80877,3280],{"class":274},[268,80879,5728],{"class":305},[268,80881,80882],{"class":282},") { isPrime ",[268,80884,302],{"class":274},[268,80886,3200],{"class":305},[268,80888,2272],{"class":282},[268,80890,8880],{"class":274},[268,80892,25000],{"class":282},[268,80894,80895],{"class":270,"line":8955},[268,80896,11972],{"class":282},[268,80898,80899,80901,80904,80906],{"class":270,"line":8966},[268,80900,9686],{"class":274},[268,80902,80903],{"class":282}," (isPrime) primes.",[268,80905,12499],{"class":278},[268,80907,11221],{"class":282},[268,80909,80910],{"class":270,"line":8974},[268,80911,1948],{"class":282},[268,80913,80914,80916],{"class":270,"line":8985},[268,80915,1240],{"class":274},[268,80917,80918],{"class":282}," primes;\n",[268,80920,80921],{"class":270,"line":8990},[268,80922,314],{"class":282},[268,80924,80925,80927,80929,80931,80934,80936,80938,80940,80942,80944,80946],{"class":270,"line":8997},[268,80926,61438],{"class":282},[268,80928,79005],{"class":278},[268,80930,622],{"class":282},[268,80932,80933],{"class":289},"\"go\"",[268,80935,6232],{"class":282},[268,80937,35737],{"class":278},[268,80939,622],{"class":282},[268,80941,64737],{"class":289},[268,80943,35745],{"class":282},[268,80945,9414],{"class":274},[268,80947,9914],{"class":282},[268,80949,80950,80952,80954,80956,80958,80960,80963],{"class":270,"line":9002},[268,80951,12441],{"class":274},[268,80953,5583],{"class":305},[268,80955,616],{"class":274},[268,80957,80779],{"class":278},[268,80959,622],{"class":282},[268,80961,80962],{"class":305},"5_000_000",[268,80964,628],{"class":282},[268,80966,80967,80969],{"class":270,"line":14676},[268,80968,48431],{"class":278},[268,80970,6852],{"class":282},[268,80972,80973],{"class":270,"line":14681},[268,80974,20047],{"class":282},[23,80976,80978,80984,80993,81002],{"className":80977},[26],[28,80979,80981,80983],{"className":80980},[31],[33,80982],{"disabled":35,"type":36}," Move the computation into a Web Worker — since JS is single-threaded, any synchronous CPU-bound work on the main thread blocks rendering and event handling no matter how it's scheduled; a worker runs on a separate thread so the main thread stays responsive",[28,80985,80987,80989,80990,80992],{"className":80986},[31],[33,80988],{"disabled":35,"type":36}," Wrap the call in a ",[39,80991,91],{}," so it runs asynchronously without blocking",[28,80994,80996,4353,80998,81001],{"className":80995},[31],[33,80997],{"disabled":35,"type":36},[39,80999,81000],{},"setTimeout(() => findPrimesUpTo(5_000_000), 0)"," to defer it to a macrotask",[28,81003,81005,81007,81008,81010],{"className":81004},[31],[33,81006],{"disabled":35,"type":36}," Mark the function ",[39,81009,379],{}," so it yields control back to the event loop periodically",[66,81012,81013,81015,81020],{},[69,81014,71],{},[73,81016,81017,81019],{},[76,81018,78],{}," A — Move the computation into a Web Worker — since JS is single-threaded, any synchronous CPU-bound work on the main thread blocks rendering and event handling no matter how it's scheduled; a worker runs on a separate thread so the main thread stays responsive",[73,81021,81022,355,81024,81026,81027,81029,81030,81033,81034,81036,81037,81039,81040,81042],{},[76,81023,84],{},[76,81025,438],{}," JavaScript on the main thread is single-threaded and cooperative — once a synchronous function starts running, it monopolizes the thread (blocking layout, painting, and input handling) until it returns, no matter how it got invoked. A Web Worker executes on an entirely separate thread, so the loop runs without ever touching the thread responsible for rendering and interaction. Option B is wrong — wrapping in a ",[39,81028,91],{}," doesn't make the executor's synchronous body non-blocking; the loop still runs to completion inline. Option C only delays ",[104,81031,81032],{},"when"," the freeze starts, not whether it happens. Option D is wrong — ",[39,81035,379],{}," functions don't magically yield mid-loop; only an actual ",[39,81038,12304],{}," (or moving off-thread) does, and there's no ",[39,81041,12304],{}," anywhere in this loop.",[15,81044,81045,81049,81085],{},[18,81046,81048],{"id":81047},"q14-a-single-page-app-ships-one-3mb-js-bundle-containing-code-for-every-route-including-an-admin-dashboard-only-2-of-users-ever-visit-whats-the-standard-fix-and-what-does-it-primarily-improve","Q14. A single-page app ships one 3MB JS bundle containing code for every route, including an admin dashboard only 2% of users ever visit. What's the standard fix, and what does it primarily improve?",[23,81050,81052,81058,81064,81073],{"className":81051},[26],[28,81053,81055,81057],{"className":81054},[31],[33,81056],{"disabled":35,"type":36}," Minify the bundle further — minification alone can typically cut a well-structured bundle to under 3MB total",[28,81059,81061,81063],{"className":81060},[31],[33,81062],{"disabled":35,"type":36}," Split the bundle by route\u002Ffeature (code splitting) and lazy-load the admin dashboard's code only when a user navigates to it — this reduces the initial bundle size, improving time-to-interactive for the 98% of users who never load that code",[28,81065,81067,81069,81070,81072],{"className":81066},[31],[33,81068],{"disabled":35,"type":36}," Inline all JS into the HTML ",[39,81071,442],{}," so there's no separate network request",[28,81074,81076,81078,81079,81081,81082,81084],{"className":81075},[31],[33,81077],{"disabled":35,"type":36}," Move all JS to inline ",[39,81080,434],{}," tags at the bottom of ",[39,81083,1740],{}," instead of an external file",[66,81086,81087,81089,81094],{},[69,81088,71],{},[73,81090,81091,81093],{},[76,81092,78],{}," B — Split the bundle by route\u002Ffeature (code splitting) and lazy-load the admin dashboard's code only when a user navigates to it — this reduces the initial bundle size, improving time-to-interactive for the 98% of users who never load that code",[73,81095,81096,81098,81099,81101,81102,81104],{},[76,81097,84],{}," Code splitting plus lazy loading (e.g., dynamic ",[39,81100,46068],{},") lets the bundler emit separate chunks per route\u002Ffeature, so the browser downloads and parses only what the current page needs, shrinking the critical bundle most users actually pay for. Option A overstates what minification alone can realistically achieve on an already-built, feature-complete bundle. Options C and D just relocate the same amount of JS without reducing what has to be downloaded and parsed before the page becomes interactive — they can make things worse by blocking ",[39,81103,442],{}," parsing or bloating the HTML document itself.",[15,81106,81107,81115,81154],{},[18,81108,81110,81111,81114],{"id":81109},"q15-a-page-renders-a-scrollable-table-of-50000-rows-by-mapping-the-full-dataset-directly-to-50000-tr-elements-causing-visible-jank-whats-the-standard-fix-and-why-does-it-help","Q15. A page renders a scrollable table of 50,000 rows by mapping the full dataset directly to 50,000 ",[39,81112,81113],{},"\u003Ctr>"," elements, causing visible jank. What's the standard fix, and why does it help?",[23,81116,81118,81130,81139,81145],{"className":81117},[26],[28,81119,81121,81123,81124,2029,81127,81129],{"className":81120},[31],[33,81122],{"disabled":35,"type":36}," Replace the ",[39,81125,81126],{},"\u003Ctable>",[39,81128,64559],{},"s, since divs render faster than table elements",[28,81131,81133,77484,81135,81138],{"className":81132},[31],[33,81134],{"disabled":35,"type":36},[39,81136,81137],{},"will-change: transform"," to every row to force GPU acceleration of all 50,000 rows",[28,81140,81142,81144],{"className":81141},[31],[33,81143],{"disabled":35,"type":36}," Use virtualization\u002Fwindowing to render only the rows currently visible in the viewport (plus a small buffer), swapping their content as the user scrolls — this keeps the number of live DOM nodes small regardless of dataset size, avoiding the cost of creating\u002Flaying out\u002Fpainting tens of thousands of nodes at once",[28,81146,81148,4353,81150,81153],{"className":81147},[31],[33,81149],{"disabled":35,"type":36},[39,81151,81152],{},"list-style: none"," to skip the browser's default list rendering",[66,81155,81156,81158,81163],{},[69,81157,71],{},[73,81159,81160,81162],{},[76,81161,78],{}," C — Use virtualization\u002Fwindowing to render only the rows currently visible in the viewport (plus a small buffer), swapping their content as the user scrolls — this keeps the number of live DOM nodes small regardless of dataset size, avoiding the cost of creating\u002Flaying out\u002Fpainting tens of thousands of nodes at once",[73,81164,81165,81167,81168,81171,81172,446,81174,81176],{},[76,81166,84],{}," Virtualization decouples the number of live DOM nodes from the size of the underlying dataset — only the handful of rows actually in (or near) the viewport ever exist as real elements, with the rest represented purely as data until they scroll into view. This keeps DOM node count, layout cost, and paint cost roughly constant no matter how large the dataset grows. Option A is a myth — element tag choice has negligible impact next to node count. Option B actually makes things worse, since ",[39,81169,81170],{},"will-change"," reserves GPU compositing layers per element and applying it to 50,000 rows wastes memory. Option D is irrelevant to ",[39,81173,81126],{},[39,81175,81113],{}," rendering, which has no list markers to begin with.",[15,81178,81179,81183,81252,81299],{"language":247},[18,81180,81182],{"id":81181},"q16-a-particle-based-game-loop-allocates-thousands-of-new-particle-objects-per-second-and-discards-them-once-off-screen-running-at-60fps-players-notice-periodic-stutters-whats-a-common-cause-and-fix","Q16. A particle-based game loop allocates thousands of new particle objects per second and discards them once off-screen, running at 60fps. Players notice periodic stutters. What's a common cause and fix?",[257,81184,81185],{"language":247},[260,81186,81188],{"className":262,"code":81187,"language":247,"meta":264,"style":264},"function spawnParticles(n) {\n  for (let i = 0; i \u003C n; i++) {\n    particles.push(new Particle(x, y, vx, vy));\n  }\n}\n",[39,81189,81190,81203,81227,81244,81248],{"__ignoreMap":264},[268,81191,81192,81194,81197,81199,81201],{"class":270,"line":271},[268,81193,275],{"class":274},[268,81195,81196],{"class":278}," spawnParticles",[268,81198,622],{"class":282},[268,81200,4599],{"class":1222},[268,81202,1235],{"class":282},[268,81204,81205,81207,81209,81211,81213,81215,81217,81219,81221,81223,81225],{"class":270,"line":286},[268,81206,9659],{"class":274},[268,81208,2182],{"class":282},[268,81210,240],{"class":274},[268,81212,9384],{"class":282},[268,81214,302],{"class":274},[268,81216,5728],{"class":305},[268,81218,9391],{"class":282},[268,81220,1076],{"class":274},[268,81222,80817],{"class":282},[268,81224,9401],{"class":274},[268,81226,1235],{"class":282},[268,81228,81229,81232,81234,81236,81238,81241],{"class":270,"line":296},[268,81230,81231],{"class":282},"    particles.",[268,81233,12499],{"class":278},[268,81235,622],{"class":282},[268,81237,2689],{"class":274},[268,81239,81240],{"class":278}," Particle",[268,81242,81243],{"class":282},"(x, y, vx, vy));\n",[268,81245,81246],{"class":270,"line":311},[268,81247,1948],{"class":282},[268,81249,81250],{"class":270,"line":788},[268,81251,314],{"class":282},[23,81253,81255,81267,81279,81293],{"className":81254},[26],[28,81256,81258,81260,81261,81263,81264,81266],{"className":81257},[31],[33,81259],{"disabled":35,"type":36}," The stutters are caused by ",[39,81262,62893],{}," itself pausing periodically; switching to ",[39,81265,47386],{}," fixes it",[28,81268,81270,81272,81273,81275,81276],{"className":81269},[31],[33,81271],{"disabled":35,"type":36}," The stutters are unrelated to allocation; they're caused by using ",[39,81274,1468],{}," instead of object literals for ",[39,81277,81278],{},"Particle",[28,81280,81282,81284,81285,81287,81288,5425,81290,81292],{"className":81281},[31],[33,81283],{"disabled":35,"type":36}," Switching ",[39,81286,81278],{}," fields from ",[39,81289,240],{},[39,81291,243],{}," prevents the stutter by making objects immutable",[28,81294,81296,81298],{"className":81295},[31],[33,81297],{"disabled":35,"type":36}," Constantly allocating and discarding thousands of short-lived objects per second creates heavy garbage collection pressure, and the GC's collection pauses cause the stutters; an object pool that reuses a fixed set of pre-allocated particle objects (resetting their fields instead of reallocating) avoids the allocation churn",[66,81300,81301,81303,81308],{},[69,81302,71],{},[73,81304,81305,81307],{},[76,81306,78],{}," D — Constantly allocating and discarding thousands of short-lived objects per second creates heavy garbage collection pressure, and the GC's collection pauses cause the stutters; an object pool that reuses a fixed set of pre-allocated particle objects (resetting their fields instead of reallocating) avoids the allocation churn",[73,81309,81310,355,81312,81314],{},[76,81311,84],{},[76,81313,438],{}," High-frequency allocation of short-lived objects fills the young generation heap quickly, triggering frequent minor GC cycles; even brief collection pauses are enough to drop frames in a 60fps loop, producing visible stutter. An object pool sidesteps this by allocating a fixed set of particles once up front and recycling them (resetting position\u002Fvelocity fields) instead of creating and discarding new ones every frame, which drastically cuts allocation churn and GC pressure. Option A blames the wrong scheduler and proposes a strictly worse alternative (see Q12). Options B and C misattribute the cause to unrelated syntax choices that don't affect allocation behavior.",[15,81316,81317,81328,81366],{},[18,81318,81320,81321,81323,81324,81327],{"id":81319},"q17-a-developer-notices-the-app-feels-slow-and-immediately-rewrites-a-for-loop-as-arrayreduce-because-functional-style-is-faster-without-measuring-anything-first-whats-wrong-with-this-approach","Q17. A developer notices the app feels slow and immediately rewrites a ",[39,81322,6926],{}," loop as ",[39,81325,81326],{},"array.reduce()"," because \"functional style is faster,\" without measuring anything first. What's wrong with this approach?",[23,81329,81331,81337,81349,81360],{"className":81330},[26],[28,81332,81334,81336],{"className":81333},[31],[33,81335],{"disabled":35,"type":36}," This is premature optimization based on assumption rather than data; the actual bottleneck could be anywhere (a layout thrash, an unbatched network waterfall, a memory leak), and swapping loop syntax alone rarely matters for performance — the correct approach is to profile first (e.g., the browser's Performance\u002FProfiler panel) to find the actual hot path before changing code",[28,81338,81340,52864,81342,81345,81346,81348],{"className":81339},[31],[33,81341],{"disabled":35,"type":36},[39,81343,81344],{},"reduce()"," is always faster than a ",[39,81347,6926],{}," loop in every JS engine",[28,81350,81352,355,81354,81356,81357,81359],{"className":81351},[31],[33,81353],{"disabled":35,"type":36},[39,81355,81344],{}," should always be avoided since it's slower than ",[39,81358,6926],{}," loops in every case",[28,81361,81363,81365],{"className":81362},[31],[33,81364],{"disabled":35,"type":36}," Rewriting loop syntax is the single most impactful optimization available in JavaScript",[66,81367,81368,81370,81375],{},[69,81369,71],{},[73,81371,81372,81374],{},[76,81373,78],{}," A — This is premature optimization based on assumption rather than data; the actual bottleneck could be anywhere (a layout thrash, an unbatched network waterfall, a memory leak), and swapping loop syntax alone rarely matters for performance — the correct approach is to profile first (e.g., the browser's Performance\u002FProfiler panel) to find the actual hot path before changing code",[73,81376,81377,81379,81380,446,81383,81386,81387,186,81389,81391],{},[76,81378,84],{}," \"Feels slow\" is a symptom, not a diagnosis — the actual bottleneck is just as likely to be a network waterfall, layout thrashing, an unbounded cache, or a single hot function buried deep in a call stack as it is to be loop syntax, and guessing wastes effort on code that may not matter at all. Profiling tools (flame graphs, the Performance panel, ",[39,81381,81382],{},"console.time",[39,81384,81385],{},"performance.mark"," around suspected hot paths) point directly at where time is actually spent. Options B and D both overstate loop-syntax swaps as a universal win, and option C overstates the opposite — in reality, the difference between ",[39,81388,6926],{},[39,81390,81344],{}," is usually negligible next to real bottlenecks and is engine\u002Fcase-dependent.",[15,81393,81394,81401,81485,81534],{"language":247},[18,81395,81397,81398,81400],{"id":81396},"q18-el-is-a-dom-element-passed-in-from-various-parts-of-the-app-some-are-later-removed-from-the-dom-with-no-other-references-held-whats-the-memory-problem-and-whats-the-direct-fix","Q18. ",[39,81399,25687],{}," is a DOM element passed in from various parts of the app; some are later removed from the DOM with no other references held. What's the memory problem, and what's the direct fix?",[257,81402,81403],{"language":247},[260,81404,81406],{"className":262,"code":81405,"language":247,"meta":264,"style":264},"const cache = new Map();\nfunction getMetadata(el) {\n  if (!cache.has(el)) {\n    cache.set(el, computeExpensiveMetadata(el));\n  }\n  return cache.get(el);\n}\n",[39,81407,81408,81422,81435,81451,81466,81470,81481],{"__ignoreMap":264},[268,81409,81410,81412,81414,81416,81418,81420],{"class":270,"line":271},[268,81411,243],{"class":274},[268,81413,15807],{"class":305},[268,81415,616],{"class":274},[268,81417,11370],{"class":274},[268,81419,11373],{"class":278},[268,81421,794],{"class":282},[268,81423,81424,81426,81429,81431,81433],{"class":270,"line":286},[268,81425,275],{"class":274},[268,81427,81428],{"class":278}," getMetadata",[268,81430,622],{"class":282},[268,81432,25687],{"class":1222},[268,81434,1235],{"class":282},[268,81436,81437,81439,81441,81443,81446,81448],{"class":270,"line":296},[268,81438,9863],{"class":274},[268,81440,2182],{"class":282},[268,81442,5418],{"class":274},[268,81444,81445],{"class":282},"cache.",[268,81447,37875],{"class":278},[268,81449,81450],{"class":282},"(el)) {\n",[268,81452,81453,81455,81457,81460,81463],{"class":270,"line":311},[268,81454,37907],{"class":282},[268,81456,37910],{"class":278},[268,81458,81459],{"class":282},"(el, ",[268,81461,81462],{"class":278},"computeExpensiveMetadata",[268,81464,81465],{"class":282},"(el));\n",[268,81467,81468],{"class":270,"line":788},[268,81469,1948],{"class":282},[268,81471,81472,81474,81476,81478],{"class":270,"line":1951},[268,81473,1240],{"class":274},[268,81475,37883],{"class":282},[268,81477,32437],{"class":278},[268,81479,81480],{"class":282},"(el);\n",[268,81482,81483],{"class":270,"line":8955},[268,81484,314],{"class":282},[23,81486,81488,81497,81516,81526],{"className":81487},[26],[28,81489,81491,81493,81494,81496],{"className":81490},[31],[33,81492],{"disabled":35,"type":36}," There's no problem — ",[39,81495,2672],{}," automatically drops entries whose keys are no longer referenced elsewhere",[28,81498,81500,355,81502,81504,81505,81507,81508,81510,81511,2029,81513,81515],{"className":81499},[31],[33,81501],{"disabled":35,"type":36},[39,81503,15925],{}," (a ",[39,81506,2672],{},") holds a strong reference to each ",[39,81509,25687],{}," key, so as long as an entry exists in the cache, the removed DOM element can never be garbage collected, even though nothing else references it — replacing ",[39,81512,2672],{},[39,81514,40238],{}," lets those keys (and their entries) be collected once the element has no other referrers",[28,81517,81519,81521,81522,81525],{"className":81518},[31],[33,81520],{"disabled":35,"type":36}," The fix is to call ",[39,81523,81524],{},"cache.clear()"," after every use",[28,81527,81529,355,81531,81533],{"className":81528},[31],[33,81530],{"disabled":35,"type":36},[39,81532,40238],{}," would make this worse, since weak references are collected too aggressively and could drop entries while still in use elsewhere",[66,81535,81536,81538,81552],{},[69,81537,71],{},[73,81539,81540,1727,81542,81504,81544,81507,81546,81510,81548,2029,81550,81515],{},[76,81541,78],{},[39,81543,15925],{},[39,81545,2672],{},[39,81547,25687],{},[39,81549,2672],{},[39,81551,40238],{},[73,81553,81554,81556,81557,81559,81560,81562,81563,81565,81566,81569,81570,81572,81573,81575],{},[76,81555,84],{}," A regular ",[39,81558,2672],{}," retains every key strongly, exactly like any other reference — so simply being a ",[39,81561,2672],{}," key is enough to keep an otherwise-unreferenced, detached DOM element alive indefinitely, leaking memory as elements accumulate over the session. ",[39,81564,40238],{}," holds its keys ",[104,81567,81568],{},"weakly",": once nothing outside the ",[39,81571,40238],{}," references a given key object, the engine is free to collect it, and the corresponding entry disappears automatically. Option A invents automatic eviction ",[39,81574,2672],{}," doesn't have. Option C is a workaround that discards the entire cache's usefulness rather than fixing the leak surgically. Option D misunderstands weak references — they're only collected when truly unreachable elsewhere, not \"aggressively.\"",[15,81577,81578,81585,81638,81700],{"language":247},[18,81579,81581,81582,81584],{"id":81580},"q19-having-switched-the-metadata-cache-to-a-weakmap-a-developer-tries-to-run-this-what-happens","Q19. Having switched the metadata cache to a ",[39,81583,40238],{},", a developer tries to run this. What happens?",[257,81586,81587],{"language":247},[260,81588,81590],{"className":262,"code":81589,"language":247,"meta":264,"style":264},"console.log(cache.size);\nfor (const [key, value] of cache) {\n  console.log(key, value);\n}\n",[39,81591,81592,81601,81625,81634],{"__ignoreMap":264},[268,81593,81594,81596,81598],{"class":270,"line":271},[268,81595,1353],{"class":282},[268,81597,1356],{"class":278},[268,81599,81600],{"class":282},"(cache.size);\n",[268,81602,81603,81605,81607,81609,81611,81613,81615,81617,81619,81622],{"class":270,"line":286},[268,81604,6926],{"class":274},[268,81606,2182],{"class":282},[268,81608,243],{"class":274},[268,81610,8710],{"class":282},[268,81612,19849],{"class":305},[268,81614,42],{"class":282},[268,81616,4780],{"class":305},[268,81618,19897],{"class":282},[268,81620,81621],{"class":274},"of",[268,81623,81624],{"class":282}," cache) {\n",[268,81626,81627,81629,81631],{"class":270,"line":296},[268,81628,5556],{"class":282},[268,81630,1356],{"class":278},[268,81632,81633],{"class":282},"(key, value);\n",[268,81635,81636],{"class":270,"line":311},[268,81637,314],{"class":282},[23,81639,81641,81655,81669,81690],{"className":81640},[26],[28,81642,81644,355,81646,81649,81650,75862,81652,81654],{"className":81643},[31],[33,81645],{"disabled":35,"type":36},[39,81647,81648],{},"cache.size"," returns the count correctly, but ",[39,81651,9163],{},[39,81653,40238],{}," is not iterable",[28,81656,81658,81660,81661,4387,81663,81665,81666,81668],{"className":81657},[31],[33,81659],{"disabled":35,"type":36}," Both work identically to ",[39,81662,2672],{},[39,81664,40238],{}," is just a ",[39,81667,2672],{}," with automatic cleanup",[28,81670,81672,355,81674,81676,81677,5893,81680,446,81683,81686,81687,81689],{"className":81671},[31],[33,81673],{"disabled":35,"type":36},[39,81675,40238],{}," has neither ",[39,81678,81679],{},".size",[39,81681,81682],{},".keys()",[39,81684,81685],{},".entries()","\u002Fiteration support at all — this is deliberate, since the collection's contents can change at any moment as the engine garbage-collects keys, so exposing enumeration would make behavior non-deterministic; if you need to enumerate or count entries, a regular ",[39,81688,2672],{}," (with manual cleanup) is the right tool instead",[28,81691,81693,355,81695,2278,81697,81699],{"className":81692},[31],[33,81694],{"disabled":35,"type":36},[39,81696,81648],{},[39,81698,827],{},", but iteration is supported and returns only the currently-live entries",[66,81701,81702,81704,81718],{},[69,81703,71],{},[73,81705,81706,1004,81708,81676,81710,5893,81712,446,81714,81686,81716,81689],{},[76,81707,78],{},[39,81709,40238],{},[39,81711,81679],{},[39,81713,81682],{},[39,81715,81685],{},[39,81717,2672],{},[73,81719,81720,355,81722,355,81724,2269,81727,5992,81729,81731,81732,81735,81736,81738,81739,183,81741,81743,81744,5893,81746,81748,81749,81751,81752,2029,81754,81756,81757,81759],{},[76,81721,84],{},[76,81723,365],{},[39,81725,81726],{},"console.log(cache.size)",[39,81728,833],{},[39,81730,81679],{}," getter exists on ",[39,81733,81734],{},"WeakMap.prototype","), and the ",[39,81737,9163],{}," loop throws a ",[39,81740,827],{},[39,81742,40238],{}," implements neither ",[39,81745,10339],{},[39,81747,81685],{},". This is an intentional spec design: garbage collection timing is non-deterministic and implementation-defined, so if you could enumerate a ",[39,81750,40238],{},"'s contents, the results (and even whether a collection pass happened mid-iteration) would be observable and inconsistent across engines — the spec avoids that entirely by disallowing enumeration. Options A and D each get one half right but the other half wrong. Option B conflates ",[39,81753,40238],{},[39,81755,2672],{},", which does support both ",[39,81758,81679],{}," and iteration.",[15,81761,81762,81770,81816],{},[18,81763,81765,81766,81769],{"id":81764},"q20-a-profiler-flame-graph-shows-80-of-a-slow-interactions-time-inside-a-single-recalculatelayout-function-called-synchronously-once-per-scroll-event-dozens-of-times-per-second-whats-the-most-appropriate-first-fix","Q20. A profiler flame graph shows 80% of a slow interaction's time inside a single ",[39,81767,81768],{},"recalculateLayout()"," function, called synchronously once per scroll event (dozens of times per second). What's the most appropriate first fix?",[23,81771,81773,81779,81790,81804],{"className":81772},[26],[28,81774,81776,81778],{"className":81775},[31],[33,81777],{"disabled":35,"type":36}," Rewrite the entire app in a different framework, since the framework is likely the root cause",[28,81780,81782,77484,81784,446,81786,81789],{"className":81781},[31],[33,81783],{"disabled":35,"type":36},[39,81785,81382],{},[39,81787,81788],{},"console.timeEnd"," calls throughout the codebase before making any change, since more logging is always the correct first step",[28,81791,81793,81795,81796,81798,81799,446,81801,81803],{"className":81792},[31],[33,81794],{"disabled":35,"type":36}," Convert all ",[39,81797,1440],{}," declarations in the file to ",[39,81800,243],{},[39,81802,240],{},", since modern syntax is inherently faster",[28,81805,81807,81809,81810,81812,81813,81815],{"className":81806},[31],[33,81808],{"disabled":35,"type":36}," Throttle the scroll handler so ",[39,81811,81768],{}," runs at a capped rate (or move the work to ",[39,81814,62893],{},") — this directly targets the measured bottleneck (call frequency) without speculative, unrelated changes",[66,81817,81818,81820,81829],{},[69,81819,71],{},[73,81821,81822,81824,81825,81812,81827,81815],{},[76,81823,78],{}," D — Throttle the scroll handler so ",[39,81826,81768],{},[39,81828,62893],{},[73,81830,81831,81833,81834,81836],{},[76,81832,84],{}," The profiler already identified the exact bottleneck: an expensive function invoked far more often than necessary on a high-frequency event. The direct, evidence-backed fix is to cut the call frequency — throttling, or batching the work into a single ",[39,81835,62893],{}," callback per visual frame — rather than guessing at unrelated changes. Option B misunderstands the situation: the profiling data already exists, so adding scattered manual timers is redundant busywork, not \"the correct first step.\" Options A and C are classic cargo-cult \"optimizations\" — a framework rewrite and syntax modernization — that don't address the measured cause at all and risk introducing new bugs for no measured benefit.",[2107,81838,81839],{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-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 .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}",{"title":264,"searchDepth":286,"depth":286,"links":81841},[81842,81843,81845,81846,81847,81848,81849,81851,81852,81854,81856,81858,81860,81861,81862,81864,81865,81867,81869,81871],{"id":78974,"depth":296,"text":78975},{"id":79179,"depth":296,"text":81844},"Q2. What's the memory\u002Fbehavior consequence of removing clockEl without clearing the interval?",{"id":79355,"depth":296,"text":79356},{"id":79504,"depth":296,"text":79505},{"id":79559,"depth":296,"text":79560},{"id":79617,"depth":296,"text":79618},{"id":79873,"depth":296,"text":81850},"Q7. What perf benefit does V8 get from a and b being built with the same property order and types?",{"id":80062,"depth":296,"text":80063},{"id":80207,"depth":296,"text":81853},"Q9. getArea(shape) reads shape.width * shape.height and runs thousands of times per frame. Why is it faster when every shape has the same property layout than when shapes vary?",{"id":80319,"depth":296,"text":81855},"Q10. In a hot path, what's the perf concern with delete cfg.debug, and what's the preferred alternative?",{"id":80459,"depth":296,"text":81857},"Q11. Why can iterating\u002Fsumming dense be significantly faster than doing the same over sparse or alsoSparse?",{"id":80681,"depth":296,"text":81859},"Q12. An animation loop uses setInterval(update, 16) instead of requestAnimationFrame(update). Beyond potential drift from the display's refresh rate, what's another concrete downside in production?",{"id":80764,"depth":296,"text":80765},{"id":81047,"depth":296,"text":81048},{"id":81109,"depth":296,"text":81863},"Q15. A page renders a scrollable table of 50,000 rows by mapping the full dataset directly to 50,000 \u003Ctr> elements, causing visible jank. What's the standard fix, and why does it help?",{"id":81181,"depth":296,"text":81182},{"id":81319,"depth":296,"text":81866},"Q17. A developer notices the app feels slow and immediately rewrites a for loop as array.reduce() because \"functional style is faster,\" without measuring anything first. What's wrong with this approach?",{"id":81396,"depth":296,"text":81868},"Q18. el is a DOM element passed in from various parts of the app; some are later removed from the DOM with no other references held. What's the memory problem, and what's the direct fix?",{"id":81580,"depth":296,"text":81870},"Q19. Having switched the metadata cache to a WeakMap, a developer tries to run this. What happens?",{"id":81764,"depth":296,"text":81872},"Q20. A profiler flame graph shows 80% of a slow interaction's time inside a single recalculateLayout() function, called synchronously once per scroll event (dozens of times per second). What's the most appropriate first fix?",{},"\u002Fjs\u002F26-performance-and-optimization",{"title":78964,"description":264},"js\u002F26-performance-and-optimization","iiEdztdP3x6sfaV7LQodrgUsKiM7-b6FISZPQkPo9KA",{"id":81879,"title":81880,"body":81881,"description":264,"extension":2144,"meta":83864,"navigation":35,"path":83865,"seo":83866,"stem":83867,"__hash__":83868},"content\u002Fjs\u002F27-tooling-and-build-systems.md","27 — Tooling & Build Systems",{"type":8,"value":81882,"toc":83831},[81883,81886,81941,82128,82227,82276,82366,82426,82560,82611,82771,82868,83003,83077,83127,83235,83290,83466,83551,83606,83763,83828],[11,81884,81880],{"id":81885},"_27-tooling-build-systems",[15,81887,81888,81892,81919],{"language":247},[18,81889,81891],{"id":81890},"q1-why-do-bundlers-like-webpack-vite-esbuild-or-rollup-exist-in-a-modern-javascript-project","Q1. Why do bundlers like webpack, Vite, esbuild, or Rollup exist in a modern JavaScript project?",[23,81893,81895,81901,81907,81913],{"className":81894},[26],[28,81896,81898,81900],{"className":81897},[31],[33,81899],{"disabled":35,"type":36}," They are required by the JavaScript language specification for any project that uses more than one file",[28,81902,81904,81906],{"className":81903},[31],[33,81905],{"disabled":35,"type":36}," They combine and resolve a project's module graph into fewer output files, cutting down HTTP requests, and enable whole-program optimizations (like tree-shaking) that aren't possible when analyzing files one at a time",[28,81908,81910,81912],{"className":81909},[31],[33,81911],{"disabled":35,"type":36}," They exist only to add TypeScript support to a project",[28,81914,81916,81918],{"className":81915},[31],[33,81917],{"disabled":35,"type":36}," They replace the browser's JavaScript engine with a faster one",[66,81920,81921,81923,81928],{},[69,81922,71],{},[73,81924,81925,81927],{},[76,81926,78],{}," B — They combine and resolve a project's module graph into fewer output files, cutting down HTTP requests, and enable whole-program optimizations (like tree-shaking) that aren't possible when analyzing files one at a time",[73,81929,81930,81932,81933,81935,81936,446,81938,81940],{},[76,81931,84],{}," Before bundlers, shipping many separate ",[39,81934,434],{}," files meant many separate HTTP round trips and no way to statically analyze which code was actually reachable. A bundler walks the ",[39,81937,662],{},[39,81939,655],{}," graph starting from an entry point, resolves every dependency, and emits a small number of optimized output files — while also unlocking cross-file analysis like tree-shaking and code splitting. Nothing in the ECMAScript spec requires a bundler (option A) — Node and modern browsers can load ESM natively — and bundlers operate on the source code, not the JS engine itself (option D). TypeScript support (option C) is a separate, optional concern usually handled by a transpiler step.",[15,81942,81943,81960,82068,82101],{"language":247},[18,81944,81946,81947,81950,81951,81954,81955,8828,81957,81959],{"id":81945},"q2-why-can-a-bundler-safely-remove-multiply-from-the-production-bundle-below-but-couldnt-perform-the-same-removal-if-mathutilsjs-used-commonjs-moduleexports-require-instead","Q2. Why can a bundler safely remove ",[39,81948,81949],{},"multiply"," from the production bundle below, but couldn't perform the same removal if ",[39,81952,81953],{},"mathUtils.js"," used CommonJS (",[39,81956,658],{},[39,81958,655],{},") instead?",[257,81961,81962],{"language":247},[260,81963,81965],{"className":262,"code":81964,"language":247,"meta":264,"style":264},"\u002F\u002F mathUtils.js\nexport function add(a, b) { return a + b; }\nexport function multiply(a, b) { return a * b; }\n\n\u002F\u002F app.js\nimport { add } from '.\u002FmathUtils.js';\nconsole.log(add(2, 3));\n",[39,81966,81967,81972,81998,82025,82029,82034,82048],{"__ignoreMap":264},[268,81968,81969],{"class":270,"line":271},[268,81970,81971],{"class":29390},"\u002F\u002F mathUtils.js\n",[268,81973,81974,81976,81978,81980,81982,81984,81986,81988,81990,81992,81994,81996],{"class":270,"line":286},[268,81975,665],{"class":274},[268,81977,12080],{"class":274},[268,81979,1217],{"class":278},[268,81981,622],{"class":282},[268,81983,1223],{"class":1222},[268,81985,42],{"class":282},[268,81987,1232],{"class":1222},[268,81989,29387],{"class":282},[268,81991,9151],{"class":274},[268,81993,1243],{"class":282},[268,81995,1246],{"class":274},[268,81997,46420],{"class":282},[268,81999,82000,82002,82004,82007,82009,82011,82013,82015,82017,82019,82021,82023],{"class":270,"line":296},[268,82001,665],{"class":274},[268,82003,12080],{"class":274},[268,82005,82006],{"class":278}," multiply",[268,82008,622],{"class":282},[268,82010,1223],{"class":1222},[268,82012,42],{"class":282},[268,82014,1232],{"class":1222},[268,82016,29387],{"class":282},[268,82018,9151],{"class":274},[268,82020,1243],{"class":282},[268,82022,6134],{"class":274},[268,82024,46420],{"class":282},[268,82026,82027],{"class":270,"line":311},[268,82028,5033],{"emptyLinePlaceholder":35},[268,82030,82031],{"class":270,"line":788},[268,82032,82033],{"class":29390},"\u002F\u002F app.js\n",[268,82035,82036,82038,82041,82043,82046],{"class":270,"line":1951},[268,82037,662],{"class":274},[268,82039,82040],{"class":282}," { add } ",[268,82042,44539],{"class":274},[268,82044,82045],{"class":289}," '.\u002FmathUtils.js'",[268,82047,293],{"class":282},[268,82049,82050,82052,82054,82056,82058,82060,82062,82064,82066],{"class":270,"line":8955},[268,82051,1353],{"class":282},[268,82053,1356],{"class":278},[268,82055,622],{"class":282},[268,82057,41889],{"class":278},[268,82059,622],{"class":282},[268,82061,2258],{"class":305},[268,82063,42],{"class":282},[268,82065,3423],{"class":305},[268,82067,4818],{"class":282},[23,82069,82071,82083,82089,82095],{"className":82070},[26],[28,82072,82074,82076,82077,82079,82080,82082],{"className":82073},[31],[33,82075],{"disabled":35,"type":36}," Because ESM import\u002Fexport bindings are static and analyzable at build time, so the bundler can prove ",[39,82078,81949],{}," is never referenced anywhere in the graph; ",[39,82081,714],{}," is an ordinary function call that can execute conditionally or dynamically, so the bundler can't prove a given export is unused",[28,82084,82086,82088],{"className":82085},[31],[33,82087],{"disabled":35,"type":36}," Because ESM files are always smaller in byte size than CommonJS files",[28,82090,82092,82094],{"className":82091},[31],[33,82093],{"disabled":35,"type":36}," Because CommonJS modules cannot be included in a bundle at all",[28,82096,82098,82100],{"className":82097},[31],[33,82099],{"disabled":35,"type":36}," Because tree-shaking only works when the project also uses TypeScript",[66,82102,82103,82105,82114],{},[69,82104,71],{},[73,82106,82107,82109,82110,82079,82112,82082],{},[76,82108,78],{}," A — Because ESM import\u002Fexport bindings are static and analyzable at build time, so the bundler can prove ",[39,82111,81949],{},[39,82113,714],{},[73,82115,82116,44322,82118,446,82120,82122,82123,186,82125,82127],{},[76,82117,84],{},[39,82119,662],{},[39,82121,665],{}," statements must appear at the top level with a fixed, literal set of names, so a bundler can build a complete, static picture of what's exported and what's actually imported and used — anything unreferenced is provably dead code. CommonJS's ",[39,82124,714],{},[39,82126,658],{}," are just regular JavaScript values and function calls; they can be wrapped in conditionals, computed with variables, or reassigned at runtime, so a bundler generally cannot prove a given property will never be accessed and must keep the whole module. This is the core mechanical reason \"tree-shaking needs ESM\" — it's not a licensing or file-size issue (options B, C are false), and it has nothing to do with TypeScript (option D).",[15,82129,82130,82141,82177,82208],{"language":1751},[18,82131,82133,82134,82137,82138,82140],{"id":82132},"q3-what-does-setting-sideeffects-false-in-a-librarys-packagejson-tell-a-bundler-like-webpack-and-what-risk-does-it-introduce-if-the-claim-is-wrong","Q3. What does setting ",[39,82135,82136],{},"\"sideEffects\": false"," in a library's ",[39,82139,737],{}," tell a bundler like webpack, and what risk does it introduce if the claim is wrong?",[257,82142,82143],{"language":1751},[260,82144,82146],{"className":1767,"code":82145,"language":1751,"meta":264,"style":264},"{\n  \"name\": \"date-utils\",\n  \"sideEffects\": false\n}\n",[39,82147,82148,82152,82163,82173],{"__ignoreMap":264},[268,82149,82150],{"class":270,"line":271},[268,82151,1775],{"class":282},[268,82153,82154,82156,82158,82161],{"class":270,"line":286},[268,82155,1780],{"class":305},[268,82157,1783],{"class":282},[268,82159,82160],{"class":289},"\"date-utils\"",[268,82162,1789],{"class":282},[268,82164,82165,82168,82170],{"class":270,"line":296},[268,82166,82167],{"class":305},"  \"sideEffects\"",[268,82169,1783],{"class":282},[268,82171,82172],{"class":305},"false\n",[268,82174,82175],{"class":270,"line":311},[268,82176,314],{"class":282},[23,82178,82180,82186,82192,82202],{"className":82179},[26],[28,82181,82183,82185],{"className":82182},[31],[33,82184],{"disabled":35,"type":36}," It disables minification for that specific package during the build",[28,82187,82189,82191],{"className":82188},[31],[33,82190],{"disabled":35,"type":36}," It forces the bundler to always include the entire package in the output, regardless of whether it's used",[28,82193,82195,82197,82198,82201],{"className":82194},[31],[33,82196],{"disabled":35,"type":36}," It tells the bundler that importing any module in this package triggers no meaningful top-level side effects, so unused exports (and even entire unused modules) can be safely dropped; if a module secretly does something at import time — e.g. ",[39,82199,82200],{},"window.foo = ..."," executed at the top level — the bundler may strip it out anyway, silently breaking behavior that depended on it running",[28,82203,82205,82207],{"className":82204},[31],[33,82206],{"disabled":35,"type":36}," It tells npm to skip running the package's install scripts",[66,82209,82210,82212,82219],{},[69,82211,71],{},[73,82213,82214,82216,82217,82201],{},[76,82215,78],{}," C — It tells the bundler that importing any module in this package triggers no meaningful top-level side effects, so unused exports (and even entire unused modules) can be safely dropped; if a module secretly does something at import time — e.g. ",[39,82218,82200],{},[73,82220,82221,82223,82224,82226],{},[76,82222,84],{}," By default, bundlers must conservatively assume any module might do something important just by being imported (register a polyfill, patch a global, run an analytics ping), so they keep it even if none of its exports are used. ",[39,82225,82136],{}," is the package author's explicit promise that no module in the package needs to run \"just for its side effects,\" which lets the bundler drop whole unused files, not just unused exports. It's a real footgun: if that promise is false for even one file, tree-shaking can delete code the app silently relied on. It has nothing to do with minification (A), it does the opposite of \"always include everything\" (B), and it's unrelated to npm lifecycle scripts (D).",[15,82228,82229,82233,82260],{"language":247},[18,82230,82232],{"id":82231},"q4-what-problem-do-source-maps-solve-when-debugging-a-production-javascript-app-in-the-browsers-devtools","Q4. What problem do source maps solve when debugging a production JavaScript app in the browser's devtools?",[23,82234,82236,82242,82248,82254],{"className":82235},[26],[28,82237,82239,82241],{"className":82238},[31],[33,82240],{"disabled":35,"type":36}," They speed up the browser's JavaScript engine execution at runtime",[28,82243,82245,82247],{"className":82244},[31],[33,82246],{"disabled":35,"type":36}," They map positions in the minified\u002Ftranspiled output back to the corresponding location in the original source, so devtools can display original file names, line numbers, and variable names instead of one unreadable minified line",[28,82249,82251,82253],{"className":82250},[31],[33,82252],{"disabled":35,"type":36}," They automatically fix runtime errors before they can occur",[28,82255,82257,82259],{"className":82256},[31],[33,82258],{"disabled":35,"type":36}," They replace the need for a transpilation step entirely",[66,82261,82262,82264,82269],{},[69,82263,71],{},[73,82265,82266,82268],{},[76,82267,78],{}," B — They map positions in the minified\u002Ftranspiled output back to the corresponding location in the original source, so devtools can display original file names, line numbers, and variable names instead of one unreadable minified line",[73,82270,82271,812,82273,82275],{},[76,82272,84],{},[39,82274,39625],{}," file (or an inline base64 data-URI version of it) encodes a position-by-position mapping between the shipped output and the original authored source. When an error is thrown or a breakpoint is set in the minified bundle, devtools consult the source map to show you the original, human-readable source instead of a single 200KB line of renamed variables. It's purely a debugging aid — it has no effect on runtime speed (A), can't prevent errors from happening (C), and is unrelated to whether transpilation is needed (D).",[15,82277,82279,82286,82297,82300,82331],{"language":82278},"bash",[18,82280,82282,82283,82285],{"id":82281},"q5-a-production-bundle-ends-with-the-line-shown-below-and-the-corresponding-map-file-is-deployed-alongside-it-on-the-public-web-server","Q5. A production bundle ends with the line shown below, and the corresponding ",[39,82284,39625],{}," file is deployed alongside it on the public web server.",[257,82287,82288],{"language":247},[260,82289,82291],{"className":262,"code":82290,"language":247,"meta":264,"style":264},"\u002F\u002F# sourceMappingURL=app.min.js.map\n",[39,82292,82293],{"__ignoreMap":264},[268,82294,82295],{"class":270,"line":271},[268,82296,82290],{"class":29390},[73,82298,82299],{},"What is the practical risk of doing this on a public-facing deployment?",[23,82301,82303,82309,82315,82321],{"className":82302},[26],[28,82304,82306,82308],{"className":82305},[31],[33,82307],{"disabled":35,"type":36}," There is no risk — browsers silently ignore this comment outside of development mode",[28,82310,82312,82314],{"className":82311},[31],[33,82313],{"disabled":35,"type":36}," It causes the bundled JavaScript to execute twice on page load",[28,82316,82318,82320],{"className":82317},[31],[33,82319],{"disabled":35,"type":36}," It prevents Hot Module Replacement from working correctly in the next local development session",[28,82322,82324,82326,82327,82330],{"className":82323},[31],[33,82325],{"disabled":35,"type":36}," Anyone can open devtools, let it fetch ",[39,82328,82329],{},"app.min.js.map",", and reconstruct the full original, unminified source — including original file structure and variable names — because the map file embeds the complete original source content; teams that want minification's obfuscation benefit typically exclude source maps from public deploys, or upload them privately to an error-tracking service instead",[66,82332,82333,82335,82342],{},[69,82334,71],{},[73,82336,82337,82339,82340,82330],{},[76,82338,78],{}," D — Anyone can open devtools, let it fetch ",[39,82341,82329],{},[73,82343,82344,355,82346,8828,82348,82351,82352,82355,82356,82358,82359,82361,82362,82365],{},[76,82345,84],{},[76,82347,16523],{},[76,82349,82350],{},"Security"," — A source map's whole job is to reverse minification, so if it's publicly reachable it fully defeats any obfuscation minification provided: the ",[39,82353,82354],{},"sourcesContent"," field literally embeds the original file text. This comment is ",[104,82357,95],{}," ignored outside dev (option A is false) — any browser's devtools will follow it whenever devtools are open, in any environment. It has no effect on double execution (B) or on a ",[104,82360,69627],{}," dev session's HMR (C); those are unrelated mechanisms. The common production pattern is to still generate source maps (for your own error-tracking pipeline, e.g. Sentry) but upload them out-of-band and keep them off the public server, or omit the ",[39,82363,82364],{},"sourceMappingURL"," comment from the publicly served file.",[15,82367,82368,82372,82402],{"language":247},[18,82369,82371],{"id":82370},"q6-a-teammate-says-we-dont-need-babel-anymore-since-we-already-have-webpack-in-the-build-whats-the-flaw-in-that-reasoning","Q6. A teammate says \"we don't need Babel anymore since we already have webpack in the build.\" What's the flaw in that reasoning?",[23,82373,82375,82384,82390,82396],{"className":82374},[26],[28,82376,82378,82380,82381,82383],{"className":82377},[31],[33,82379],{"disabled":35,"type":36}," Bundling (resolving and combining a module graph, enabling tree-shaking and code splitting) and transpiling (rewriting newer syntax like optional chaining or class fields into syntax older engines can parse) are different concerns; webpack orchestrates the build and can invoke Babel as a loader, but without Babel (or an equivalent transform) newer syntax passes through unchanged and will throw a ",[39,82382,1274],{}," in engines that don't support it",[28,82385,82387,82389],{"className":82386},[31],[33,82388],{"disabled":35,"type":36}," Nothing is wrong — webpack and Babel perform the exact same job, so either one alone is sufficient",[28,82391,82393,82395],{"className":82392},[31],[33,82394],{"disabled":35,"type":36}," Babel is only relevant for TypeScript projects, so it was never needed here regardless",[28,82397,82399,82401],{"className":82398},[31],[33,82400],{"disabled":35,"type":36}," webpack cannot process any JavaScript file at all without Babel installed",[66,82403,82404,82406,82413],{},[69,82405,71],{},[73,82407,82408,82410,82411,82383],{},[76,82409,78],{}," A — Bundling (resolving and combining a module graph, enabling tree-shaking and code splitting) and transpiling (rewriting newer syntax like optional chaining or class fields into syntax older engines can parse) are different concerns; webpack orchestrates the build and can invoke Babel as a loader, but without Babel (or an equivalent transform) newer syntax passes through unchanged and will throw a ",[39,82412,1274],{},[73,82414,82415,82417,82418,82421,82422,82425],{},[76,82416,84],{}," webpack's core job is graph resolution and output generation; it has no built-in opinion about JavaScript ",[104,82419,82420],{},"syntax"," compatibility on its own. Babel's job is purely syntactic: parse newer JS, emit an equivalent AST expressed in older-compatible syntax (plus polyfills for missing runtime features, via something like ",[39,82423,82424],{},"core-js","). Plenty of projects use webpack with zero syntax-lowering — perfectly fine if you only target evergreen browsers — but the moment you need to support an older runtime, dropping Babel means shipping syntax that engine can't parse, which fails at parse time, not gracefully. Options B, C, and D each conflate two genuinely separate tools with separate responsibilities.",[15,82427,82428,82432,82463,82466,82494,82497,82527],{"language":247},[18,82429,82431],{"id":82430},"q7-before-minification","Q7. Before minification:",[257,82433,82434],{"language":247},[260,82435,82437],{"className":262,"code":82436,"language":247,"meta":264,"style":264},"const greet = (name) => `Hello, ${name}!`;\n",[39,82438,82439],{"__ignoreMap":264},[268,82440,82441,82443,82445,82447,82449,82451,82453,82455,82457,82459,82461],{"class":270,"line":271},[268,82442,243],{"class":274},[268,82444,3679],{"class":278},[268,82446,616],{"class":274},[268,82448,2182],{"class":282},[268,82450,14605],{"class":1222},[268,82452,6131],{"class":282},[268,82454,9414],{"class":274},[268,82456,16223],{"class":289},[268,82458,14605],{"class":282},[268,82460,42920],{"class":289},[268,82462,293],{"class":282},[73,82464,82465],{},"After minification:",[257,82467,82468],{"language":247},[260,82469,82471],{"className":262,"code":82470,"language":247,"meta":264,"style":264},"const greet=n=>`Hello, ${n}!`;\n",[39,82472,82473],{"__ignoreMap":264},[268,82474,82475,82477,82479,82481,82483,82485,82488,82490,82492],{"class":270,"line":271},[268,82476,243],{"class":274},[268,82478,3679],{"class":278},[268,82480,302],{"class":274},[268,82482,4599],{"class":1222},[268,82484,9414],{"class":274},[268,82486,82487],{"class":289},"`Hello, ${",[268,82489,4599],{"class":282},[268,82491,42920],{"class":289},[268,82493,293],{"class":282},[73,82495,82496],{},"A developer assumed minifying this file would make it compatible with an ES5-only browser (which doesn't support arrow functions or template literals). Why is that assumption wrong?",[23,82498,82500,82506,82512,82521],{"className":82499},[26],[28,82501,82503,82505],{"className":82502},[31],[33,82504],{"disabled":35,"type":36}," Minifiers remove all modern syntax by definition, so this specific case must be a bug in the minifier",[28,82507,82509,82511],{"className":82508},[31],[33,82510],{"disabled":35,"type":36}," Minifiers and transpilers are simply two different marketing names for the same underlying tool",[28,82513,82515,82517,82518,82520],{"className":82514},[31],[33,82516],{"disabled":35,"type":36}," Minification only shrinks code — renaming variables, stripping whitespace and comments, and similar size-focused rewrites — without changing which language-version features the code uses; the arrow function and template literal survive untouched, so an ES5-only engine still throws a ",[39,82519,1274],{},". Only transpilation (e.g. via Babel) rewrites syntax down to an older-compatible form",[28,82522,82524,82526],{"className":82523},[31],[33,82525],{"disabled":35,"type":36}," The minified code is actually less compatible with any browser than the unminified original",[66,82528,82529,82531,82538],{},[69,82530,71],{},[73,82532,82533,82535,82536,82520],{},[76,82534,78],{}," C — Minification only shrinks code — renaming variables, stripping whitespace and comments, and similar size-focused rewrites — without changing which language-version features the code uses; the arrow function and template literal survive untouched, so an ES5-only engine still throws a ",[39,82537,1274],{},[73,82539,82540,355,82542,82544,82545,82547,82548,82551,82552,5425,82554,82556,82557,82559],{},[76,82541,84],{},[76,82543,17307],{}," — Notice the minified output still contains ",[39,82546,9414],{}," and a template-literal backtick — a minifier's job (tools like Terser) is purely about ",[104,82549,82550],{},"output size",", not language-version compatibility. It happily shortens ",[39,82553,14605],{},[39,82555,4599],{}," and drops whitespace, but it has no concept of \"rewrite this arrow function as a ",[39,82558,275],{}," expression for older engines\" — that's transpilation's job, a semantically different transform. Confusing the two is a real production trap: teams sometimes ship a minified-but-not-transpiled bundle assuming \"smaller\" implies \"more compatible,\" and it silently breaks on the exact old browsers they meant to support.",[15,82561,82562,82566,82593],{"language":247},[18,82563,82565],{"id":82564},"q8-what-does-hot-module-replacement-hmr-in-a-dev-server-like-vites-or-webpack-dev-servers-do-that-a-full-page-reload-on-save-does-not","Q8. What does Hot Module Replacement (HMR) in a dev server (like Vite's or webpack-dev-server's) do that a full page reload on save does not?",[23,82567,82569,82575,82581,82587],{"className":82568},[26],[28,82570,82572,82574],{"className":82571},[31],[33,82573],{"disabled":35,"type":36}," It permanently deploys the current change straight to production automatically",[28,82576,82578,82580],{"className":82577},[31],[33,82579],{"disabled":35,"type":36}," It swaps only the updated module(s) into the already-running application in the browser, preserving in-memory state — a form's typed-in text, a Redux store, an open modal's state — that a full page reload would otherwise wipe out",[28,82582,82584,82586],{"className":82583},[31],[33,82585],{"disabled":35,"type":36}," It compiles the app faster, but the browser still performs a full page reload on every save regardless",[28,82588,82590,82592],{"className":82589},[31],[33,82591],{"disabled":35,"type":36}," It works only for CSS files and has no effect on JavaScript module updates",[66,82594,82595,82597,82602],{},[69,82596,71],{},[73,82598,82599,82601],{},[76,82600,78],{}," B — It swaps only the updated module(s) into the already-running application in the browser, preserving in-memory state — a form's typed-in text, a Redux store, an open modal's state — that a full page reload would otherwise wipe out",[73,82603,82604,82606,82607,82610],{},[76,82605,84],{}," HMR relies on the dev server pushing just the changed module's new code over a persistent connection (typically a WebSocket), and a small runtime in the page replaces that module in place, re-running only what's needed to apply the update, without tearing down the whole JS execution context. That's precisely why it's valuable during development of stateful UI: you can tweak a component's rendering logic and see the change instantly without losing whatever state you'd navigated into. Option A confuses a dev-only mechanism with deployment. Option C describes what a fast ",[104,82608,82609],{},"full reload"," setup does, which is a different (and less state-preserving) feature. Option D is wrong — HMR is commonly used for JS component updates too, not just CSS.",[15,82612,82613,82627,82663,82675,82730],{"language":1751},[18,82614,82616,82617,82619,82620,82622,82623,82626],{"id":82615},"q9-two-developers-run-npm-install-on-different-days-using-only-the-packagejson-snippet-below-with-no-package-lockjson-present-or-committed-to-the-repository","Q9. Two developers run ",[39,82618,1965],{}," on different days, using only the ",[39,82621,737],{}," snippet below — with no ",[39,82624,82625],{},"package-lock.json"," present or committed to the repository.",[257,82628,82629],{"language":1751},[260,82630,82632],{"className":1767,"code":82631,"language":1751,"meta":264,"style":264},"{\n  \"dependencies\": {\n    \"left-pad\": \"^1.3.0\"\n  }\n}\n",[39,82633,82634,82638,82645,82655,82659],{"__ignoreMap":264},[268,82635,82636],{"class":270,"line":271},[268,82637,1775],{"class":282},[268,82639,82640,82643],{"class":270,"line":286},[268,82641,82642],{"class":305},"  \"dependencies\"",[268,82644,1933],{"class":282},[268,82646,82647,82650,82652],{"class":270,"line":296},[268,82648,82649],{"class":305},"    \"left-pad\"",[268,82651,1783],{"class":282},[268,82653,82654],{"class":289},"\"^1.3.0\"\n",[268,82656,82657],{"class":270,"line":311},[268,82658,1948],{"class":282},[268,82660,82661],{"class":270,"line":788},[268,82662,314],{"class":282},[73,82664,82665,82666,42,82668,383,82671,82674],{},"Why might they end up with different actual installed versions, and what does committing a lockfile (",[39,82667,82625],{},[39,82669,82670],{},"yarn.lock",[39,82672,82673],{},"pnpm-lock.yaml",") fix?",[23,82676,82678,82686,82700,82709],{"className":82677},[26],[28,82679,82681,355,82683,82685],{"className":82680},[31],[33,82682],{"disabled":35,"type":36},[39,82684,1965],{}," always installs the exact same version regardless of lockfiles, so this scenario is impossible",[28,82687,82689,82691,82692,82695,82696,82699],{"className":82688},[31],[33,82690],{"disabled":35,"type":36}," Lockfiles only pin versions for ",[39,82693,82694],{},"devDependencies",", never for regular ",[39,82697,82698],{},"dependencies",", so this scenario would happen with or without one",[28,82701,82703,4396,82705,82708],{"className":82702},[31],[33,82704],{"disabled":35,"type":36},[39,82706,82707],{},"^"," symbol actually means \"exact version only,\" so both installs are already guaranteed to be identical without any lockfile",[28,82710,82712,355,82714,82717,82718,82721,82722,82725,82726,82729],{"className":82711},[31],[33,82713],{"disabled":35,"type":36},[39,82715,82716],{},"^1.3.0"," permits any ",[39,82719,82720],{},"1.x.x"," release equal to or newer than ",[39,82723,82724],{},"1.3.0"," (excluding ",[39,82727,82728],{},"2.0.0","), so a new compatible version published between the two install dates — or a transitive dependency resolving its own range differently — can produce a different dependency tree on each machine; a committed lockfile pins the exact resolved version (and the full transitive tree) so every install reproduces identical versions",[66,82731,82732,82734,82746],{},[69,82733,71],{},[73,82735,82736,6901,82738,82717,82740,82721,82742,82725,82744,82729],{},[76,82737,78],{},[39,82739,82716],{},[39,82741,82720],{},[39,82743,82724],{},[39,82745,82728],{},[73,82747,82748,355,82750,82752,82753,82756,82757,82759,82760,82763,82764,82766,82767,82770],{},[76,82749,84],{},[39,82751,737],{}," alone only expresses ",[104,82754,82755],{},"acceptable ranges",", not exact versions — that's true by design, so authors can receive compatible patches automatically. The reproducibility problem is that \"acceptable range\" can resolve to a different concrete version depending on ",[104,82758,81032],{}," you install and what else is in the dependency tree at that moment, including nested (transitive) dependencies with their own ranges. A lockfile freezes the entire resolved tree — exact versions and their exact sub-dependencies — so ",[39,82761,82762],{},"npm ci"," (or the equivalent) on any machine, at any later date, installs byte-for-byte the same tree. Option A is simply false in the absence of a lockfile; option B misdescribes lockfile scope (they cover all dependency types); option C misstates what ",[39,82765,82707],{}," means (it is a ",[104,82768,82769],{},"range",", not an exact pin).",[15,82772,82773,82785,82829],{"language":247},[18,82774,82776,82777,82780,82781,82784],{"id":82775},"q10-a-library-bumps-its-published-version-from-241-straight-to-300-with-no-other-announcement-under-semantic-versioning-semver-conventions-what-should-consumers-assume","Q10. A library bumps its published version from ",[39,82778,82779],{},"2.4.1"," straight to ",[39,82782,82783],{},"3.0.0",", with no other announcement. Under semantic versioning (semver) conventions, what should consumers assume?",[23,82786,82788,82811,82817,82823],{"className":82787},[26],[28,82789,82791,82793,82794,82797,82798,82800,82801,4977,82803,82806,82807,82810],{"className":82790},[31],[33,82792],{"disabled":35,"type":36}," The release contains a backwards-incompatible (\"breaking\") change to the public API — code that worked against ",[39,82795,82796],{},"2.x"," may need modification to work against ",[39,82799,82783],{},"; by contrast, a ",[39,82802,82779],{},[39,82804,82805],{},"2.5.0"," bump would promise new backwards-compatible features, and → ",[39,82808,82809],{},"2.4.2"," would promise only backwards-compatible bug fixes",[28,82812,82814,82816],{"className":82813},[31],[33,82815],{"disabled":35,"type":36}," Nothing meaningfully changed except bug fixes, so it's safe to upgrade blindly",[28,82818,82820,82822],{"className":82819},[31],[33,82821],{"disabled":35,"type":36}," The major version number is purely cosmetic marketing and carries no contractual meaning under semver",[28,82824,82826,82828],{"className":82825},[31],[33,82827],{"disabled":35,"type":36}," It means the package now requires a completely different JavaScript runtime, such as switching from Node.js to Deno",[66,82830,82831,82833,82848],{},[69,82832,71],{},[73,82834,82835,82837,82838,82797,82840,82800,82842,4977,82844,82806,82846,82810],{},[76,82836,78],{}," A — The release contains a backwards-incompatible (\"breaking\") change to the public API — code that worked against ",[39,82839,82796],{},[39,82841,82783],{},[39,82843,82779],{},[39,82845,82805],{},[39,82847,82809],{},[73,82849,82850,82852,82853,82856,82857,82859,82860,4977,82862,82864,82865,82867],{},[76,82851,84],{}," Semver's ",[39,82854,82855],{},"MAJOR.MINOR.PATCH"," scheme is a contract: PATCH bumps promise backwards-compatible bug fixes only, MINOR bumps promise backwards-compatible new functionality, and MAJOR bumps are the ",[104,82858,3117],{}," place a breaking change is allowed to happen under the convention — so a ",[39,82861,82796],{},[39,82863,82783],{}," jump is the explicit signal to consult a changelog\u002Fmigration guide before upgrading, not to upgrade blindly (ruling out option B). The version number is meaningful, not cosmetic (ruling out C), and a major bump says nothing by itself about runtime requirements (ruling out D) — that would be called out separately, e.g. in an ",[39,82866,2013],{}," field.",[15,82869,82870,82881,82944,82984],{"language":247},[18,82871,82873,82874,82876,82877,82880],{"id":82872},"q11-what-does-a-bundler-typically-do-with-the-dynamic-import-call-below-that-it-would-not-do-with-a-static-import-openmodal-from-modaljs-placed-at-the-top-of-the-file","Q11. What does a bundler typically do with the dynamic ",[39,82875,46068],{}," call below that it would not do with a static ",[39,82878,82879],{},"import { openModal } from '.\u002Fmodal.js'"," placed at the top of the file?",[257,82882,82883],{"language":247},[260,82884,82886],{"className":262,"code":82885,"language":247,"meta":264,"style":264},"button.addEventListener('click', async () => {\n  const { openModal } = await import('.\u002Fmodal.js');\n  openModal();\n});\n",[39,82887,82888,82908,82933,82940],{"__ignoreMap":264},[268,82889,82890,82892,82894,82896,82898,82900,82902,82904,82906],{"class":270,"line":271},[268,82891,35734],{"class":282},[268,82893,35737],{"class":278},[268,82895,622],{"class":282},[268,82897,35742],{"class":289},[268,82899,42],{"class":282},[268,82901,379],{"class":274},[268,82903,15158],{"class":282},[268,82905,9414],{"class":274},[268,82907,9914],{"class":282},[268,82909,82910,82912,82914,82917,82919,82921,82923,82926,82928,82931],{"class":270,"line":286},[268,82911,12441],{"class":274},[268,82913,20200],{"class":282},[268,82915,82916],{"class":305},"openModal",[268,82918,7908],{"class":282},[268,82920,302],{"class":274},[268,82922,52502],{"class":274},[268,82924,82925],{"class":274}," import",[268,82927,622],{"class":282},[268,82929,82930],{"class":289},"'.\u002Fmodal.js'",[268,82932,628],{"class":282},[268,82934,82935,82938],{"class":270,"line":296},[268,82936,82937],{"class":278},"  openModal",[268,82939,794],{"class":282},[268,82941,82942],{"class":270,"line":311},[268,82943,20047],{"class":282},[23,82945,82947,82957,82966,82975],{"className":82946},[26],[28,82948,82950,82952,82953,82956],{"className":82949},[31],[33,82951],{"disabled":35,"type":36}," It ignores the dynamic import entirely and bundles ",[39,82954,82955],{},"modal.js"," into the main bundle exactly as if it had been statically imported",[28,82958,82960,82962,82963,82965],{"className":82959},[31],[33,82961],{"disabled":35,"type":36}," It runs the code inside ",[39,82964,82955],{}," on a separate operating-system thread automatically",[28,82967,82969,82971,82972,82974],{"className":82968},[31],[33,82970],{"disabled":35,"type":36}," It extracts ",[39,82973,82955],{}," (and its own dependencies) into a separate chunk file that's only fetched over the network when the click handler actually executes, instead of being downloaded as part of the initial page load — shrinking the initial bundle",[28,82976,82978,82980,82981,82983],{"className":82977},[31],[33,82979],{"disabled":35,"type":36}," It silently converts every export inside ",[39,82982,82955],{}," from ESM syntax into CommonJS syntax",[66,82985,82986,82988,82995],{},[69,82987,71],{},[73,82989,82990,82992,82993,82974],{},[76,82991,78],{}," C — It extracts ",[39,82994,82955],{},[73,82996,82997,82999,83000,83002],{},[76,82998,84],{}," A dynamic ",[39,83001,46068],{}," call returns a promise and is a recognized signal to essentially every modern bundler that the target module and its subgraph should become their own on-demand chunk, fetched lazily at runtime rather than being force-included in the entry bundle. This is the mechanism behind route-based and feature-based code splitting — code the user might never trigger (like a rarely opened modal) never has to be downloaded until it's needed. It doesn't run on a separate thread (B is a misconception conflating this with Web Workers), it's not ignored (A is simply the opposite of what code splitting is for), and it doesn't force a module-format conversion (D) — the output format is a build configuration choice, unrelated to whether the import is static or dynamic.",[15,83004,83005,83009,83043],{"language":247},[18,83006,83008],{"id":83007},"q12-a-teams-ci-pipeline-runs-both-eslint-and-prettier-a-developer-asks-isnt-that-redundant-dont-they-both-just-check-code-style-whats-the-accurate-distinction","Q12. A team's CI pipeline runs both ESLint and Prettier. A developer asks: \"isn't that redundant — don't they both just check code style?\" What's the accurate distinction?",[23,83010,83012,83018,83031,83037],{"className":83011},[26],[28,83013,83015,83017],{"className":83014},[31],[33,83016],{"disabled":35,"type":36}," Prettier is the one that catches actual bugs, while ESLint only reformats whitespace",[28,83019,83021,83023,83024,83026,83027,83030],{"className":83020},[31],[33,83022],{"disabled":35,"type":36}," ESLint performs static analysis to catch potential bugs and enforce code-quality rules (e.g. unused variables, unreachable code, misuse of ",[39,83025,3197],{},"), while Prettier is purely an opinionated code formatter that rewrites whitespace, quote style, and line breaks without understanding code semantics; they're complementary tools, and teams commonly disable ESLint's own formatting-related rules (e.g. via ",[39,83028,83029],{},"eslint-config-prettier",") so the two don't fight over the same lines",[28,83032,83034,83036],{"className":83033},[31],[33,83035],{"disabled":35,"type":36}," Yes, it's redundant — either tool alone already provides everything the other one does",[28,83038,83040,83042],{"className":83039},[31],[33,83041],{"disabled":35,"type":36}," Only one of the two tools is actually allowed to run inside a CI pipeline at a time",[66,83044,83045,83047,83056],{},[69,83046,71],{},[73,83048,83049,83051,83052,83026,83054,83030],{},[76,83050,78],{}," B — ESLint performs static analysis to catch potential bugs and enforce code-quality rules (e.g. unused variables, unreachable code, misuse of ",[39,83053,3197],{},[39,83055,83029],{},[73,83057,83058,355,83060,83062,83063,83066,83067,83069,83070,83073,83074,83076],{},[76,83059,84],{},[76,83061,17307],{}," — ESLint parses code into an AST and applies rules that reason about ",[104,83064,83065],{},"meaning"," — \"this variable is never read,\" \"this promise is never awaited,\" \"this ",[39,83068,8884],{}," case falls through unintentionally\" — the kind of issue that can indicate an actual bug. Prettier has no opinion on any of that; it only reprints code in a single canonical style so diffs and reviews aren't cluttered by formatting bikeshedding. Running both isn't redundant, it's standard practice — but running ESLint's ",[104,83071,83072],{},"formatting"," rules alongside Prettier's formatting ",[104,83075,13519],{}," be redundant (and can conflict), which is why teams disable that overlapping subset specifically.",[15,83078,83079,83083,83110],{"language":247},[18,83080,83082],{"id":83081},"q13-a-teams-ci-pipeline-for-a-js-project-runs-in-order-install-dependencies-lint-unit-tests-build-a-new-hire-asks-why-the-build-step-often-the-slowest-runs-last-instead-of-first-whats-the-reasoning","Q13. A team's CI pipeline for a JS project runs, in order: install dependencies → lint → unit tests → build. A new hire asks why the build step — often the slowest — runs last instead of first. What's the reasoning?",[23,83084,83086,83092,83098,83104],{"className":83085},[26],[28,83087,83089,83091],{"className":83088},[31],[33,83090],{"disabled":35,"type":36}," The build must run last because bundlers are only able to process code that has already passed its unit tests",[28,83093,83095,83097],{"className":83094},[31],[33,83096],{"disabled":35,"type":36}," Lint and test are required to run after the build because they need the already-compiled output to work against",[28,83099,83101,83103],{"className":83100},[31],[33,83102],{"disabled":35,"type":36}," The step order is arbitrary and has no measurable effect on how quickly the pipeline reports a failure",[28,83105,83107,83109],{"className":83106},[31],[33,83108],{"disabled":35,"type":36}," Running the fastest, cheapest checks first — lint typically finishes in seconds — means the pipeline fails fast on trivial issues before spending time on slower steps; if lint fails, there's no reason to wait through a multi-minute build (or a slower test suite) just to discover a problem that a quick static check already caught",[66,83111,83112,83114,83119],{},[69,83113,71],{},[73,83115,83116,83118],{},[76,83117,78],{}," D — Running the fastest, cheapest checks first — lint typically finishes in seconds — means the pipeline fails fast on trivial issues before spending time on slower steps; if lint fails, there's no reason to wait through a multi-minute build (or a slower test suite) just to discover a problem that a quick static check already caught",[73,83120,83121,83123,83124,83126],{},[76,83122,84],{}," CI ordering is usually optimized for \"fail fast\": cheap, high-signal checks run first so a broken commit is rejected in seconds rather than after minutes of unnecessary work. Lint is typically the fastest (pure static analysis, no execution), tests are next (they execute code but are usually scoped and parallelizable), and a full production build is often the slowest step because it involves bundling, minification, and sometimes type-checking a whole project. Neither lint nor tests structurally depend on build output in a typical JS setup (ruling out B), and the build doesn't require passing tests to ",[104,83125,13701],{}," — teams just choose not to waste time building a commit that's already known to be broken (ruling out A). Ordering absolutely affects feedback latency, so C is false too.",[15,83128,83129,83137,83165,83168,83205],{"language":247},[18,83130,83132,83133,83136],{"id":83131},"q14-a-frontend-team-changes-the-vite_api_url-environment-variable-on-their-server-after-already-deploying-a-built-vite-app-expecting-the-running-app-to-pick-up-the-new-url-on-the-next-page-load-without-a-rebuild","Q14. A frontend team changes the ",[39,83134,83135],{},"VITE_API_URL"," environment variable on their server after already deploying a built Vite app, expecting the running app to pick up the new URL on the next page load without a rebuild.",[257,83138,83139],{"language":247},[260,83140,83142],{"className":262,"code":83141,"language":247,"meta":264,"style":264},"console.log(import.meta.env.VITE_API_URL);\n",[39,83143,83144],{"__ignoreMap":264},[268,83145,83146,83148,83150,83152,83154,83156,83158,83161,83163],{"class":270,"line":271},[268,83147,1353],{"class":282},[268,83149,1356],{"class":278},[268,83151,622],{"class":282},[268,83153,662],{"class":274},[268,83155,462],{"class":282},[268,83157,20320],{"class":305},[268,83159,83160],{"class":282},".env.",[268,83162,83135],{"class":305},[268,83164,628],{"class":282},[73,83166,83167],{},"Why doesn't this work?",[23,83169,83171,83184,83190,83199],{"className":83170},[26],[28,83172,83174,355,83176,83179,83180,83183],{"className":83173},[31],[33,83175],{"disabled":35,"type":36},[39,83177,83178],{},"import.meta.env.VITE_API_URL"," is resolved at build time — Vite statically replaces that expression with the literal value present in the environment when ",[39,83181,83182],{},"vite build"," ran, baking it directly into the generated static JS files; there's no runtime process left in the browser to re-read a server environment variable, so the already-deployed static files must be rebuilt (and redeployed) for a new value to take effect",[28,83185,83187,83189],{"className":83186},[31],[33,83188],{"disabled":35,"type":36}," Environment variables are always read live from the server on every page load in any frontend framework, so this should already be working",[28,83191,83193,355,83195,83198],{"className":83192},[31],[33,83194],{"disabled":35,"type":36},[39,83196,83197],{},"import.meta.env"," never reads from environment variables at all — it only reads from a static config file that has nothing to do with the server environment",[28,83200,83202,83204],{"className":83201},[31],[33,83203],{"disabled":35,"type":36}," The value only updates the next time the browser itself is restarted, but otherwise updates automatically on every request",[66,83206,83207,83209,83217],{},[69,83208,71],{},[73,83210,83211,3459,83213,83179,83215,83183],{},[76,83212,78],{},[39,83214,83178],{},[39,83216,83182],{},[73,83218,83219,355,83221,83223,83224,83227,83228,83230,83231,83234],{},[76,83220,84],{},[76,83222,16523],{}," — This is a common point of confusion carried over from backend habits, where ",[39,83225,83226],{},"process.env.X"," really is read live at runtime by a running Node process. In a bundled frontend app, ",[39,83229,83178],{}," (or Create React App's ",[39,83232,83233],{},"process.env.REACT_APP_X",") is a compile-time substitution: the bundler literally replaces that expression with a hardcoded string in the emitted JS during the build step, because there is no server-side process running in the user's browser to consult a live environment variable. Changing the server's env var after the fact changes nothing about files that were already generated and shipped — a fresh build is required. Options B, C, and D each describe behavior that doesn't apply to a statically bundled frontend.",[15,83236,83237,83241,83272],{"language":247},[18,83238,83240],{"id":83239},"q15-a-developer-replaces-a-large-date-handling-library-with-a-smaller-alternative-expecting-the-production-bundle-to-shrink-as-a-result-but-never-actually-checks-whats-the-best-practice-next-step-before-assuming-the-optimization-worked","Q15. A developer replaces a large date-handling library with a smaller alternative, expecting the production bundle to shrink as a result — but never actually checks. What's the best-practice next step before assuming the optimization worked?",[23,83242,83244,83250,83256,83266],{"className":83243},[26],[28,83245,83247,83249],{"className":83246},[31],[33,83248],{"disabled":35,"type":36}," Trust the change without verification, since swapping to a \"smaller\" library logically implies a smaller bundle",[28,83251,83253,83255],{"className":83252},[31],[33,83254],{"disabled":35,"type":36}," Only check the bundle size in a staging environment, and never verify it locally during development",[28,83257,83259,83261,83262,83265],{"className":83258},[31],[33,83260],{"disabled":35,"type":36}," Inspect the actual build output — e.g. with a bundle analyzer (webpack-bundle-analyzer, or Vite's ",[39,83263,83264],{},"rollup-plugin-visualizer",") or by diffing the output file sizes before and after — since the real bundle size depends on how well the bundler tree-shakes both libraries, whether other code still imports the old library transitively, and whether duplicate copies get pulled in through other dependencies; assumptions about size are frequently wrong until actually measured",[28,83267,83269,83271],{"className":83268},[31],[33,83270],{"disabled":35,"type":36}," Assume bundle size no longer matters at all once gzip or Brotli compression is applied by the server",[66,83273,83274,83276,83283],{},[69,83275,71],{},[73,83277,83278,83280,83281,83265],{},[76,83279,78],{}," C — Inspect the actual build output — e.g. with a bundle analyzer (webpack-bundle-analyzer, or Vite's ",[39,83282,83264],{},[73,83284,83285,355,83287,83289],{},[76,83286,84],{},[76,83288,55328],{}," — Swapping libraries feels like an obvious win, but the actual result depends on build-tool behavior you can't fully predict from source code alone: maybe another dependency still transitively pulls in the old library (so it never actually left the bundle), maybe the \"smaller\" library tree-shakes worse in practice, or maybe a duplicate version sneaks in through a nested dependency's own lockfile. A bundle analyzer visualizes exactly what ended up in the output and how large each module actually is, turning an assumption into a measurement. Compression (option D) reduces bytes over the wire but doesn't change parse\u002Fexecution cost, so it doesn't make bundle size irrelevant, and skipping local checks (option B) just delays discovering a mistake.",[15,83291,83292,83318,83379,83427],{"language":247},[18,83293,56897,83295,45131,83298,83301,83302,83305,83306,83309,83310,34860,83312,83314,83315,83317],{"id":83294},"q16-appjs-imports-analyticsjs-purely-for-its-side-effect-and-never-calls-track-assuming-the-analytics-packages-packagejson-does-not-set-sideeffects-false-what-happens-during-tree-shaking",[39,83296,83297],{},"app.js",[39,83299,83300],{},"analytics.js"," purely for its side effect and never calls ",[39,83303,83304],{},"track",". Assuming the ",[39,83307,83308],{},"analytics"," package's ",[39,83311,737],{},[104,83313,95],{}," set ",[39,83316,82136],{},", what happens during tree-shaking?",[257,83319,83320],{"language":247},[260,83321,83323],{"className":262,"code":83322,"language":247,"meta":264,"style":264},"\u002F\u002F analytics.js\nconsole.log('Analytics module loaded');\nexport function track(event) { \u002F* ... *\u002F }\n\n\u002F\u002F app.js\nimport '.\u002Fanalytics.js';\n",[39,83324,83325,83330,83343,83362,83366,83370],{"__ignoreMap":264},[268,83326,83327],{"class":270,"line":271},[268,83328,83329],{"class":29390},"\u002F\u002F analytics.js\n",[268,83331,83332,83334,83336,83338,83341],{"class":270,"line":286},[268,83333,1353],{"class":282},[268,83335,1356],{"class":278},[268,83337,622],{"class":282},[268,83339,83340],{"class":289},"'Analytics module loaded'",[268,83342,628],{"class":282},[268,83344,83345,83347,83349,83352,83354,83356,83358,83360],{"class":270,"line":296},[268,83346,665],{"class":274},[268,83348,12080],{"class":274},[268,83350,83351],{"class":278}," track",[268,83353,622],{"class":282},[268,83355,65240],{"class":1222},[268,83357,29387],{"class":282},[268,83359,29391],{"class":29390},[268,83361,29394],{"class":282},[268,83363,83364],{"class":270,"line":311},[268,83365,5033],{"emptyLinePlaceholder":35},[268,83367,83368],{"class":270,"line":788},[268,83369,82033],{"class":29390},[268,83371,83372,83374,83377],{"class":270,"line":1951},[268,83373,662],{"class":274},[268,83375,83376],{"class":289}," '.\u002Fanalytics.js'",[268,83378,293],{"class":282},[23,83380,83382,83394,83409,83415],{"className":83381},[26],[28,83383,83385,83387,83388,83390,83391,83393],{"className":83384},[31],[33,83386],{"disabled":35,"type":36}," The bundler removes the entire ",[39,83389,83300],{}," module, since ",[39,83392,83304],{}," is never referenced anywhere",[28,83395,83397,83399,83400,83402,83403,83405,83406,83408],{"className":83396},[31],[33,83398],{"disabled":35,"type":36}," The bundler must keep the whole module — including the unused ",[39,83401,83304],{}," function — because it can't prove the top-level ",[39,83404,5627],{}," call is free of observable side effects, and running it is required for correctness; tree-shaking only removes code the bundler can prove is both unused ",[104,83407,31781],{}," side-effect-free to skip",[28,83410,83412,83414],{"className":83411},[31],[33,83413],{"disabled":35,"type":36}," The build fails with an error, because top-level side effects are disallowed in ES modules",[28,83416,83418,83420,83421,83423,83424,83426],{"className":83417},[31],[33,83419],{"disabled":35,"type":36}," Only the ",[39,83422,5627],{}," line is stripped from the output, while ",[39,83425,83304],{}," is kept regardless",[66,83428,83429,83431,83442],{},[69,83430,71],{},[73,83432,83433,83435,83436,83402,83438,83405,83440,83408],{},[76,83434,78],{}," B — The bundler must keep the whole module — including the unused ",[39,83437,83304],{},[39,83439,5627],{},[104,83441,31781],{},[73,83443,83444,355,83446,83448,83449,83452,83453,83456,83457,83459,83460,83462,83463,83465],{},[76,83445,84],{},[76,83447,16523],{}," — Tree-shaking's soundness guarantee requires proving a piece of code has ",[104,83450,83451],{},"no observable effect"," if removed. A statement like ",[39,83454,83455],{},"console.log(...)"," sitting directly at module scope executes the moment the module is evaluated, and removing it would change observable program behavior (the log line simply wouldn't appear) — so the bundler conservatively keeps the whole module, ",[39,83458,83304],{}," included, even though ",[39,83461,83304],{}," itself is never called. This is exactly the scenario ",[39,83464,82136],{}," (see Q3) exists to override: it lets the package author explicitly promise no module needs to run \"just for its side effects,\" unlocking the removal the bundler otherwise can't safely perform on its own. ES modules impose no such restriction (ruling out C), and bundlers don't selectively remove single statements from a kept module while leaving unrelated exports (ruling out D).",[15,83467,83468,83477,83517],{"language":247},[18,83469,83471,83472,19439,83474,83476],{"id":83470},"q17-a-project-ends-up-with-both-a-package-lockjson-and-a-pnpm-lockyaml-committed-after-a-teammate-ran-a-different-package-manager-locally-by-mistake-whats-the-practical-problem","Q17. A project ends up with both a ",[39,83473,82625],{},[39,83475,82673],{}," committed, after a teammate ran a different package manager locally by mistake. What's the practical problem?",[23,83478,83480,83491,83497,83503],{"className":83479},[26],[28,83481,83483,355,83485,83487,83488,83490],{"className":83482},[31],[33,83484],{"disabled":35,"type":36},[39,83486,82673],{}," always silently takes priority over ",[39,83489,82625],{},", in every package manager, so nothing actually breaks",[28,83492,83494,83496],{"className":83493},[31],[33,83495],{"disabled":35,"type":36}," Lockfiles are optional metadata that npm, yarn, and pnpm all ignore by default during install, so committing more than one changes nothing",[28,83498,83500,83502],{"className":83499},[31],[33,83501],{"disabled":35,"type":36}," No problem exists — every major package manager automatically merges and reconciles any lockfile format it finds",[28,83504,83506,83508,83509,83512,83513,83516],{"className":83505},[31],[33,83507],{"disabled":35,"type":36}," Each package manager reads and trusts only its own lockfile format, so mixing formats causes inconsistent dependency resolution between teammates and CI depending on which tool happens to run, defeating the reproducibility guarantee lockfiles exist to provide; teams typically enforce a single package manager (e.g. via a ",[39,83510,83511],{},"packageManager"," field or a CI check) and ",[39,83514,83515],{},".gitignore"," the rest",[66,83518,83519,83521,83530],{},[69,83520,71],{},[73,83522,83523,83525,83526,83512,83528,83516],{},[76,83524,78],{}," D — Each package manager reads and trusts only its own lockfile format, so mixing formats causes inconsistent dependency resolution between teammates and CI depending on which tool happens to run, defeating the reproducibility guarantee lockfiles exist to provide; teams typically enforce a single package manager (e.g. via a ",[39,83527,83511],{},[39,83529,83515],{},[73,83531,83532,83534,83535,83537,83538,83540,83541,83543,83544,83546,83547,83550],{},[76,83533,84],{}," npm only consults ",[39,83536,82625],{},", pnpm only consults ",[39,83539,82673],{},", and yarn only consults ",[39,83542,82670],{}," — none of them read or reconcile a rival tool's lockfile. If both files sit in the repo, whichever teammate (or CI job) happens to run ",[39,83545,1965],{}," gets npm's resolution, while whoever runs ",[39,83548,83549],{},"pnpm install"," gets pnpm's — potentially different dependency trees, entirely defeating the point of having a lockfile at all. There's no automatic merging or precedence between formats (ruling out A and C), and lockfiles are very much respected by default, not ignored (ruling out B) — that's the entire reason this mismatch causes a real problem instead of a harmless no-op.",[15,83552,83553,83557,83584],{"language":247},[18,83554,83556],{"id":83555},"q18-vite-uses-esbuild-to-pre-bundle-dependencies-and-serve-native-esm-during-development-but-switches-to-rollup-for-the-production-build-given-that-esbuild-is-dramatically-faster-than-rollup-why-not-just-use-esbuild-for-production-too","Q18. Vite uses esbuild to pre-bundle dependencies and serve native ESM during development, but switches to Rollup for the production build. Given that esbuild is dramatically faster than Rollup, why not just use esbuild for production too?",[23,83558,83560,83566,83572,83578],{"className":83559},[26],[28,83561,83563,83565],{"className":83562},[31],[33,83564],{"disabled":35,"type":36}," esbuild's plugin ecosystem and fine-grained output control (advanced code-splitting strategies, broader plugin compatibility, more mature tree-shaking edge-case handling) have historically lagged Rollup's, so Vite trades esbuild's raw speed for Rollup's more battle-tested, flexible production output; using native ESM plus esbuild's fast transforms in dev is fine there because dev-server responsiveness matters more than squeezing out the optimal final bundle shape",[28,83567,83569,83571],{"className":83568},[31],[33,83570],{"disabled":35,"type":36}," esbuild is a CSS-only tool and cannot process JavaScript at all",[28,83573,83575,83577],{"className":83574},[31],[33,83576],{"disabled":35,"type":36}," Rollup is required because esbuild is fundamentally incapable of running inside a Node.js process",[28,83579,83581,83583],{"className":83580},[31],[33,83582],{"disabled":35,"type":36}," The two tools always produce byte-for-byte identical output, so the choice between them is arbitrary either way",[66,83585,83586,83588,83593],{},[69,83587,71],{},[73,83589,83590,83592],{},[76,83591,78],{}," A — esbuild's plugin ecosystem and fine-grained output control (advanced code-splitting strategies, broader plugin compatibility, more mature tree-shaking edge-case handling) have historically lagged Rollup's, so Vite trades esbuild's raw speed for Rollup's more battle-tested, flexible production output; using native ESM plus esbuild's fast transforms in dev is fine there because dev-server responsiveness matters more than squeezing out the optimal final bundle shape",[73,83594,83595,355,83597,83599,83600,83602,83603,83605],{},[76,83596,84],{},[76,83598,17307],{}," — This is a genuine, deliberate design trade-off in Vite's architecture: development mode optimizes for near-instant server start and updates (esbuild transforms individual files on the fly, and the browser handles module resolution natively via ESM ",[39,83601,662],{},"), while a production build optimizes for the ",[104,83604,80219],{}," and correctness of the final shipped bundle, where Rollup's more mature plugin API and configurable output (chunking strategy, more thorough dead-code elimination in edge cases) matter more than raw build speed. esbuild absolutely processes JavaScript, not just CSS (ruling out B), and runs fine under Node (ruling out C) — Vite itself uses it there. The two tools do not produce identical output (ruling out D); if they did, there'd be no reason for Vite to use two different bundlers in the first place.",[15,83607,83608,83620,83650,83671,83717],{"language":247},[18,83609,83611,83612,83615,83616,83619],{"id":83610},"q19-importing-the-whole-lodash-package-published-as-commonjs-exposed-as-one-default-exported-object-typically-leaves-the-entire-library-in-the-production-bundle-while-importing-from-lodash-es-and-destructuring-lets-unused-functions-be-tree-shaken-away-why","Q19. Importing the whole ",[39,83613,83614],{},"lodash"," package (published as CommonJS, exposed as one default-exported object) typically leaves the entire library in the production bundle, while importing from ",[39,83617,83618],{},"lodash-es"," and destructuring lets unused functions be tree-shaken away. Why?",[257,83621,83622],{"language":247},[260,83623,83625],{"className":262,"code":83624,"language":247,"meta":264,"style":264},"import _ from 'lodash';\nconsole.log(_.debounce);\n",[39,83626,83627,83641],{"__ignoreMap":264},[268,83628,83629,83631,83634,83636,83639],{"class":270,"line":271},[268,83630,662],{"class":274},[268,83632,83633],{"class":282}," _ ",[268,83635,44539],{"class":274},[268,83637,83638],{"class":289}," 'lodash'",[268,83640,293],{"class":282},[268,83642,83643,83645,83647],{"class":270,"line":286},[268,83644,1353],{"class":282},[268,83646,1356],{"class":278},[268,83648,83649],{"class":282},"(_.debounce);\n",[257,83651,83652],{"language":247},[260,83653,83655],{"className":262,"code":83654,"language":247,"meta":264,"style":264},"import { debounce } from 'lodash-es';\n",[39,83656,83657],{"__ignoreMap":264},[268,83658,83659,83661,83664,83666,83669],{"class":270,"line":271},[268,83660,662],{"class":274},[268,83662,83663],{"class":282}," { debounce } ",[268,83665,44539],{"class":274},[268,83667,83668],{"class":289}," 'lodash-es'",[268,83670,293],{"class":282},[23,83672,83674,83684,83690,83711],{"className":83673},[26],[28,83675,83677,355,83679,83681,83682],{"className":83676},[31],[33,83678],{"disabled":35,"type":36},[39,83680,83618],{}," is simply a smaller library that ships fewer functions than ",[39,83683,83614],{},[28,83685,83687,83689],{"className":83686},[31],[33,83688],{"disabled":35,"type":36}," Bundlers cannot process CommonJS packages at all, so the first snippet would actually fail to build",[28,83691,83693,83695,83696,83699,83700,83703,83704,83706,83707,83710],{"className":83692},[31],[33,83694],{"disabled":35,"type":36}," CommonJS's ",[39,83697,83698],{},"module.exports = { ... }"," produces a single, dynamically-constructed export value that a bundler can't statically split apart, so ",[39,83701,83702],{},"import _ from 'lodash'"," pulls in that whole object as one indivisible unit; ",[39,83705,83618],{}," ships genuine ESM named exports per function, so the bundler's static analysis can see exactly which named export (",[39,83708,83709],{},"debounce",") is actually referenced and drop the rest",[28,83712,83714,83716],{"className":83713},[31],[33,83715],{"disabled":35,"type":36}," The difference only matters for local development builds and has no effect once a production build is generated",[66,83718,83719,83721,83734],{},[69,83720,71],{},[73,83722,83723,83725,83726,83699,83728,83703,83730,83706,83732,83710],{},[76,83724,78],{}," C — CommonJS's ",[39,83727,83698],{},[39,83729,83702],{},[39,83731,83618],{},[39,83733,83709],{},[73,83735,83736,355,83738,83740,83741,83743,83744,83747,83748,83750,83751,83753,83754,83757,83758,186,83760,83762],{},[76,83737,84],{},[76,83739,55328],{}," — This is the same underlying mechanism as Q2 and Q16, applied to a real-world library people actually hit in production. ",[39,83742,83614],{},"'s CommonJS build exports one big object literal at runtime — from the bundler's static perspective, that's an opaque value, not a set of individually analyzable bindings, so accessing ",[39,83745,83746],{},"_.debounce"," gives no static guarantee the other ~300 functions are unused. ",[39,83749,83618],{}," restructures the exact same functionality as individual ESM named exports, which ",[104,83752,70614],{}," statically analyzable, so ",[39,83755,83756],{},"import { debounce } from 'lodash-es'"," lets the bundler prove every other export is dead code and drop it. ",[39,83759,83614],{},[39,83761,83618],{}," contain the same functions (ruling out A); bundlers handle CommonJS routinely, just without tree-shaking granularity (ruling out B); and this affects production bundle size specifically, since that's when tree-shaking is applied (ruling out D).",[15,83764,83765,83773,83806],{"language":247},[18,83766,83768,83769,83772],{"id":83767},"q20-after-switching-to-a-production-build-a-team-notices-their-bundle-size-barely-shrank-despite-the-app-only-using-a-handful-of-functions-from-a-large-utility-library-based-on-everything-above-which-of-the-following-is-the-least-likely-actual-cause","Q20. After switching to a production build, a team notices their bundle size barely shrank despite the app only using a handful of functions from a large utility library. Based on everything above, which of the following is the ",[76,83770,83771],{},"LEAST likely"," actual cause?",[23,83774,83776,83782,83794,83800],{"className":83775},[26],[28,83777,83779,83781],{"className":83778},[31],[33,83780],{"disabled":35,"type":36}," The library is published only as CommonJS, so its exports can't be statically split apart and tree-shaken by the bundler",[28,83783,83785,83787,83788,83790,83791,83793],{"className":83784},[31],[33,83786],{"disabled":35,"type":36}," The library's ",[39,83789,737],{}," is missing ",[39,83792,82136],{}," (or declares it incorrectly), so the bundler conservatively keeps modules it can't prove are free of side effects",[28,83795,83797,83799],{"className":83796},[31],[33,83798],{"disabled":35,"type":36}," Nobody on the team actually inspected the build output with a bundle analyzer, so an earlier attempted fix may not have taken effect, or an entirely different dependency is the real source of the bloat",[28,83801,83803,83805],{"className":83802},[31],[33,83804],{"disabled":35,"type":36}," The bundler's minifier failed to rename any local variables during minification, inflating the file size",[66,83807,83808,83810,83815],{},[69,83809,71],{},[73,83811,83812,83814],{},[76,83813,78],{}," D — The bundler's minifier failed to rename any local variables during minification, inflating the file size",[73,83816,83817,83819,83820,83823,83824,83827],{},[76,83818,84],{}," Variable-renaming is a minification detail that shaves bytes off ",[104,83821,83822],{},"already-included"," code — it has essentially nothing to do with why unused exports from a library would fail to be removed from the bundle in the first place, which is squarely a tree-shaking question, not a minification one (see Q7's distinction between the two). By contrast, options A, B, and C are all genuine, common root causes of \"tree-shaking didn't work\": a CommonJS-only library defeats static analysis outright (Q2, Q19); a missing or incorrect ",[39,83825,83826],{},"sideEffects"," flag forces the bundler to keep modules it can't prove are safe to drop (Q3, Q16); and skipping verification with a real bundle analyzer (Q15) means the team is guessing rather than diagnosing, which is often itself the actual blocker to fixing the real cause.",[2107,83829,83830],{},"html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}",{"title":264,"searchDepth":286,"depth":286,"links":83832},[83833,83834,83836,83838,83839,83841,83842,83843,83844,83846,83848,83850,83851,83852,83854,83855,83857,83859,83860,83862],{"id":81890,"depth":296,"text":81891},{"id":81945,"depth":296,"text":83835},"Q2. Why can a bundler safely remove multiply from the production bundle below, but couldn't perform the same removal if mathUtils.js used CommonJS (module.exports \u002F require) instead?",{"id":82132,"depth":296,"text":83837},"Q3. What does setting \"sideEffects\": false in a library's package.json tell a bundler like webpack, and what risk does it introduce if the claim is wrong?",{"id":82231,"depth":296,"text":82232},{"id":82281,"depth":296,"text":83840},"Q5. A production bundle ends with the line shown below, and the corresponding .map file is deployed alongside it on the public web server.",{"id":82370,"depth":296,"text":82371},{"id":82430,"depth":296,"text":82431},{"id":82564,"depth":296,"text":82565},{"id":82615,"depth":296,"text":83845},"Q9. Two developers run npm install on different days, using only the package.json snippet below — with no package-lock.json present or committed to the repository.",{"id":82775,"depth":296,"text":83847},"Q10. A library bumps its published version from 2.4.1 straight to 3.0.0, with no other announcement. Under semantic versioning (semver) conventions, what should consumers assume?",{"id":82872,"depth":296,"text":83849},"Q11. What does a bundler typically do with the dynamic import() call below that it would not do with a static import { openModal } from '.\u002Fmodal.js' placed at the top of the file?",{"id":83007,"depth":296,"text":83008},{"id":83081,"depth":296,"text":83082},{"id":83131,"depth":296,"text":83853},"Q14. A frontend team changes the VITE_API_URL environment variable on their server after already deploying a built Vite app, expecting the running app to pick up the new URL on the next page load without a rebuild.",{"id":83239,"depth":296,"text":83240},{"id":83294,"depth":296,"text":83856},"Q16. app.js imports analytics.js purely for its side effect and never calls track. Assuming the analytics package's package.json does not set \"sideEffects\": false, what happens during tree-shaking?",{"id":83470,"depth":296,"text":83858},"Q17. A project ends up with both a package-lock.json and a pnpm-lock.yaml committed, after a teammate ran a different package manager locally by mistake. What's the practical problem?",{"id":83555,"depth":296,"text":83556},{"id":83610,"depth":296,"text":83861},"Q19. Importing the whole lodash package (published as CommonJS, exposed as one default-exported object) typically leaves the entire library in the production bundle, while importing from lodash-es and destructuring lets unused functions be tree-shaken away. Why?",{"id":83767,"depth":296,"text":83863},"Q20. After switching to a production build, a team notices their bundle size barely shrank despite the app only using a handful of functions from a large utility library. Based on everything above, which of the following is the LEAST likely actual cause?",{},"\u002Fjs\u002F27-tooling-and-build-systems",{"title":81880,"description":264},"js\u002F27-tooling-and-build-systems","GKZ93eJ8EGk32A-cYoUodPOmwRE51IDt5_3SurByzmw",{"id":83870,"title":83871,"body":83872,"description":83879,"extension":2144,"meta":84442,"navigation":35,"path":84443,"seo":84444,"stem":84445,"__hash__":84446},"content\u002Fjs\u002Findex.md","JavaScript: Zero to Hero",{"type":8,"value":83873,"toc":84432},[83874,83877,83880,83885,83905,83909,83912,83916,83920,84074,84078,84228,84232,84316,84320],[11,83875,83871],{"id":83876},"javascript-zero-to-hero",[73,83878,83879],{},"A complete quiz-based curriculum covering JavaScript from first principles to expert-level, production-grade knowledge. Every quiz is self-contained — read the explanations, not just the answers, to build a full mental model of the language.",[83881,83882,83884],"h2",{"id":83883},"how-to-use-this-quiz-track","How to Use This Quiz Track",[23,83886,83887,83890,83893,83899],{},[28,83888,83889],{},"Work through the parts in order; later quizzes assume knowledge from earlier ones.",[28,83891,83892],{},"Each quiz has 20 multiple-choice questions, ordered from basic recall to edge cases to best-practice judgment calls.",[28,83894,83895,83896,83898],{},"Click ",[76,83897,71],{}," only after committing to a choice — the explanations cover why distractors are wrong, which is where the real quizing happens.",[28,83900,83901,83902,83904],{},"Questions favor \"gotchas\" (coercion traps, event-loop ordering, ",[39,83903,950],{}," binding surprises) over rote recall, so expect to be wrong sometimes on the first pass.",[83881,83906,83908],{"id":83907},"prerequisites","Prerequisites",[73,83910,83911],{},"None for Part 1. Basic command-line comfort helps for the tooling and Node.js-flavored questions in later parts.",[83881,83913,83915],{"id":83914},"curriculum","Curriculum",[18,83917,83919],{"id":83918},"part-1-foundations","Part 1 — Foundations",[83921,83922,83923,83938],"table",{},[83924,83925,83926],"thead",{},[83927,83928,83929,83932,83935],"tr",{},[83930,83931,78878],"th",{},[83930,83933,83934],{},"Topic",[83930,83936,83937],{},"Why It Matters",[83939,83940,83941,83955,83974,83991,84009,84022,84035,84048,84061],"tbody",{},[83927,83942,83943,83947,83952],{},[83944,83945,83946],"td",{},"01",[83944,83948,83949],{},[1223,83950,83951],{"href":2146},"Introduction & Setup",[83944,83953,83954],{},"Where JS runs, engines, and the ECMAScript version treadmill — context for every quirk that follows.",[83927,83956,83957,83960,83965],{},[83944,83958,83959],{},"02",[83944,83961,83962],{},[1223,83963,83964],{"href":5205},"Variables & Data Types",[83944,83966,83967,446,83969,446,83971,83973],{},[39,83968,1440],{},[39,83970,240],{},[39,83972,243],{}," scoping and the primitive vs. reference type split drive most beginner bugs.",[83927,83975,83976,83979,83984],{},[83944,83977,83978],{},"03",[83944,83980,83981],{},[1223,83982,83983],{"href":8671},"Operators & Expressions",[83944,83985,83986,7507,83988,83990],{},[39,83987,3197],{},[39,83989,3280],{},", coercion rules, and operator precedence are classic interview traps.",[83927,83992,83993,83996,84001],{},[83944,83994,83995],{},"04",[83944,83997,83998],{},[1223,83999,84000],{"href":12640},"Control Flow",[83944,84002,84003,84004,7507,84006,84008],{},"Truthy\u002Ffalsy edge cases and loop scoping (",[39,84005,240],{},[39,84007,1440],{}," in closures) trip up even experienced devs.",[83927,84010,84011,84014,84019],{},[83944,84012,84013],{},"05",[83944,84015,84016],{},[1223,84017,84018],{"href":16044},"Functions & Scope",[83944,84020,84021],{},"Hoisting, the TDZ, and function vs. arrow semantics underpin everything else in JS.",[83927,84023,84024,84027,84032],{},[83944,84025,84026],{},"06",[83944,84028,84029],{},[1223,84030,84031],{"href":19503},"Strings & Template Literals",[83944,84033,84034],{},"Immutability, Unicode surrogate pairs, and tagged templates are common gotchas in string handling.",[83927,84036,84037,84040,84045],{},[83944,84038,84039],{},"07",[83944,84041,84042],{},[1223,84043,84044],{"href":23344},"Objects & Properties",[83944,84046,84047],{},"Property descriptors, shallow vs. deep copies, and key coercion shape real-world bugs.",[83927,84049,84050,84053,84058],{},[83944,84051,84052],{},"08",[83944,84054,84055],{},[1223,84056,84057],{"href":26804},"Arrays & Array Methods",[83944,84059,84060],{},"Mutating vs. non-mutating methods and sparse arrays cause subtle production issues.",[83927,84062,84063,84066,84071],{},[83944,84064,84065],{},"09",[83944,84067,84068],{},[1223,84069,84070],{"href":29535},"Destructuring & Spread",[83944,84072,84073],{},"Default values, nested patterns, and spread vs. rest are everywhere in modern codebases.",[18,84075,84077],{"id":84076},"part-2-core-language-mastery","Part 2 — Core Language Mastery",[83921,84079,84080,84090],{},[83924,84081,84082],{},[83927,84083,84084,84086,84088],{},[83930,84085,78878],{},[83930,84087,83934],{},[83930,84089,83937],{},[83939,84091,84092,84104,84120,84132,84151,84163,84182,84200,84213],{},[83927,84093,84094,84096,84101],{},[83944,84095,5825],{},[83944,84097,84098],{},[1223,84099,84100],{"href":34144},"Classes & Prototypes",[83944,84102,84103],{},"Classes are sugar over the prototype chain — understanding both explains inheritance bugs.",[83927,84105,84106,84108,84115],{},[83944,84107,6879],{},[83944,84109,84110],{},[1223,84111,84112,84113,34159],{"href":37261},"The ",[39,84114,950],{},[83944,84116,84117,84119],{},[39,84118,950],{}," binding rules are the single most-misunderstood part of JavaScript.",[83927,84121,84122,84124,84129],{},[83944,84123,16513],{},[83944,84125,84126],{},[1223,84127,84128],{"href":40907},"Closures & Lexical Scope",[83944,84130,84131],{},"Closures power memoization, private state, and are a top source of loop-variable bugs.",[83927,84133,84134,84137,84142],{},[83944,84135,84136],{},"13",[83944,84138,84139],{},[1223,84140,84141],{"href":44165},"Higher-Order Functions",[83944,84143,84144,446,84146,446,84148,84150],{},[39,84145,23950],{},[39,84147,14962],{},[39,84149,14980],{}," composition is the backbone of idiomatic modern JS.",[83927,84152,84153,84155,84160],{},[83944,84154,6159],{},[83944,84156,84157],{},[1223,84158,84159],{"href":47287},"Modules",[83944,84161,84162],{},"ESM vs. CommonJS interop and circular imports are frequent real-world pain points.",[83927,84164,84165,84167,84172],{},[83944,84166,24207],{},[83944,84168,84169],{},[1223,84170,84171],{"href":50735},"Callbacks & the Event Loop",[83944,84173,84174,84175,84178,84179,462],{},"Microtask vs. macrotask ordering explains why ",[39,84176,84177],{},"Promise.then"," beats ",[39,84180,84181],{},"setTimeout(0)",[83927,84183,84184,84187,84192],{},[83944,84185,84186],{},"16",[83944,84188,84189],{},[1223,84190,84191],{"href":54512},"Promises",[83944,84193,84194,84195,16134,84197,84199],{},"Chaining, error propagation, and ",[39,84196,52467],{},[39,84198,52509],{}," are daily async concerns.",[83927,84201,84202,84205,84210],{},[83944,84203,84204],{},"17",[83944,84206,84207],{},[1223,84208,84209],{"href":57634},"Async\u002FAwait",[83944,84211,84212],{},"Await ordering, parallel vs. sequential awaits, and try\u002Fcatch scope are frequent bugs.",[83927,84214,84215,84217,84222],{},[83944,84216,75181],{},[83944,84218,84219],{},[1223,84220,84221],{"href":61229},"Error Handling",[83944,84223,84224,84225,84227],{},"Custom errors, ",[39,84226,51954],{}," semantics, and swallowed rejections shape reliability.",[18,84229,84231],{"id":84230},"part-3-browser-application-layer","Part 3 — Browser & Application Layer",[83921,84233,84234,84244],{},[83924,84235,84236],{},[83927,84237,84238,84240,84242],{},[83930,84239,78878],{},[83930,84241,83934],{},[83930,84243,83937],{},[83939,84245,84246,84259,84271,84285,84303],{},[83927,84247,84248,84251,84256],{},[83944,84249,84250],{},"19",[83944,84252,84253],{},[1223,84254,84255],{"href":64535},"The DOM",[83944,84257,84258],{},"Reflow\u002Frepaint costs and live vs. static node lists affect UI performance.",[83927,84260,84261,84263,84268],{},[83944,84262,6149],{},[83944,84264,84265],{},[1223,84266,84267],{"href":67200},"Events",[83944,84269,84270],{},"Bubbling, capturing, and delegation are essential for building efficient UIs.",[83927,84272,84273,84275,84280],{},[83944,84274,42534],{},[83944,84276,84277],{},[1223,84278,84279],{"href":69412},"Web Storage & APIs",[83944,84281,84282,84284],{},[39,84283,67220],{}," quotas, synchronous cost, and Fetch API quirks matter in production.",[83927,84286,84287,84290,84295],{},[83944,84288,84289],{},"22",[83944,84291,84292],{},[1223,84293,84294],{"href":71580},"Timers & Scheduling",[83944,84296,84297,84299,84300,84302],{},[39,84298,9578],{}," drift, ",[39,84301,62893],{},", and debounce\u002Fthrottle are UI staples.",[83927,84304,84305,84308,84313],{},[83944,84306,84307],{},"23",[83944,84309,84310],{},[1223,84311,84312],{"href":75449},"Functional Programming",[83944,84314,84315],{},"Currying, composition, and immutability patterns are increasingly idiomatic in JS.",[18,84317,84319],{"id":84318},"part-4-advanced-professional","Part 4 — Advanced & Professional",[83921,84321,84322,84332],{},[83924,84323,84324],{},[83927,84325,84326,84328,84330],{},[83930,84327,78878],{},[83930,84329,83934],{},[83930,84331,83937],{},[83939,84333,84334,84348,84360,84373,84386,84400,84416],{},[83927,84335,84336,84339,84345],{},[83944,84337,84338],{},"24",[83944,84340,84341],{},[1223,84342,84344],{"href":84343},"\u002Fjs\u002F24-design-patterns","Design Patterns",[83944,84346,84347],{},"Module, singleton, observer, and factory patterns recur across every large JS codebase.",[83927,84349,84350,84352,84357],{},[83944,84351,31527],{},[83944,84353,84354],{},[1223,84355,84356],{"href":78958},"Testing",[83944,84358,84359],{},"Mocking, spies, and async test pitfalls determine whether a test suite is trustworthy.",[83927,84361,84362,84365,84370],{},[83944,84363,84364],{},"26",[83944,84366,84367],{},[1223,84368,84369],{"href":81874},"Performance & Optimization",[83944,84371,84372],{},"Memory leaks, debouncing, and V8 optimization quirks matter at scale.",[83927,84374,84375,84378,84383],{},[83944,84376,84377],{},"27",[83944,84379,84380],{},[1223,84381,84382],{"href":83865},"Tooling & Build Systems",[83944,84384,84385],{},"Bundlers, tree-shaking, and source maps are unavoidable in modern JS delivery.",[83927,84387,84388,84391,84397],{},[83944,84389,84390],{},"28",[83944,84392,84393],{},[1223,84394,84396],{"href":84395},"\u002Fjs\u002F28-typescript-essentials","TypeScript Essentials",[83944,84398,84399],{},"Structural typing and type narrowing are now baseline JS-adjacent knowledge.",[83927,84401,84402,84405,84410],{},[83944,84403,84404],{},"29",[83944,84406,84407],{},[1223,84408,82350],{"href":84409},"\u002Fjs\u002F29-security",[83944,84411,84412,84413,84415],{},"XSS, prototype pollution, and unsafe ",[39,84414,1341],{}," usage are the most common JS vulnerabilities.",[83927,84417,84418,84420,84426],{},[83944,84419,24274],{},[83944,84421,84422],{},[1223,84423,84425],{"href":84424},"\u002Fjs\u002F30-exercises-and-projects","Exercises & Projects (Capstone)",[83944,84427,84428,84429,84431],{},"A mixed-review capstone pulling together async, closures, ",[39,84430,950],{},", and performance.",{"title":264,"searchDepth":286,"depth":286,"links":84433},[84434,84435,84436],{"id":83883,"depth":286,"text":83884},{"id":83907,"depth":286,"text":83908},{"id":83914,"depth":286,"text":83915,"children":84437},[84438,84439,84440,84441],{"id":83918,"depth":296,"text":83919},{"id":84076,"depth":296,"text":84077},{"id":84230,"depth":296,"text":84231},{"id":84318,"depth":296,"text":84319},{},"\u002Fjs",{"title":83871,"description":83879},"js\u002Findex","HYCfnR2BfKSfg2ZwJtI7FAfHMjGoZFaCECoABp3WJr0",{"id":84448,"title":6,"body":84449,"description":264,"extension":2144,"meta":86850,"navigation":35,"path":86851,"seo":86852,"stem":86853,"__hash__":86854},"content\u002Flua\u002F01-introduction-and-setup.md",{"type":8,"value":84450,"toc":86819},[84451,84453,84504,84579,84671,84758,84910,85046,85148,85293,85432,85588,85683,85830,85942,86062,86151,86287,86452,86586,86710,86816],[11,84452,6],{"id":13},[15,84454,84455,84459,84486],{},[18,84456,84458],{"id":84457},"q1-what-is-lua-fundamentally-designed-to-be","Q1. What is Lua fundamentally designed to be?",[23,84460,84462,84468,84474,84480],{"className":84461},[26],[28,84463,84465,84467],{"className":84464},[31],[33,84466],{"disabled":35,"type":36}," A lightweight, embeddable scripting language meant to be hosted inside larger applications",[28,84469,84471,84473],{"className":84470},[31],[33,84472],{"disabled":35,"type":36}," A general-purpose systems programming language for writing operating systems",[28,84475,84477,84479],{"className":84476},[31],[33,84478],{"disabled":35,"type":36}," A markup language for describing web page layouts",[28,84481,84483,84485],{"className":84482},[31],[33,84484],{"disabled":35,"type":36}," A statically-typed compiled language for high-performance servers",[66,84487,84488,84490,84495],{},[69,84489,71],{},[73,84491,84492,84494],{},[76,84493,78],{}," A — A lightweight, embeddable scripting language meant to be hosted inside larger applications",[73,84496,84497,84499,84500,84503],{},[76,84498,84],{}," Lua was created in 1993 at PUC-Rio specifically to be embedded into C host applications as a configuration\u002Fextension language; its small footprint, C API, and minimal standard library all reflect that goal. It's not aimed at OS development (option B) or markup (option C); while it can run standalone scripts, that's a side effect of the reference ",[39,84501,84502],{},"lua"," interpreter, not the language's primary design goal, and option D wrongly implies static typing and ahead-of-time compilation, which Lua doesn't have.",[15,84505,84506,84517,84555],{},[18,84507,84509,84510,84512,84513,84516],{"id":84508},"q2-which-statement-accurately-describes-the-relationship-between-lua-the-referencepuc-lua-interpreter-and-luajit-luajit","Q2. Which statement accurately describes the relationship between ",[39,84511,84502],{}," (the reference\u002FPUC-Lua interpreter) and ",[39,84514,84515],{},"luajit"," (LuaJIT)?",[23,84518,84520,84529,84535,84541],{"className":84519},[26],[28,84521,84523,84525,84526,84528],{"className":84522},[31],[33,84524],{"disabled":35,"type":36}," They are the same VM; ",[39,84527,84515],{}," is just a faster build flag for the reference interpreter",[28,84530,84532,84534],{"className":84531},[31],[33,84533],{"disabled":35,"type":36}," LuaJIT is a strict superset that always supports every language feature added in the latest PUC-Lua release",[28,84536,84538,84540],{"className":84537},[31],[33,84539],{"disabled":35,"type":36}," LuaJIT is a separate implementation with its own VM and JIT compiler, and its language support lags behind — it targets roughly Lua 5.1 semantics with some 5.2 extensions, not 5.4",[28,84542,84544,84546,84547,84550,84551,84554],{"className":84543},[31],[33,84545],{"disabled":35,"type":36}," LuaJIT only works with Lua bytecode compiled by ",[39,84548,84549],{},"luac",", not with ",[39,84552,84553],{},".lua"," source files",[66,84556,84557,84559,84564],{},[69,84558,71],{},[73,84560,84561,84563],{},[76,84562,78],{}," C — LuaJIT is a separate implementation with its own VM and JIT compiler, and its language support lags behind — it targets roughly Lua 5.1 semantics with some 5.2 extensions, not 5.4",[73,84565,84566,84568,84569,446,84572,84575,84576,84578],{},[76,84567,84],{}," LuaJIT (by Mike Pall) is a from-scratch VM and JIT compiler with excellent performance, but its core language-version tracking stalled around 5.1 with a handful of 5.2-ish additions; it does not support Lua 5.3\u002F5.4 features such as the integer subtype, native bitwise-operator syntax, or ",[39,84570,84571],{},"\u003Cconst>",[39,84573,84574],{},"\u003Cclose>"," attributes. Option A is wrong because they are distinct codebases, not a build flag; option B inverts reality; option D is wrong because LuaJIT compiles and runs ",[39,84577,84553],{}," source directly, just like PUC-Lua.",[15,84580,84581,84585,84605,84646],{"language":82278},[18,84582,84584],{"id":84583},"q3-given-the-following-two-invocations-whats-the-key-difference-in-behavior","Q3. Given the following two invocations, what's the key difference in behavior?",[257,84586,84587],{"language":82278},[260,84588,84591],{"className":84589,"code":84590,"language":82278,"meta":264,"style":264},"language-bash shiki shiki-themes github-light github-dark","lua script.lua\nlua\n",[39,84592,84593,84600],{"__ignoreMap":264},[268,84594,84595,84597],{"class":270,"line":271},[268,84596,84502],{"class":278},[268,84598,84599],{"class":289}," script.lua\n",[268,84601,84602],{"class":270,"line":286},[268,84603,84604],{"class":278},"lua\n",[23,84606,84608,84617,84627,84636],{"className":84607},[26],[28,84609,84611,84613,84614],{"className":84610},[31],[33,84612],{"disabled":35,"type":36}," Both start an interactive REPL; the filename is ignored unless preceded by ",[39,84615,84616],{},"-i",[28,84618,84620,84622,84623,84626],{"className":84619},[31],[33,84621],{"disabled":35,"type":36}," The first executes ",[39,84624,84625],{},"script.lua"," as a program and exits; the second (no arguments) starts the interactive read-eval-print loop",[28,84628,84630,84632,84633],{"className":84629},[31],[33,84631],{"disabled":35,"type":36}," The first is invalid syntax; you must use ",[39,84634,84635],{},"lua -f script.lua",[28,84637,84639,84641,84642,84645],{"className":84638},[31],[33,84640],{"disabled":35,"type":36}," The second only works if a ",[39,84643,84644],{},".luarc"," config file is present in the current directory",[66,84647,84648,84650,84657],{},[69,84649,71],{},[73,84651,84652,84654,84655,84626],{},[76,84653,78],{}," B — The first executes ",[39,84656,84625],{},[73,84658,84659,84661,84662,84664,84665,84667,84668,84670],{},[76,84660,84],{}," Passing a filename runs that chunk to completion and exits (unless the script itself starts a loop); running bare ",[39,84663,84502],{}," with no script argument drops you into the interactive prompt (",[39,84666,6435],{},") for evaluating statements and expressions one at a time. Option A confuses ",[39,84669,84616],{}," (which runs a script AND then keeps the REPL open) with plain script execution; options C and D describe flags and config files that don't exist in stock Lua.",[15,84672,84673,84681,84723],{},[18,84674,84676,84677,84680],{"id":84675},"q4-what-best-distinguishes-luac-the-standalone-interpreter-from-lua-as-a-language-and-runtime","Q4. What best distinguishes ",[39,84678,84679],{},"lua.c"," (the standalone interpreter) from \"Lua\" as a language and runtime?",[23,84682,84684,84695,84703,84711],{"className":84683},[26],[28,84685,84687,355,84689,84691,84692,84694],{"className":84686},[31],[33,84688],{"disabled":35,"type":36},[39,84690,84679],{}," is required to compile any ",[39,84693,84553],{}," file; without it Lua code cannot run at all",[28,84696,84698,355,84700,84702],{"className":84697},[31],[33,84699],{"disabled":35,"type":36},[39,84701,84679],{}," is the only supported way to call Lua from C++ or other languages",[28,84704,84706,355,84708,84710],{"className":84705},[31],[33,84707],{"disabled":35,"type":36},[39,84709,84679],{}," replaced the Lua VM starting in version 5.4",[28,84712,84714,355,84716,84718,84719,84722],{"className":84713},[31],[33,84715],{"disabled":35,"type":36},[39,84717,84679],{}," is a thin, optional command-line front-end built on the same ",[39,84720,84721],{},"liblua"," C API that any host application uses to embed Lua — the language itself doesn't require a standalone binary",[66,84724,84725,84727,84735],{},[69,84726,71],{},[73,84728,84729,6901,84731,84718,84733,84722],{},[76,84730,78],{},[39,84732,84679],{},[39,84734,84721],{},[73,84736,84737,84739,84740,84742,84743,84745,84746,84748,84749,84751,84752,84754,84755,84757],{},[76,84738,84],{}," Lua's core is a C library (",[39,84741,84721],{},") that exposes the Lua C API; ",[39,84744,84679],{}," is just a small sample client of that API that happens to ship as the ",[39,84747,84502],{}," command. Real-world embedding (games, editor configs, server scripting) links ",[39,84750,84721],{}," directly and often never touches ",[39,84753,84679],{},". Options A and B overstate the standalone binary's necessity, and option C is fabricated — the VM has evolved across versions, but ",[39,84756,84679],{}," never \"replaced\" it.",[15,84759,84760,84768,84836,84878],{"language":84502},[18,84761,84763,84764,84767],{"id":84762},"q5-this-script-uses-a-gotolabel-pair-what-happens-when-you-run-it-with-lua-51-vs-lua-54","Q5. This script uses a ",[39,84765,84766],{},"goto","\u002Flabel pair. What happens when you run it with Lua 5.1 vs Lua 5.4?",[257,84769,84770],{"language":84502},[260,84771,84774],{"className":84772,"code":84773,"language":84502,"meta":264,"style":264},"language-lua shiki shiki-themes github-light github-dark","local i = 1\n::top::\nprint(i)\ni = i + 1\nif i \u003C= 3 then goto top end\n",[39,84775,84776,84788,84793,84801,84814],{"__ignoreMap":264},[268,84777,84778,84781,84783,84785],{"class":270,"line":271},[268,84779,84780],{"class":274},"local",[268,84782,9384],{"class":282},[268,84784,302],{"class":274},[268,84786,84787],{"class":305}," 1\n",[268,84789,84790],{"class":270,"line":286},[268,84791,84792],{"class":289},"::top::\n",[268,84794,84795,84798],{"class":270,"line":296},[268,84796,84797],{"class":305},"print",[268,84799,84800],{"class":282},"(i)\n",[268,84802,84803,84806,84808,84810,84812],{"class":270,"line":311},[268,84804,84805],{"class":282},"i ",[268,84807,302],{"class":274},[268,84809,9384],{"class":282},[268,84811,1246],{"class":274},[268,84813,84787],{"class":305},[268,84815,84816,84818,84820,84822,84824,84827,84830,84833],{"class":270,"line":788},[268,84817,2179],{"class":274},[268,84819,9384],{"class":282},[268,84821,6776],{"class":274},[268,84823,3396],{"class":305},[268,84825,84826],{"class":274}," then",[268,84828,84829],{"class":274}," goto",[268,84831,84832],{"class":289}," top",[268,84834,84835],{"class":274}," end\n",[23,84837,84839,84848,84857,84869],{"className":84838},[26],[28,84840,84842,84844,84845,84847],{"className":84841},[31],[33,84843],{"disabled":35,"type":36}," It behaves identically on both — ",[39,84846,84766],{}," has existed since Lua 5.0",[28,84849,84851,84853,84854,84856],{"className":84850},[31],[33,84852],{"disabled":35,"type":36}," It runs fine on 5.4 but fails to parse on 5.1, because ",[39,84855,84766],{},"\u002Flabels were introduced in Lua 5.2",[28,84858,84860,84862,84863,84865,84866,84868],{"className":84859},[31],[33,84861],{"disabled":35,"type":36}," It runs fine on 5.1 but fails on 5.4, because ",[39,84864,84766],{}," was removed in favor of ",[39,84867,8880],{}," in 5.3",[28,84870,84872,84874,84875,84877],{"className":84871},[31],[33,84873],{"disabled":35,"type":36}," Neither version supports ",[39,84876,84766],{},"; only LuaJIT does",[66,84879,84880,84882,84889],{},[69,84881,71],{},[73,84883,84884,84886,84887,84856],{},[76,84885,78],{}," B — It runs fine on 5.4 but fails to parse on 5.1, because ",[39,84888,84766],{},[73,84890,84891,355,84893,186,84895,84898,84899,99,84901,3277,84904,84906,84907,84909],{},[76,84892,84],{},[39,84894,84766],{},[39,84896,84897],{},"::label::"," syntax were added in Lua 5.2; feeding this to a 5.1 interpreter (or most LuaJIT builds, which track roughly 5.1 syntax) raises a syntax error near ",[39,84900,84766],{},[39,84902,84903],{},"::",[76,84905,182],{}," code using ",[39,84908,84766],{}," is a quick way to accidentally require 5.2+, so it's worth checking the target interpreter's version before relying on it. Option C and D are invented behaviors; option A ignores the real version boundary.",[15,84911,84912,84916,84968,85003],{"language":84502},[18,84913,84915],{"id":84914},"q6-what-does-this-print-under-lua-54","Q6. What does this print under Lua 5.4?",[257,84917,84918],{"language":84502},[260,84919,84921],{"className":84772,"code":84920,"language":84502,"meta":264,"style":264},"print(7 \u002F 2)\nprint(7 \u002F\u002F 2)\nprint(7.0 \u002F\u002F 2)\n",[39,84922,84923,84938,84953],{"__ignoreMap":264},[268,84924,84925,84927,84929,84931,84934,84936],{"class":270,"line":271},[268,84926,84797],{"class":305},[268,84928,622],{"class":282},[268,84930,26963],{"class":305},[268,84932,84933],{"class":274}," \u002F",[268,84935,2214],{"class":305},[268,84937,20702],{"class":282},[268,84939,84940,84942,84944,84946,84949,84951],{"class":270,"line":286},[268,84941,84797],{"class":305},[268,84943,622],{"class":282},[268,84945,26963],{"class":305},[268,84947,84948],{"class":274}," \u002F\u002F",[268,84950,2214],{"class":305},[268,84952,20702],{"class":282},[268,84954,84955,84957,84959,84962,84964,84966],{"class":270,"line":296},[268,84956,84797],{"class":305},[268,84958,622],{"class":282},[268,84960,84961],{"class":305},"7.0",[268,84963,84948],{"class":274},[268,84965,2214],{"class":305},[268,84967,20702],{"class":282},[23,84969,84971,84979,84987,84995],{"className":84970},[26],[28,84972,84974,355,84976],{"className":84973},[31],[33,84975],{"disabled":35,"type":36},[39,84977,84978],{},"3.5  3  3.0",[28,84980,84982,355,84984],{"className":84981},[31],[33,84983],{"disabled":35,"type":36},[39,84985,84986],{},"3  3  3",[28,84988,84990,355,84992],{"className":84989},[31],[33,84991],{"disabled":35,"type":36},[39,84993,84994],{},"3.5  3.5  3.5",[28,84996,84998,355,85000],{"className":84997},[31],[33,84999],{"disabled":35,"type":36},[39,85001,85002],{},"4  3  3.0",[66,85004,85005,85007,85013],{},[69,85006,71],{},[73,85008,85009,3459,85011],{},[76,85010,78],{},[39,85012,84978],{},[73,85014,85015,355,85017,85019,85020,11464,85023,3277,85026,85029,85030,830,85033,85035,85036,830,85039,85042,85043,85045],{},[76,85016,84],{},[39,85018,446],{}," is always float division in Lua 5.3+, so ",[39,85021,85022],{},"7 \u002F 2",[39,85024,85025],{},"3.5",[39,85027,85028],{},"\u002F\u002F"," is floor division, also introduced in 5.3, which preserves the \"more float-like\" operand's type: two integer operands yield an integer floor (",[39,85031,85032],{},"7 \u002F\u002F 2",[39,85034,3423],{},"), but if either operand is a float the result is a float floor (",[39,85037,85038],{},"7.0 \u002F\u002F 2",[39,85040,85041],{},"3.0","). Option B wrongly assumes ",[39,85044,446],{}," truncates like C integer division; option D wrongly rounds instead of flooring, and also gets the type wrong for the first result.",[15,85047,85048,85052,85086,85120],{"language":84502},[18,85049,85051],{"id":85050},"q7-what-happens-when-this-runs-on-lua-54","Q7. What happens when this runs on Lua 5.4?",[257,85053,85054],{"language":84502},[260,85055,85057],{"className":84772,"code":85056,"language":84502,"meta":264,"style":264},"local MAX_RETRIES \u003Cconst> = 5\nMAX_RETRIES = MAX_RETRIES + 1\n",[39,85058,85059,85073],{"__ignoreMap":264},[268,85060,85061,85063,85066,85068,85070],{"class":270,"line":271},[268,85062,84780],{"class":274},[268,85064,85065],{"class":282}," MAX_RETRIES ",[268,85067,84571],{"class":274},[268,85069,616],{"class":274},[268,85071,85072],{"class":305}," 5\n",[268,85074,85075,85078,85080,85082,85084],{"class":270,"line":286},[268,85076,85077],{"class":282},"MAX_RETRIES ",[268,85079,302],{"class":274},[268,85081,85065],{"class":282},[268,85083,1246],{"class":274},[268,85085,84787],{"class":305},[23,85087,85089,85098,85104,85112],{"className":85088},[26],[28,85090,85092,85094,85095,85097],{"className":85091},[31],[33,85093],{"disabled":35,"type":36}," It runs fine; ",[39,85096,84571],{}," is just a linting hint with no runtime effect",[28,85099,85101,85103],{"className":85100},[31],[33,85102],{"disabled":35,"type":36}," It raises a runtime error only if the reassignment line actually executes inside a loop",[28,85105,85107,85109,85110,74268],{"className":85106},[31],[33,85108],{"disabled":35,"type":36}," It raises a compile-time error: attempt to assign to a ",[39,85111,84571],{},[28,85113,85115,355,85117,85119],{"className":85114},[31],[33,85116],{"disabled":35,"type":36},[39,85118,84571],{}," is only valid on function parameters, so this is a syntax error on the first line",[66,85121,85122,85124,85131],{},[69,85123,71],{},[73,85125,85126,85128,85129,74268],{},[76,85127,78],{}," C — It raises a compile-time error: attempt to assign to a ",[39,85130,84571],{},[73,85132,85133,355,85135,85137,85138,85141,85142,85144,85145,85147],{},[76,85134,84],{},[39,85136,84571],{}," attributes (Lua 5.4+) are enforced at compile time — the compiler rejects any later assignment to that name with an error like ",[39,85139,85140],{},"attempt to assign to const variable 'MAX_RETRIES'"," before the script even runs. Option A underestimates it (it's not merely advisory); option B wrongly treats it as a runtime-only, control-flow-dependent check; option D is false — ",[39,85143,84571],{}," attaches to ",[39,85146,84780],{}," declarations, not to parameters.",[15,85149,85150,85157,85228,85263],{"language":84502},[18,85151,85153,85154,85156],{"id":85152},"q8-what-is-the-purpose-of-the-close-attribute-in-this-lua-54-snippet","Q8. What is the purpose of the ",[39,85155,84574],{}," attribute in this Lua 5.4 snippet?",[257,85158,85159],{"language":84502},[260,85160,85162],{"className":84772,"code":85161,"language":84502,"meta":264,"style":264},"local function open_log()\n  local f \u003Cclose> = io.open(\"app.log\", \"w\")\n  f:write(\"started\\n\")\nend\n",[39,85163,85164,85175,85202,85223],{"__ignoreMap":264},[268,85165,85166,85168,85170,85173],{"class":270,"line":271},[268,85167,84780],{"class":274},[268,85169,12080],{"class":274},[268,85171,85172],{"class":278}," open_log",[268,85174,47668],{"class":282},[268,85176,85177,85180,85183,85185,85187,85190,85192,85195,85197,85200],{"class":270,"line":286},[268,85178,85179],{"class":274},"  local",[268,85181,85182],{"class":282}," f ",[268,85184,84574],{"class":274},[268,85186,616],{"class":274},[268,85188,85189],{"class":305}," io.open",[268,85191,622],{"class":282},[268,85193,85194],{"class":289},"\"app.log\"",[268,85196,42],{"class":282},[268,85198,85199],{"class":289},"\"w\"",[268,85201,20702],{"class":282},[268,85203,85204,85207,85209,85211,85213,85216,85218,85221],{"class":270,"line":296},[268,85205,85206],{"class":278},"  f",[268,85208,10728],{"class":282},[268,85210,54067],{"class":305},[268,85212,622],{"class":282},[268,85214,85215],{"class":289},"\"started",[268,85217,16322],{"class":305},[268,85219,85220],{"class":289},"\"",[268,85222,20702],{"class":282},[268,85224,85225],{"class":270,"line":311},[268,85226,85227],{"class":274},"end\n",[23,85229,85231,85239,85245,85251],{"className":85230},[26],[28,85232,85234,85236,85237],{"className":85233},[31],[33,85235],{"disabled":35,"type":36}," It makes the variable read-only for the rest of the block, identical to ",[39,85238,84571],{},[28,85240,85242,85244],{"className":85241},[31],[33,85243],{"disabled":35,"type":36}," It closes over the enclosing function's upvalues to prevent memory leaks",[28,85246,85248,85250],{"className":85247},[31],[33,85249],{"disabled":35,"type":36}," It is purely cosmetic documentation with no effect until Lua 5.5",[28,85252,85254,85256,85257,85260,85261],{"className":85253},[31],[33,85255],{"disabled":35,"type":36}," It marks the value as to-be-closed: when the variable goes out of scope (normally or via error), Lua automatically calls its ",[39,85258,85259],{},"__close"," metamethod, similar to RAII\u002F",[39,85262,382],{},[66,85264,85265,85267,85276],{},[69,85266,71],{},[73,85268,85269,85271,85272,85260,85274],{},[76,85270,78],{}," D — It marks the value as to-be-closed: when the variable goes out of scope (normally or via error), Lua automatically calls its ",[39,85273,85259],{},[39,85275,382],{},[73,85277,85278,355,85280,85282,85283,85285,85286,85289,85290,85292],{},[76,85279,84],{},[39,85281,84574],{}," (5.4+) guarantees the value's ",[39,85284,85259],{}," metamethod runs when the variable leaves scope — including during error unwinding — giving deterministic cleanup (file handles, locks) without a manual ",[39,85287,85288],{},"pcall","-and-cleanup dance. Option A confuses it with the unrelated ",[39,85291,84571],{}," attribute; option B misapplies the term \"closure\" to something it doesn't mean here; option C is false — it is fully functional in 5.4, not a no-op reserved for a future version.",[15,85294,85295,85299,85337,85391],{"language":84502},[18,85296,85298],{"id":85297},"q9-you-run-this-snippet-with-lua-51-what-happens","Q9. You run this snippet with Lua 5.1. What happens?",[257,85300,85301],{"language":84502},[260,85302,85304],{"className":84772,"code":85303,"language":84502,"meta":264,"style":264},"local flags = 6\nlocal mask = 2\nprint(flags & mask)\n",[39,85305,85306,85318,85330],{"__ignoreMap":264},[268,85307,85308,85310,85313,85315],{"class":270,"line":271},[268,85309,84780],{"class":274},[268,85311,85312],{"class":282}," flags ",[268,85314,302],{"class":274},[268,85316,85317],{"class":305}," 6\n",[268,85319,85320,85322,85325,85327],{"class":270,"line":286},[268,85321,84780],{"class":274},[268,85323,85324],{"class":282}," mask ",[268,85326,302],{"class":274},[268,85328,85329],{"class":305}," 2\n",[268,85331,85332,85334],{"class":270,"line":296},[268,85333,84797],{"class":305},[268,85335,85336],{"class":282},"(flags & mask)\n",[23,85338,85340,85352,85372,85382],{"className":85339},[26],[28,85341,85343,85345,85346,4387,85348,85351],{"className":85342},[31],[33,85344],{"disabled":35,"type":36}," Prints ",[39,85347,2258],{},[39,85349,85350],{},"&"," is bitwise AND and has worked the same way since Lua 5.0",[28,85353,85355,85357,85358,42,85360,42,85362,42,85365,42,85368,85371],{"className":85354},[31],[33,85356],{"disabled":35,"type":36}," Raises a syntax error, because native bitwise operators (",[39,85359,85350],{},[39,85361,18141],{},[39,85363,85364],{},"~",[39,85366,85367],{},"\u003C\u003C",[39,85369,85370],{},">>",") were only added in Lua 5.3",[28,85373,85375,85345,85377,2833,85379,85381],{"className":85374},[31],[33,85376],{"disabled":35,"type":36},[39,85378,15049],{},[39,85380,85350],{}," is silently reinterpreted as string concatenation",[28,85383,85385,85387,85388,47835],{"className":85384},[31],[33,85386],{"disabled":35,"type":36}," Works, but only if you ",[39,85389,85390],{},"require(\"bit32\")",[66,85392,85393,85395,85410],{},[69,85394,71],{},[73,85396,85397,85399,85400,42,85402,42,85404,42,85406,42,85408,85371],{},[76,85398,78],{}," B — Raises a syntax error, because native bitwise operators (",[39,85401,85350],{},[39,85403,18141],{},[39,85405,85364],{},[39,85407,85367],{},[39,85409,85370],{},[73,85411,85412,85414,85415,85417,85418,355,85421,85424,85425,85428,85429,85431],{},[76,85413,84],{}," Bitwise operator syntax is new to Lua 5.3; on 5.1 (and LuaJIT's default dialect) the parser doesn't recognize ",[39,85416,85350],{}," as an operator at all, so it throws a syntax error. Lua 5.1 has no built-in bitwise support; Lua 5.2 added the ",[39,85419,85420],{},"bit32",[104,85422,85423],{},"library"," (function calls like ",[39,85426,85427],{},"bit32.band","), not the operator syntax, so option D conflates a different version's library with this version's operator — and the operator still wouldn't parse regardless of any ",[39,85430,655],{},". Options A and C describe fabricated behaviors.",[15,85433,85434,85442,85494,85543],{"language":84502},[18,85435,85437,85438,85441],{"id":85436},"q10-given-the-table-below-what-does-printt0-t1-t3-output","Q10. Given the table below, what does ",[39,85439,85440],{},"print(t[0], t[1], t[3])"," output?",[257,85443,85444],{"language":84502},[260,85445,85447],{"className":84772,"code":85446,"language":84502,"meta":264,"style":264},"local t = {10, 20, 30}\nprint(t[0], t[1], t[3])\n",[39,85448,85449,85473],{"__ignoreMap":264},[268,85450,85451,85453,85456,85458,85461,85463,85465,85467,85469,85471],{"class":270,"line":271},[268,85452,84780],{"class":274},[268,85454,85455],{"class":282}," t ",[268,85457,302],{"class":274},[268,85459,85460],{"class":282}," {",[268,85462,5825],{"class":305},[268,85464,42],{"class":282},[268,85466,6149],{"class":305},[268,85468,42],{"class":282},[268,85470,24274],{"class":305},[268,85472,314],{"class":282},[268,85474,85475,85477,85480,85482,85485,85487,85489,85491],{"class":270,"line":286},[268,85476,84797],{"class":305},[268,85478,85479],{"class":282},"(t[",[268,85481,3307],{"class":305},[268,85483,85484],{"class":282},"], t[",[268,85486,2255],{"class":305},[268,85488,85484],{"class":282},[268,85490,3423],{"class":305},[268,85492,85493],{"class":282},"])\n",[23,85495,85497,85514,85523,85531],{"className":85496},[26],[28,85498,85500,355,85502,85505,85506,85509,85510,85513],{"className":85499},[31],[33,85501],{"disabled":35,"type":36},[39,85503,85504],{},"nil  10  30"," — Lua arrays\u002Ftables are conventionally 1-indexed, so ",[39,85507,85508],{},"t[1]"," is the first element and ",[39,85511,85512],{},"t[0]"," is simply an unset key",[28,85515,85517,355,85519,85522],{"className":85516},[31],[33,85518],{"disabled":35,"type":36},[39,85520,85521],{},"10  20  30"," — indexing starts at 0 like most C-family languages",[28,85524,85526,85528,85529],{"className":85525},[31],[33,85527],{"disabled":35,"type":36}," An \"index out of range\" runtime error on ",[39,85530,85512],{},[28,85532,85534,355,85536,62238,85539,85542],{"className":85533},[31],[33,85535],{"disabled":35,"type":36},[39,85537,85538],{},"nil  nil  20",[39,85540,85541],{},"{10, 20, 30}"," builds the table in reverse",[66,85544,85545,85547,85557],{},[69,85546,71],{},[73,85548,85549,3459,85551,85505,85553,85509,85555,85513],{},[76,85550,78],{},[39,85552,85504],{},[39,85554,85508],{},[39,85556,85512],{},[73,85558,85559,85561,85562,85564,85565,5789,85568,85570,85571,85574,85575,85577,85578,42,85581,42,85584,85587],{},[76,85560,84],{}," The table constructor ",[39,85563,85541],{}," assigns sequential integer keys starting at 1 (",[39,85566,85567],{},"t[1]=10, t[2]=20, t[3]=30",[39,85569,85512],{}," was never set, so indexing it just returns ",[39,85572,85573],{},"nil"," — Lua tables don't bounds-check or error on missing keys, they simply return ",[39,85576,85573],{},". This 1-based convention is a deliberate, pervasive design choice (matching ",[39,85579,85580],{},"string.sub",[39,85582,85583],{},"ipairs",[39,85585,85586],{},"table.insert",", and friends), not an off-by-one bug. Option B wrongly assumes C-style 0-indexing; option C invents an error Lua doesn't raise for plain table access; option D is not how table constructors work.",[15,85589,85590,85597,85626,85657],{"language":82278},[18,85591,85593,85594,85596],{"id":85592},"q11-you-compile-a-script-with-lua-54s-luac-and-then-try-to-run-the-output-on-a-machine-that-only-has-lua-51-installed","Q11. You compile a script with Lua 5.4's ",[39,85595,84549],{}," and then try to run the output on a machine that only has Lua 5.1 installed:",[257,85598,85599],{"language":82278},[260,85600,85602],{"className":84589,"code":85601,"language":82278,"meta":264,"style":264},"luac5.4 -o app.luac app.lua\nlua5.1 app.luac\n",[39,85603,85604,85618],{"__ignoreMap":264},[268,85605,85606,85609,85612,85615],{"class":270,"line":271},[268,85607,85608],{"class":278},"luac5.4",[268,85610,85611],{"class":305}," -o",[268,85613,85614],{"class":289}," app.luac",[268,85616,85617],{"class":289}," app.lua\n",[268,85619,85620,85623],{"class":270,"line":286},[268,85621,85622],{"class":278},"lua5.1",[268,85624,85625],{"class":289}," app.luac\n",[23,85627,85629,85635,85645,85651],{"className":85628},[26],[28,85630,85632,85634],{"className":85631},[31],[33,85633],{"disabled":35,"type":36}," It runs correctly; Lua bytecode has been stable and cross-version compatible since 5.0",[28,85636,85638,85640,85641,85644],{"className":85637},[31],[33,85639],{"disabled":35,"type":36}," It automatically falls back to interpreting ",[39,85642,85643],{},"app.luac"," as source text",[28,85646,85648,85650],{"className":85647},[31],[33,85649],{"disabled":35,"type":36}," It fails — precompiled Lua bytecode is tied to the exact Lua version (and often platform\u002Fword-size) it was compiled for, so 5.4 bytecode is not portable to a 5.1 VM",[28,85652,85654,85656],{"className":85653},[31],[33,85655],{"disabled":35,"type":36}," It works, but only for scripts that don't use functions",[66,85658,85659,85661,85666],{},[69,85660,71],{},[73,85662,85663,85665],{},[76,85664,78],{}," C — It fails — precompiled Lua bytecode is tied to the exact Lua version (and often platform\u002Fword-size) it was compiled for, so 5.4 bytecode is not portable to a 5.1 VM",[73,85667,85668,355,85670,85672,85673,85675,85676,85678,85679,85682],{},[76,85669,84],{},[76,85671,182],{}," the Lua bytecode format changes between major versions (and can vary by platform, e.g. integer size), so ",[39,85674,84549],{},"-compiled chunks are only guaranteed to load on a matching Lua version\u002Fbuild — running 5.4 bytecode on a 5.1 ",[39,85677,84502],{}," typically fails with a \"bad header\" or version-mismatch load error. Option A is a common but false assumption carried over from source-level compatibility; options B and D describe behavior Lua doesn't have — a ",[39,85680,85681],{},".luac"," file is binary, not valid Lua source, so it can't be reinterpreted as text.",[15,85684,85685,85693,85733,85779],{"language":84502},[18,85686,85688,85689,85692],{"id":85687},"q12-you-need-to-comment-out-this-block-which-itself-contains-a-sequence-inside-a-string-which-statement-about-the-comment-form-shown-is-correct","Q12. You need to comment out this block, which itself contains a ",[39,85690,85691],{},"]]"," sequence inside a string. Which statement about the comment form shown is correct?",[257,85694,85695],{"language":84502},[260,85696,85698],{"className":84772,"code":85697,"language":84502,"meta":264,"style":264},"--[[\nlocal msg = \"use [[double brackets]] for long strings\"\nprint(msg)\n]]\n",[39,85699,85700,85705,85721,85728],{"__ignoreMap":264},[268,85701,85702],{"class":270,"line":271},[268,85703,85704],{"class":29390},"--[[\n",[268,85706,85707,85710,85713,85716,85718],{"class":270,"line":286},[268,85708,85709],{"class":29390},"local msg = \"use [[double brackets]]",[268,85711,85712],{"class":274}," for",[268,85714,85715],{"class":282}," long ",[268,85717,17076],{"class":305},[268,85719,85720],{"class":289},"\"\n",[268,85722,85723,85725],{"class":270,"line":296},[268,85724,84797],{"class":305},[268,85726,85727],{"class":282},"(msg)\n",[268,85729,85730],{"class":270,"line":311},[268,85731,85732],{"class":282},"]]\n",[23,85734,85736,85748,85758,85767],{"className":85735},[26],[28,85737,85739,85741,85742,10834,85744,85747],{"className":85738},[31],[33,85740],{"disabled":35,"type":36}," The form shown above works fine; Lua ignores nested ",[39,85743,85691],{},[39,85745,85746],{},"--[[ ... ]]"," comment",[28,85749,85751,85753,85754,85757],{"className":85750},[31],[33,85752],{"disabled":35,"type":36}," You must escape the inner brackets as ",[39,85755,85756],{},"\\]\\]"," for this to work",[28,85759,85761,85763,85764,85766],{"className":85760},[31],[33,85762],{"disabled":35,"type":36}," Block comments in Lua don't support multi-line content at all; only ",[39,85765,72712],{}," is allowed",[28,85768,85770,85772,85773,85775,85776,12177],{"className":85769},[31],[33,85771],{"disabled":35,"type":36}," It's a syntax error \u002F the comment closes early — the first ",[39,85774,85691],{}," inside the string prematurely ends the comment, so use a longer bracket level like ",[39,85777,85778],{},"--[==[ ... ]==]",[66,85780,85781,85783,85792],{},[69,85782,71],{},[73,85784,85785,85787,85788,85775,85790,12177],{},[76,85786,78],{}," D — It's a syntax error \u002F the comment closes early — the first ",[39,85789,85691],{},[39,85791,85778],{},[73,85793,85794,355,85796,85798,85799,355,85801,85803,85804,85807,85808,42,85811,85814,85815,85817,85818,85820,85821,85823,85824,85826,85827,85829],{},[76,85795,84],{},[39,85797,85746],{}," closes at the ",[104,85800,12590],{},[39,85802,85691],{}," it encounters, regardless of context, so this comment actually ends right after ",[39,85805,85806],{},"[[double brackets"," and the remaining ",[39,85809,85810],{},"for long strings\"",[39,85812,85813],{},"print(msg)",", and the trailing ",[39,85816,85691],{}," are left as broken code. The fix is a higher long-bracket level — ",[39,85819,85778],{}," — whose closing delimiter must match the exact number of ",[39,85822,302],{}," signs, so an inner ",[39,85825,85691],{}," no longer terminates it. ",[76,85828,365],{}," this is a classic Lua gotcha when commenting out code that itself contains long-bracket strings. Option A is the wrong-but-tempting assumption; option B invents an escape mechanism long brackets don't use; option C is false, since block comments explicitly exist for multi-line content.",[15,85831,85832,85836,85864,85909],{"language":84502},[18,85833,85835],{"id":85834},"q13-what-happens-when-you-try-to-run-this","Q13. What happens when you try to run this?",[257,85837,85838],{"language":84502},[260,85839,85841],{"className":84772,"code":85840,"language":84502,"meta":264,"style":264},"local end = 10\nprint(end)\n",[39,85842,85843,85854],{"__ignoreMap":264},[268,85844,85845,85847,85849,85851],{"class":270,"line":271},[268,85846,84780],{"class":274},[268,85848,49117],{"class":274},[268,85850,616],{"class":274},[268,85852,85853],{"class":305}," 10\n",[268,85855,85856,85858,85860,85862],{"class":270,"line":286},[268,85857,84797],{"class":305},[268,85859,622],{"class":282},[268,85861,13951],{"class":274},[268,85863,20702],{"class":282},[23,85865,85867,85885,85894,85900],{"className":85866},[26],[28,85868,85870,85872,85873,2272,85875,85877,85878,446,85880,446,85882,85884],{"className":85869},[31],[33,85871],{"disabled":35,"type":36}," It runs fine and prints ",[39,85874,5825],{},[39,85876,13951],{}," is only special inside ",[39,85879,2179],{},[39,85881,6926],{},[39,85883,275],{}," blocks",[28,85886,85888,85890,85891,85893],{"className":85887},[31],[33,85889],{"disabled":35,"type":36}," It raises a syntax error, because ",[39,85892,13951],{}," is a reserved keyword and cannot be used as an identifier anywhere",[28,85895,85897,85899],{"className":85896},[31],[33,85898],{"disabled":35,"type":36}," It's allowed, but only in Lua 5.1 for backward compatibility with 4.x",[28,85901,85903,85905,85906,85908],{"className":85902},[31],[33,85904],{"disabled":35,"type":36}," It runs, but ",[39,85907,13951],{}," silently becomes a global instead of a local",[66,85910,85911,85913,85920],{},[69,85912,71],{},[73,85914,85915,85917,85918,85893],{},[76,85916,78],{}," B — It raises a syntax error, because ",[39,85919,13951],{},[73,85921,85922,85924,85925,85928,85929,85932,85933,99,85936,355,85939,85941],{},[76,85923,84],{}," Lua has a fixed, case-sensitive set of reserved keywords (",[39,85926,85927],{},"and, break, do, else, elseif, end, false, for, function, goto, if, in, local, nil, not, or, repeat, return, then, true, until, while",") that can never be used as identifiers, in any scope, in any version — the parser rejects ",[39,85930,85931],{},"local end = 10"," immediately. Note that ",[39,85934,85935],{},"End",[39,85937,85938],{},"END",[104,85940,13519],{}," be legal identifiers, since Lua is case-sensitive and only the exact lowercase keyword is reserved. Option A wrongly assumes context-sensitivity Lua doesn't have; options C and D invent exceptions that don't exist.",[15,85943,85944,85948,85978,86024],{"language":84502},[18,85945,85947],{"id":85946},"q14-what-does-this-print","Q14. What does this print?",[257,85949,85950],{"language":84502},[260,85951,85953],{"className":84772,"code":85952,"language":84502,"meta":264,"style":264},"print(nil, true, 10, \"hi\")\n",[39,85954,85955],{"__ignoreMap":264},[268,85956,85957,85959,85961,85963,85965,85967,85969,85971,85973,85976],{"class":270,"line":271},[268,85958,84797],{"class":305},[268,85960,622],{"class":282},[268,85962,85573],{"class":305},[268,85964,42],{"class":282},[268,85966,2185],{"class":305},[268,85968,42],{"class":282},[268,85970,5825],{"class":305},[268,85972,42],{"class":282},[268,85974,85975],{"class":289},"\"hi\"",[268,85977,20702],{"class":282},[23,85979,85981,85994,86003,86015],{"className":85980},[26],[28,85982,85984,355,85986,85989,85990,85993],{"className":85983},[31],[33,85985],{"disabled":35,"type":36},[39,85987,85988],{},"nil true 10 hi"," with each argument converted via ",[39,85991,85992],{},"tostring()"," and separated by a tab character",[28,85995,85997,85999,86000,86002],{"className":85996},[31],[33,85998],{"disabled":35,"type":36}," An error, because ",[39,86001,84797],{}," can't accept mixed types in one call",[28,86004,86006,50010,86008,86011,86012,86014],{"className":86005},[31],[33,86007],{"disabled":35,"type":36},[39,86009,86010],{},"hi"," is printed; ",[39,86013,84797],{}," in Lua only shows its last argument",[28,86016,86018,355,86020,86023],{"className":86017},[31],[33,86019],{"disabled":35,"type":36},[39,86021,86022],{},"nil, true, 10, \"hi\""," including the commas and quotes, since Lua prints the literal source",[66,86025,86026,86028,86036],{},[69,86027,71],{},[73,86029,86030,3459,86032,85989,86034,85993],{},[76,86031,78],{},[39,86033,85988],{},[39,86035,85992],{},[73,86037,86038,355,86040,14552,86042,86044,86045,86047,86048,42,86051,7083,86053,86055,86056,86058,86059,86061],{},[76,86039,84],{},[39,86041,84797],{},[39,86043,85992],{}," on every argument it receives and writes them to stdout separated by tab characters, ending with a newline — so ",[39,86046,85573],{}," becomes the string ",[39,86049,86050],{},"\"nil\"",[39,86052,2185],{},[39,86054,63696],{},", and no quotes are added around string arguments. Options B and C invent restrictions ",[39,86057,84797],{}," doesn't have, since it's variadic and prints every argument it's given; option D confuses ",[39,86060,84797],{},"'s runtime output with Lua source-code literal syntax.",[15,86063,86064,86075,86115],{},[18,86065,86067,86068,86070,86071,86074],{"id":86066},"q15-compared-to-ecosystems-like-nodejs-npm-or-python-pip-what-should-you-expect-out-of-the-box-from-a-fresh-lua-installation-regarding-package-management","Q15. Compared to ecosystems like Node.js (",[39,86069,110],{},") or Python (",[39,86072,86073],{},"pip","), what should you expect out-of-the-box from a fresh Lua installation regarding package management?",[23,86076,86078,86088,86096,86109],{"className":86077},[26],[28,86079,86081,86083,86084,86087],{"className":86080},[31],[33,86082],{"disabled":35,"type":36}," Lua ships with a bundled package manager called ",[39,86085,86086],{},"luaget"," since 5.3",[28,86089,86091,355,86093,86095],{"className":86090},[31],[33,86092],{"disabled":35,"type":36},[39,86094,714],{}," automatically downloads missing modules from a central registry the first time they're used",[28,86097,86099,86101,86102,86104,86105,86108],{"className":86098},[31],[33,86100],{"disabled":35,"type":36}," There is no bundled package manager — ",[39,86103,714],{}," only loads modules already present on disk\u002F",[39,86106,86107],{},"package.path","; LuaRocks is the de-facto community package manager but must be installed separately",[28,86110,86112,86114],{"className":86111},[31],[33,86113],{"disabled":35,"type":36}," Package management is handled entirely by the operating system's package manager (apt\u002Fbrew), and Lua has no module system of its own",[66,86116,86117,86119,86128],{},[69,86118,71],{},[73,86120,86121,86123,86124,86104,86126,86108],{},[76,86122,78],{}," C — There is no bundled package manager — ",[39,86125,714],{},[39,86127,86107],{},[73,86129,86130,86132,86133,86135,86136,446,86138,86141,86142,86144,86145,86147,86148,86150],{},[76,86131,84],{}," Historically Lua ships lean and dependency-free; ",[39,86134,714],{}," is purely a local module loader that searches ",[39,86137,86107],{},[39,86139,86140],{},"package.cpath",", with zero networking involved. LuaRocks fills the npm\u002Fpip role but is a separate install, which trips up newcomers who expect ",[39,86143,1965],{},"-style tooling to exist by default. Option A invents a nonexistent tool; option B describes behavior ",[39,86146,655],{}," has never had; option D understates that Lua does have its own ",[39,86149,655],{},"\u002Fmodule mechanism independent of the OS.",[15,86152,86153,86157,86214,86252],{"language":84502},[18,86154,86156],{"id":86155},"q16-which-statement-about-the-following-code-is-correct","Q16. Which statement about the following code is correct?",[257,86158,86159],{"language":84502},[260,86160,86162],{"className":84772,"code":86161,"language":84502,"meta":264,"style":264},"local a = 1\nlocal b = 2;\nlocal c = 3;;\nprint(a + b + c)\n",[39,86163,86164,86174,86186,86199],{"__ignoreMap":264},[268,86165,86166,86168,86170,86172],{"class":270,"line":271},[268,86167,84780],{"class":274},[268,86169,1243],{"class":282},[268,86171,302],{"class":274},[268,86173,84787],{"class":305},[268,86175,86176,86178,86180,86182,86184],{"class":270,"line":286},[268,86177,84780],{"class":274},[268,86179,2209],{"class":282},[268,86181,302],{"class":274},[268,86183,2214],{"class":305},[268,86185,293],{"class":282},[268,86187,86188,86190,86192,86194,86196],{"class":270,"line":296},[268,86189,84780],{"class":274},[268,86191,38290],{"class":282},[268,86193,302],{"class":274},[268,86195,3396],{"class":305},[268,86197,86198],{"class":282},";;\n",[268,86200,86201,86203,86205,86207,86209,86211],{"class":270,"line":311},[268,86202,84797],{"class":305},[268,86204,7218],{"class":282},[268,86206,1246],{"class":274},[268,86208,2209],{"class":282},[268,86210,1246],{"class":274},[268,86212,86213],{"class":282}," c)\n",[23,86215,86217,86227,86236,86242],{"className":86216},[26],[28,86218,86220,86222,86223,86226],{"className":86219},[31],[33,86221],{"disabled":35,"type":36}," Only the first two lines are valid; ",[39,86224,86225],{},"local c = 3;;"," is a syntax error from the double semicolon",[28,86228,86230,86232,86233,86235],{"className":86229},[31],[33,86231],{"disabled":35,"type":36}," The double semicolon on line 3 causes ",[39,86234,16484],{}," to be declared twice, triggering a \"variable already defined\" error",[28,86237,86239,86241],{"className":86238},[31],[33,86240],{"disabled":35,"type":36}," Semicolons are required after every statement in Lua 5.4, unlike earlier versions, so lines 1 and 3 are actually errors",[28,86243,86245,86247,86248,86251],{"className":86244},[31],[33,86246],{"disabled":35,"type":36}," All lines are valid — semicolons are optional statement separators in Lua and can even appear as standalone empty statements, so ",[39,86249,86250],{},";;"," is harmless",[66,86253,86254,86256,86263],{},[69,86255,71],{},[73,86257,86258,86260,86261,86251],{},[76,86259,78],{}," D — All lines are valid — semicolons are optional statement separators in Lua and can even appear as standalone empty statements, so ",[39,86262,86250],{},[73,86264,86265,86267,86268,86270,86271,86273,86274,86276,86277,86280,86281,86283,86284,86286],{},[76,86266,84],{}," Lua treats ",[39,86269,10769],{}," as an optional statement separator; an empty statement (just ",[39,86272,10769],{},") is legal and does nothing, so ",[39,86275,86225],{}," is simply ",[39,86278,86279],{},"local c = 3"," followed by a no-op empty statement. ",[76,86282,930],{}," most style guides recommend omitting semicolons except where needed to disambiguate (e.g. before a line starting with ",[39,86285,622],{},"), but including them is never wrong. Options A and B invent errors that don't occur; option C is false in every Lua version, since semicolons have never been mandatory.",[15,86288,86289,86293,86369,86415],{"language":84502},[18,86290,86292],{"id":86291},"q17-this-function-has-a-subtle-bug-what-is-it","Q17. This function has a subtle bug. What is it?",[257,86294,86295],{"language":84502},[260,86296,86298],{"className":84772,"code":86297,"language":84502,"meta":264,"style":264},"function computeTotal(items)\n  total = 0\n  for i = 1, #items do\n    total = total + items[i]\n  end\n  return total\nend\n",[39,86299,86300,86310,86319,86339,86353,86358,86365],{"__ignoreMap":264},[268,86301,86302,86304,86307],{"class":270,"line":271},[268,86303,275],{"class":274},[268,86305,86306],{"class":278}," computeTotal",[268,86308,86309],{"class":282},"(items)\n",[268,86311,86312,86314,86316],{"class":270,"line":286},[268,86313,774],{"class":282},[268,86315,302],{"class":274},[268,86317,86318],{"class":305}," 0\n",[268,86320,86321,86323,86325,86327,86329,86331,86333,86336],{"class":270,"line":296},[268,86322,9659],{"class":274},[268,86324,9384],{"class":282},[268,86326,302],{"class":274},[268,86328,2199],{"class":305},[268,86330,42],{"class":282},[268,86332,78878],{"class":274},[268,86334,86335],{"class":282},"items ",[268,86337,86338],{"class":274},"do\n",[268,86340,86341,86344,86346,86348,86350],{"class":270,"line":311},[268,86342,86343],{"class":282},"    total ",[268,86345,302],{"class":274},[268,86347,21479],{"class":282},[268,86349,1246],{"class":274},[268,86351,86352],{"class":282}," items[i]\n",[268,86354,86355],{"class":270,"line":788},[268,86356,86357],{"class":274},"  end\n",[268,86359,86360,86362],{"class":270,"line":1951},[268,86361,1240],{"class":274},[268,86363,86364],{"class":282}," total\n",[268,86366,86367],{"class":270,"line":8955},[268,86368,85227],{"class":274},[23,86370,86372,86381,86392,86403],{"className":86371},[26],[28,86373,86375,86377,86378,86380],{"className":86374},[31],[33,86376],{"disabled":35,"type":36}," There is no bug; ",[39,86379,805],{}," is correctly scoped to the function since it's assigned inside it",[28,86382,86384,355,86386,86388,86389,86391],{"className":86383},[31],[33,86385],{"disabled":35,"type":36},[39,86387,805],{}," is missing a ",[39,86390,84780],{}," declaration, so it's created as a global variable — it can silently collide with other code using the same name",[28,86393,86395,355,86397,86400,86401],{"className":86394},[31],[33,86396],{"disabled":35,"type":36},[39,86398,86399],{},"#items"," is invalid syntax; length must be computed with ",[39,86402,61759],{},[28,86404,86406,4396,86408,86410,86411,86414],{"className":86405},[31],[33,86407],{"disabled":35,"type":36},[39,86409,6926],{}," loop should use ",[39,86412,86413],{},"ipairs(items)"," instead, or it won't iterate at all",[66,86416,86417,86419,86427],{},[69,86418,71],{},[73,86420,86421,1727,86423,86388,86425,86391],{},[76,86422,78],{},[39,86424,805],{},[39,86426,84780],{},[73,86428,86429,86431,86432,86435,86436,86438,86439,86441,86442,86445,86446,86448,86449,86451],{},[76,86430,84],{}," Lua's default assignment behavior is global-by-default — ",[39,86433,86434],{},"total = 0"," inside the function, without ",[39,86437,84780],{},", creates (or overwrites) a global variable, not a function-local one. It \"happens to work\" here because it's reset to 0 on every call, but it pollutes the global namespace and could clash with an unrelated global named ",[39,86440,805],{}," elsewhere in a large embedded application; the fix is ",[39,86443,86444],{},"local total = 0",". Option A misses the footgun precisely because the code superficially works; option C is false, since ",[39,86447,78878],{}," is Lua's built-in length operator; option D is a style preference, not a bug, since the numeric ",[39,86450,6926],{}," loop shown works fine for a dense array-like table.",[15,86453,86454,86458,86498,86544],{"language":84502},[18,86455,86457],{"id":86456},"q18-what-does-this-print-on-a-standard-lua-54-build","Q18. What does this print on a standard Lua 5.4 build?",[257,86459,86460],{"language":84502},[260,86461,86463],{"className":84772,"code":86462,"language":84502,"meta":264,"style":264},"print(math.type(1), math.type(1.0), 1 == 1.0)\n",[39,86464,86465],{"__ignoreMap":264},[268,86466,86467,86469,86471,86474,86476,86478,86480,86482,86484,86487,86489,86491,86493,86496],{"class":270,"line":271},[268,86468,84797],{"class":305},[268,86470,622],{"class":282},[268,86472,86473],{"class":305},"math.type",[268,86475,622],{"class":282},[268,86477,2255],{"class":305},[268,86479,33111],{"class":282},[268,86481,86473],{"class":305},[268,86483,622],{"class":282},[268,86485,86486],{"class":305},"1.0",[268,86488,33111],{"class":282},[268,86490,2255],{"class":305},[268,86492,3165],{"class":274},[268,86494,86495],{"class":305}," 1.0",[268,86497,20702],{"class":282},[23,86499,86501,86513,86526,86535],{"className":86500},[26],[28,86502,86504,355,86506,86509,86510,86512],{"className":86503},[31],[33,86505],{"disabled":35,"type":36},[39,86507,86508],{},"integer  float  true"," — 5.4 distinguishes integer and float subtypes internally, but ",[39,86511,3197],{}," still compares them by mathematical value",[28,86514,86516,355,86518,86521,86522,23643,86524],{"className":86515},[31],[33,86517],{"disabled":35,"type":36},[39,86519,86520],{},"number  number  true"," — Lua only has one numeric type, so ",[39,86523,86473],{},[39,86525,1383],{},[28,86527,86529,355,86531,86534],{"className":86528},[31],[33,86530],{"disabled":35,"type":36},[39,86532,86533],{},"integer  float  false"," — different subtypes are never considered equal",[28,86536,86538,86540,86541,86543],{"className":86537},[31],[33,86539],{"disabled":35,"type":36}," This errors, because ",[39,86542,86473],{}," doesn't exist until Lua 5.5",[66,86545,86546,86548,86556],{},[69,86547,71],{},[73,86549,86550,3459,86552,86509,86554,86512],{},[76,86551,78],{},[39,86553,86508],{},[39,86555,3197],{},[73,86557,86558,86560,86561,86564,86565,830,86568,86570,86571,7507,86574,10819,86577,86579,86580,86582,86583,86585],{},[76,86559,84],{}," Since Lua 5.3, numbers have two subtypes — integer and float — distinguishable via ",[39,86562,86563],{},"math.type()",", but arithmetic and comparison operators still treat them as one unified \"number\" for equality purposes, so ",[39,86566,86567],{},"1 == 1.0",[39,86569,2185],{}," even though their subtypes differ (",[39,86572,86573],{},"\"integer\"",[39,86575,86576],{},"\"float\"",[76,86578,182],{}," this subtype distinction doesn't exist in Lua 5.1\u002F5.2 or in LuaJIT's default number model, where all numbers are doubles and ",[39,86581,86473],{}," isn't available, so code relying on it silently breaks on those runtimes. Option B describes pre-5.3 behavior; option C wrongly assumes subtype mismatch breaks numeric equality; option D is fabricated, since ",[39,86584,86473],{}," has existed since 5.3.",[15,86587,86588,86595,86629,86670],{"language":84502},[18,86589,86591,86592,86594],{"id":86590},"q19-in-a-modern-53-interactive-lua-session-whats-the-difference-between-typing-these-two-entries-at-the-prompt","Q19. In a modern (5.3+) interactive ",[39,86593,84502],{}," session, what's the difference between typing these two entries at the prompt?",[257,86596,86597],{"language":84502},[260,86598,86600],{"className":84772,"code":86599,"language":84502,"meta":264,"style":264},"> 2 + 2\n> print(2 + 2)\n",[39,86601,86602,86612],{"__ignoreMap":264},[268,86603,86604,86606,86608,86610],{"class":270,"line":271},[268,86605,6435],{"class":274},[268,86607,2214],{"class":305},[268,86609,3350],{"class":274},[268,86611,85329],{"class":305},[268,86613,86614,86616,86619,86621,86623,86625,86627],{"class":270,"line":286},[268,86615,6435],{"class":274},[268,86617,86618],{"class":305}," print",[268,86620,622],{"class":282},[268,86622,2258],{"class":305},[268,86624,3350],{"class":274},[268,86626,2214],{"class":305},[268,86628,20702],{"class":282},[23,86630,86632,86640,86646,86662],{"className":86631},[26],[28,86633,86635,86637,86638],{"className":86634},[31],[33,86636],{"disabled":35,"type":36}," They behave differently: the first is a syntax error because bare expressions aren't valid statements, so you must always call ",[39,86639,84797],{},[28,86641,86643,86645],{"className":86642},[31],[33,86644],{"disabled":35,"type":36}," The first only works in LuaJIT's REPL, not in standard Lua",[28,86647,86649,86651,86652,86655,86656,86659,86660,13454],{"className":86648},[31],[33,86650],{"disabled":35,"type":36}," They behave the same way: the standalone expression ",[39,86653,86654],{},"2 + 2"," is auto-detected by the REPL, implicitly wrapped as ",[39,86657,86658],{},"return 2 + 2",", and its result is printed, same visible output as the explicit ",[39,86661,84797],{},[28,86663,86665,86667,86668],{"className":86664},[31],[33,86666],{"disabled":35,"type":36}," The first silently discards the result and prints nothing, while only the second shows ",[39,86669,15049],{},[66,86671,86672,86674,86685],{},[69,86673,71],{},[73,86675,86676,86678,86679,86655,86681,86659,86683,13454],{},[76,86677,78],{}," C — They behave the same way: the standalone expression ",[39,86680,86654],{},[39,86682,86658],{},[39,86684,84797],{},[73,86686,86687,86689,86690,86692,86693,86695,86696,86698,86699,86702,86703,86706,86707,86709],{},[76,86688,84],{}," Since Lua 5.2's ",[39,86691,84679],{},", when a line typed at the interactive prompt doesn't parse as a valid statement, the REPL retries it prefixed with ",[39,86694,9151],{},", then prints any returned values — so typing a bare expression is a convenient shortcut that ends up displaying the same ",[39,86697,15049],{}," as an explicit ",[39,86700,86701],{},"print(2 + 2)",". Older 5.1-style REPLs instead required an explicit ",[39,86704,86705],{},"=2+2"," shortcut for this. Option A wrongly treats the shortcut as invalid; option B is false, since this is standard ",[39,86708,84679],{}," behavior, not LuaJIT-specific; option D invents silent-discard behavior that doesn't happen.",[15,86711,86712,86716,86758,86791],{"language":84502},[18,86713,86715],{"id":86714},"q20-youre-embedding-a-scripting-layer-into-a-performance-sensitive-c-application-and-the-scripts-must-use-this-pattern-unmodified","Q20. You're embedding a scripting layer into a performance-sensitive C application, and the scripts must use this pattern unmodified:",[257,86717,86718],{"language":84502},[260,86719,86721],{"className":84772,"code":86720,"language":84502,"meta":264,"style":264},"local flags \u003Cconst> = 0xF0 & 0x3C\nlocal step = 10 \u002F\u002F 3\n",[39,86722,86723,86742],{"__ignoreMap":264},[268,86724,86725,86727,86729,86731,86733,86736,86739],{"class":270,"line":271},[268,86726,84780],{"class":274},[268,86728,85312],{"class":282},[268,86730,84571],{"class":274},[268,86732,616],{"class":274},[268,86734,86735],{"class":305}," 0xF0",[268,86737,86738],{"class":282}," & ",[268,86740,86741],{"class":305},"0x3C\n",[268,86743,86744,86746,86749,86751,86753,86755],{"class":270,"line":286},[268,86745,84780],{"class":274},[268,86747,86748],{"class":282}," step ",[268,86750,302],{"class":274},[268,86752,306],{"class":305},[268,86754,84948],{"class":274},[268,86756,86757],{"class":305}," 3\n",[23,86759,86761,86767,86773,86779],{"className":86760},[26],[28,86762,86764,86766],{"className":86763},[31],[33,86765],{"disabled":35,"type":36}," LuaJIT, because it's always faster and a strict superset of PUC-Lua",[28,86768,86770,86772],{"className":86769},[31],[33,86771],{"disabled":35,"type":36}," Lua 5.1, since bitwise and floor-division support was available from the very first release",[28,86774,86776,86778],{"className":86775},[31],[33,86777],{"disabled":35,"type":36}," Any Lua version works identically, since these are all part of core Lua syntax since 5.0",[28,86780,86782,86784,86785,86787,86788,86790],{"className":86781},[31],[33,86783],{"disabled":35,"type":36}," Lua 5.3 or newer (e.g. 5.4), because ",[39,86786,84571],{},", native bitwise operators, and ",[39,86789,85028],{}," all require 5.3+ language support that LuaJIT's default dialect doesn't provide",[66,86792,86793,86795,86804],{},[69,86794,71],{},[73,86796,86797,86799,86800,86787,86802,86790],{},[76,86798,78],{}," D — Lua 5.3 or newer (e.g. 5.4), because ",[39,86801,84571],{},[39,86803,85028],{},[73,86805,86806,355,86808,86810,86811,186,86813,86815],{},[76,86807,84],{},[39,86809,84571],{}," is 5.4-only, while ",[39,86812,85350],{},[39,86814,85028],{}," require 5.3+; LuaJIT's mainline branch tracks roughly 5.1 syntax plus a few extras and does not parse this snippet, so despite LuaJIT's raw speed advantage, it's the wrong choice when the requirement is running this specific 5.3+\u002F5.4 syntax unmodified — a real-world case where \"faster\" and \"compatible\" pull in different directions. Option A is the tempting-but-wrong performance-first answer; options B and C are simply factually wrong about when these features were introduced.",[2107,86817,86818],{},"html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-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 .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 .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}",{"title":264,"searchDepth":286,"depth":286,"links":86820},[86821,86822,86824,86825,86827,86829,86830,86831,86833,86834,86836,86838,86840,86841,86842,86844,86845,86846,86847,86849],{"id":84457,"depth":296,"text":84458},{"id":84508,"depth":296,"text":86823},"Q2. Which statement accurately describes the relationship between lua (the reference\u002FPUC-Lua interpreter) and luajit (LuaJIT)?",{"id":84583,"depth":296,"text":84584},{"id":84675,"depth":296,"text":86826},"Q4. What best distinguishes lua.c (the standalone interpreter) from \"Lua\" as a language and runtime?",{"id":84762,"depth":296,"text":86828},"Q5. This script uses a goto\u002Flabel pair. What happens when you run it with Lua 5.1 vs Lua 5.4?",{"id":84914,"depth":296,"text":84915},{"id":85050,"depth":296,"text":85051},{"id":85152,"depth":296,"text":86832},"Q8. What is the purpose of the \u003Cclose> attribute in this Lua 5.4 snippet?",{"id":85297,"depth":296,"text":85298},{"id":85436,"depth":296,"text":86835},"Q10. Given the table below, what does print(t[0], t[1], t[3]) output?",{"id":85592,"depth":296,"text":86837},"Q11. You compile a script with Lua 5.4's luac and then try to run the output on a machine that only has Lua 5.1 installed:",{"id":85687,"depth":296,"text":86839},"Q12. You need to comment out this block, which itself contains a ]] sequence inside a string. Which statement about the comment form shown is correct?",{"id":85834,"depth":296,"text":85835},{"id":85946,"depth":296,"text":85947},{"id":86066,"depth":296,"text":86843},"Q15. Compared to ecosystems like Node.js (npm) or Python (pip), what should you expect out-of-the-box from a fresh Lua installation regarding package management?",{"id":86155,"depth":296,"text":86156},{"id":86291,"depth":296,"text":86292},{"id":86456,"depth":296,"text":86457},{"id":86590,"depth":296,"text":86848},"Q19. In a modern (5.3+) interactive lua session, what's the difference between typing these two entries at the prompt?",{"id":86714,"depth":296,"text":86715},{},"\u002Flua\u002F01-introduction-and-setup",{"title":6,"description":264},"lua\u002F01-introduction-and-setup","cIZUhiDaAJPW1Ul4nDsBd5qfWpBamtb2hplglFE-fEA",{"id":86856,"title":86857,"body":86858,"description":86865,"extension":2144,"meta":87348,"navigation":35,"path":87349,"seo":87350,"stem":87351,"__hash__":87352},"content\u002Flua\u002Findex.md","Lua: Zero to Hero",{"type":8,"value":86859,"toc":87338},[86860,86863,86866,86868,86893,86895,86898,86900,86902,87011,87015,87105,87109,87180,87184],[11,86861,86857],{"id":86862},"lua-zero-to-hero",[73,86864,86865],{},"A complete quiz-based curriculum covering Lua from first principles to expert-level, production-grade knowledge. Lua's minimalism is deceptive — nearly everything (objects, modules, namespaces) is built from one primitive, the table, and this track is sequenced around the handful of mechanisms (metatables, closures, coroutines) that make that possible.",[83881,86867,83884],{"id":83883},[23,86869,86870,86873,86875,86880,86890],{},[28,86871,86872],{},"Work through the parts in order; Part 2 onward assumes comfort with tables and closures from Part 1.",[28,86874,83892],{},[28,86876,83895,86877,86879],{},[76,86878,71],{}," only after committing to a choice — the explanations cover the underlying mechanism (metamethods, upvalue sharing, coroutine state machines), not just the right letter.",[28,86881,86882,86883,86885,86886,86889],{},"Expect classic Lua \"wat\" moments — 1-based indexing, the ",[39,86884,78878],{}," operator on tables with holes, and ",[39,86887,86888],{},".."," string coercion — turned into quiz questions.",[28,86891,86892],{},"Questions target Lua 5.4 (the current reference implementation) and call out version differences (5.1\u002F5.2\u002F5.3, LuaJIT) where they matter in practice.",[83881,86894,83908],{"id":83907},[73,86896,86897],{},"None for Part 1, though familiarity with any dynamically-typed scripting language helps the table\u002Fclosure model click faster.",[83881,86899,83915],{"id":83914},[18,86901,83919],{"id":83918},[83921,86903,86904,86914],{},[83924,86905,86906],{},[83927,86907,86908,86910,86912],{},[83930,86909,78878],{},[83930,86911,83934],{},[83930,86913,83937],{},[83939,86915,86916,86931,86946,86961,86982,86995],{},[83927,86917,86918,86920,86924],{},[83944,86919,83946],{},[83944,86921,86922],{},[1223,86923,83951],{"href":86851},[83944,86925,86926,7507,86928,86930],{},[39,86927,84502],{},[39,86929,84515],{},", embedding vs standalone, and version fragmentation (5.1–5.4) shape which features and libraries are actually available.",[83927,86932,86933,86935,86940],{},[83944,86934,83959],{},[83944,86936,86937],{},[1223,86938,83964],{"href":86939},"\u002Flua\u002F02-variables-and-data-types",[83944,86941,86942,86943,86945],{},"Globals-by-default, ",[39,86944,85573],{},", and the integer\u002Ffloat subtype split (5.3+) are frequent sources of subtle bugs.",[83927,86947,86948,86950,86955],{},[83944,86949,83978],{},[83944,86951,86952],{},[1223,86953,83983],{"href":86954},"\u002Flua\u002F03-operators-and-expressions",[83944,86956,86957,86958,86960],{},"String-to-number coercion via arithmetic operators and ",[39,86959,86888],{}," concatenation are classic gotcha territory.",[83927,86962,86963,86965,86970],{},[83944,86964,83995],{},[83944,86966,86967],{},[1223,86968,84000],{"href":86969},"\u002Flua\u002F04-control-flow",[83944,86971,86972,86975,86976,86978,86979,86981],{},[39,86973,86974],{},"repeat...until","'s scoping quirk and the absence of ",[39,86977,8880],{},"-with-label (only ",[39,86980,84766],{},") surprise newcomers.",[83927,86983,86984,86986,86992],{},[83944,86985,84013],{},[83944,86987,86988],{},[1223,86989,86991],{"href":86990},"\u002Flua\u002F05-strings-and-patterns","Strings & Patterns",[83944,86993,86994],{},"Lua patterns are not regex — the differences trip up anyone assuming PCRE-style syntax.",[83927,86996,86997,86999,87005],{},[83944,86998,84026],{},[83944,87000,87001],{},[1223,87002,87004],{"href":87003},"\u002Flua\u002F06-tables","Tables",[83944,87006,87007,87008,87010],{},"The array\u002Fhash duality and the famously undefined ",[39,87009,78878],{}," operator on tables with holes are the single biggest source of Lua bugs.",[18,87012,87014],{"id":87013},"part-2-functions-scope","Part 2 — Functions & Scope",[83921,87016,87017,87027],{},[83924,87018,87019],{},[83927,87020,87021,87023,87025],{},[83930,87022,78878],{},[83930,87024,83934],{},[83930,87026,83937],{},[83939,87028,87029,87045,87061,87080],{},[83927,87030,87031,87033,87039],{},[83944,87032,84039],{},[83944,87034,87035],{},[1223,87036,87038],{"href":87037},"\u002Flua\u002F07-functions","Functions",[83944,87040,87041,87042,87044],{},"Multiple return values and varargs (",[39,87043,15329],{},") are used pervasively and behave differently from most mainstream languages.",[83927,87046,87047,87049,87055],{},[83944,87048,84052],{},[83944,87050,87051],{},[1223,87052,87054],{"href":87053},"\u002Flua\u002F08-closures-and-upvalues","Closures & Upvalues",[83944,87056,87057,87058,87060],{},"Shared upvalues across loop iterations are Lua's version of the classic JS ",[39,87059,1440],{},"-in-a-loop bug.",[83927,87062,87063,87065,87071],{},[83944,87064,84065],{},[83944,87066,87067],{},[1223,87068,87070],{"href":87069},"\u002Flua\u002F09-metatables-and-metamethods","Metatables & Metamethods",[83944,87072,87073,446,87076,87079],{},[39,87074,87075],{},"__index",[39,87077,87078],{},"__newindex"," and operator metamethods are how Lua achieves everything from OOP to operator overloading.",[83927,87081,87082,87084,87090],{},[83944,87083,5825],{},[83944,87085,87086],{},[1223,87087,87089],{"href":87088},"\u002Flua\u002F10-oop-with-tables-and-metatables","OOP with Tables & Metatables",[83944,87091,87092,87093,87096,87097,87100,87101,87104],{},"Colon-call sugar (",[39,87094,87095],{},"obj:method()",") hides an implicit ",[39,87098,87099],{},"self"," that's a frequent source of ",[39,87102,87103],{},"attempt to call a nil value"," errors.",[18,87106,87108],{"id":87107},"part-3-control-errors","Part 3 — Control & Errors",[83921,87110,87111,87121],{},[83924,87112,87113],{},[83927,87114,87115,87117,87119],{},[83930,87116,78878],{},[83930,87118,83934],{},[83930,87120,83937],{},[83939,87122,87123,87144,87162],{},[83927,87124,87125,87127,87132],{},[83944,87126,6879],{},[83944,87128,87129],{},[1223,87130,84221],{"href":87131},"\u002Flua\u002F11-error-handling",[83944,87133,87134,446,87136,87139,87140,446,87142,462],{},[39,87135,85288],{},[39,87137,87138],{},"xpcall"," and non-string error objects are Lua's whole error model — there's no ",[39,87141,23142],{},[39,87143,12488],{},[83927,87145,87146,87148,87154],{},[83944,87147,16513],{},[83944,87149,87150],{},[1223,87151,87153],{"href":87152},"\u002Flua\u002F12-coroutines","Coroutines",[83944,87155,87156,446,87159,87161],{},[39,87157,87158],{},"resume",[39,87160,57179],{}," state machines power generators, cooperative schedulers, and game-engine update loops.",[83927,87163,87164,87166,87172],{},[83944,87165,84136],{},[83944,87167,87168],{},[1223,87169,87171],{"href":87170},"\u002Flua\u002F13-modules-and-require","Modules & require",[83944,87173,87174,87176,87177,87179],{},[39,87175,655],{}," caching and ",[39,87178,86107],{}," resolution order are essential for structuring any non-trivial project.",[18,87181,87183],{"id":87182},"part-4-advanced-systems","Part 4 — Advanced & Systems",[83921,87185,87186,87196],{},[83924,87187,87188],{},[83927,87189,87190,87192,87194],{},[83930,87191,78878],{},[83930,87193,83934],{},[83930,87195,83937],{},[83939,87197,87198,87211,87224,87248,87272,87285,87304,87326],{},[83927,87199,87200,87202,87208],{},[83944,87201,6159],{},[83944,87203,87204],{},[1223,87205,87207],{"href":87206},"\u002Flua\u002F14-garbage-collection","Garbage Collection",[83944,87209,87210],{},"Incremental vs. generational GC (5.4) and weak tables matter for anyone building caches or long-running processes.",[83927,87212,87213,87215,87221],{},[83944,87214,24207],{},[83944,87216,87217],{},[1223,87218,87220],{"href":87219},"\u002Flua\u002F15-the-c-api-and-ffi","The C API & FFI",[83944,87222,87223],{},"Lua's defining use case is embedding — the stack-based C API and LuaJIT's FFI are how host applications actually integrate it.",[83927,87225,87226,87228,87234],{},[83944,87227,84186],{},[83944,87229,87230],{},[1223,87231,87233],{"href":87232},"\u002Flua\u002F16-advanced-metaprogramming","Advanced Metaprogramming",[83944,87235,87236,42,87239,87242,87243,446,87245,87247],{},[39,87237,87238],{},"__call",[39,87240,87241],{},"__tostring",", and proxy tables via ",[39,87244,87075],{},[39,87246,87078],{}," enable sandboxing and DSL-style APIs.",[83927,87249,87250,87252,87258],{},[83944,87251,84204],{},[83944,87253,87254],{},[1223,87255,87257],{"href":87256},"\u002Flua\u002F17-standard-library-deep-dive","Standard Library Deep Dive",[83944,87259,87260,87263,87264,87267,87268,87271],{},[39,87261,87262],{},"table.sort"," stability, ",[39,87265,87266],{},"os.time"," granularity, and ",[39,87269,87270],{},"io"," buffering behavior matter in real scripts.",[83927,87273,87274,87276,87282],{},[83944,87275,75181],{},[83944,87277,87278],{},[1223,87279,87281],{"href":87280},"\u002Flua\u002F18-performance-and-luajit","Performance & LuaJIT",[83944,87283,87284],{},"JIT trace compilation, deoptimization triggers, and table pre-sizing are where Lua performance work actually happens.",[83927,87286,87287,87289,87294],{},[83944,87288,84250],{},[83944,87290,87291],{},[1223,87292,84356],{"href":87293},"\u002Flua\u002F19-testing",[83944,87295,87296,87297,186,87300,87303],{},"Frameworks like ",[39,87298,87299],{},"busted",[39,87301,87302],{},"luaunit",", plus common assertion\u002Fmocking patterns, determine test suite trustworthiness.",[83927,87305,87306,87308,87313],{},[83944,87307,6149],{},[83944,87309,87310],{},[1223,87311,82350],{"href":87312},"\u002Flua\u002F20-security",[83944,87314,87315,446,87318,87321,87322,87325],{},[39,87316,87317],{},"load",[39,87319,87320],{},"loadstring"," on untrusted input and unsandboxed ",[39,87323,87324],{},"os.execute"," are the most common Lua vulnerabilities (notably in game modding and CDN edge scripts).",[83927,87327,87328,87330,87335],{},[83944,87329,42534],{},[83944,87331,87332],{},[1223,87333,84425],{"href":87334},"\u002Flua\u002F21-exercises-and-projects",[83944,87336,87337],{},"A mixed-review capstone spanning metatables, coroutines, closures, and error handling.",{"title":264,"searchDepth":286,"depth":286,"links":87339},[87340,87341,87342],{"id":83883,"depth":286,"text":83884},{"id":83907,"depth":286,"text":83908},{"id":83914,"depth":286,"text":83915,"children":87343},[87344,87345,87346,87347],{"id":83918,"depth":296,"text":83919},{"id":87013,"depth":296,"text":87014},{"id":87107,"depth":296,"text":87108},{"id":87182,"depth":296,"text":87183},{},"\u002Flua",{"title":86857,"description":86865},"lua\u002Findex","L-VlIQsKSs48TvQak4xkyfYYvLSlSo80OBAj9zwY8r8",{"id":87354,"title":6,"body":87355,"description":264,"extension":2144,"meta":88938,"navigation":35,"path":88939,"seo":88940,"stem":88941,"__hash__":88942},"content\u002Fpython\u002F01-introduction-and-setup.md",{"type":8,"value":87356,"toc":88905},[87357,87359,87406,87453,87549,87662,87719,87805,87856,87963,88024,88106,88184,88255,88354,88466,88515,88594,88653,88702,88817,88902],[11,87358,6],{"id":13},[15,87360,87361,87365,87392],{},[18,87362,87364],{"id":87363},"q1-what-is-cpython","Q1. What is CPython?",[23,87366,87368,87374,87380,87386],{"className":87367},[26],[28,87369,87371,87373],{"className":87370},[31],[33,87372],{"disabled":35,"type":36}," It is a third-party JIT-compiled alternative to Python",[28,87375,87377,87379],{"className":87376},[31],[33,87378],{"disabled":35,"type":36}," It is the reference implementation of Python, written primarily in C",[28,87381,87383,87385],{"className":87382},[31],[33,87384],{"disabled":35,"type":36}," It is a tool that transpiles Python source into C++ for compilation",[28,87387,87389,87391],{"className":87388},[31],[33,87390],{"disabled":35,"type":36}," It is the deprecated Python 2 interpreter, superseded by Python 3",[66,87393,87394,87396,87401],{},[69,87395,71],{},[73,87397,87398,87400],{},[76,87399,78],{}," B — It is the reference implementation of Python, written primarily in C",[73,87402,87403,87405],{},[76,87404,84],{}," CPython is the original and most widely used Python interpreter, implemented in C, and it is what most people mean when they say \"Python.\" Option A describes PyPy, a different implementation. Option C misdescribes CPython — it compiles Python source to bytecode executed by a virtual machine, not to C++. Option D is wrong because CPython supports both historical Python 2 releases and current Python 3 releases; it isn't tied to one language version.",[15,87407,87408,87412,87439],{},[18,87409,87411],{"id":87410},"q2-a-team-runs-a-long-lived-cpu-bound-pure-python-service-and-wants-a-drop-in-interpreter-swap-for-better-throughput-which-alternative-implementation-is-specifically-known-for-using-a-jit-compiler-to-speed-up-such-workloads","Q2. A team runs a long-lived, CPU-bound pure-Python service and wants a drop-in interpreter swap for better throughput. Which alternative implementation is specifically known for using a JIT compiler to speed up such workloads?",[23,87413,87415,87421,87427,87433],{"className":87414},[26],[28,87416,87418,87420],{"className":87417},[31],[33,87419],{"disabled":35,"type":36}," Jython",[28,87422,87424,87426],{"className":87423},[31],[33,87425],{"disabled":35,"type":36}," PyPy",[28,87428,87430,87432],{"className":87429},[31],[33,87431],{"disabled":35,"type":36}," IronPython",[28,87434,87436,87438],{"className":87435},[31],[33,87437],{"disabled":35,"type":36}," MicroPython",[66,87440,87441,87443,87448],{},[69,87442,71],{},[73,87444,87445,87447],{},[76,87446,78],{}," B — PyPy",[73,87449,87450,87452],{},[76,87451,84],{}," PyPy includes a just-in-time compiler that can dramatically speed up long-running pure-Python code by compiling hot code paths to machine code at runtime. Jython (A) targets the JVM and IronPython (C) targets .NET — both let Python interoperate with those platforms but neither is primarily a JIT speed play for pure-Python workloads. MicroPython (D) is a lean reimplementation for microcontrollers, prioritizing footprint over raw throughput.",[15,87454,87456,87463,87482,87521],{"language":87455},"python",[18,87457,87459,87460,87462],{"id":87458},"q3-in-python-3-how-must-print-be-used","Q3. In Python 3, how must ",[39,87461,84797],{}," be used?",[257,87464,87465],{"language":87455},[260,87466,87469],{"className":87467,"code":87468,"language":87455,"meta":264,"style":264},"language-python shiki shiki-themes github-light github-dark","print(\"deployment finished\")\n",[39,87470,87471],{"__ignoreMap":264},[268,87472,87473,87475,87477,87480],{"class":270,"line":271},[268,87474,84797],{"class":305},[268,87476,622],{"class":282},[268,87478,87479],{"class":289},"\"deployment finished\"",[268,87481,20702],{"class":282},[23,87483,87485,87494,87503,87515],{"className":87484},[26],[28,87486,87488,87490,87491],{"className":87487},[31],[33,87489],{"disabled":35,"type":36}," As a statement, without parentheses: ",[39,87492,87493],{},"print \"deployment finished\"",[28,87495,87497,87499,87500],{"className":87496},[31],[33,87498],{"disabled":35,"type":36}," As a function call, with parentheses: ",[39,87501,87502],{},"print(\"deployment finished\")",[28,87504,87506,87508,87509,4387,87512,87514],{"className":87505},[31],[33,87507],{"disabled":35,"type":36}," Only via ",[39,87510,87511],{},"sys.stdout.write",[39,87513,84797],{}," was removed in Python 3",[28,87516,87518,87520],{"className":87517},[31],[33,87519],{"disabled":35,"type":36}," Either form works interchangeably in Python 3",[66,87522,87523,87525,87532],{},[69,87524,71],{},[73,87526,87527,87529,87530],{},[76,87528,78],{}," B — As a function call, with parentheses: ",[39,87531,87502],{},[73,87533,87534,87536,87537,87539,87540,87542,87543,87545,87546,87548],{},[76,87535,84],{}," Python 3 turned ",[39,87538,84797],{}," into a regular builtin function, so it must be called with parentheses. Option A is the Python 2 statement form and raises a ",[39,87541,1274],{}," under Python 3. Option C is false — ",[39,87544,84797],{}," still exists as a convenient wrapper; you are not forced onto ",[39,87547,87511],{},". Option D is wrong because the statement form is not valid Python 3 syntax at all.",[15,87550,87551,87558,87578,87620],{"language":87455},[18,87552,87554,87555,87557],{"id":87553},"q4-what-does-true-division-return-in-python-3-when-dividing-two-integers","Q4. What does ",[39,87556,446],{}," (true division) return in Python 3 when dividing two integers?",[257,87559,87560],{"language":87455},[260,87561,87563],{"className":87467,"code":87562,"language":87455,"meta":264,"style":264},"result = 7 \u002F 2\n",[39,87564,87565],{"__ignoreMap":264},[268,87566,87567,87570,87572,87574,87576],{"class":270,"line":271},[268,87568,87569],{"class":282},"result ",[268,87571,302],{"class":274},[268,87573,41908],{"class":305},[268,87575,84933],{"class":274},[268,87577,85329],{"class":305},[23,87579,87581,87591,87602,87612],{"className":87580},[26],[28,87582,87584,355,87586,87588,87589],{"className":87583},[31],[33,87585],{"disabled":35,"type":36},[39,87587,3423],{},", an integer truncated toward zero, matching Python 2's ",[39,87590,446],{},[28,87592,87594,355,87596,87598,87599,87601],{"className":87593},[31],[33,87595],{"disabled":35,"type":36},[39,87597,85025],{},", a float — Python 3's ",[39,87600,446],{}," always performs true division",[28,87603,87605,812,87607,2833,87609,87611],{"className":87604},[31],[33,87606],{"disabled":35,"type":36},[39,87608,827],{},[39,87610,446],{}," requires float operands explicitly",[28,87613,87615,355,87617,87619],{"className":87614},[31],[33,87616],{"disabled":35,"type":36},[39,87618,3423],{},", an integer floored toward negative infinity",[66,87621,87622,87624,87632],{},[69,87623,71],{},[73,87625,87626,1727,87628,87598,87630,87601],{},[76,87627,78],{},[39,87629,85025],{},[39,87631,446],{},[73,87633,87634,87636,87637,87639,87640,87643,87644,87647,87648,87650,87651,87653,87654,87656,87657,87659,87660,462],{},[76,87635,84],{}," In Python 3, ",[39,87638,446],{}," always performs true division and returns a ",[39,87641,87642],{},"float",", even when both operands are ",[39,87645,87646],{},"int",". This is a deliberate change from Python 2, where ",[39,87649,446],{}," between two ints performed floor division by default. Option A describes the old Python 2 behavior. Option D describes what ",[39,87652,85028],{}," (floor division) does, not ",[39,87655,446],{},". Option C is wrong — ",[39,87658,446],{}," works fine on ints and simply promotes the result to ",[39,87661,87642],{},[15,87663,87664,87672,87703],{},[18,87665,87667,87668,87671],{"id":87666},"q5-what-does-a-pyc-file-contain","Q5. What does a ",[39,87669,87670],{},".pyc"," file contain?",[23,87673,87675,87681,87687,87697],{"className":87674},[26],[28,87676,87678,87680],{"className":87677},[31],[33,87679],{"disabled":35,"type":36}," Native machine code compiled for the host CPU",[28,87682,87684,87686],{"className":87683},[31],[33,87685],{"disabled":35,"type":36}," Compiled Python bytecode, cached to speed up future imports of that module",[28,87688,87690,87692,87693,87696],{"className":87689},[31],[33,87691],{"disabled":35,"type":36}," A minified copy of the original ",[39,87694,87695],{},".py"," source text",[28,87698,87700,87702],{"className":87699},[31],[33,87701],{"disabled":35,"type":36}," An encrypted, obfuscated version of the source code",[66,87704,87705,87707,87712],{},[69,87706,71],{},[73,87708,87709,87711],{},[76,87710,78],{}," B — Compiled Python bytecode, cached to speed up future imports of that module",[73,87713,87714,355,87716,87718],{},[76,87715,84],{},[39,87717,87670],{}," files hold the compiled bytecode for a module so that CPython can skip re-parsing and re-compiling the source text on subsequent imports, speeding up startup. It is not native machine code (A) — CPython's bytecode still runs on the interpreter's virtual machine. It is not a text-based minified copy (C), and it provides no meaningful security or obfuscation (D); bytecode can be decompiled fairly easily.",[15,87720,87721,87729,87773],{},[18,87722,87724,87725,87728],{"id":87723},"q6-where-does-cpython-3-store-cached-bytecode-for-an-imported-module-named-utilspy-by-default","Q6. Where does CPython 3 store cached bytecode for an imported module named ",[39,87726,87727],{},"utils.py",", by default?",[23,87730,87732,87744,87757,87763],{"className":87731},[26],[28,87733,87735,26514,87737,87740,87741],{"className":87734},[31],[33,87736],{"disabled":35,"type":36},[39,87738,87739],{},"__pycache__\u002F"," directory next to the source, e.g. ",[39,87742,87743],{},"__pycache__\u002Futils.cpython-311.pyc",[28,87745,87747,87749,87750,87753,87754,87756],{"className":87746},[31],[33,87748],{"disabled":35,"type":36}," As ",[39,87751,87752],{},"utils.pyc",", directly replacing ",[39,87755,87727],{}," in place",[28,87758,87760,87762],{"className":87759},[31],[33,87761],{"disabled":35,"type":36}," In the interpreter's installation directory, keyed by project name",[28,87764,87766,87768,87769,87772],{"className":87765},[31],[33,87767],{"disabled":35,"type":36}," In a single, project-wide ",[39,87770,87771],{},"compiled.pyc"," bundle",[66,87774,87775,87777,87786],{},[69,87776,71],{},[73,87778,87779,87781,87782,87740,87784],{},[76,87780,78],{}," A — Inside a ",[39,87783,87739],{},[39,87785,87743],{},[73,87787,87788,87790,87791,87794,87795,87798,87799,87801,87802,87804],{},[76,87789,84],{}," Since Python 3.2 (PEP 3147), cached bytecode lives in a ",[39,87792,87793],{},"__pycache__"," subdirectory alongside the source, with a filename tagged by interpreter implementation and version (e.g., ",[39,87796,87797],{},"cpython-311","). Option B describes the old Python 2 layout, where ",[39,87800,87670],{}," sat next to ",[39,87803,87695],{}," with no subfolder. Options C and D describe caching schemes CPython does not use.",[15,87806,87807,87811,87838],{},[18,87808,87810],{"id":87809},"q7-per-pep-8-how-many-spaces-should-be-used-for-each-indentation-level","Q7. Per PEP 8, how many spaces should be used for each indentation level?",[23,87812,87814,87820,87826,87832],{"className":87813},[26],[28,87815,87817,87819],{"className":87816},[31],[33,87818],{"disabled":35,"type":36}," 2 spaces",[28,87821,87823,87825],{"className":87822},[31],[33,87824],{"disabled":35,"type":36}," 4 spaces",[28,87827,87829,87831],{"className":87828},[31],[33,87830],{"disabled":35,"type":36}," A single hard tab character",[28,87833,87835,87837],{"className":87834},[31],[33,87836],{"disabled":35,"type":36}," 8 spaces",[66,87839,87840,87842,87847],{},[69,87841,71],{},[73,87843,87844,87846],{},[76,87845,78],{}," B — 4 spaces",[73,87848,87849,87851,87852,87855],{},[76,87850,84],{}," PEP 8 recommends 4 spaces per indentation level and explicitly recommends spaces over tabs. Options A and D are used by some other languages\u002Fstyle guides but are not the PEP 8 recommendation for Python. Option C is discouraged: PEP 8 says tabs and spaces should not be mixed, and spaces are preferred; Python 3 even raises a ",[39,87853,87854],{},"TabError"," if a file inconsistently mixes tabs and spaces in a way that changes meaning.",[15,87857,87858,87865,87896,87929],{"language":82278},[18,87859,87861,87862,87864],{"id":87860},"q8-at-the-interactive-repl-what-does-the-special-name-_-refer-to-immediately-after-evaluating-an-expression","Q8. At the interactive REPL, what does the special name ",[39,87863,52315],{}," refer to immediately after evaluating an expression?",[257,87866,87867],{"language":82278},[260,87868,87870],{"className":84589,"code":87869,"language":82278,"meta":264,"style":264},">>> 40 + 2\n42\n>>> _\n",[39,87871,87872,87884,87889],{"__ignoreMap":264},[268,87873,87874,87877,87880,87882],{"class":270,"line":271},[268,87875,87876],{"class":282},">>> ",[268,87878,87879],{"class":278},"40",[268,87881,3350],{"class":289},[268,87883,85329],{"class":305},[268,87885,87886],{"class":270,"line":286},[268,87887,87888],{"class":278},"42\n",[268,87890,87891,87893],{"class":270,"line":296},[268,87892,87876],{"class":282},[268,87894,87895],{"class":278},"_\n",[23,87897,87899,87907,87917,87923],{"className":87898},[26],[28,87900,87902,87904,87905,2690],{"className":87901},[31],[33,87903],{"disabled":35,"type":36}," The value of the last expression evaluated at the prompt (here, ",[39,87906,4659],{},[28,87908,87910,812,87912,4387,87914,87916],{"className":87909},[31],[33,87911],{"disabled":35,"type":36},[39,87913,1274],{},[39,87915,52315],{}," has no special meaning in Python",[28,87918,87920,87922],{"className":87919},[31],[33,87921],{"disabled":35,"type":36}," The current line number in the session",[28,87924,87926,87928],{"className":87925},[31],[33,87927],{"disabled":35,"type":36}," The name of the most recently called function",[66,87930,87931,87933,87940],{},[69,87932,71],{},[73,87934,87935,87937,87938,2690],{},[76,87936,78],{}," A — The value of the last expression evaluated at the prompt (here, ",[39,87939,4659],{},[73,87941,87942,355,87944,87946,87947,87949,87950,87952,87953,87955,87956,87959,87960,87962],{},[76,87943,84],{},[76,87945,16523],{}," — the interactive interpreter automatically binds ",[39,87948,52315],{}," to the result of the last statement that produced a displayed value, which is convenient for chaining exploratory work at the prompt. This behavior is unique to the interactive REPL; it does not happen when running a ",[39,87951,87695],{}," file as a script, which is the trap — code relying on ",[39,87954,52315],{}," outside the REPL will raise a ",[39,87957,87958],{},"NameError"," (unless ",[39,87961,52315],{}," was assigned some other way, e.g. as the conventional \"throwaway\" variable name).",[15,87964,87965,87972,88002],{},[18,87966,87968,87969,87971],{"id":87967},"q9-what-determines-whether-cpython-recompiles-a-module-instead-of-reusing-its-cached-pyc-under-the-default-non-hash-based-invalidation-mode","Q9. What determines whether CPython recompiles a module instead of reusing its cached ",[39,87970,87670],{},", under the default (non hash-based) invalidation mode?",[23,87973,87975,87984,87990,87996],{"className":87974},[26],[28,87976,87978,87980,87981,87983],{"className":87977},[31],[33,87979],{"disabled":35,"type":36}," CPython compares the source file's modification time and size, embedded in the ",[39,87982,87670],{}," header, against the current source file",[28,87985,87987,87989],{"className":87986},[31],[33,87988],{"disabled":35,"type":36}," CPython recompiles on every run regardless of any cache, since caching is opt-in and off by default",[28,87991,87993,87995],{"className":87992},[31],[33,87994],{"disabled":35,"type":36}," CPython caches bytecode permanently and never re-checks the source afterward",[28,87997,87999,88001],{"className":87998},[31],[33,88000],{"disabled":35,"type":36}," CPython computes a SHA-256 hash of the full source on every import and compares it, ignoring timestamps entirely",[66,88003,88004,88006,88013],{},[69,88005,71],{},[73,88007,88008,88010,88011,87983],{},[76,88009,78],{}," A — CPython compares the source file's modification time and size, embedded in the ",[39,88012,87670],{},[73,88014,88015,88017,88018,88020,88021,88023],{},[76,88016,84],{}," By default, CPython uses timestamp-based invalidation: the ",[39,88019,87670],{}," header stores the source's mtime and size, and a mismatch triggers recompilation. Option D describes hash-based ",[39,88022,87670],{}," invalidation, a real but opt-in mode added in PEP 552 (Python 3.7+) — it exists, but it is not the default, which is the gotcha. Option B is wrong because caching is on by default for imported modules. Option C is wrong because stale caches are actively detected, not blindly trusted forever.",[15,88025,88026,88039,88074],{},[18,88027,88029,88030,88033,88034,88036,88037,1685],{"id":88028},"q10-does-the-script-you-run-directly-eg-python-apppy-get-its-own-pyc-written-to-__pycache__","Q10. Does the script you run directly (e.g., ",[39,88031,88032],{},"python app.py",") get its own ",[39,88035,87670],{}," written to ",[39,88038,87793],{},[23,88040,88042,88048,88058,88068],{"className":88041},[26],[28,88043,88045,88047],{"className":88044},[31],[33,88046],{"disabled":35,"type":36}," Yes — every executed file is cached identically, including the entry-point script",[28,88049,88051,88053,88054,88057],{"className":88050},[31],[33,88052],{"disabled":35,"type":36}," No — only imported modules are cached; the file run directly as ",[39,88055,88056],{},"__main__"," is compiled fresh each run and not cached",[28,88059,88061,88063,88064,88067],{"className":88060},[31],[33,88062],{"disabled":35,"type":36}," Yes, but only when the ",[39,88065,88066],{},"-O"," flag is passed",[28,88069,88071,88073],{"className":88070},[31],[33,88072],{"disabled":35,"type":36}," No — CPython never caches bytecode for any file, despite common belief",[66,88075,88076,88078,88085],{},[69,88077,71],{},[73,88079,88080,88082,88083,88057],{},[76,88081,78],{}," B — No — only imported modules are cached; the file run directly as ",[39,88084,88056],{},[73,88086,88087,355,88089,88091,88092,88094,88095,88098,88099,88102,88103,88105],{},[76,88088,84],{},[76,88090,55328],{}," — CPython caches bytecode for modules reached via the import system, but the top-level script executed as ",[39,88093,88056],{}," is recompiled every invocation, since there's no stable cache-invalidation target the way there is for an importable module. This surprises developers who expect a ",[39,88096,88097],{},"__pycache__\u002Fapp.cpython-311.pyc"," to appear next to ",[39,88100,88101],{},"app.py"," after running it directly — it won't, though any modules ",[39,88104,88101],{}," imports will get cached.",[15,88107,88108,88118,88156],{},[18,88109,88111,88112,88114,88115,88117],{"id":88110},"q11-two-different-python-versions-39-and-311-both-import-the-same-utilspy-from-a-shared-__pycache__-directory-what-happens","Q11. Two different Python versions, 3.9 and 3.11, both import the same ",[39,88113,87727],{}," from a shared ",[39,88116,87793],{}," directory. What happens?",[23,88119,88121,88131,88144,88150],{"className":88120},[26],[28,88122,88124,88126,88127,88130],{"className":88123},[31],[33,88125],{"disabled":35,"type":36}," A version-conflict ",[39,88128,88129],{},"ImportError"," is raised immediately",[28,88132,88134,88136,88137,186,88140,88143],{"className":88133},[31],[33,88135],{"disabled":35,"type":36}," Each interpreter reads and writes its own version-tagged file (",[39,88138,88139],{},"utils.cpython-39.pyc",[39,88141,88142],{},"utils.cpython-311.pyc","), so both coexist safely",[28,88145,88147,88149],{"className":88146},[31],[33,88148],{"disabled":35,"type":36}," The second interpreter to run overwrites and corrupts the first interpreter's cache entry",[28,88151,88153,88155],{"className":88152},[31],[33,88154],{"disabled":35,"type":36}," Only one Python version may be installed on a machine at a time, so this scenario cannot occur",[66,88157,88158,88160,88169],{},[69,88159,71],{},[73,88161,88162,88164,88165,186,88167,88143],{},[76,88163,78],{}," B — Each interpreter reads and writes its own version-tagged file (",[39,88166,88139],{},[39,88168,88142],{},[73,88170,88171,355,88173,88176,88177,88179,88180,88183],{},[76,88172,84],{},[76,88174,88175],{},"Portability"," — the PEP 3147 naming scheme embeds the implementation and version tag in the cache filename specifically so multiple interpreters can safely share one ",[39,88178,87793],{}," directory without clobbering each other's bytecode. Options A, C, and D describe conflicts that the tagging scheme was designed to prevent; multiple Python versions coexisting on one machine (e.g., via ",[39,88181,88182],{},"pyenv"," or system packages) is routine.",[15,88185,88186,88193,88232],{},[18,88187,88189,88190,88192],{"id":88188},"q12-a-developer-deletes-a-stray-__pycache__-directory-before-committing-a-project-to-git-is-this-safe","Q12. A developer deletes a stray ",[39,88191,87793],{}," directory before committing a project to git. Is this safe?",[23,88194,88196,88208,88220,88226],{"className":88195},[26],[28,88197,88199,88201,88202,88204,88205,88207],{"className":88198},[31],[33,88200],{"disabled":35,"type":36}," No — ",[39,88203,87670],{}," files sometimes contain unique logic not present in the ",[39,88206,87695],{}," source, so deleting them causes data loss",[28,88209,88211,88213,88214,88216,88217,88219],{"className":88210},[31],[33,88212],{"disabled":35,"type":36}," Yes — ",[39,88215,87793],{}," is a disposable, regeneratable cache; it is generally recommended to ",[39,88218,83515],{}," it rather than commit it",[28,88221,88223,88225],{"className":88222},[31],[33,88224],{"disabled":35,"type":36}," No — deleting it forces a full reinstall of the Python interpreter",[28,88227,88229,88231],{"className":88228},[31],[33,88230],{"disabled":35,"type":36}," Yes, but only because the interpreter falls back to Python 2 mode without a valid cache",[66,88233,88234,88236,88245],{},[69,88235,71],{},[73,88237,88238,88240,88241,88216,88243,88219],{},[76,88239,78],{}," B — Yes — ",[39,88242,87793],{},[39,88244,83515],{},[73,88246,88247,355,88249,88251,88252,88254],{},[76,88248,84],{},[39,88250,87670],{}," files are purely derived artifacts recompiled automatically from ",[39,88253,87695],{}," source as needed, so removing them is always safe and they are conventionally excluded from version control. Option A is a myth — bytecode caches never contain logic absent from the source they were compiled from. Options C and D describe consequences that simply do not occur; deleting a cache directory has zero effect on the interpreter installation itself.",[15,88256,88257,88264,88312],{},[18,88258,88260,88261,88263],{"id":88259},"q13-which-statement-correctly-contrasts-str-between-python-2-and-python-3","Q13. Which statement correctly contrasts ",[39,88262,17109],{}," between Python 2 and Python 3?",[23,88265,88267,88279,88297,88306],{"className":88266},[26],[28,88268,88270,88272,88273,88275,88276,88278],{"className":88269},[31],[33,88271],{"disabled":35,"type":36}," In Python 2, ",[39,88274,17109],{}," held Unicode code points by default; Python 3's ",[39,88277,17109],{}," became raw bytes",[28,88280,88282,88272,88284,88286,88287,88290,88291,88293,88294,1558],{"className":88281},[31],[33,88283],{"disabled":35,"type":36},[39,88285,17109],{}," was a byte sequence by default (with a separate ",[39,88288,88289],{},"unicode"," type for text); in Python 3, ",[39,88292,17109],{}," became a sequence of Unicode code points, and raw bytes moved to the distinct ",[39,88295,88296],{},"bytes",[28,88298,88300,88302,88303,88305],{"className":88299},[31],[33,88301],{"disabled":35,"type":36}," Both versions treat ",[39,88304,17109],{}," identically as raw, undecoded bytes",[28,88307,88309,88311],{"className":88308},[31],[33,88310],{"disabled":35,"type":36}," Python 3 removed the text\u002Fbytes distinction entirely, merging both into one type",[66,88313,88314,88316,88329],{},[69,88315,71],{},[73,88317,88318,88320,88321,88286,88323,88290,88325,88293,88327,1558],{},[76,88319,78],{}," B — In Python 2, ",[39,88322,17109],{},[39,88324,88289],{},[39,88326,17109],{},[39,88328,88296],{},[73,88330,88331,88333,88334,88336,88337,88339,88340,88342,88343,88345,88346,186,88348,88350,88351,88353],{},[76,88332,84],{}," This is one of the largest Python 2 → 3 breaking changes: Python 2's ",[39,88335,17109],{}," was really a byte string (with ",[39,88338,88289],{}," as the separate text type), while Python 3 flips this so ",[39,88341,17109],{}," is text (Unicode) and ",[39,88344,88296],{}," is the explicit binary type, with no implicit coercion between them. Option A states the reverse of the truth. Options C and D understate a distinction that Python 3 in fact made stricter, not looser — mixing ",[39,88347,17109],{},[39,88349,88296],{}," in Python 3 raises a ",[39,88352,827],{}," rather than silently coercing.",[15,88355,88356,88366,88383,88421],{"language":82278},[18,88357,88359,88360,88362,88363,1685],{"id":88358},"q14-what-is-the-effect-of-invoking-the-interpreter-with-the-o-flag-eg-python-o-apppy","Q14. What is the effect of invoking the interpreter with the ",[39,88361,88066],{}," flag, e.g. ",[39,88364,88365],{},"python -O app.py",[257,88367,88368],{"language":82278},[260,88369,88371],{"className":84589,"code":88370,"language":82278,"meta":264,"style":264},"python -O app.py\n",[39,88372,88373],{"__ignoreMap":264},[268,88374,88375,88377,88380],{"class":270,"line":271},[268,88376,87455],{"class":278},[268,88378,88379],{"class":305}," -O",[268,88381,88382],{"class":289}," app.py\n",[23,88384,88386,88403,88409,88415],{"className":88385},[26],[28,88387,88389,88391,88392,88395,88396,88399,88400],{"className":88388},[31],[33,88390],{"disabled":35,"type":36}," It enables basic optimizations — ",[39,88393,88394],{},"assert"," statements and code guarded by ",[39,88397,88398],{},"if __debug__:"," are stripped, and cache files are tagged ",[39,88401,88402],{},"opt-1.pyc",[28,88404,88406,88408],{"className":88405},[31],[33,88407],{"disabled":35,"type":36}," It automatically reformats the source file to comply with PEP 8",[28,88410,88412,88414],{"className":88411},[31],[33,88413],{"disabled":35,"type":36}," It runs the script inside an online, network-sandboxed mode",[28,88416,88418,88420],{"className":88417},[31],[33,88419],{"disabled":35,"type":36}," It has no effect under CPython and is only meaningful under Jython",[66,88422,88423,88425,88436],{},[69,88424,71],{},[73,88426,88427,88429,88430,88395,88432,88399,88434],{},[76,88428,78],{}," A — It enables basic optimizations — ",[39,88431,88394],{},[39,88433,88398],{},[39,88435,88402],{},[73,88437,88438,355,88440,3990,88442,9122,88444,5425,88447,88450,88451,88453,88454,88456,88457,88459,88460,88462,88463,88465],{},[76,88439,84],{},[76,88441,16523],{},[39,88443,88066],{},[39,88445,88446],{},"__debug__",[39,88448,88449],{},"False",", causing ",[39,88452,88394],{}," statements (and any ",[39,88455,88398],{}," blocks) to be compiled out entirely — a common trap because assertions silently stop firing in ",[39,88458,88066],{}," mode, so they must never be relied on for input validation or security checks in production. Options B and C describe behavior ",[39,88461,88066],{}," does not have. Option D is wrong — ",[39,88464,88066],{}," is a genuine, commonly used CPython flag.",[15,88467,88468,88472,88499],{},[18,88469,88471],{"id":88470},"q15-per-pep-8-what-is-the-recommended-maximum-line-length-for-code","Q15. Per PEP 8, what is the recommended maximum line length for code?",[23,88473,88475,88481,88487,88493],{"className":88474},[26],[28,88476,88478,88480],{"className":88477},[31],[33,88479],{"disabled":35,"type":36}," 79 characters, with slightly more latitude (up to ~72) suggested for flowing text like docstrings and comments",[28,88482,88484,88486],{"className":88483},[31],[33,88485],{"disabled":35,"type":36}," 120 characters, strictly enforced by the interpreter",[28,88488,88490,88492],{"className":88489},[31],[33,88491],{"disabled":35,"type":36}," There is no guidance at all; PEP 8 leaves line length entirely to team preference",[28,88494,88496,88498],{"className":88495},[31],[33,88497],{"disabled":35,"type":36}," 40 characters",[66,88500,88501,88503,88508],{},[69,88502,71],{},[73,88504,88505,88507],{},[76,88506,78],{}," A — 79 characters, with slightly more latitude (up to ~72) suggested for flowing text like docstrings and comments",[73,88509,88510,355,88512,88514],{},[76,88511,84],{},[76,88513,17307],{}," — PEP 8 recommends limiting lines to 79 characters (with long, flowing text such as comments\u002Fdocstrings recommended to wrap around 72), specifically to support side-by-side diffs and multiple open files. Option B is a common team override but not the PEP 8 default. Option C understates PEP 8, which does give a concrete number even though many real-world projects relax it. Option D is far stricter than PEP 8 actually recommends.",[15,88516,88517,88521,88537,88575],{"language":87455},[18,88518,88520],{"id":88519},"q16-per-pep-8-naming-conventions-how-should-a-module-level-constant-be-named","Q16. Per PEP 8 naming conventions, how should a module-level constant be named?",[257,88522,88523],{"language":87455},[260,88524,88526],{"className":87467,"code":88525,"language":87455,"meta":264,"style":264},"MAX_RETRIES = 3\n",[39,88527,88528],{"__ignoreMap":264},[268,88529,88530,88533,88535],{"class":270,"line":271},[268,88531,88532],{"class":305},"MAX_RETRIES",[268,88534,616],{"class":274},[268,88536,86757],{"class":305},[23,88538,88540,88549,88557,88566],{"className":88539},[26],[28,88541,88543,88545,88546],{"className":88542},[31],[33,88544],{"disabled":35,"type":36}," camelCase, e.g. ",[39,88547,88548],{},"maxRetries",[28,88550,88552,88554,88555],{"className":88551},[31],[33,88553],{"disabled":35,"type":36}," UPPER_SNAKE_CASE, e.g. ",[39,88556,88532],{},[28,88558,88560,88562,88563],{"className":88559},[31],[33,88561],{"disabled":35,"type":36}," PascalCase, e.g. ",[39,88564,88565],{},"MaxRetries",[28,88567,88569,88571,88572],{"className":88568},[31],[33,88570],{"disabled":35,"type":36}," Always underscore-prefixed, e.g. ",[39,88573,88574],{},"_maxretries",[66,88576,88577,88579,88586],{},[69,88578,71],{},[73,88580,88581,88583,88584],{},[76,88582,78],{}," B — UPPER_SNAKE_CASE, e.g. ",[39,88585,88532],{},[73,88587,88588,88590,88591,88593],{},[76,88589,84],{}," PEP 8 reserves UPPER_SNAKE_CASE for constants, snake_case for functions\u002Fvariables, and PascalCase (CapWords) for classes, so ",[39,88592,88532],{}," correctly signals \"constant\" to readers. Option A is the JavaScript convention, not Python's. Option C (PascalCase) is PEP 8's convention for class names, not constants. Option D's leading underscore signals \"internal\u002Fnon-public,\" an orthogonal concern to constant-ness.",[15,88595,88596,88600,88627],{},[18,88597,88599],{"id":88598},"q17-a-team-is-starting-a-brand-new-production-codebase-in-2026-which-major-version-should-they-target","Q17. A team is starting a brand-new production codebase in 2026. Which major version should they target?",[23,88601,88603,88609,88615,88621],{"className":88602},[26],[28,88604,88606,88608],{"className":88605},[31],[33,88607],{"disabled":35,"type":36}," Python 2, since it has been stable and unchanged for years",[28,88610,88612,88614],{"className":88611},[31],[33,88613],{"disabled":35,"type":36}," Python 3 — Python 2 reached official end-of-life in January 2020 and no longer receives security patches",[28,88616,88618,88620],{"className":88617},[31],[33,88619],{"disabled":35,"type":36}," Either is fine, since Python 2 and 3 source is fully interchangeable",[28,88622,88624,88626],{"className":88623},[31],[33,88625],{"disabled":35,"type":36}," It's irrelevant — CPython auto-detects and transparently runs either syntax",[66,88628,88629,88631,88636],{},[69,88630,71],{},[73,88632,88633,88635],{},[76,88634,78],{}," B — Python 3 — Python 2 reached official end-of-life in January 2020 and no longer receives security patches",[73,88637,88638,355,88640,88642,88643,88646,88647,88649,88650,88652],{},[76,88639,84],{},[76,88641,17613],{}," — Python 2's \"stability\" in option A is really abandonment: it stopped receiving even security fixes after January 1, 2020, making it a liability for new production work. Option C is a myth; Python 2 and 3 have real syntactic and semantic differences (print, integer division, string types, etc.) that require porting, not blind compatibility. Option D is false — a ",[39,88644,88645],{},"python2","-only script (e.g., using the ",[39,88648,84797],{}," statement) is a ",[39,88651,1274],{}," under a Python 3 interpreter.",[15,88654,88655,88659,88686],{},[18,88656,88658],{"id":88657},"q18-when-is-it-appropriate-to-consider-pypy-instead-of-cpython-in-production","Q18. When is it appropriate to consider PyPy instead of CPython in production?",[23,88660,88662,88668,88674,88680],{"className":88661},[26],[28,88663,88665,88667],{"className":88664},[31],[33,88666],{"disabled":35,"type":36}," For a long-running, CPU-bound, pure-Python workload where JIT warm-up time is acceptable and speed matters — PyPy can substantially outperform CPython there",[28,88669,88671,88673],{"className":88670},[31],[33,88672],{"disabled":35,"type":36}," Always — PyPy is a strict superset of CPython with zero compatibility trade-offs, including every C-extension module",[28,88675,88677,88679],{"className":88676},[31],[33,88678],{"disabled":35,"type":36}," Never — PyPy cannot execute real-world Python code",[28,88681,88683,88685],{"className":88682},[31],[33,88684],{"disabled":35,"type":36}," Only for short-lived CLI scripts, since PyPy has effectively no startup cost",[66,88687,88688,88690,88695],{},[69,88689,71],{},[73,88691,88692,88694],{},[76,88693,78],{}," A — For a long-running, CPU-bound, pure-Python workload where JIT warm-up time is acceptable and speed matters — PyPy can substantially outperform CPython there",[73,88696,88697,355,88699,88701],{},[76,88698,84],{},[76,88700,55328],{}," — PyPy's JIT needs time to warm up and profile hot paths before it pays off, so it shines on long-lived processes, not brief scripts (making option D backwards). Option B is the tempting-but-wrong choice: historically PyPy has had incomplete or slower support for CPython's C-extension API, so libraries with heavy C extensions (some numeric\u002Fscientific packages) are not automatically a free win — compatibility must be checked. Option C is simply false; PyPy runs the vast majority of pure-Python code correctly.",[15,88703,88704,88708,88730,88780],{"language":82278},[18,88705,88707],{"id":88706},"q19-what-is-the-recommended-way-to-confirm-exactly-which-python-interpreter-and-version-will-run-a-project-especially-with-multiple-installs-or-virtual-environments-present","Q19. What is the recommended way to confirm exactly which Python interpreter and version will run a project, especially with multiple installs or virtual environments present?",[257,88709,88710],{"language":82278},[260,88711,88713],{"className":84589,"code":88712,"language":82278,"meta":264,"style":264},"python --version\nwhich python\n",[39,88714,88715,88722],{"__ignoreMap":264},[268,88716,88717,88719],{"class":270,"line":271},[268,88718,87455],{"class":278},[268,88720,88721],{"class":305}," --version\n",[268,88723,88724,88727],{"class":270,"line":286},[268,88725,88726],{"class":305},"which",[268,88728,88729],{"class":289}," python\n",[23,88731,88733,88749,88758,88767],{"className":88732},[26],[28,88734,88736,88738,88739,186,88742,7255,88745,88748],{"className":88735},[31],[33,88737],{"disabled":35,"type":36}," Run ",[39,88740,88741],{},"python --version",[39,88743,88744],{},"which python",[39,88746,88747],{},"where python"," on Windows) to check both the version and the exact executable path in use",[28,88750,88752,88754,88755,88757],{"className":88751},[31],[33,88753],{"disabled":35,"type":36}," Assume the system ",[39,88756,87455],{}," command always resolves to Python 3, since Python 2 was removed from every OS by 2021",[28,88759,88761,88763,88764,88766],{"className":88760},[31],[33,88762],{"disabled":35,"type":36}," Open a ",[39,88765,87670],{}," file in a text editor and read the version header",[28,88768,88770,88772,88773,88775,88776,88779],{"className":88769},[31],[33,88771],{"disabled":35,"type":36}," Check the script's file extension — ",[39,88774,87695],{}," always means Python 3, ",[39,88777,88778],{},".py2"," means Python 2",[66,88781,88782,88784,88795],{},[69,88783,71],{},[73,88785,88786,88788,88789,186,88791,7255,88793,88748],{},[76,88787,78],{}," A — Run ",[39,88790,88741],{},[39,88792,88744],{},[39,88794,88747],{},[73,88796,88797,355,88799,88801,88802,88804,88805,88807,88808,88810,88811,88813,88814,88816],{},[76,88798,84],{},[76,88800,17307],{}," — on many systems ",[39,88803,87455],{}," may still resolve to Python 2, to a ",[39,88806,88182],{}," shim, or to a virtual environment's interpreter, so checking both the reported version and the resolved binary path avoids running against the wrong interpreter. Option B is a real-world trap — some Linux distributions and older macOS installs kept ",[39,88809,87455],{}," pointing at Python 2 well past its EOL. Options C and D describe checks that don't actually work; ",[39,88812,88778],{}," is not a recognized extension and ",[39,88815,87670],{}," is binary, not readable version metadata.",[15,88818,88819,88823,88840,88877],{"language":82278},[18,88820,88822],{"id":88821},"q20-what-is-the-idiomatic-way-to-explore-a-scripts-own-functionsclasses-interactively-without-retyping-all-of-its-definitions-at-the-prompt","Q20. What is the idiomatic way to explore a script's own functions\u002Fclasses interactively without retyping all of its definitions at the prompt?",[257,88824,88825],{"language":82278},[260,88826,88828],{"className":84589,"code":88827,"language":82278,"meta":264,"style":264},"python -i script.py\n",[39,88829,88830],{"__ignoreMap":264},[268,88831,88832,88834,88837],{"class":270,"line":271},[268,88833,87455],{"class":278},[268,88835,88836],{"class":305}," -i",[268,88838,88839],{"class":289}," script.py\n",[23,88841,88843,88853,88862,88868],{"className":88842},[26],[28,88844,88846,88848,88849,88852],{"className":88845},[31],[33,88847],{"disabled":35,"type":36}," Manually retype every class and function definition at the ",[39,88850,88851],{},">>>"," prompt each session",[28,88854,88856,4353,88858,88861],{"className":88855},[31],[33,88857],{"disabled":35,"type":36},[39,88859,88860],{},"python -i script.py"," (or an enhanced shell like IPython) to run the script and then drop into an interactive session with its namespace already loaded",[28,88863,88865,88867],{"className":88864},[31],[33,88866],{"disabled":35,"type":36}," There is no way to combine a script with the REPL — they are mutually exclusive execution modes",[28,88869,88871,88873,88874,88876],{"className":88870},[31],[33,88872],{"disabled":35,"type":36}," Rename the script to ",[39,88875,87670],{}," and import that file directly into the REPL",[66,88878,88879,88881,88887],{},[69,88880,71],{},[73,88882,88883,4409,88885,88861],{},[76,88884,78],{},[39,88886,88860],{},[73,88888,88889,355,88891,53650,88893,88895,88896,88898,88899,88901],{},[76,88890,84],{},[76,88892,17307],{},[39,88894,84616],{}," flag executes the given script and then hands control to an interactive prompt with all of that script's top-level names already bound, which is the standard way to poke at real project state without retyping code. Option A works but wastes effort and invites transcription errors. Option C is simply false. Option D doesn't work as described — you don't \"import\" a ",[39,88897,87670],{}," by renaming a ",[39,88900,87695],{},"; the cache format is an implementation detail, not a user-facing import mechanism.",[2107,88903,88904],{},"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 .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-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 .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 .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}",{"title":264,"searchDepth":286,"depth":286,"links":88906},[88907,88908,88909,88911,88913,88915,88917,88918,88920,88922,88924,88926,88928,88930,88932,88933,88934,88935,88936,88937],{"id":87363,"depth":296,"text":87364},{"id":87410,"depth":296,"text":87411},{"id":87458,"depth":296,"text":88910},"Q3. In Python 3, how must print be used?",{"id":87553,"depth":296,"text":88912},"Q4. What does \u002F (true division) return in Python 3 when dividing two integers?",{"id":87666,"depth":296,"text":88914},"Q5. What does a .pyc file contain?",{"id":87723,"depth":296,"text":88916},"Q6. Where does CPython 3 store cached bytecode for an imported module named utils.py, by default?",{"id":87809,"depth":296,"text":87810},{"id":87860,"depth":296,"text":88919},"Q8. At the interactive REPL, what does the special name _ refer to immediately after evaluating an expression?",{"id":87967,"depth":296,"text":88921},"Q9. What determines whether CPython recompiles a module instead of reusing its cached .pyc, under the default (non hash-based) invalidation mode?",{"id":88028,"depth":296,"text":88923},"Q10. Does the script you run directly (e.g., python app.py) get its own .pyc written to __pycache__?",{"id":88110,"depth":296,"text":88925},"Q11. Two different Python versions, 3.9 and 3.11, both import the same utils.py from a shared __pycache__ directory. What happens?",{"id":88188,"depth":296,"text":88927},"Q12. A developer deletes a stray __pycache__ directory before committing a project to git. Is this safe?",{"id":88259,"depth":296,"text":88929},"Q13. Which statement correctly contrasts str between Python 2 and Python 3?",{"id":88358,"depth":296,"text":88931},"Q14. What is the effect of invoking the interpreter with the -O flag, e.g. python -O app.py?",{"id":88470,"depth":296,"text":88471},{"id":88519,"depth":296,"text":88520},{"id":88598,"depth":296,"text":88599},{"id":88657,"depth":296,"text":88658},{"id":88706,"depth":296,"text":88707},{"id":88821,"depth":296,"text":88822},{},"\u002Fpython\u002F01-introduction-and-setup",{"title":6,"description":264},"python\u002F01-introduction-and-setup","yMQ8Hor4P5NFEEZ0_C9RQOFJ204AULep8Zd8rbOpUB0",{"id":88944,"title":2152,"body":88945,"description":264,"extension":2144,"meta":91644,"navigation":35,"path":91645,"seo":91646,"stem":91647,"__hash__":91648},"content\u002Fpython\u002F02-variables-and-data-types.md",{"type":8,"value":88946,"toc":91609},[88947,88949,89050,89145,89298,89358,89500,89661,89781,89943,90123,90284,90395,90552,90764,90843,90936,91054,91139,91260,91448,91606],[11,88948,2152],{"id":2157},[15,88950,88951,88955,88985,89017],{"language":87455},[18,88952,88954],{"id":88953},"q1-which-statement-correctly-describes-pythons-object-model","Q1. Which statement correctly describes Python's object model?",[257,88956,88957],{"language":87455},[260,88958,88960],{"className":87467,"code":88959,"language":87455,"meta":264,"style":264},"x = 42\ndef greet(): pass\n",[39,88961,88962,88972],{"__ignoreMap":264},[268,88963,88964,88967,88969],{"class":270,"line":271},[268,88965,88966],{"class":282},"x ",[268,88968,302],{"class":274},[268,88970,88971],{"class":305}," 42\n",[268,88973,88974,88977,88979,88982],{"class":270,"line":286},[268,88975,88976],{"class":274},"def",[268,88978,3679],{"class":278},[268,88980,88981],{"class":282},"(): ",[268,88983,88984],{"class":274},"pass\n",[23,88986,88988,88997,89003,89009],{"className":88987},[26],[28,88989,88991,88993,88994,88996],{"className":88990},[31],[33,88992],{"disabled":35,"type":36}," Only class instances are objects; primitives like ",[39,88995,87646],{}," and functions are special language constructs",[28,88998,89000,89002],{"className":88999},[31],[33,89001],{"disabled":35,"type":36}," Everything referenced by a name — integers, strings, functions, classes, and modules — is an object with a type and identity",[28,89004,89006,89008],{"className":89005},[31],[33,89007],{"disabled":35,"type":36}," Only mutable values (lists, dicts) are objects; immutable values are stored inline, not as objects",[28,89010,89012,89014,89015],{"className":89011},[31],[33,89013],{"disabled":35,"type":36}," Objects exist only after you explicitly instantiate a class with ",[39,89016,16952],{},[66,89018,89019,89021,89026],{},[69,89020,71],{},[73,89022,89023,89025],{},[76,89024,78],{}," B — Everything referenced by a name — integers, strings, functions, classes, and modules — is an object with a type and identity",[73,89027,89028,89030,89031,42,89033,89035,89036,186,89038,89040,89041,89044,89045,186,89047,89049],{},[76,89029,84],{}," In Python, \"everything is an object\" is not a slogan but a literal implementation fact: ",[39,89032,4659],{},[39,89034,12761],{},", and even the ",[39,89037,87646],{},[39,89039,275],{}," types themselves are objects with a type, an identity (",[39,89042,89043],{},"id()","), and typically attributes. Option A is the kind of assumption carried over from languages with true primitive types, which Python does not have. Option C is backwards — immutability affects whether an object can change in place, not whether it \"is\" an object. Option D is wrong because literals like ",[39,89046,4659],{},[39,89048,85975],{}," are objects the moment they're created, with no explicit constructor call required.",[15,89051,89052,89061,89087,89122],{"language":87455},[18,89053,89055,89056,89058,89059,1685],{"id":89054},"q2-what-happens-when-a-name-already-bound-to-an-int-is-reassigned-to-a-str","Q2. What happens when a name already bound to an ",[39,89057,87646],{}," is reassigned to a ",[39,89060,17109],{},[257,89062,89063],{"language":87455},[260,89064,89066],{"className":87467,"code":89065,"language":87455,"meta":264,"style":264},"status = 200\nstatus = \"OK\"\n",[39,89067,89068,89078],{"__ignoreMap":264},[268,89069,89070,89073,89075],{"class":270,"line":271},[268,89071,89072],{"class":282},"status ",[268,89074,302],{"class":274},[268,89076,89077],{"class":305}," 200\n",[268,89079,89080,89082,89084],{"class":270,"line":286},[268,89081,89072],{"class":282},[268,89083,302],{"class":274},[268,89085,89086],{"class":289}," \"OK\"\n",[23,89088,89090,89098,89104,89113],{"className":89089},[26],[28,89091,89093,812,89095,89097],{"className":89092},[31],[33,89094],{"disabled":35,"type":36},[39,89096,827],{},", because a variable's type cannot change after first assignment",[28,89099,89101,89103],{"className":89100},[31],[33,89102],{"disabled":35,"type":36}," This is legal — Python is dynamically typed, so a name can be rebound to any object regardless of the previous object's type",[28,89105,89107,89109,89110,89112],{"className":89106},[31],[33,89108],{"disabled":35,"type":36}," The assignment silently converts ",[39,89111,18260],{}," to an integer to match the variable's original type",[28,89114,89116,89118,89119,11115],{"className":89115},[31],[33,89117],{"disabled":35,"type":36}," It works only if both statements are inside the same ",[39,89120,89121],{},"with",[66,89123,89124,89126,89131],{},[69,89125,71],{},[73,89127,89128,89130],{},[76,89129,78],{}," B — This is legal — Python is dynamically typed, so a name can be rebound to any object regardless of the previous object's type",[73,89132,89133,89135,89136,89138,89139,89141,89142,89144],{},[76,89134,84],{}," Python variables are just names in a namespace bound to objects; the name ",[39,89137,13305],{}," has no fixed type of its own, so rebinding it to a ",[39,89140,17109],{}," after an ",[39,89143,87646],{}," is completely legal at runtime. Option A confuses Python with statically-typed languages that give variables a fixed declared type. Option C invents a coercion Python never performs implicitly between unrelated types. Option D's premise is irrelevant — no such scoping restriction exists.",[15,89146,89147,89155,89205,89250],{"language":87455},[18,89148,89150,89151,186,89153,1685],{"id":89149},"q3-what-is-the-core-difference-between-is-and","Q3. What is the core difference between ",[39,89152,4447],{},[39,89154,3197],{},[257,89156,89157],{"language":87455},[260,89158,89160],{"className":87467,"code":89159,"language":87455,"meta":264,"style":264},"a = [1, 2, 3]\nb = [1, 2, 3]\n",[39,89161,89162,89184],{"__ignoreMap":264},[268,89163,89164,89167,89169,89171,89173,89175,89177,89179,89181],{"class":270,"line":271},[268,89165,89166],{"class":282},"a ",[268,89168,302],{"class":274},[268,89170,8710],{"class":282},[268,89172,2255],{"class":305},[268,89174,42],{"class":282},[268,89176,2258],{"class":305},[268,89178,42],{"class":282},[268,89180,3423],{"class":305},[268,89182,89183],{"class":282},"]\n",[268,89185,89186,89189,89191,89193,89195,89197,89199,89201,89203],{"class":270,"line":286},[268,89187,89188],{"class":282},"b ",[268,89190,302],{"class":274},[268,89192,8710],{"class":282},[268,89194,2255],{"class":305},[268,89196,42],{"class":282},[268,89198,2258],{"class":305},[268,89200,42],{"class":282},[268,89202,3423],{"class":305},[268,89204,89183],{"class":282},[23,89206,89208,89219,89233,89239],{"className":89207},[26],[28,89209,89211,355,89213,89215,89216,89218],{"className":89210},[31],[33,89212],{"disabled":35,"type":36},[39,89214,4447],{}," checks value equality; ",[39,89217,3197],{}," checks object identity",[28,89220,89222,355,89224,89226,89227,89229,89230,2690],{"className":89221},[31],[33,89223],{"disabled":35,"type":36},[39,89225,4447],{}," checks object identity (same object in memory); ",[39,89228,3197],{}," checks value equality (calls ",[39,89231,89232],{},"__eq__",[28,89234,89236,89238],{"className":89235},[31],[33,89237],{"disabled":35,"type":36}," They are fully interchangeable for all built-in types",[28,89240,89242,355,89244,89246,89247,89249],{"className":89241},[31],[33,89243],{"disabled":35,"type":36},[39,89245,4447],{}," only works on numbers; ",[39,89248,3197],{}," only works on strings",[66,89251,89252,89254,89264],{},[69,89253,71],{},[73,89255,89256,1727,89258,89226,89260,89229,89262,2690],{},[76,89257,78],{},[39,89259,4447],{},[39,89261,3197],{},[39,89263,89232],{},[73,89265,89266,355,89268,89270,89271,5904,89274,89276,89277,89279,89280,830,89283,89286,89287,830,89290,89292,89293,186,89295,89297],{},[76,89267,84],{},[39,89269,4447],{}," answers \"are these the same object?\" (equivalent to comparing ",[39,89272,89273],{},"id(a) == id(b)",[39,89275,3197],{}," answers \"do these compare equal?\" by invoking ",[39,89278,89232],{},". In the code above, ",[39,89281,89282],{},"a == b",[39,89284,89285],{},"True"," (same contents) but ",[39,89288,89289],{},"a is b",[39,89291,88449],{}," (two distinct list objects). Option A states the definitions backwards. Option C is a common trap — for mutable objects and most non-cached immutables, ",[39,89294,4447],{},[39,89296,3197],{}," diverge exactly as shown here. Option D is simply false; both operators work across types.",[15,89299,89300,89307,89334],{},[18,89301,89303,89304,89306],{"id":89302},"q4-what-does-the-built-in-id-function-return","Q4. What does the built-in ",[39,89305,89043],{}," function return?",[23,89308,89310,89316,89322,89328],{"className":89309},[26],[28,89311,89313,89315],{"className":89312},[31],[33,89314],{"disabled":35,"type":36}," The object's type name as a string",[28,89317,89319,89321],{"className":89318},[31],[33,89320],{"disabled":35,"type":36}," An integer that is guaranteed unique among currently alive objects during the program's run — in CPython, typically the object's memory address",[28,89323,89325,89327],{"className":89324},[31],[33,89326],{"disabled":35,"type":36}," A cryptographic hash of the object's contents",[28,89329,89331,89333],{"className":89330},[31],[33,89332],{"disabled":35,"type":36}," The line number where the object was created",[66,89335,89336,89338,89343],{},[69,89337,71],{},[73,89339,89340,89342],{},[76,89341,78],{}," B — An integer that is guaranteed unique among currently alive objects during the program's run — in CPython, typically the object's memory address",[73,89344,89345,355,89347,89349,89350,89353,89354,89357],{},[76,89346,84],{},[39,89348,89043],{}," returns a value guaranteed to be unique and constant for an object for its lifetime; CPython implements this as the object's memory address, but that detail is implementation-specific and should not be relied on beyond identity comparison. Option A describes ",[39,89351,89352],{},"type(obj).__name__",". Option C describes ",[39,89355,89356],{},"hash()",", which is a different, value-based concept and is not guaranteed unique. Option D describes nothing Python tracks by default.",[15,89359,89360,89364,89431],{},[18,89361,89363],{"id":89362},"q5-which-of-these-is-the-correct-classification-of-built-in-types-by-mutability","Q5. Which of these is the correct classification of built-in types by mutability?",[23,89365,89367,89388,89416,89422],{"className":89366},[26],[28,89368,89370,89372,89373,42,89375,42,89377,89380,89381,42,89383,42,89386],{"className":89369},[31],[33,89371],{"disabled":35,"type":36}," Mutable: ",[39,89374,87646],{},[39,89376,17109],{},[39,89378,89379],{},"tuple"," — Immutable: ",[39,89382,14924],{},[39,89384,89385],{},"dict",[39,89387,37910],{},[28,89389,89391,89372,89393,42,89395,42,89397,42,89399,89380,89402,42,89404,42,89406,42,89408,42,89410,42,89413],{"className":89390},[31],[33,89392],{"disabled":35,"type":36},[39,89394,14924],{},[39,89396,89385],{},[39,89398,37910],{},[39,89400,89401],{},"bytearray",[39,89403,87646],{},[39,89405,87642],{},[39,89407,17109],{},[39,89409,89379],{},[39,89411,89412],{},"bool",[39,89414,89415],{},"frozenset",[28,89417,89419,89421],{"className":89418},[31],[33,89420],{"disabled":35,"type":36}," All built-in container types are mutable; only numbers are immutable",[28,89423,89425,89427,89428],{"className":89424},[31],[33,89426],{"disabled":35,"type":36}," Mutability is a runtime flag you must set explicitly with ",[39,89429,89430],{},"mutable=True",[66,89432,89433,89435,89460],{},[69,89434,71],{},[73,89436,89437,89439,89440,42,89442,42,89444,42,89446,89380,89448,42,89450,42,89452,42,89454,42,89456,42,89458],{},[76,89438,78],{}," B — Mutable: ",[39,89441,14924],{},[39,89443,89385],{},[39,89445,37910],{},[39,89447,89401],{},[39,89449,87646],{},[39,89451,87642],{},[39,89453,17109],{},[39,89455,89379],{},[39,89457,89412],{},[39,89459,89415],{},[73,89461,89462,355,89464,42,89466,42,89468,137,89470,89472,89473,42,89476,42,89479,89481,89482,42,89484,42,89486,42,89488,42,89490,137,89492,89494,89495,186,89497,89499],{},[76,89463,84],{},[39,89465,14924],{},[39,89467,89385],{},[39,89469,37910],{},[39,89471,89401],{}," support in-place mutation (",[39,89474,89475],{},"append",[39,89477,89478],{},"__setitem__",[39,89480,41889],{},", and friends), whereas ",[39,89483,87646],{},[39,89485,87642],{},[39,89487,17109],{},[39,89489,89379],{},[39,89491,89412],{},[39,89493,89415],{}," cannot be changed after creation — any \"modification\" actually produces a new object. Option A has the classification exactly backwards. Option C is wrong because ",[39,89496,89379],{},[39,89498,89415],{}," are containers that are nonetheless immutable. Option D describes a mechanism Python does not have — mutability is a property of the type, not a per-instance flag.",[15,89501,89502,89515,89561,89611],{"language":87455},[18,89503,89505,89506,186,89509,30040,89512,89514],{"id":89504},"q6-what-is-the-difference-between-typeobj-someclass-and-isinstanceobj-someclass-when-obj-might-be-an-instance-of-a-subclass","Q6. What is the difference between ",[39,89507,89508],{},"type(obj) == SomeClass",[39,89510,89511],{},"isinstance(obj, SomeClass)",[39,89513,22990],{}," might be an instance of a subclass?",[257,89516,89517],{"language":87455},[260,89518,89520],{"className":87467,"code":89519,"language":87455,"meta":264,"style":264},"class Animal: pass\nclass Dog(Animal): pass\n\nd = Dog()\n",[39,89521,89522,89532,89547,89551],{"__ignoreMap":264},[268,89523,89524,89526,89528,89530],{"class":270,"line":271},[268,89525,1468],{"class":274},[268,89527,29687],{"class":278},[268,89529,1783],{"class":282},[268,89531,88984],{"class":274},[268,89533,89534,89536,89538,89540,89542,89545],{"class":270,"line":286},[268,89535,1468],{"class":274},[268,89537,30493],{"class":278},[268,89539,622],{"class":282},[268,89541,29893],{"class":278},[268,89543,89544],{"class":282},"): ",[268,89546,88984],{"class":274},[268,89548,89549],{"class":270,"line":296},[268,89550,5033],{"emptyLinePlaceholder":35},[268,89552,89553,89556,89558],{"class":270,"line":311},[268,89554,89555],{"class":282},"d ",[268,89557,302],{"class":274},[268,89559,89560],{"class":282}," Dog()\n",[23,89562,89564,89570,89593,89603],{"className":89563},[26],[28,89565,89567,89569],{"className":89566},[31],[33,89568],{"disabled":35,"type":36}," They always behave identically for every object",[28,89571,89573,355,89575,830,89578,89580,89581,89583,89584,830,89587,2833,89589,89592],{"className":89572},[31],[33,89574],{"disabled":35,"type":36},[39,89576,89577],{},"type(d) == Animal",[39,89579,88449],{}," for a ",[39,89582,30602],{}," instance, while ",[39,89585,89586],{},"isinstance(d, Animal)",[39,89588,89285],{},[39,89590,89591],{},"isinstance"," accounts for inheritance",[28,89594,89596,355,89598,830,89600,89602],{"className":89595},[31],[33,89597],{"disabled":35,"type":36},[39,89599,89577],{},[39,89601,89285],{}," because Python treats subclasses as equal types",[28,89604,89606,355,89608,89610],{"className":89605},[31],[33,89607],{"disabled":35,"type":36},[39,89609,89591],{}," only works with built-in types, not user-defined classes",[66,89612,89613,89615,89631],{},[69,89614,71],{},[73,89616,89617,1727,89619,830,89621,89580,89623,89583,89625,830,89627,2833,89629,89592],{},[76,89618,78],{},[39,89620,89577],{},[39,89622,88449],{},[39,89624,30602],{},[39,89626,89586],{},[39,89628,89285],{},[39,89630,89591],{},[73,89632,89633,355,89635,89638,89639,89641,89642,89644,89645,89647,89648,89650,89651,89653,89654,89657,89658,89660],{},[76,89634,84],{},[39,89636,89637],{},"type(d)"," returns the exact class ",[39,89640,30602],{},", which does not equal ",[39,89643,29893],{},", whereas ",[39,89646,89591],{}," walks the MRO and correctly reports that a ",[39,89649,30602],{}," \"is-an\" ",[39,89652,29893],{},". This distinction matters constantly in real code that accepts subclasses polymorphically. Option A ignores exactly this divergence. Option C misunderstands ",[39,89655,89656],{},"type()",", which never treats a subclass as equal to its parent. Option D is false — ",[39,89659,89591],{}," works uniformly across built-in and user-defined classes.",[15,89662,89663,89673,89709,89748],{"language":87455},[18,89664,89666,89667,7501,89669,358,89671,1685],{"id":89665},"q7-what-happens-when-you-execute-b-a-where-a-is-a-list","Q7. What happens when you execute ",[39,89668,2849],{},[39,89670,1223],{},[39,89672,14924],{},[257,89674,89675],{"language":87455},[260,89676,89678],{"className":87467,"code":89677,"language":87455,"meta":264,"style":264},"a = [1, 2, 3]\nb = a\n",[39,89679,89680,89700],{"__ignoreMap":264},[268,89681,89682,89684,89686,89688,89690,89692,89694,89696,89698],{"class":270,"line":271},[268,89683,89166],{"class":282},[268,89685,302],{"class":274},[268,89687,8710],{"class":282},[268,89689,2255],{"class":305},[268,89691,42],{"class":282},[268,89693,2258],{"class":305},[268,89695,42],{"class":282},[268,89697,3423],{"class":305},[268,89699,89183],{"class":282},[268,89701,89702,89704,89706],{"class":270,"line":286},[268,89703,89188],{"class":282},[268,89705,302],{"class":274},[268,89707,89708],{"class":282}," a\n",[23,89710,89712,89720,89731,89739],{"className":89711},[26],[28,89713,89715,89717,89718],{"className":89714},[31],[33,89716],{"disabled":35,"type":36}," A new, independent copy of the list is created and bound to ",[39,89719,1232],{},[28,89721,89723,355,89725,89727,89728,89730],{"className":89722},[31],[33,89724],{"disabled":35,"type":36},[39,89726,1232],{}," becomes a second name bound to the exact same list object as ",[39,89729,1223],{},"; no copying occurs",[28,89732,89734,355,89736,89738],{"className":89733},[31],[33,89735],{"disabled":35,"type":36},[39,89737,1232],{}," is bound to a lazily-copied \"view\" that only copies on first mutation",[28,89740,89742,89744,89745,89747],{"className":89741},[31],[33,89743],{"disabled":35,"type":36}," This raises a ",[39,89746,827],{}," because lists cannot be reassigned",[66,89749,89750,89752,89760],{},[69,89751,71],{},[73,89753,89754,1727,89756,89727,89758,89730],{},[76,89755,78],{},[39,89757,1232],{},[39,89759,1223],{},[73,89761,89762,89764,89765,186,89767,89769,89770,830,89772,89774,89775,89777,89778,89780],{},[76,89763,84],{}," Assignment in Python never copies an object; it binds a name to whatever object is on the right-hand side. So ",[39,89766,1223],{},[39,89768,1232],{}," here are two labels for one list, and ",[39,89771,89289],{},[39,89773,89285],{}," — mutating through either name affects what the other sees. Option A describes copy semantics found in some other languages, not Python's default ",[39,89776,302],{},". Option C describes copy-on-write, a strategy CPython does not use for ",[39,89779,14924],{}," assignment. Option D is false; reassignment is always legal.",[15,89782,89783,89787,89856,89899],{"language":87455},[18,89784,89786],{"id":89785},"q8-given-the-following-what-is-printed-and-why","Q8. Given the following, what is printed, and why?",[257,89788,89789],{"language":87455},[260,89790,89792],{"className":87467,"code":89791,"language":87455,"meta":264,"style":264},"a = 100\nb = 100\nprint(a is b)\n\nx = 1000\ny = 1000\nprint(x is y)\n",[39,89793,89794,89803,89811,89822,89826,89835,89844],{"__ignoreMap":264},[268,89795,89796,89798,89800],{"class":270,"line":271},[268,89797,89166],{"class":282},[268,89799,302],{"class":274},[268,89801,89802],{"class":305}," 100\n",[268,89804,89805,89807,89809],{"class":270,"line":286},[268,89806,89188],{"class":282},[268,89808,302],{"class":274},[268,89810,89802],{"class":305},[268,89812,89813,89815,89817,89819],{"class":270,"line":296},[268,89814,84797],{"class":305},[268,89816,7218],{"class":282},[268,89818,4447],{"class":274},[268,89820,89821],{"class":282}," b)\n",[268,89823,89824],{"class":270,"line":311},[268,89825,5033],{"emptyLinePlaceholder":35},[268,89827,89828,89830,89832],{"class":270,"line":788},[268,89829,88966],{"class":282},[268,89831,302],{"class":274},[268,89833,89834],{"class":305}," 1000\n",[268,89836,89837,89840,89842],{"class":270,"line":1951},[268,89838,89839],{"class":282},"y ",[268,89841,302],{"class":274},[268,89843,89834],{"class":305},[268,89845,89846,89848,89851,89853],{"class":270,"line":8955},[268,89847,84797],{"class":305},[268,89849,89850],{"class":282},"(x ",[268,89852,4447],{"class":274},[268,89854,89855],{"class":282}," y)\n",[23,89857,89859,89869,89879,89889],{"className":89858},[26],[28,89860,89862,355,89864,1133,89866,89868],{"className":89861},[31],[33,89863],{"disabled":35,"type":36},[39,89865,89285],{},[39,89867,89285],{}," — CPython always caches and reuses every integer object",[28,89870,89872,355,89874,1133,89876,89878],{"className":89871},[31],[33,89873],{"disabled":35,"type":36},[39,89875,89285],{},[39,89877,88449],{}," — CPython pre-caches and interns small integers in the range -5 to 256, but not arbitrary larger integers, which may or may not be separate objects depending on context",[28,89880,89882,355,89884,1133,89886,89888],{"className":89881},[31],[33,89883],{"disabled":35,"type":36},[39,89885,88449],{},[39,89887,88449],{}," — integers are never cached in CPython",[28,89890,89892,355,89894,1133,89896,89898],{"className":89891},[31],[33,89893],{"disabled":35,"type":36},[39,89895,88449],{},[39,89897,89285],{}," — only large integers are cached to save memory",[66,89900,89901,89903,89911],{},[69,89902,71],{},[73,89904,89905,1727,89907,1133,89909,89878],{},[76,89906,78],{},[39,89908,89285],{},[39,89910,88449],{},[73,89912,89913,355,89915,89917,89918,89920,89921,89923,89924,89926,89927,89930,89931,89933,89934,89936,89937,89939,89940,89942],{},[76,89914,84],{},[76,89916,55328],{}," — as a memory optimization, CPython pre-allocates and reuses a singleton object for every integer from -5 to 256, so ",[39,89919,89289],{}," is reliably ",[39,89922,89285],{}," for ",[39,89925,13912],{},". Numbers outside that range are ordinarily created fresh each time (",[39,89928,89929],{},"x is y"," is typically ",[39,89932,88449],{},", though this is an implementation detail that can vary — e.g. constant-folding within the same compiled code unit can sometimes make it ",[39,89935,89285],{}," too). The trap is treating ",[39,89938,4447],{}," as safe for comparing arbitrary integers just because it \"worked\" during testing with small numbers; always use ",[39,89941,3197],{}," for integer value comparison.",[15,89944,89945,89949,90038,90075],{"language":87455},[18,89946,89948],{"id":89947},"q9-what-is-the-most-accurate-description-of-cpython-string-interning","Q9. What is the most accurate description of CPython string interning?",[257,89950,89951],{"language":87455},[260,89952,89954],{"className":87467,"code":89953,"language":87455,"meta":264,"style":264},"s1 = \"hello\"\ns2 = \"hello\"\nprint(s1 is s2)\n\ns3 = \"\".join([\"h\", \"e\", \"l\", \"l\", \"o\"])\nprint(s1 is s3)\n",[39,89955,89956,89966,89975,89987,89991,90027],{"__ignoreMap":264},[268,89957,89958,89961,89963],{"class":270,"line":271},[268,89959,89960],{"class":282},"s1 ",[268,89962,302],{"class":274},[268,89964,89965],{"class":289}," \"hello\"\n",[268,89967,89968,89971,89973],{"class":270,"line":286},[268,89969,89970],{"class":282},"s2 ",[268,89972,302],{"class":274},[268,89974,89965],{"class":289},[268,89976,89977,89979,89982,89984],{"class":270,"line":296},[268,89978,84797],{"class":305},[268,89980,89981],{"class":282},"(s1 ",[268,89983,4447],{"class":274},[268,89985,89986],{"class":282}," s2)\n",[268,89988,89989],{"class":270,"line":311},[268,89990,5033],{"emptyLinePlaceholder":35},[268,89992,89993,89996,89998,90000,90003,90006,90008,90011,90013,90016,90018,90020,90022,90025],{"class":270,"line":788},[268,89994,89995],{"class":282},"s3 ",[268,89997,302],{"class":274},[268,89999,16759],{"class":289},[268,90001,90002],{"class":282},".join([",[268,90004,90005],{"class":289},"\"h\"",[268,90007,42],{"class":282},[268,90009,90010],{"class":289},"\"e\"",[268,90012,42],{"class":282},[268,90014,90015],{"class":289},"\"l\"",[268,90017,42],{"class":282},[268,90019,90015],{"class":289},[268,90021,42],{"class":282},[268,90023,90024],{"class":289},"\"o\"",[268,90026,85493],{"class":282},[268,90028,90029,90031,90033,90035],{"class":270,"line":1951},[268,90030,84797],{"class":305},[268,90032,89981],{"class":282},[268,90034,4447],{"class":274},[268,90036,90037],{"class":282}," s3)\n",[23,90039,90041,90047,90056,90067],{"className":90040},[26],[28,90042,90044,90046],{"className":90043},[31],[33,90045],{"disabled":35,"type":36}," All strings with equal content are always the same object, no matter how they are constructed",[28,90048,90050,90052,90053,90055],{"className":90049},[31],[33,90051],{"disabled":35,"type":36}," Compile-time string literals that look like identifiers are commonly interned and may share identity, but strings built at runtime (e.g. via concatenation or ",[39,90054,18112],{},") are typically distinct objects even with identical content",[28,90057,90059,90061,90062,90064,90065],{"className":90058},[31],[33,90060],{"disabled":35,"type":36}," No strings are ever interned in CPython; ",[39,90063,4447],{}," on strings is always ",[39,90066,88449],{},[28,90068,90070,90072,90073],{"className":90069},[31],[33,90071],{"disabled":35,"type":36}," Interning applies only to numeric strings like ",[39,90074,3415],{},[66,90076,90077,90079,90086],{},[69,90078,71],{},[73,90080,90081,90083,90084,90055],{},[76,90082,78],{}," B — Compile-time string literals that look like identifiers are commonly interned and may share identity, but strings built at runtime (e.g. via concatenation or ",[39,90085,18112],{},[73,90087,90088,355,90090,90092,90093,90096,90097,20143,90099,90102,90103,90106,90107,830,90110,90112,90113,90115,90116,90118,90119,23662,90121,462],{},[76,90089,84],{},[76,90091,16523],{}," — CPython, as an optimization, often interns short literals that resemble identifiers at compile time, so ",[39,90094,90095],{},"s1 is s2"," frequently prints ",[39,90098,89285],{},[39,90100,90101],{},"s3",", built at runtime via ",[39,90104,90105],{},"\"\".join(...)",", is a freshly allocated string object even though it's equal in content, so ",[39,90108,90109],{},"s1 is s3",[39,90111,88449],{},". This is a classic footgun: code that appears to work using ",[39,90114,4447],{}," for string comparison in a quick test can silently break once the string is produced dynamically (e.g., from user input, formatting, or ",[39,90117,1246],{}," concatenation). Always compare string values with ",[39,90120,3197],{},[39,90122,4447],{},[15,90124,90125,90129,90174,90225],{"language":87455},[18,90126,90128],{"id":90127},"q10-what-does-the-following-print-and-why-is-it-surprising","Q10. What does the following print, and why is it surprising?",[257,90130,90131],{"language":87455},[260,90132,90134],{"className":87467,"code":90133,"language":87455,"meta":264,"style":264},"n = float(\"nan\")\nprint(n == n)\nprint(n is n)\n",[39,90135,90136,90153,90164],{"__ignoreMap":264},[268,90137,90138,90141,90143,90146,90148,90151],{"class":270,"line":271},[268,90139,90140],{"class":282},"n ",[268,90142,302],{"class":274},[268,90144,90145],{"class":305}," float",[268,90147,622],{"class":282},[268,90149,90150],{"class":289},"\"nan\"",[268,90152,20702],{"class":282},[268,90154,90155,90157,90159,90161],{"class":270,"line":286},[268,90156,84797],{"class":305},[268,90158,13376],{"class":282},[268,90160,3197],{"class":274},[268,90162,90163],{"class":282}," n)\n",[268,90165,90166,90168,90170,90172],{"class":270,"line":296},[268,90167,84797],{"class":305},[268,90169,13376],{"class":282},[268,90171,4447],{"class":274},[268,90173,90163],{"class":282},[23,90175,90177,90187,90205,90215],{"className":90176},[26],[28,90178,90180,355,90182,1133,90184,90186],{"className":90179},[31],[33,90181],{"disabled":35,"type":36},[39,90183,89285],{},[39,90185,89285],{}," — a value always equals itself",[28,90188,90190,355,90192,1133,90194,90196,90197,4948,90199,90201,90202,90204],{"className":90189},[31],[33,90191],{"disabled":35,"type":36},[39,90193,88449],{},[39,90195,89285],{}," — per IEEE 754, NaN never equals itself under ",[39,90198,3197],{},[39,90200,4447],{}," compares identity, and it's the same object bound to ",[39,90203,4599],{}," both times",[28,90206,90208,355,90210,1133,90212,90214],{"className":90207},[31],[33,90209],{"disabled":35,"type":36},[39,90211,88449],{},[39,90213,88449],{}," — NaN breaks both identity and equality checks",[28,90216,90218,355,90220,1133,90222,90224],{"className":90217},[31],[33,90219],{"disabled":35,"type":36},[39,90221,89285],{},[39,90223,88449],{}," — NaN is equal to itself but Python creates a new object on each reference",[66,90226,90227,90229,90243],{},[69,90228,71],{},[73,90230,90231,1727,90233,1133,90235,90196,90237,4948,90239,90201,90241,90204],{},[76,90232,78],{},[39,90234,88449],{},[39,90236,89285],{},[39,90238,3197],{},[39,90240,4447],{},[39,90242,4599],{},[73,90244,90245,355,90247,3990,90249,90252,90253,830,90255,10548,90257,830,90260,90262,90263,90265,90266,830,90269,90271,90272,90275,90276,90279,90280,90283],{},[76,90246,84],{},[76,90248,16523],{},[39,90250,90251],{},"NaN != NaN"," is mandated by the IEEE 754 floating-point standard (any comparison involving NaN except ",[39,90254,7733],{},[39,90256,88449],{},[39,90258,90259],{},"n == n",[39,90261,88449],{}," even though ",[39,90264,4599],{}," is literally the same object as itself. ",[39,90267,90268],{},"n is n",[39,90270,89285],{}," because identity doesn't care about the value-equality rules at all — it's trivially the same object. This is a real production gotcha: ",[39,90273,90274],{},"x == x"," is not a safe way to detect NaN; use ",[39,90277,90278],{},"math.isnan(x)"," instead, and remember ",[39,90281,90282],{},"NaN in some_list"," can silently fail to find a NaN it should logically match.",[15,90285,90286,90290,90328,90360],{"language":87455},[18,90287,90289],{"id":90288},"q11-do-two-independently-created-empty-tuples-share-identity","Q11. Do two independently created empty tuples share identity?",[257,90291,90292],{"language":87455},[260,90293,90295],{"className":87467,"code":90294,"language":87455,"meta":264,"style":264},"t1 = ()\nt2 = ()\nprint(t1 is t2)\n",[39,90296,90297,90307,90316],{"__ignoreMap":264},[268,90298,90299,90302,90304],{"class":270,"line":271},[268,90300,90301],{"class":282},"t1 ",[268,90303,302],{"class":274},[268,90305,90306],{"class":282}," ()\n",[268,90308,90309,90312,90314],{"class":270,"line":286},[268,90310,90311],{"class":282},"t2 ",[268,90313,302],{"class":274},[268,90315,90306],{"class":282},[268,90317,90318,90320,90323,90325],{"class":270,"line":296},[268,90319,84797],{"class":305},[268,90321,90322],{"class":282},"(t1 ",[268,90324,4447],{"class":274},[268,90326,90327],{"class":282}," t2)\n",[23,90329,90331,90337,90343,90349],{"className":90330},[26],[28,90332,90334,90336],{"className":90333},[31],[33,90335],{"disabled":35,"type":36}," No — every tuple literal, even an empty one, allocates a new object",[28,90338,90340,90342],{"className":90339},[31],[33,90341],{"disabled":35,"type":36}," Yes — CPython caches a singleton empty tuple, so both names typically refer to the same object",[28,90344,90346,90348],{"className":90345},[31],[33,90347],{"disabled":35,"type":36}," Only inside function bodies, never at module level",[28,90350,90352,90354,90355,8574,90358],{"className":90351},[31],[33,90353],{"disabled":35,"type":36}," Only if both are explicitly declared with ",[39,90356,90357],{},"tuple()",[39,90359,16952],{},[66,90361,90362,90364,90369],{},[69,90363,71],{},[73,90365,90366,90368],{},[76,90367,78],{}," B — Yes — CPython caches a singleton empty tuple, so both names typically refer to the same object",[73,90370,90371,355,90373,90375,90376,830,90379,90381,90382,830,90385,90387,90388,90391,90392,90394],{},[76,90372,84],{},[76,90374,55328],{}," — because the empty tuple is immutable and has no meaningful internal state to diverge, CPython optimizes by reusing one singleton empty-tuple object everywhere, so ",[39,90377,90378],{},"t1 is t2",[39,90380,89285],{},". This is a CPython implementation detail (not a language guarantee), unlike, say, empty lists, where ",[39,90383,90384],{},"[] is []",[39,90386,88449],{}," because lists are mutable and must never be silently shared. The lesson generalizes: never write code whose correctness ",[104,90389,90390],{},"depends"," on such identity caching — use ",[39,90393,3197],{}," for comparisons regardless.",[15,90396,90397,90401,90471,90517],{"language":87455},[18,90398,90400],{"id":90399},"q12-a-function-receives-a-mutable-list-and-appends-to-it-but-also-reassigns-the-parameter-name-inside-the-function-what-does-the-caller-observe","Q12. A function receives a mutable list and appends to it, but also reassigns the parameter name inside the function. What does the caller observe?",[257,90402,90403],{"language":87455},[260,90404,90406],{"className":87467,"code":90405,"language":87455,"meta":264,"style":264},"def process(items):\n    items.append(\"processed\")\n    items = [\"replaced\"]\n\ndata = [\"order-1\"]\nprocess(data)\nprint(data)\n",[39,90407,90408,90417,90427,90441,90445,90459,90464],{"__ignoreMap":264},[268,90409,90410,90412,90414],{"class":270,"line":271},[268,90411,88976],{"class":274},[268,90413,10851],{"class":278},[268,90415,90416],{"class":282},"(items):\n",[268,90418,90419,90422,90425],{"class":270,"line":286},[268,90420,90421],{"class":282},"    items.append(",[268,90423,90424],{"class":289},"\"processed\"",[268,90426,20702],{"class":282},[268,90428,90429,90432,90434,90436,90439],{"class":270,"line":296},[268,90430,90431],{"class":282},"    items ",[268,90433,302],{"class":274},[268,90435,8710],{"class":282},[268,90437,90438],{"class":289},"\"replaced\"",[268,90440,89183],{"class":282},[268,90442,90443],{"class":270,"line":311},[268,90444,5033],{"emptyLinePlaceholder":35},[268,90446,90447,90450,90452,90454,90457],{"class":270,"line":788},[268,90448,90449],{"class":282},"data ",[268,90451,302],{"class":274},[268,90453,8710],{"class":282},[268,90455,90456],{"class":289},"\"order-1\"",[268,90458,89183],{"class":282},[268,90460,90461],{"class":270,"line":1951},[268,90462,90463],{"class":282},"process(data)\n",[268,90465,90466,90468],{"class":270,"line":8955},[268,90467,84797],{"class":305},[268,90469,90470],{"class":282},"(data)\n",[23,90472,90474,90483,90500,90509],{"className":90473},[26],[28,90475,90477,355,90479,90482],{"className":90476},[31],[33,90478],{"disabled":35,"type":36},[39,90480,90481],{},"[\"replaced\"]"," — the reassignment inside the function propagates back to the caller",[28,90484,90486,355,90488,90491,90492,90494,90495,90497,90498],{"className":90485},[31],[33,90487],{"disabled":35,"type":36},[39,90489,90490],{},"[\"order-1\", \"processed\"]"," — the in-place ",[39,90493,89475],{}," mutates the shared object the caller sees, but rebinding the local name ",[39,90496,56380],{}," only affects the local scope, not the caller's ",[39,90499,21188],{},[28,90501,90503,355,90505,90508],{"className":90502},[31],[33,90504],{"disabled":35,"type":36},[39,90506,90507],{},"[\"order-1\"]"," — function calls never affect the caller's objects",[28,90510,90512,812,90514,90516],{"className":90511},[31],[33,90513],{"disabled":35,"type":36},[39,90515,827],{},", because you cannot both mutate and reassign a parameter in the same function",[66,90518,90519,90521,90533],{},[69,90520,71],{},[73,90522,90523,1727,90525,90491,90527,90494,90529,90497,90531],{},[76,90524,78],{},[39,90526,90490],{},[39,90528,89475],{},[39,90530,56380],{},[39,90532,21188],{},[73,90534,90535,90537,90538,90541,90542,90545,90546,90548,90549,90551],{},[76,90536,84],{}," Python passes arguments by binding the parameter name to the same object the caller passed (\"pass by object reference\"). ",[39,90539,90540],{},"items.append(...)"," mutates that shared list, so the caller sees it. But ",[39,90543,90544],{},"items = [\"replaced\"]"," merely rebinds the local name ",[39,90547,56380],{}," to point at a brand-new list — it does not, and cannot, reach back and change what ",[39,90550,21188],{}," points to. Beginners often expect either \"everything propagates\" (A) or \"nothing propagates\" (C); the real behavior is a mix, and it's the single most common source of confusion around Python's argument-passing model. Option D describes a restriction that doesn't exist.",[15,90553,90554,90560,90614,90685],{"language":87455},[18,90555,90557,90558,1685],{"id":90556},"q13-what-does-the-following-print-and-what-does-it-reveal-about-bool","Q13. What does the following print, and what does it reveal about ",[39,90559,89412],{},[257,90561,90562],{"language":87455},[260,90563,90565],{"className":87467,"code":90564,"language":87455,"meta":264,"style":264},"print(True == 1)\nprint(isinstance(True, int))\nprint(True + True)\n",[39,90566,90567,90581,90599],{"__ignoreMap":264},[268,90568,90569,90571,90573,90575,90577,90579],{"class":270,"line":271},[268,90570,84797],{"class":305},[268,90572,622],{"class":282},[268,90574,89285],{"class":305},[268,90576,3165],{"class":274},[268,90578,2199],{"class":305},[268,90580,20702],{"class":282},[268,90582,90583,90585,90587,90589,90591,90593,90595,90597],{"class":270,"line":286},[268,90584,84797],{"class":305},[268,90586,622],{"class":282},[268,90588,89591],{"class":305},[268,90590,622],{"class":282},[268,90592,89285],{"class":305},[268,90594,42],{"class":282},[268,90596,87646],{"class":305},[268,90598,47690],{"class":282},[268,90600,90601,90603,90605,90607,90609,90612],{"class":270,"line":296},[268,90602,84797],{"class":305},[268,90604,622],{"class":282},[268,90606,89285],{"class":305},[268,90608,3350],{"class":274},[268,90610,90611],{"class":305}," True",[268,90613,20702],{"class":282},[23,90615,90617,90629,90656,90668],{"className":90616},[26],[28,90618,90620,355,90622,42,90624,42,90626,90628],{"className":90619},[31],[33,90621],{"disabled":35,"type":36},[39,90623,88449],{},[39,90625,88449],{},[39,90627,827],{}," — booleans are unrelated to integers",[28,90630,90632,355,90634,42,90636,42,90638,3990,90640,90642,90643,90645,90646,446,90648,90650,90651,446,90653,90655],{"className":90631},[31],[33,90633],{"disabled":35,"type":36},[39,90635,89285],{},[39,90637,89285],{},[39,90639,2258],{},[39,90641,89412],{}," is a subclass of ",[39,90644,87646],{}," in Python, so ",[39,90647,89285],{},[39,90649,88449],{}," behave as ",[39,90652,2255],{},[39,90654,3307],{}," in arithmetic and comparisons",[28,90657,90659,355,90661,42,90663,42,90665,90667],{"className":90658},[31],[33,90660],{"disabled":35,"type":36},[39,90662,89285],{},[39,90664,88449],{},[39,90666,827],{}," — booleans equal integers by value but are not related by type",[28,90669,90671,355,90673,42,90675,42,90677,3990,90679,90681,90682,90684],{"className":90670},[31],[33,90672],{"disabled":35,"type":36},[39,90674,88449],{},[39,90676,89285],{},[39,90678,2258],{},[39,90680,89412],{}," inherits from ",[39,90683,87646],{}," but the values are never equal",[66,90686,90687,90689,90711],{},[69,90688,71],{},[73,90690,90691,1727,90693,42,90695,42,90697,3990,90699,90642,90701,90645,90703,446,90705,90650,90707,446,90709,90655],{},[76,90692,78],{},[39,90694,89285],{},[39,90696,89285],{},[39,90698,2258],{},[39,90700,89412],{},[39,90702,87646],{},[39,90704,89285],{},[39,90706,88449],{},[39,90708,2255],{},[39,90710,3307],{},[73,90712,90713,355,90715,3990,90717,90719,90720,90722,90723,186,90725,90727,90728,186,90730,90732,90733,830,90736,42,90738,830,90741,137,90743,5409,90746,90748,90749,11464,90752,137,90754,90757,90758,186,90761,462],{},[76,90714,84],{},[76,90716,16523],{},[39,90718,89412],{}," is literally a subclass of ",[39,90721,87646],{},", with ",[39,90724,89285],{},[39,90726,88449],{}," behaving as ",[39,90729,2255],{},[39,90731,3307],{}," respectively; that's why ",[39,90734,90735],{},"True == 1",[39,90737,89285],{},[39,90739,90740],{},"isinstance(True, int)",[39,90742,89285],{},[39,90744,90745],{},"True + True",[39,90747,2258],{}," without error. This surprises people who assume booleans are a wholly separate type. It has real consequences: ",[39,90750,90751],{},"sum([True, False, True])",[39,90753,2258],{},[39,90755,90756],{},"{1: \"a\", True: \"b\"}"," collapses to a single key because ",[39,90759,90760],{},"1 == True",[39,90762,90763],{},"hash(1) == hash(True)",[15,90765,90766,90778,90813],{},[18,90767,90769,90770,90773,90774,90777],{"id":90768},"q14-is-it-safe-to-compare-idobj_a-idobj_b-for-two-objects-that-existed-at-different-non-overlapping-points-in-a-long-running-program-to-conclude-they-were-the-same-object","Q14. Is it safe to compare ",[39,90771,90772],{},"id(obj_a) == id(obj_b)"," for two objects that existed at ",[104,90775,90776],{},"different, non-overlapping"," points in a long-running program to conclude they were \"the same object\"?",[23,90779,90781,90790,90799,90807],{"className":90780},[26],[28,90782,90784,90786,90787,90789],{"className":90783},[31],[33,90785],{"disabled":35,"type":36}," Yes, ",[39,90788,89043],{}," values are globally unique for all time, so a match always proves it was the same object",[28,90791,90793,90795,90796,90798],{"className":90792},[31],[33,90794],{"disabled":35,"type":36}," No — once an object is garbage-collected, CPython may reuse its freed memory address for a completely unrelated new object, so a matching ",[39,90797,89043],{}," across non-overlapping lifetimes proves nothing",[28,90800,90802,79131,90804,90806],{"className":90801},[31],[33,90803],{"disabled":35,"type":36},[39,90805,89043],{}," is randomized on every call and never repeats",[28,90808,90810,90812],{"className":90809},[31],[33,90811],{"disabled":35,"type":36}," Yes, but only for immutable types",[66,90814,90815,90817,90824],{},[69,90816,71],{},[73,90818,90819,90821,90822,90798],{},[76,90820,78],{}," B — No — once an object is garbage-collected, CPython may reuse its freed memory address for a completely unrelated new object, so a matching ",[39,90823,89043],{},[73,90825,90826,355,90828,3990,90830,90832,90833,90836,90837,90839,90840,90842],{},[76,90827,84],{},[76,90829,17613],{},[39,90831,89043],{}," uniqueness is only guaranteed among objects that are alive ",[104,90834,90835],{},"at the same time","; CPython's allocator is free to hand a freshly freed address to a brand-new, unrelated object. A long-running service that logs ",[39,90838,89043],{}," values to \"track\" objects across time can be misled into thinking two clearly different objects are the same one. The safe pattern is to keep a live reference (preventing garbage collection) for as long as identity needs to be checked, rather than persisting bare ",[39,90841,89043],{}," integers.",[15,90844,90845,90856,90878,90913],{"language":87455},[18,90846,90848,90849,90851,90852,90855],{"id":90847},"q15-what-is-the-idiomatic-way-to-check-whether-obj-is-an-instance-of-myclass-or-one-of-its-subclasses","Q15. What is the idiomatic way to check whether ",[39,90850,22990],{}," is an instance of ",[39,90853,90854],{},"MyClass"," or one of its subclasses?",[257,90857,90858],{"language":87455},[260,90859,90861],{"className":87467,"code":90860,"language":87455,"meta":264,"style":264},"if isinstance(obj, MyClass):\n    ...\n",[39,90862,90863,90873],{"__ignoreMap":264},[268,90864,90865,90867,90870],{"class":270,"line":271},[268,90866,2179],{"class":274},[268,90868,90869],{"class":305}," isinstance",[268,90871,90872],{"class":282},"(obj, MyClass):\n",[268,90874,90875],{"class":270,"line":286},[268,90876,90877],{"class":305},"    ...\n",[23,90879,90881,90889,90897,90905],{"className":90880},[26],[28,90882,90884,355,90886],{"className":90883},[31],[33,90885],{"disabled":35,"type":36},[39,90887,90888],{},"if type(obj) == MyClass:",[28,90890,90892,355,90894],{"className":90891},[31],[33,90893],{"disabled":35,"type":36},[39,90895,90896],{},"if isinstance(obj, MyClass):",[28,90898,90900,355,90902],{"className":90899},[31],[33,90901],{"disabled":35,"type":36},[39,90903,90904],{},"if obj.__class__.__name__ == \"MyClass\":",[28,90906,90908,355,90910],{"className":90907},[31],[33,90909],{"disabled":35,"type":36},[39,90911,90912],{},"if str(type(obj)) == \"MyClass\":",[66,90914,90915,90917,90923],{},[69,90916,71],{},[73,90918,90919,1727,90921],{},[76,90920,78],{},[39,90922,90896],{},[73,90924,90925,355,90927,3990,90929,90931,90932,90935],{},[76,90926,84],{},[76,90928,17307],{},[39,90930,89591],{}," is the idiomatic, subclass-aware check and also gracefully supports checking against a tuple of types (",[39,90933,90934],{},"isinstance(obj, (int, float))","). Option A silently excludes legitimate subclass instances, which routinely breaks polymorphic code paths (e.g., custom exceptions or ORM model subclasses). Options C and D are fragile string-matching hacks that break under refactors, module renames, or subclassing, and are never the recommended approach.",[15,90937,90938,90945,90969,91004],{"language":87455},[18,90939,90941,90942,1685],{"id":90940},"q16-what-is-the-idiomatic-way-to-check-whether-a-variable-is-none","Q16. What is the idiomatic way to check whether a variable is ",[39,90943,90944],{},"None",[257,90946,90947],{"language":87455},[260,90948,90950],{"className":87467,"code":90949,"language":87455,"meta":264,"style":264},"if value is None:\n    ...\n",[39,90951,90952,90965],{"__ignoreMap":264},[268,90953,90954,90956,90958,90960,90963],{"class":270,"line":271},[268,90955,2179],{"class":274},[268,90957,4789],{"class":282},[268,90959,4447],{"class":274},[268,90961,90962],{"class":305}," None",[268,90964,8931],{"class":282},[268,90966,90967],{"class":270,"line":286},[268,90968,90877],{"class":305},[23,90970,90972,90980,90988,90996],{"className":90971},[26],[28,90973,90975,355,90977],{"className":90974},[31],[33,90976],{"disabled":35,"type":36},[39,90978,90979],{},"if value == None:",[28,90981,90983,355,90985],{"className":90982},[31],[33,90984],{"disabled":35,"type":36},[39,90986,90987],{},"if value is None:",[28,90989,90991,355,90993],{"className":90990},[31],[33,90992],{"disabled":35,"type":36},[39,90994,90995],{},"if not value:",[28,90997,90999,355,91001],{"className":90998},[31],[33,91000],{"disabled":35,"type":36},[39,91002,91003],{},"if value.__eq__(None):",[66,91005,91006,91008,91014],{},[69,91007,71],{},[73,91009,91010,1727,91012],{},[76,91011,78],{},[39,91013,90987],{},[73,91015,91016,355,91018,3990,91020,91022,91023,446,91025,89923,91028,91030,91031,91034,91035,91037,91038,91040,91041,91043,91044,91046,91047,42,91049,137,91051,91053],{},[76,91017,84],{},[76,91019,17307],{},[39,91021,90944],{}," is a singleton, so identity comparison is both correct and faster than an equality check, and PEP 8 explicitly recommends ",[39,91024,4447],{},[39,91026,91027],{},"is not",[39,91029,90944],{}," comparisons. Option A technically often works too (since ",[39,91032,91033],{},"None.__eq__"," falls back to identity-like behavior for the default case), but it's non-idiomatic and, critically, an object could override ",[39,91036,89232],{}," to claim it equals ",[39,91039,90944],{},", silently breaking an ",[39,91042,3197],{}," check in a way ",[39,91045,4447],{}," never can. Option C is a different, broader check — it also matches falsy values like ",[39,91048,3307],{},[39,91050,3294],{},[39,91052,3290],{},", which is a common and dangerous conflation with \"is None\". Option D is needlessly indirect and bypasses Python's reflected-comparison protocol.",[15,91055,91056,91065,91103],{},[18,91057,91059,91060,7501,91062,91064],{"id":91058},"q17-should-application-logic-ever-rely-on-cpythons-small-integer-or-string-interning-caching-ie-using-is-where-is-meant","Q17. Should application logic ever rely on CPython's small-integer or string-interning caching (i.e., using ",[39,91061,4447],{},[39,91063,3197],{}," is meant)?",[23,91066,91068,91074,91086,91092],{"className":91067},[26],[28,91069,91071,91073],{"className":91070},[31],[33,91072],{"disabled":35,"type":36}," Yes — it's a documented, guaranteed language feature safe to depend on",[28,91075,91077,91079,91080,91082,91083,91085],{"className":91076},[31],[33,91078],{"disabled":35,"type":36}," No — it is a CPython implementation detail that can change between versions\u002Fimplementations (e.g., PyPy) and even between contexts (interactive shell vs. module vs. ",[39,91081,88066],{}," optimizations); use ",[39,91084,3197],{}," for value comparisons",[28,91087,91089,91091],{"className":91088},[31],[33,91090],{"disabled":35,"type":36}," Yes, but only for integers, never for strings",[28,91093,91095,91097,91098,186,91100,91102],{"className":91094},[31],[33,91096],{"disabled":35,"type":36}," It doesn't matter, since ",[39,91099,4447],{},[39,91101,3197],{}," always agree for built-in immutable types",[66,91104,91105,91107,91116],{},[69,91106,71],{},[73,91108,91109,91111,91112,91082,91114,91085],{},[76,91110,78],{}," B — No — it is a CPython implementation detail that can change between versions\u002Fimplementations (e.g., PyPy) and even between contexts (interactive shell vs. module vs. ",[39,91113,88066],{},[39,91115,3197],{},[73,91117,91118,355,91120,91122,91123,91126,91127,91129,91130,91133,91134,186,91136,91138],{},[76,91119,84],{},[76,91121,88175],{}," — small-int caching and string interning are documented as CPython optimizations, not language guarantees; other implementations (PyPy, Jython) or even future CPython releases are free to cache differently, or not at all. Code that happens to pass tests because ",[39,91124,91125],{},"100 is 100"," was ",[39,91128,89285],{}," can fail unpredictably in a different environment or with slightly larger numbers. Option D is directly contradicted by the ",[39,91131,91132],{},"x = 1000; y = 1000"," example seen earlier in this quiz, where ",[39,91135,4447],{},[39,91137,3197],{}," diverge.",[15,91140,91141,91147,91186,91225],{"language":87455},[18,91142,91144,91145,1685],{"id":91143},"q18-which-of-the-following-can-be-used-as-a-key-in-a-dict","Q18. Which of the following can be used as a key in a ",[39,91146,89385],{},[257,91148,91149],{"language":87455},[260,91150,91152],{"className":87467,"code":91151,"language":87455,"meta":264,"style":264},"config = {\n    (\"region\", \"us-east-1\"): \"primary\",\n}\n",[39,91153,91154,91163,91182],{"__ignoreMap":264},[268,91155,91156,91159,91161],{"class":270,"line":271},[268,91157,91158],{"class":282},"config ",[268,91160,302],{"class":274},[268,91162,9914],{"class":282},[268,91164,91165,91167,91170,91172,91175,91177,91180],{"class":270,"line":286},[268,91166,17101],{"class":282},[268,91168,91169],{"class":289},"\"region\"",[268,91171,42],{"class":282},[268,91173,91174],{"class":289},"\"us-east-1\"",[268,91176,89544],{"class":282},[268,91178,91179],{"class":289},"\"primary\"",[268,91181,1789],{"class":282},[268,91183,91184],{"class":270,"line":296},[268,91185,314],{"class":282},[23,91187,91189,91197,91209,91217],{"className":91188},[26],[28,91190,91192,812,91194,91196],{"className":91191},[31],[33,91193],{"disabled":35,"type":36},[39,91195,14924],{},", since dict keys can be any object",[28,91198,91200,812,91202,91204,91205,91208],{"className":91199},[31],[33,91201],{"disabled":35,"type":36},[39,91203,89379],{}," of hashable elements, like ",[39,91206,91207],{},"(\"region\", \"us-east-1\")",", since it is immutable and hashable",[28,91210,91212,812,91214,91216],{"className":91211},[31],[33,91213],{"disabled":35,"type":36},[39,91215,89385],{},", since nesting dictionaries is common",[28,91218,91220,812,91222,91224],{"className":91219},[31],[33,91221],{"disabled":35,"type":36},[39,91223,37910],{},", since sets are also collections",[66,91226,91227,91229,91237],{},[69,91228,71],{},[73,91230,91231,853,91233,91204,91235,91208],{},[76,91232,78],{},[39,91234,89379],{},[39,91236,91207],{},[73,91238,91239,91241,91242,91245,91246,91248,91249,42,91251,137,91253,91255,91256,91259],{},[76,91240,84],{}," Dict keys must be hashable, which in practice means immutable (or at least implementing a stable ",[39,91243,91244],{},"__hash__","); a ",[39,91247,89379],{}," of hashable elements qualifies and is a common composite-key pattern. ",[39,91250,14924],{},[39,91252,89385],{},[39,91254,37910],{}," are all mutable and unhashable by default, so using any of them as a key raises ",[39,91257,91258],{},"TypeError: unhashable type",". This ties directly back to mutability: a hash must stay constant for an object's lifetime, and a mutable object's contents — and thus its \"natural\" hash — could change after insertion, which would corrupt the hash table.",[15,91261,91262,91271,91332,91384],{"language":87455},[18,91263,91265,91266,91268,91269,1685],{"id":91264},"q19-what-is-the-correct-defensive-way-to-convert-untrusted-user-input-like-abc-to-an-int","Q19. What is the correct, defensive way to convert untrusted user input like ",[39,91267,7004],{}," to an ",[39,91270,87646],{},[257,91272,91273],{"language":87455},[260,91274,91276],{"className":87467,"code":91275,"language":87455,"meta":264,"style":264},"raw = input(\"Enter age: \")\ntry:\n    age = int(raw)\nexcept ValueError:\n    age = None\n",[39,91277,91278,91294,91300,91313,91323],{"__ignoreMap":264},[268,91279,91280,91283,91285,91287,91289,91292],{"class":270,"line":271},[268,91281,91282],{"class":282},"raw ",[268,91284,302],{"class":274},[268,91286,17937],{"class":305},[268,91288,622],{"class":282},[268,91290,91291],{"class":289},"\"Enter age: \"",[268,91293,20702],{"class":282},[268,91295,91296,91298],{"class":270,"line":286},[268,91297,23142],{"class":274},[268,91299,8931],{"class":282},[268,91301,91302,91305,91307,91310],{"class":270,"line":296},[268,91303,91304],{"class":282},"    age ",[268,91306,302],{"class":274},[268,91308,91309],{"class":305}," int",[268,91311,91312],{"class":282},"(raw)\n",[268,91314,91315,91318,91321],{"class":270,"line":311},[268,91316,91317],{"class":274},"except",[268,91319,91320],{"class":305}," ValueError",[268,91322,8931],{"class":282},[268,91324,91325,91327,91329],{"class":270,"line":788},[268,91326,91304],{"class":282},[268,91328,302],{"class":274},[268,91330,91331],{"class":305}," None\n",[23,91333,91335,91344,91362,91371],{"className":91334},[26],[28,91336,91338,39927,91340,91343],{"className":91337},[31],[33,91339],{"disabled":35,"type":36},[39,91341,91342],{},"int(raw)"," directly and trust it will always succeed",[28,91345,91347,91349,91350,91353,91354,91357,91358,91361],{"className":91346},[31],[33,91348],{"disabled":35,"type":36}," Wrap the conversion in ",[39,91351,91352],{},"try\u002Fexcept ValueError"," (as shown), since ",[39,91355,91356],{},"int()"," raises ",[39,91359,91360],{},"ValueError"," on non-numeric strings rather than returning a sentinel",[28,91363,91365,4353,91367,91370],{"className":91364},[31],[33,91366],{"disabled":35,"type":36},[39,91368,91369],{},"float(raw)"," instead, since it never raises exceptions",[28,91372,91374,91376,91377,91380,91381,91383],{"className":91373},[31],[33,91375],{"disabled":35,"type":36}," Check ",[39,91378,91379],{},"raw.isdigit()"," only, since that alone guarantees ",[39,91382,91356],{}," will succeed for any valid integer, including negatives",[66,91385,91386,91388,91399],{},[69,91387,71],{},[73,91389,91390,91392,91393,91353,91395,91357,91397,91361],{},[76,91391,78],{}," B — Wrap the conversion in ",[39,91394,91352],{},[39,91396,91356],{},[39,91398,91360],{},[73,91400,91401,355,91403,2338,91405,91408,91409,91411,91412,99,91414,91416,91417,91419,91420,91357,91422,91424,91425,91428,91429,4912,91432,91434,91435,91437,91438,830,91441,91443,91444,91447],{},[76,91402,84],{},[39,91404,91356],{},[39,91406,91407],{},"float()",") raise ",[39,91410,91360],{}," for unparseable strings instead of returning ",[39,91413,90944],{},[39,91415,3307],{},", so unguarded conversion of external input is a production crash waiting to happen — catching ",[39,91418,91360],{}," is the correct handling. Option A ignores that risk entirely. Option C is wrong on its face — ",[39,91421,91407],{},[39,91423,91360],{}," too (e.g., ",[39,91426,91427],{},"float(\"abc\")","). Option D is a subtle trap: ",[39,91430,91431],{},"str.isdigit()",[39,91433,88449],{}," for a leading ",[39,91436,6244],{}," sign (",[39,91439,91440],{},"\"-5\".isdigit()",[39,91442,88449],{},"), so relying on it alone would reject legitimate negative integers even though ",[39,91445,91446],{},"int(\"-5\")"," succeeds fine.",[15,91449,91450,91461,91521,91565],{"language":87455},[18,91451,91453,91454,91457,91458,91460],{"id":91452},"q20-two-engineers-are-debugging-why-mutating-settings_copy-also-changed-settings-elsewhere-in-a-large-codebase-what-is-the-most-likely-root-cause","Q20. Two engineers are debugging why mutating ",[39,91455,91456],{},"settings_copy"," also changed ",[39,91459,20975],{}," elsewhere in a large codebase. What is the most likely root cause?",[257,91462,91463],{"language":87455},[260,91464,91466],{"className":87467,"code":91465,"language":87455,"meta":264,"style":264},"settings = {\"debug\": False}\nsettings_copy = settings\nsettings_copy[\"debug\"] = True\nprint(settings[\"debug\"])\n",[39,91467,91468,91486,91496,91510],{"__ignoreMap":264},[268,91469,91470,91473,91475,91477,91480,91482,91484],{"class":270,"line":271},[268,91471,91472],{"class":282},"settings ",[268,91474,302],{"class":274},[268,91476,85460],{"class":282},[268,91478,91479],{"class":289},"\"debug\"",[268,91481,1783],{"class":282},[268,91483,88449],{"class":305},[268,91485,314],{"class":282},[268,91487,91488,91491,91493],{"class":270,"line":286},[268,91489,91490],{"class":282},"settings_copy ",[268,91492,302],{"class":274},[268,91494,91495],{"class":282}," settings\n",[268,91497,91498,91501,91503,91505,91507],{"class":270,"line":296},[268,91499,91500],{"class":282},"settings_copy[",[268,91502,91479],{"class":289},[268,91504,19897],{"class":282},[268,91506,302],{"class":274},[268,91508,91509],{"class":305}," True\n",[268,91511,91512,91514,91517,91519],{"class":270,"line":311},[268,91513,84797],{"class":305},[268,91515,91516],{"class":282},"(settings[",[268,91518,91479],{"class":289},[268,91520,85493],{"class":282},[23,91522,91524,91533,91551,91559],{"className":91523},[26],[28,91525,91527,355,91529,91532],{"className":91526},[31],[33,91528],{"disabled":35,"type":36},[39,91530,91531],{},"settings_copy = settings"," silently created a deep copy, and the bug lies elsewhere",[28,91534,91536,355,91538,91540,91541,42,91544,383,91547,91550],{"className":91535},[31],[33,91537],{"disabled":35,"type":36},[39,91539,91531],{}," only creates a new alias to the same dict object — no copy was ever made, so mutating one mutates both; a real copy requires ",[39,91542,91543],{},"dict(settings)",[39,91545,91546],{},"settings.copy()",[39,91548,91549],{},"copy.deepcopy(settings)"," for nested structures",[28,91552,91554,355,91556,91558],{"className":91553},[31],[33,91555],{"disabled":35,"type":36},[39,91557,89385],{}," objects are immutable, so this code should have raised an exception",[28,91560,91562,91564],{"className":91561},[31],[33,91563],{"disabled":35,"type":36}," This is a garbage collector bug and cannot be fixed in user code",[66,91566,91567,91569,91581],{},[69,91568,71],{},[73,91570,91571,1727,91573,91540,91575,42,91577,383,91579,91550],{},[76,91572,78],{},[39,91574,91531],{},[39,91576,91543],{},[39,91578,91546],{},[39,91580,91549],{},[73,91582,91583,355,91585,91587,91588,91590,91591,8828,91593,91595,91596,91599,91600,91602,91603,91605],{},[76,91584,84],{},[76,91586,17307],{}," — this is the single most common real-world \"why did my data change on its own\" bug: plain ",[39,91589,302],{}," never copies a mutable object, it only adds another name pointing at the same one. The fix is to explicitly request a copy — a shallow copy (",[39,91592,91543],{},[39,91594,91546],{},") is enough for a flat dict of immutable values, while nested mutable structures need ",[39,91597,91598],{},"copy.deepcopy",". Option A describes behavior ",[39,91601,302],{}," simply does not have. Option C is false — ",[39,91604,89385],{}," is mutable by design. Option D misattributes an application-level aliasing bug to the garbage collector, which is unrelated.",[2107,91607,91608],{},"html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}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 .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}",{"title":264,"searchDepth":286,"depth":286,"links":91610},[91611,91612,91614,91616,91618,91619,91621,91623,91624,91625,91626,91627,91628,91630,91632,91634,91636,91638,91640,91642],{"id":88953,"depth":296,"text":88954},{"id":89054,"depth":296,"text":91613},"Q2. What happens when a name already bound to an int is reassigned to a str?",{"id":89149,"depth":296,"text":91615},"Q3. What is the core difference between is and ==?",{"id":89302,"depth":296,"text":91617},"Q4. What does the built-in id() function return?",{"id":89362,"depth":296,"text":89363},{"id":89504,"depth":296,"text":91620},"Q6. What is the difference between type(obj) == SomeClass and isinstance(obj, SomeClass) when obj might be an instance of a subclass?",{"id":89665,"depth":296,"text":91622},"Q7. What happens when you execute b = a where a is a list?",{"id":89785,"depth":296,"text":89786},{"id":89947,"depth":296,"text":89948},{"id":90127,"depth":296,"text":90128},{"id":90288,"depth":296,"text":90289},{"id":90399,"depth":296,"text":90400},{"id":90556,"depth":296,"text":91629},"Q13. What does the following print, and what does it reveal about bool?",{"id":90768,"depth":296,"text":91631},"Q14. Is it safe to compare id(obj_a) == id(obj_b) for two objects that existed at different, non-overlapping points in a long-running program to conclude they were \"the same object\"?",{"id":90847,"depth":296,"text":91633},"Q15. What is the idiomatic way to check whether obj is an instance of MyClass or one of its subclasses?",{"id":90940,"depth":296,"text":91635},"Q16. What is the idiomatic way to check whether a variable is None?",{"id":91058,"depth":296,"text":91637},"Q17. Should application logic ever rely on CPython's small-integer or string-interning caching (i.e., using is where == is meant)?",{"id":91143,"depth":296,"text":91639},"Q18. Which of the following can be used as a key in a dict?",{"id":91264,"depth":296,"text":91641},"Q19. What is the correct, defensive way to convert untrusted user input like \"abc\" to an int?",{"id":91452,"depth":296,"text":91643},"Q20. Two engineers are debugging why mutating settings_copy also changed settings elsewhere in a large codebase. What is the most likely root cause?",{},"\u002Fpython\u002F02-variables-and-data-types",{"title":2152,"description":264},"python\u002F02-variables-and-data-types","FolA5sswrjI0chDBgpu-qNnDTbTFI9OQloHc6wBjo3c",{"id":91650,"title":5211,"body":91651,"description":264,"extension":2144,"meta":94125,"navigation":35,"path":94126,"seo":94127,"stem":94128,"__hash__":94129},"content\u002Fpython\u002F03-operators-and-expressions.md",{"type":8,"value":91652,"toc":94103},[91653,91655,91776,91878,91991,92141,92238,92354,92504,92596,92694,92797,92907,93091,93276,93383,93482,93627,93768,93889,93984,94100],[11,91654,5211],{"id":5216},[15,91656,91657,91661,91696,91735],{"language":87455},[18,91658,91660],{"id":91659},"q1-what-does-the-following-print","Q1. What does the following print?",[257,91662,91663],{"language":87455},[260,91664,91666],{"className":87467,"code":91665,"language":87455,"meta":264,"style":264},"print(7 \u002F 2)\nprint(7 \u002F\u002F 2)\n",[39,91667,91668,91682],{"__ignoreMap":264},[268,91669,91670,91672,91674,91676,91678,91680],{"class":270,"line":271},[268,91671,84797],{"class":305},[268,91673,622],{"class":282},[268,91675,26963],{"class":305},[268,91677,84933],{"class":274},[268,91679,2214],{"class":305},[268,91681,20702],{"class":282},[268,91683,91684,91686,91688,91690,91692,91694],{"class":270,"line":286},[268,91685,84797],{"class":305},[268,91687,622],{"class":282},[268,91689,26963],{"class":305},[268,91691,84948],{"class":274},[268,91693,2214],{"class":305},[268,91695,20702],{"class":282},[23,91697,91699,91708,91717,91726],{"className":91698},[26],[28,91700,91702,355,91704,1133,91706],{"className":91701},[31],[33,91703],{"disabled":35,"type":36},[39,91705,85025],{},[39,91707,3423],{},[28,91709,91711,355,91713,1133,91715],{"className":91710},[31],[33,91712],{"disabled":35,"type":36},[39,91714,3423],{},[39,91716,85025],{},[28,91718,91720,355,91722,1133,91724],{"className":91719},[31],[33,91721],{"disabled":35,"type":36},[39,91723,85025],{},[39,91725,85025],{},[28,91727,91729,355,91731,1133,91733],{"className":91728},[31],[33,91730],{"disabled":35,"type":36},[39,91732,15049],{},[39,91734,3423],{},[66,91736,91737,91739,91747],{},[69,91738,71],{},[73,91740,91741,3459,91743,1133,91745],{},[76,91742,78],{},[39,91744,85025],{},[39,91746,3423],{},[73,91748,91749,355,91751,91753,91754,91756,91757,91759,91760,91762,91763,2182,91765,2758,91767,91769,91770,91772,91773,91775],{},[76,91750,84],{},[39,91752,446],{}," is true division and always returns a ",[39,91755,87642],{}," in Python 3, regardless of operand types. ",[39,91758,85028],{}," is floor division; with two ",[39,91761,87646],{}," operands it returns the floored quotient as an ",[39,91764,87646],{},[39,91766,3423],{},[39,91768,85025],{},"). B swaps the two operators' behavior. C wrongly assumes ",[39,91771,85028],{}," also returns a float for int operands. D rounds ",[39,91774,85022],{}," incorrectly instead of truncating toward the floor.",[15,91777,91778,91782,91815,91847],{"language":87455},[18,91779,91781],{"id":91780},"q2-what-does-the-following-print","Q2. What does the following print?",[257,91783,91784],{"language":87455},[260,91785,91787],{"className":87467,"code":91786,"language":87455,"meta":264,"style":264},"x = 5\nprint(1 \u003C x \u003C 10)\n",[39,91788,91789,91797],{"__ignoreMap":264},[268,91790,91791,91793,91795],{"class":270,"line":271},[268,91792,88966],{"class":282},[268,91794,302],{"class":274},[268,91796,85072],{"class":305},[268,91798,91799,91801,91803,91805,91807,91809,91811,91813],{"class":270,"line":286},[268,91800,84797],{"class":305},[268,91802,622],{"class":282},[268,91804,2255],{"class":305},[268,91806,6457],{"class":274},[268,91808,2382],{"class":282},[268,91810,1076],{"class":274},[268,91812,306],{"class":305},[268,91814,20702],{"class":282},[23,91816,91818,91825,91832,91840],{"className":91817},[26],[28,91819,91821,355,91823],{"className":91820},[31],[33,91822],{"disabled":35,"type":36},[39,91824,88449],{},[28,91826,91828,355,91830],{"className":91827},[31],[33,91829],{"disabled":35,"type":36},[39,91831,89285],{},[28,91833,91835,91837,91838],{"className":91834},[31],[33,91836],{"disabled":35,"type":36}," Raises ",[39,91839,1274],{},[28,91841,91843,355,91845],{"className":91842},[31],[33,91844],{"disabled":35,"type":36},[39,91846,5825],{},[66,91848,91849,91851,91857],{},[69,91850,71],{},[73,91852,91853,1727,91855],{},[76,91854,78],{},[39,91856,89285],{},[73,91858,91859,91861,91862,26085,91865,91868,91869,91871,91872,91874,91875,91877],{},[76,91860,84],{}," Python evaluates the chained comparison ",[39,91863,91864],{},"1 \u003C x \u003C 10",[39,91866,91867],{},"(1 \u003C x) and (x \u003C 10)",". Both sub-comparisons are ",[39,91870,89285],{}," here, so the result is ",[39,91873,89285],{},". C is wrong because chained comparisons are ordinary, valid Python syntax. D is wrong because comparison operators always yield a ",[39,91876,89412],{},", never one of the compared values.",[15,91879,91880,91884,91909,91940],{"language":87455},[18,91881,91883],{"id":91882},"q3-what-does-the-following-print","Q3. What does the following print?",[257,91885,91886],{"language":87455},[260,91887,91889],{"className":87467,"code":91888,"language":87455,"meta":264,"style":264},"print(5 \u003C 3 \u003C 10)\n",[39,91890,91891],{"__ignoreMap":264},[268,91892,91893,91895,91897,91899,91901,91903,91905,91907],{"class":270,"line":271},[268,91894,84797],{"class":305},[268,91896,622],{"class":282},[268,91898,2429],{"class":305},[268,91900,6457],{"class":274},[268,91902,3396],{"class":305},[268,91904,6457],{"class":274},[268,91906,306],{"class":305},[268,91908,20702],{"class":282},[23,91910,91912,91919,91926,91933],{"className":91911},[26],[28,91913,91915,355,91917],{"className":91914},[31],[33,91916],{"disabled":35,"type":36},[39,91918,89285],{},[28,91920,91922,91837,91924],{"className":91921},[31],[33,91923],{"disabled":35,"type":36},[39,91925,1274],{},[28,91927,91929,355,91931],{"className":91928},[31],[33,91930],{"disabled":35,"type":36},[39,91932,88449],{},[28,91934,91936,355,91938],{"className":91935},[31],[33,91937],{"disabled":35,"type":36},[39,91939,3423],{},[66,91941,91942,91944,91950],{},[69,91943,71],{},[73,91945,91946,1004,91948],{},[76,91947,78],{},[39,91949,88449],{},[73,91951,91952,355,91954,6405,91957,6320,91960,6320,91963,91965,91966,91969,91970,91972,91973,91975,91976,4977,91979,4977,91982,91984,91985,91987,91988,91990],{},[76,91953,84],{},[39,91955,91956],{},"5 \u003C 3 \u003C 10",[39,91958,91959],{},"(5 \u003C 3) and (3 \u003C 10)",[39,91961,91962],{},"False and True",[39,91964,88449],{},". A programmer used to C-family languages might expect left-to-right evaluation like ",[39,91967,91968],{},"(5 \u003C 3) \u003C 10",", which — because ",[39,91971,89412],{}," is a subtype of ",[39,91974,87646],{}," in Python — would actually compute ",[39,91977,91978],{},"False \u003C 10",[39,91980,91981],{},"0 \u003C 10",[39,91983,89285],{},". That is genuinely ",[104,91986,95],{}," how Python parses a comparison chain, which is why the real answer flips to ",[39,91989,88449],{},". B is wrong: chaining is valid syntax. D is nonsensical since comparisons never return an operand's value.",[15,91992,91993,91997,92054,92096],{"language":87455},[18,91994,91996],{"id":91995},"q4-what-does-the-following-print","Q4. What does the following print?",[257,91998,91999],{"language":87455},[260,92000,92002],{"className":87467,"code":92001,"language":87455,"meta":264,"style":264},"def f():\n    print(\"called\")\n    return 5\n\nprint(1 \u003C f() \u003C 10)\n",[39,92003,92004,92013,92025,92031,92035],{"__ignoreMap":264},[268,92005,92006,92008,92010],{"class":270,"line":271},[268,92007,88976],{"class":274},[268,92009,35259],{"class":278},[268,92011,92012],{"class":282},"():\n",[268,92014,92015,92018,92020,92023],{"class":270,"line":286},[268,92016,92017],{"class":305},"    print",[268,92019,622],{"class":282},[268,92021,92022],{"class":289},"\"called\"",[268,92024,20702],{"class":282},[268,92026,92027,92029],{"class":270,"line":296},[268,92028,9871],{"class":274},[268,92030,85072],{"class":305},[268,92032,92033],{"class":270,"line":311},[268,92034,5033],{"emptyLinePlaceholder":35},[268,92036,92037,92039,92041,92043,92045,92048,92050,92052],{"class":270,"line":788},[268,92038,84797],{"class":305},[268,92040,622],{"class":282},[268,92042,2255],{"class":305},[268,92044,6457],{"class":274},[268,92046,92047],{"class":282}," f() ",[268,92049,1076],{"class":274},[268,92051,306],{"class":305},[268,92053,20702],{"class":282},[23,92055,92057,92067,92076,92086],{"className":92056},[26],[28,92058,92060,355,92062,92064,92065],{"className":92059},[31],[33,92061],{"disabled":35,"type":36},[39,92063,55334],{}," is printed twice, then ",[39,92066,89285],{},[28,92068,92070,355,92072,92064,92074],{"className":92069},[31],[33,92071],{"disabled":35,"type":36},[39,92073,55334],{},[39,92075,88449],{},[28,92077,92079,355,92081,92083,92084],{"className":92078},[31],[33,92080],{"disabled":35,"type":36},[39,92082,55334],{}," is never printed, then ",[39,92085,89285],{},[28,92087,92089,355,92091,92093,92094],{"className":92088},[31],[33,92090],{"disabled":35,"type":36},[39,92092,55334],{}," is printed once, then ",[39,92095,89285],{},[66,92097,92098,92100,92108],{},[69,92099,71],{},[73,92101,92102,6901,92104,92093,92106],{},[76,92103,78],{},[39,92105,55334],{},[39,92107,89285],{},[73,92109,92110,92112,92113,92116,92117,92120,92121,92124,92125,92127,92128,92130,92131,186,92134,92137,92138,92140],{},[76,92111,84],{}," In a chained comparison, each middle sub-expression is evaluated only once and its value is reused for both surrounding comparisons. ",[39,92114,92115],{},"1 \u003C f() \u003C 10"," is not sugar for ",[39,92118,92119],{},"1 \u003C f() and f() \u003C 10"," (which would call ",[39,92122,92123],{},"f()"," twice, as A\u002FB assume) — it calls ",[39,92126,92123],{}," a single time, gets ",[39,92129,2429],{},", and checks ",[39,92132,92133],{},"1 \u003C 5",[39,92135,92136],{},"5 \u003C 10",", both ",[39,92139,89285],{},". C is wrong because the middle value must still be computed before any comparison can happen.",[15,92142,92143,92147,92180,92211],{"language":87455},[18,92144,92146],{"id":92145},"q5-what-does-the-following-print","Q5. What does the following print?",[257,92148,92149],{"language":87455},[260,92150,92152],{"className":87467,"code":92151,"language":87455,"meta":264,"style":264},"a = 100\nb = 100\nprint(a is b)\n",[39,92153,92154,92162,92170],{"__ignoreMap":264},[268,92155,92156,92158,92160],{"class":270,"line":271},[268,92157,89166],{"class":282},[268,92159,302],{"class":274},[268,92161,89802],{"class":305},[268,92163,92164,92166,92168],{"class":270,"line":286},[268,92165,89188],{"class":282},[268,92167,302],{"class":274},[268,92169,89802],{"class":305},[268,92171,92172,92174,92176,92178],{"class":270,"line":296},[268,92173,84797],{"class":305},[268,92175,7218],{"class":282},[268,92177,4447],{"class":274},[268,92179,89821],{"class":282},[23,92181,92183,92190,92197,92204],{"className":92182},[26],[28,92184,92186,355,92188],{"className":92185},[31],[33,92187],{"disabled":35,"type":36},[39,92189,89285],{},[28,92191,92193,355,92195],{"className":92192},[31],[33,92194],{"disabled":35,"type":36},[39,92196,88449],{},[28,92198,92200,91837,92202],{"className":92199},[31],[33,92201],{"disabled":35,"type":36},[39,92203,87958],{},[28,92205,92207,355,92209],{"className":92206},[31],[33,92208],{"disabled":35,"type":36},[39,92210,90944],{},[66,92212,92213,92215,92221],{},[69,92214,71],{},[73,92216,92217,3459,92219],{},[76,92218,78],{},[39,92220,89285],{},[73,92222,92223,92225,92226,92228,92229,92231,92232,92234,92235,92237],{},[76,92224,84],{}," CPython pre-allocates and caches small integers from -5 to 256 inclusive as singleton objects. Every reference to the literal ",[39,92227,13912],{}," resolves to the same cached object, so identity (",[39,92230,4447],{},") happens to agree with equality (",[39,92233,3197],{},") here. B is what you'd expect for arbitrary objects in general, but it doesn't hold inside this cached range — which is exactly the trap: it teaches beginners that ",[39,92236,4447],{}," \"works\" for ints when really it's a caching accident.",[15,92239,92240,92244,92277,92317],{"language":87455},[18,92241,92243],{"id":92242},"q6-what-does-the-following-print","Q6. What does the following print?",[257,92245,92246],{"language":87455},[260,92247,92249],{"className":87467,"code":92248,"language":87455,"meta":264,"style":264},"a = 1000\nb = 1000\nprint(a is b)\n",[39,92250,92251,92259,92267],{"__ignoreMap":264},[268,92252,92253,92255,92257],{"class":270,"line":271},[268,92254,89166],{"class":282},[268,92256,302],{"class":274},[268,92258,89834],{"class":305},[268,92260,92261,92263,92265],{"class":270,"line":286},[268,92262,89188],{"class":282},[268,92264,302],{"class":274},[268,92266,89834],{"class":305},[268,92268,92269,92271,92273,92275],{"class":270,"line":296},[268,92270,84797],{"class":305},[268,92272,7218],{"class":282},[268,92274,4447],{"class":274},[268,92276,89821],{"class":282},[23,92278,92280,92289,92300,92308],{"className":92279},[26],[28,92281,92283,92285,92286,92288],{"className":92282},[31],[33,92284],{"disabled":35,"type":36}," Always ",[39,92287,88449],{},", because 1000 is outside the small-int cache",[28,92290,92292,92294,92295,99,92297,92299],{"className":92291},[31],[33,92293],{"disabled":35,"type":36}," Unspecified — CPython may print ",[39,92296,89285],{},[39,92298,88449],{}," depending on compile-time constant folding and context, so don't rely on it",[28,92301,92303,92285,92305,92307],{"className":92302},[31],[33,92304],{"disabled":35,"type":36},[39,92306,89285],{},", because Python caches every integer used in a program",[28,92309,92311,91837,92313,92316],{"className":92310},[31],[33,92312],{"disabled":35,"type":36},[39,92314,92315],{},"OverflowError"," since 1000 doesn't fit in a cached slot",[66,92318,92319,92321,92330],{},[69,92320,71],{},[73,92322,92323,92325,92326,99,92328,92299],{},[76,92324,78],{}," B — Unspecified — CPython may print ",[39,92327,89285],{},[39,92329,88449],{},[73,92331,92332,92334,92335,830,92337,92339,92340,92342,92343,92345,92346,92348,92349,92351,92352,462],{},[76,92333,84],{}," Only integers from -5 to 256 are guaranteed cached singletons. Outside that range, whether ",[39,92336,89289],{},[39,92338,89285],{}," depends on implementation details like whether both ",[39,92341,70543],{}," literals get folded into the same code object's constant pool (common when both lines are compiled together, e.g. inside one script or function) versus compiled as separate top-level statements at an interactive prompt. This is not part of the language spec and can vary by CPython version or context, so A's \"always ",[39,92344,88449],{},"\" is too absolute — real CPython often prints ",[39,92347,89285],{}," in a script. The takeaway either way: never use ",[39,92350,4447],{}," for integer value comparison, use ",[39,92353,3197],{},[15,92355,92356,92360,92418,92453],{"language":87455},[18,92357,92359],{"id":92358},"q7-what-does-the-following-print","Q7. What does the following print?",[257,92361,92362],{"language":87455},[260,92363,92365],{"className":87467,"code":92364,"language":87455,"meta":264,"style":264},"a = \"hello\"\nb = \"hello\"\nc = \"\".join([\"he\", \"llo\"])\nprint(a is b, a is c)\n",[39,92366,92367,92375,92383,92404],{"__ignoreMap":264},[268,92368,92369,92371,92373],{"class":270,"line":271},[268,92370,89166],{"class":282},[268,92372,302],{"class":274},[268,92374,89965],{"class":289},[268,92376,92377,92379,92381],{"class":270,"line":286},[268,92378,89188],{"class":282},[268,92380,302],{"class":274},[268,92382,89965],{"class":289},[268,92384,92385,92388,92390,92392,92394,92397,92399,92402],{"class":270,"line":296},[268,92386,92387],{"class":282},"c ",[268,92389,302],{"class":274},[268,92391,16759],{"class":289},[268,92393,90002],{"class":282},[268,92395,92396],{"class":289},"\"he\"",[268,92398,42],{"class":282},[268,92400,92401],{"class":289},"\"llo\"",[268,92403,85493],{"class":282},[268,92405,92406,92408,92410,92412,92414,92416],{"class":270,"line":311},[268,92407,84797],{"class":305},[268,92409,7218],{"class":282},[268,92411,4447],{"class":274},[268,92413,21694],{"class":282},[268,92415,4447],{"class":274},[268,92417,86213],{"class":282},[23,92419,92421,92429,92437,92445],{"className":92420},[26],[28,92422,92424,355,92426],{"className":92423},[31],[33,92425],{"disabled":35,"type":36},[39,92427,92428],{},"True True",[28,92430,92432,355,92434],{"className":92431},[31],[33,92433],{"disabled":35,"type":36},[39,92435,92436],{},"False False",[28,92438,92440,355,92442],{"className":92439},[31],[33,92441],{"disabled":35,"type":36},[39,92443,92444],{},"True False",[28,92446,92448,355,92450],{"className":92447},[31],[33,92449],{"disabled":35,"type":36},[39,92451,92452],{},"False True",[66,92454,92455,92457,92463],{},[69,92456,71],{},[73,92458,92459,1004,92461],{},[76,92460,78],{},[39,92462,92444],{},[73,92464,92465,355,92467,3990,92469,186,92471,92473,92474,92476,92477,355,92479,3277,92481,92483,92484,92487,92488,830,92491,90262,92493,830,92496,92498,92499,92501,92502,462],{},[76,92466,84],{},[76,92468,17307],{},[39,92470,1223],{},[39,92472,1232],{}," are the identical literal ",[39,92475,4436],{}," compiled into the same code object, so CPython typically interns\u002Fdedupes it, making ",[39,92478,89289],{},[39,92480,89285],{},[39,92482,16484],{}," is built at runtime via ",[39,92485,92486],{},"str.join",", producing a fresh string object with equal content but a distinct identity, so ",[39,92489,92490],{},"a is c",[39,92492,88449],{},[39,92494,92495],{},"a == c",[39,92497,89285],{},". String interning is a CPython implementation detail, not a language guarantee — never rely on ",[39,92500,4447],{}," for string equality, always use ",[39,92503,3197],{},[15,92505,92506,92510,92533,92567],{"language":87455},[18,92507,92509],{"id":92508},"q8-what-does-the-following-print","Q8. What does the following print?",[257,92511,92512],{"language":87455},[260,92513,92515],{"className":87467,"code":92514,"language":87455,"meta":264,"style":264},"print(-7 \u002F\u002F 2)\n",[39,92516,92517],{"__ignoreMap":264},[268,92518,92519,92521,92523,92525,92527,92529,92531],{"class":270,"line":271},[268,92520,84797],{"class":305},[268,92522,622],{"class":282},[268,92524,6244],{"class":274},[268,92526,26963],{"class":305},[268,92528,84948],{"class":274},[268,92530,2214],{"class":305},[268,92532,20702],{"class":282},[23,92534,92536,92544,92551,92559],{"className":92535},[26],[28,92537,92539,355,92541],{"className":92538},[31],[33,92540],{"disabled":35,"type":36},[39,92542,92543],{},"-3",[28,92545,92547,355,92549],{"className":92546},[31],[33,92548],{"disabled":35,"type":36},[39,92550,3423],{},[28,92552,92554,355,92556],{"className":92553},[31],[33,92555],{"disabled":35,"type":36},[39,92557,92558],{},"-3.5",[28,92560,92562,355,92564],{"className":92561},[31],[33,92563],{"disabled":35,"type":36},[39,92565,92566],{},"-4",[66,92568,92569,92571,92577],{},[69,92570,71],{},[73,92572,92573,6901,92575],{},[76,92574,78],{},[39,92576,92566],{},[73,92578,92579,355,92581,3990,92583,92585,92586,137,92589,92592,92593,92595],{},[76,92580,84],{},[76,92582,88175],{},[39,92584,85028],{}," floors the true quotient toward negative infinity: ",[39,92587,92588],{},"-7 \u002F 2 = -3.5",[39,92590,92591],{},"floor(-3.5) = -4",". This differs from C\u002FJava integer division, which truncates toward zero and would give ",[39,92594,92543],{}," (option A) — a common bug when porting numeric code between languages.",[15,92597,92598,92602,92626,92657],{"language":87455},[18,92599,92601],{"id":92600},"q9-what-does-the-following-print","Q9. What does the following print?",[257,92603,92604],{"language":87455},[260,92605,92607],{"className":87467,"code":92606,"language":87455,"meta":264,"style":264},"print(-7 % 3)\n",[39,92608,92609],{"__ignoreMap":264},[268,92610,92611,92613,92615,92617,92619,92622,92624],{"class":270,"line":271},[268,92612,84797],{"class":305},[268,92614,622],{"class":282},[268,92616,6244],{"class":274},[268,92618,26963],{"class":305},[268,92620,92621],{"class":274}," %",[268,92623,3396],{"class":305},[268,92625,20702],{"class":282},[23,92627,92629,92636,92643,92650],{"className":92628},[26],[28,92630,92632,355,92634],{"className":92631},[31],[33,92633],{"disabled":35,"type":36},[39,92635,2258],{},[28,92637,92639,355,92641],{"className":92638},[31],[33,92640],{"disabled":35,"type":36},[39,92642,24416],{},[28,92644,92646,355,92648],{"className":92645},[31],[33,92647],{"disabled":35,"type":36},[39,92649,26035],{},[28,92651,92653,355,92655],{"className":92652},[31],[33,92654],{"disabled":35,"type":36},[39,92656,2255],{},[66,92658,92659,92661,92667],{},[69,92660,71],{},[73,92662,92663,3459,92665],{},[76,92664,78],{},[39,92666,2258],{},[73,92668,92669,355,92671,92673,92674,92676,92677,92680,92681,29324,92684,92687,92688,92690,92691,92693],{},[76,92670,84],{},[76,92672,88175],{}," — Python's ",[39,92675,26178],{}," result always takes the sign of the divisor. ",[39,92678,92679],{},"-7 % 3"," must satisfy ",[39,92682,92683],{},"-7 == 3 * (-7 \u002F\u002F 3) + (-7 % 3)",[39,92685,92686],{},"-7 == 3 * (-3) + 2",", so the remainder is ",[39,92689,2258],{},". B (",[39,92692,24416],{},") is what a C\u002FJava-style truncating modulo would give, since it takes the sign of the dividend instead.",[15,92695,92696,92700,92728,92763],{"language":87455},[18,92697,92699],{"id":92698},"q10-what-does-the-following-print","Q10. What does the following print?",[257,92701,92702],{"language":87455},[260,92703,92705],{"className":87467,"code":92704,"language":87455,"meta":264,"style":264},"print(divmod(-7, 3))\n",[39,92706,92707],{"__ignoreMap":264},[268,92708,92709,92711,92713,92716,92718,92720,92722,92724,92726],{"class":270,"line":271},[268,92710,84797],{"class":305},[268,92712,622],{"class":282},[268,92714,92715],{"class":305},"divmod",[268,92717,622],{"class":282},[268,92719,6244],{"class":274},[268,92721,26963],{"class":305},[268,92723,42],{"class":282},[268,92725,3423],{"class":305},[268,92727,47690],{"class":282},[23,92729,92731,92739,92747,92755],{"className":92730},[26],[28,92732,92734,355,92736],{"className":92733},[31],[33,92735],{"disabled":35,"type":36},[39,92737,92738],{},"(-2, -1)",[28,92740,92742,355,92744],{"className":92741},[31],[33,92743],{"disabled":35,"type":36},[39,92745,92746],{},"(-3, 2)",[28,92748,92750,355,92752],{"className":92749},[31],[33,92751],{"disabled":35,"type":36},[39,92753,92754],{},"(-3, -1)",[28,92756,92758,355,92760],{"className":92757},[31],[33,92759],{"disabled":35,"type":36},[39,92761,92762],{},"(-2, 2)",[66,92764,92765,92767,92773],{},[69,92766,71],{},[73,92768,92769,1727,92771],{},[76,92770,78],{},[39,92772,92746],{},[73,92774,92775,355,92777,92780,92781,92784,92785,92788,92789,92792,92793,92796],{},[76,92776,84],{},[39,92778,92779],{},"divmod(a, b)"," returns the pair ",[39,92782,92783],{},"(a \u002F\u002F b, a % b)",". Here ",[39,92786,92787],{},"-7 \u002F\u002F 3 = -3"," (floors toward negative infinity) and ",[39,92790,92791],{},"-7 % 3 = 2"," (sign of the divisor), so ",[39,92794,92795],{},"divmod(-7, 3)"," bundles both results from the same floor-division\u002Fmodulo rules seen in Q8\u002FQ9 into one tuple.",[15,92798,92799,92803,92828,92861],{"language":87455},[18,92800,92802],{"id":92801},"q11-what-does-the-following-print","Q11. What does the following print?",[257,92804,92805],{"language":87455},[260,92806,92808],{"className":87467,"code":92807,"language":87455,"meta":264,"style":264},"print(2 ** 3 ** 2)\n",[39,92809,92810],{"__ignoreMap":264},[268,92811,92812,92814,92816,92818,92820,92822,92824,92826],{"class":270,"line":271},[268,92813,84797],{"class":305},[268,92815,622],{"class":282},[268,92817,2258],{"class":305},[268,92819,6265],{"class":274},[268,92821,3396],{"class":305},[268,92823,6265],{"class":274},[268,92825,2214],{"class":305},[268,92827,20702],{"class":282},[23,92829,92831,92838,92846,92853],{"className":92830},[26],[28,92832,92834,355,92836],{"className":92833},[31],[33,92835],{"disabled":35,"type":36},[39,92837,6306],{},[28,92839,92841,355,92843],{"className":92840},[31],[33,92842],{"disabled":35,"type":36},[39,92844,92845],{},"1024",[28,92847,92849,355,92851],{"className":92848},[31],[33,92850],{"disabled":35,"type":36},[39,92852,6326],{},[28,92854,92856,355,92858],{"className":92855},[31],[33,92857],{"disabled":35,"type":36},[39,92859,92860],{},"216",[66,92862,92863,92865,92871],{},[69,92864,71],{},[73,92866,92867,1004,92869],{},[76,92868,78],{},[39,92870,6326],{},[73,92872,92873,92875,92876,92878,92879,6320,92881,6320,92883,92885,92886,6320,92889,6320,92892,92894,92895,92897,92898,42,92900,42,92902,383,92904,92906],{},[76,92874,84],{}," Unlike almost every other binary operator in Python, ",[39,92877,6231],{}," is right-associative, so this is ",[39,92880,6319],{},[39,92882,6323],{},[39,92884,6326],{},". Left-associative evaluation, ",[39,92887,92888],{},"(2 ** 3) ** 2",[39,92890,92891],{},"8 ** 2",[39,92893,6306],{}," (option A), is what you'd get if ",[39,92896,6231],{}," behaved like ",[39,92899,1246],{},[39,92901,6244],{},[39,92903,6134],{},[39,92905,446],{}," — it's the one operator where associativity genuinely trips people up.",[15,92908,92909,92913,93010,93041],{"language":87455},[18,92910,92912],{"id":92911},"q12-what-does-the-following-print","Q12. What does the following print?",[257,92914,92915],{"language":87455},[260,92916,92918],{"className":87467,"code":92917,"language":87455,"meta":264,"style":264},"class Money:\n    def __init__(self, amount):\n        self.amount = amount\n\n    def __radd__(self, other):\n        return Money(self.amount + other)\n\nresult = 5 + Money(10)\nprint(result.amount)\n",[39,92919,92920,92929,92940,92953,92957,92967,92983,92987,93003],{"__ignoreMap":264},[268,92921,92922,92924,92927],{"class":270,"line":271},[268,92923,1468],{"class":274},[268,92925,92926],{"class":278}," Money",[268,92928,8931],{"class":282},[268,92930,92931,92934,92937],{"class":270,"line":286},[268,92932,92933],{"class":274},"    def",[268,92935,92936],{"class":305}," __init__",[268,92938,92939],{"class":282},"(self, amount):\n",[268,92941,92942,92945,92948,92950],{"class":270,"line":296},[268,92943,92944],{"class":305},"        self",[268,92946,92947],{"class":282},".amount ",[268,92949,302],{"class":274},[268,92951,92952],{"class":282}," amount\n",[268,92954,92955],{"class":270,"line":311},[268,92956,5033],{"emptyLinePlaceholder":35},[268,92958,92959,92961,92964],{"class":270,"line":788},[268,92960,92933],{"class":274},[268,92962,92963],{"class":305}," __radd__",[268,92965,92966],{"class":282},"(self, other):\n",[268,92968,92969,92971,92974,92976,92978,92980],{"class":270,"line":1951},[268,92970,11956],{"class":274},[268,92972,92973],{"class":282}," Money(",[268,92975,87099],{"class":305},[268,92977,92947],{"class":282},[268,92979,1246],{"class":274},[268,92981,92982],{"class":282}," other)\n",[268,92984,92985],{"class":270,"line":8955},[268,92986,5033],{"emptyLinePlaceholder":35},[268,92988,92989,92991,92993,92995,92997,92999,93001],{"class":270,"line":8966},[268,92990,87569],{"class":282},[268,92992,302],{"class":274},[268,92994,2387],{"class":305},[268,92996,3350],{"class":274},[268,92998,92973],{"class":282},[268,93000,5825],{"class":305},[268,93002,20702],{"class":282},[268,93004,93005,93007],{"class":270,"line":8974},[268,93006,84797],{"class":305},[268,93008,93009],{"class":282},"(result.amount)\n",[23,93011,93013,93020,93027,93034],{"className":93012},[26],[28,93014,93016,91837,93018],{"className":93015},[31],[33,93017],{"disabled":35,"type":36},[39,93019,827],{},[28,93021,93023,355,93025],{"className":93022},[31],[33,93024],{"disabled":35,"type":36},[39,93026,2429],{},[28,93028,93030,355,93032],{"className":93029},[31],[33,93031],{"disabled":35,"type":36},[39,93033,90944],{},[28,93035,93037,355,93039],{"className":93036},[31],[33,93038],{"disabled":35,"type":36},[39,93040,24207],{},[66,93042,93043,93045,93051],{},[69,93044,71],{},[73,93046,93047,6901,93049],{},[76,93048,78],{},[39,93050,24207],{},[73,93052,93053,93055,93056,93059,93060,3277,93063,93065,93066,93069,93070,93073,93074,93077,93078,93081,93082,93084,93085,93088,93089,462],{},[76,93054,84],{}," Python evaluates ",[39,93057,93058],{},"5 + Money(10)"," by first trying ",[39,93061,93062],{},"int.__add__(5, Money(10))",[39,93064,87646],{}," has no idea how to add a ",[39,93067,93068],{},"Money",", so that returns ",[39,93071,93072],{},"NotImplemented",". Python then falls back to the reflected method on the right operand, ",[39,93075,93076],{},"Money(10).__radd__(5)",", which returns ",[39,93079,93080],{},"Money(15)",". A would only be correct if ",[39,93083,93068],{}," defined no ",[39,93086,93087],{},"__radd__"," at all — then both dunder attempts fail and Python genuinely raises ",[39,93090,827],{},[15,93092,93093,93097,93180,93215],{"language":87455},[18,93094,93096],{"id":93095},"q13-what-does-the-following-print","Q13. What does the following print?",[257,93098,93099],{"language":87455},[260,93100,93102],{"className":87467,"code":93101,"language":87455,"meta":264,"style":264},"a = [1, 2]\nb = a\na += [3]\n\nx = 10\ny = x\nx += 1\n\nprint(b, y)\n",[39,93103,93104,93120,93128,93140,93144,93152,93161,93169,93173],{"__ignoreMap":264},[268,93105,93106,93108,93110,93112,93114,93116,93118],{"class":270,"line":271},[268,93107,89166],{"class":282},[268,93109,302],{"class":274},[268,93111,8710],{"class":282},[268,93113,2255],{"class":305},[268,93115,42],{"class":282},[268,93117,2258],{"class":305},[268,93119,89183],{"class":282},[268,93121,93122,93124,93126],{"class":270,"line":286},[268,93123,89188],{"class":282},[268,93125,302],{"class":274},[268,93127,89708],{"class":282},[268,93129,93130,93132,93134,93136,93138],{"class":270,"line":296},[268,93131,89166],{"class":282},[268,93133,14575],{"class":274},[268,93135,8710],{"class":282},[268,93137,3423],{"class":305},[268,93139,89183],{"class":282},[268,93141,93142],{"class":270,"line":311},[268,93143,5033],{"emptyLinePlaceholder":35},[268,93145,93146,93148,93150],{"class":270,"line":788},[268,93147,88966],{"class":282},[268,93149,302],{"class":274},[268,93151,85853],{"class":305},[268,93153,93154,93156,93158],{"class":270,"line":1951},[268,93155,89839],{"class":282},[268,93157,302],{"class":274},[268,93159,93160],{"class":282}," x\n",[268,93162,93163,93165,93167],{"class":270,"line":8955},[268,93164,88966],{"class":282},[268,93166,14575],{"class":274},[268,93168,84787],{"class":305},[268,93170,93171],{"class":270,"line":8966},[268,93172,5033],{"emptyLinePlaceholder":35},[268,93174,93175,93177],{"class":270,"line":8974},[268,93176,84797],{"class":305},[268,93178,93179],{"class":282},"(b, y)\n",[23,93181,93183,93191,93199,93207],{"className":93182},[26],[28,93184,93186,355,93188],{"className":93185},[31],[33,93187],{"disabled":35,"type":36},[39,93189,93190],{},"[1, 2, 3] 10",[28,93192,93194,355,93196],{"className":93193},[31],[33,93195],{"disabled":35,"type":36},[39,93197,93198],{},"[1, 2] 10",[28,93200,93202,355,93204],{"className":93201},[31],[33,93203],{"disabled":35,"type":36},[39,93205,93206],{},"[1, 2, 3] 11",[28,93208,93210,355,93212],{"className":93209},[31],[33,93211],{"disabled":35,"type":36},[39,93213,93214],{},"[1, 2] 11",[66,93216,93217,93219,93225],{},[69,93218,71],{},[73,93220,93221,3459,93223],{},[76,93222,78],{},[39,93224,93190],{},[73,93226,93227,93229,93230,93233,93234,93237,93238,93240,93241,93243,93244,93246,93247,93249,93250,93253,93254,93256,93257,93259,93260,9138,93262,93264,93265,93267,93268,89923,93270,93272,93273,93275],{},[76,93228,84],{}," Lists are mutable, so ",[39,93231,93232],{},"a += [3]"," invokes ",[39,93235,93236],{},"list.__iadd__",", which mutates the list in place and keeps ",[39,93239,1223],{},"'s identity unchanged — since ",[39,93242,1232],{}," is an alias to that same object, ",[39,93245,1232],{}," also shows ",[39,93248,23940],{},". Ints are immutable, so ",[39,93251,93252],{},"x += 1"," can't mutate ",[39,93255,5825],{}," in place; it rebinds ",[39,93258,2403],{}," to a brand-new object ",[39,93261,6879],{},[39,93263,2909],{}," still pointing at the original ",[39,93266,5825],{},". Option C's ",[39,93269,6879],{},[39,93271,2909],{}," is the mistake of assuming ",[39,93274,14575],{}," always ripples to every alias the way it does for lists.",[15,93277,93278,93282,93307,93338],{"language":87455},[18,93279,93281],{"id":93280},"q14-what-does-the-following-print","Q14. What does the following print?",[257,93283,93284],{"language":87455},[260,93285,93287],{"className":87467,"code":93286,"language":87455,"meta":264,"style":264},"print(0.1 + 0.2 == 0.3)\n",[39,93288,93289],{"__ignoreMap":264},[268,93290,93291,93293,93295,93297,93299,93301,93303,93305],{"class":270,"line":271},[268,93292,84797],{"class":305},[268,93294,622],{"class":282},[268,93296,3832],{"class":305},[268,93298,3350],{"class":274},[268,93300,3837],{"class":305},[268,93302,3165],{"class":274},[268,93304,3842],{"class":305},[268,93306,20702],{"class":282},[23,93308,93310,93317,93324,93331],{"className":93309},[26],[28,93311,93313,355,93315],{"className":93312},[31],[33,93314],{"disabled":35,"type":36},[39,93316,89285],{},[28,93318,93320,355,93322],{"className":93319},[31],[33,93321],{"disabled":35,"type":36},[39,93323,88449],{},[28,93325,93327,91837,93329],{"className":93326},[31],[33,93328],{"disabled":35,"type":36},[39,93330,827],{},[28,93332,93334,355,93336],{"className":93333},[31],[33,93335],{"disabled":35,"type":36},[39,93337,8537],{},[66,93339,93340,93342,93348],{},[69,93341,71],{},[73,93343,93344,1727,93346],{},[76,93345,78],{},[39,93347,88449],{},[73,93349,93350,355,93352,3990,93354,42,93356,137,93358,93360,93361,93363,93364,93366,93367,93369,93370,93373,93374,93376,93377,93380,93381,462],{},[76,93351,84],{},[76,93353,16523],{},[39,93355,3832],{},[39,93357,3933],{},[39,93359,8537],{}," have no exact representation in IEEE-754 binary floating point. ",[39,93362,3881],{}," actually evaluates to ",[39,93365,3885],{},", which is not bit-for-bit equal to the literal ",[39,93368,8537],{},". This is a floating-point representation issue, not a Python-specific bug, and it also underlies mixed-type arithmetic promotion (",[39,93371,93372],{},"int + float"," always promotes to ",[39,93375,87642],{},", inheriting these same representation limits). The fix is comparing with a tolerance, e.g. ",[39,93378,93379],{},"math.isclose(0.1 + 0.2, 0.3)",", instead of ",[39,93382,3197],{},[15,93384,93385,93389,93411,93442],{"language":87455},[18,93386,93388],{"id":93387},"q15-what-does-the-following-print","Q15. What does the following print?",[257,93390,93391],{"language":87455},[260,93392,93394],{"className":87467,"code":93393,"language":87455,"meta":264,"style":264},"print(0 or \"default\")\n",[39,93395,93396],{"__ignoreMap":264},[268,93397,93398,93400,93402,93404,93407,93409],{"class":270,"line":271},[268,93399,84797],{"class":305},[268,93401,622],{"class":282},[268,93403,3307],{"class":305},[268,93405,93406],{"class":274}," or",[268,93408,21295],{"class":289},[268,93410,20702],{"class":282},[23,93412,93414,93421,93428,93435],{"className":93413},[26],[28,93415,93417,355,93419],{"className":93416},[31],[33,93418],{"disabled":35,"type":36},[39,93420,89285],{},[28,93422,93424,355,93426],{"className":93423},[31],[33,93425],{"disabled":35,"type":36},[39,93427,3307],{},[28,93429,93431,355,93433],{"className":93430},[31],[33,93432],{"disabled":35,"type":36},[39,93434,9046],{},[28,93436,93438,355,93440],{"className":93437},[31],[33,93439],{"disabled":35,"type":36},[39,93441,88449],{},[66,93443,93444,93446,93452],{},[69,93445,71],{},[73,93447,93448,1004,93450],{},[76,93449,78],{},[39,93451,9046],{},[73,93453,93454,355,93456,3990,93458,446,93460,93463,93464,93466,93467,93469,93470,93472,93473,93476,93477,93479,93480,462],{},[76,93455,84],{},[76,93457,17307],{},[39,93459,31781],{},[39,93461,93462],{},"or"," don't coerce their result to ",[39,93465,89412],{},"; they evaluate operands left to right and return the first operand that decides the outcome, as-is. ",[39,93468,3307],{}," is falsy, so ",[39,93471,93462],{}," moves on and returns the actual value ",[39,93474,93475],{},"\"default\"",". B is what a strict boolean-",[39,93478,93462],{}," language would give; A\u002FD wrongly assume Python's logical operators always return ",[39,93481,89412],{},[15,93483,93484,93488,93535,93566],{"language":87455},[18,93485,93487],{"id":93486},"q16-what-does-the-following-print","Q16. What does the following print?",[257,93489,93490],{"language":87455},[260,93491,93493],{"className":87467,"code":93492,"language":87455,"meta":264,"style":264},"def choose(flag):\n    return flag and 0 or 5\n\nprint(choose(3))\n",[39,93494,93495,93505,93520,93524],{"__ignoreMap":264},[268,93496,93497,93499,93502],{"class":270,"line":271},[268,93498,88976],{"class":274},[268,93500,93501],{"class":278}," choose",[268,93503,93504],{"class":282},"(flag):\n",[268,93506,93507,93509,93512,93514,93516,93518],{"class":270,"line":286},[268,93508,9871],{"class":274},[268,93510,93511],{"class":282}," flag ",[268,93513,31781],{"class":274},[268,93515,5728],{"class":305},[268,93517,93406],{"class":274},[268,93519,85072],{"class":305},[268,93521,93522],{"class":270,"line":296},[268,93523,5033],{"emptyLinePlaceholder":35},[268,93525,93526,93528,93531,93533],{"class":270,"line":311},[268,93527,84797],{"class":305},[268,93529,93530],{"class":282},"(choose(",[268,93532,3423],{"class":305},[268,93534,47690],{"class":282},[23,93536,93538,93545,93552,93559],{"className":93537},[26],[28,93539,93541,355,93543],{"className":93540},[31],[33,93542],{"disabled":35,"type":36},[39,93544,3307],{},[28,93546,93548,355,93550],{"className":93547},[31],[33,93549],{"disabled":35,"type":36},[39,93551,3423],{},[28,93553,93555,355,93557],{"className":93554},[31],[33,93556],{"disabled":35,"type":36},[39,93558,90944],{},[28,93560,93562,355,93564],{"className":93561},[31],[33,93563],{"disabled":35,"type":36},[39,93565,2429],{},[66,93567,93568,93570,93576],{},[69,93569,71],{},[73,93571,93572,6901,93574],{},[76,93573,78],{},[39,93575,2429],{},[73,93577,93578,355,93580,3990,93582,5409,93585,93587,93588,93590,93591,93593,93594,5409,93597,2833,93599,93601,93602,93604,93605,93608,93609,30040,93611,93614,93615,93618,93619,93622,93623,93626],{},[76,93579,84],{},[76,93581,17307],{},[39,93583,93584],{},"3 and 0",[39,93586,3307],{},", because the left operand ",[39,93589,3423],{}," is truthy so ",[39,93592,31781],{}," evaluates and returns the right operand. Then ",[39,93595,93596],{},"0 or 5",[39,93598,2429],{},[39,93600,3307],{}," is falsy so ",[39,93603,93462],{}," moves on to its right operand. ",[39,93606,93607],{},"choose"," was clearly meant to return ",[39,93610,3307],{},[39,93612,93613],{},"flag"," is truthy, but the classic ",[39,93616,93617],{},"flag and X or Y"," idiom silently breaks whenever ",[39,93620,93621],{},"X"," itself is falsy — which is exactly why Python's conditional expression ",[39,93624,93625],{},"0 if flag else 5"," should be preferred over this pattern. A is the \"intended\" answer a reader would wrongly expect.",[15,93628,93629,93633,93670,93705],{"language":87455},[18,93630,93632],{"id":93631},"q17-what-does-the-following-print","Q17. What does the following print?",[257,93634,93635],{"language":87455},[260,93636,93638],{"className":87467,"code":93637,"language":87455,"meta":264,"style":264},"a = 5\nb = 3\nprint(a & b, a and b)\n",[39,93639,93640,93648,93656],{"__ignoreMap":264},[268,93641,93642,93644,93646],{"class":270,"line":271},[268,93643,89166],{"class":282},[268,93645,302],{"class":274},[268,93647,85072],{"class":305},[268,93649,93650,93652,93654],{"class":270,"line":286},[268,93651,89188],{"class":282},[268,93653,302],{"class":274},[268,93655,86757],{"class":305},[268,93657,93658,93660,93662,93664,93666,93668],{"class":270,"line":296},[268,93659,84797],{"class":305},[268,93661,7218],{"class":282},[268,93663,85350],{"class":274},[268,93665,21694],{"class":282},[268,93667,31781],{"class":274},[268,93669,89821],{"class":282},[23,93671,93673,93681,93689,93697],{"className":93672},[26],[28,93674,93676,355,93678],{"className":93675},[31],[33,93677],{"disabled":35,"type":36},[39,93679,93680],{},"1 3",[28,93682,93684,355,93686],{"className":93683},[31],[33,93685],{"disabled":35,"type":36},[39,93687,93688],{},"1 1",[28,93690,93692,355,93694],{"className":93691},[31],[33,93693],{"disabled":35,"type":36},[39,93695,93696],{},"7 3",[28,93698,93700,355,93702],{"className":93699},[31],[33,93701],{"disabled":35,"type":36},[39,93703,93704],{},"7 5",[66,93706,93707,93709,93715],{},[69,93708,71],{},[73,93710,93711,3459,93713],{},[76,93712,78],{},[39,93714,93680],{},[73,93716,93717,355,93719,93721,93722,2182,93724,6131,93726,355,93728,2182,93730,93733,93734,6320,93737,3277,93739,93741,93742,2182,93744,93746,93747,93749,93750,2182,93752,93754,93755,446,93757,93759,93760,446,93762,93764,93765,93767],{},[76,93718,84],{},[39,93720,85350],{}," is the bitwise AND operator: ",[39,93723,2429],{},[39,93725,13859],{},[39,93727,85350],{},[39,93729,3423],{},[39,93731,93732],{},"011",") = ",[39,93735,93736],{},"001",[39,93738,2255],{},[39,93740,31781],{}," is the logical operator and, as in Q15, returns an actual operand rather than a recombined value: since ",[39,93743,1223],{},[39,93745,2429],{},") is truthy, ",[39,93748,31781],{}," evaluates and returns ",[39,93751,1232],{},[39,93753,3423],{},"). This distinction matters a lot with array-like objects (e.g. NumPy arrays or pandas Series), where ",[39,93756,85350],{},[39,93758,18141],{}," are required for element-wise boolean logic because ",[39,93761,31781],{},[39,93763,93462],{}," can't be overloaded to short-circuit per-element and instead try to coerce the whole array to a single ",[39,93766,89412],{},", raising an error.",[15,93769,93770,93774,93811,93842],{"language":87455},[18,93771,93773],{"id":93772},"q18-what-does-the-following-print","Q18. What does the following print?",[257,93775,93776],{"language":87455},[260,93777,93779],{"className":87467,"code":93778,"language":87455,"meta":264,"style":264},"a = 1\nb = 2\nprint(not a == b)\n",[39,93780,93781,93789,93797],{"__ignoreMap":264},[268,93782,93783,93785,93787],{"class":270,"line":271},[268,93784,89166],{"class":282},[268,93786,302],{"class":274},[268,93788,84787],{"class":305},[268,93790,93791,93793,93795],{"class":270,"line":286},[268,93792,89188],{"class":282},[268,93794,302],{"class":274},[268,93796,85329],{"class":305},[268,93798,93799,93801,93803,93805,93807,93809],{"class":270,"line":296},[268,93800,84797],{"class":305},[268,93802,622],{"class":282},[268,93804,95],{"class":274},[268,93806,1243],{"class":282},[268,93808,3197],{"class":274},[268,93810,89821],{"class":282},[23,93812,93814,93821,93828,93835],{"className":93813},[26],[28,93815,93817,355,93819],{"className":93816},[31],[33,93818],{"disabled":35,"type":36},[39,93820,88449],{},[28,93822,93824,355,93826],{"className":93823},[31],[33,93825],{"disabled":35,"type":36},[39,93827,89285],{},[28,93829,93831,91837,93833],{"className":93830},[31],[33,93832],{"disabled":35,"type":36},[39,93834,1274],{},[28,93836,93838,355,93840],{"className":93837},[31],[33,93839],{"disabled":35,"type":36},[39,93841,2255],{},[66,93843,93844,93846,93852],{},[69,93845,71],{},[73,93847,93848,1727,93850],{},[76,93849,78],{},[39,93851,89285],{},[73,93853,93854,355,93856,93858,93859,6320,93862,6320,93865,93867,93868,29324,93871,4977,93874,93876,93877,186,93879,93882,93883,8828,93886,462],{},[76,93855,84],{},[39,93857,95],{}," binds more loosely than comparison operators, so this parses as ",[39,93860,93861],{},"not (a == b)",[39,93863,93864],{},"not False",[39,93866,89285],{},". A is the trap answer from misreading it as ",[39,93869,93870],{},"(not a) == b",[39,93872,93873],{},"False == 2",[39,93875,88449],{}," — but that grouping is not how Python's operator precedence actually works. This same looser-than-comparison binding is why ",[39,93878,91027],{},[39,93880,93881],{},"not in"," exist as their own compound operators rather than requiring ",[39,93884,93885],{},"not (x is y)",[39,93887,93888],{},"not (x in y)",[15,93890,93891,93895,93916,93947],{"language":87455},[18,93892,93894],{"id":93893},"q19-what-does-the-following-print","Q19. What does the following print?",[257,93896,93897],{"language":87455},[260,93898,93900],{"className":87467,"code":93899,"language":87455,"meta":264,"style":264},"print(1 \u003C \"a\")\n",[39,93901,93902],{"__ignoreMap":264},[268,93903,93904,93906,93908,93910,93912,93914],{"class":270,"line":271},[268,93905,84797],{"class":305},[268,93907,622],{"class":282},[268,93909,2255],{"class":305},[268,93911,6457],{"class":274},[268,93913,10871],{"class":289},[268,93915,20702],{"class":282},[23,93917,93919,93926,93933,93940],{"className":93918},[26],[28,93920,93922,355,93924],{"className":93921},[31],[33,93923],{"disabled":35,"type":36},[39,93925,89285],{},[28,93927,93929,355,93931],{"className":93928},[31],[33,93930],{"disabled":35,"type":36},[39,93932,88449],{},[28,93934,93936,91837,93938],{"className":93935},[31],[33,93937],{"disabled":35,"type":36},[39,93939,827],{},[28,93941,93943,355,93945],{"className":93942},[31],[33,93944],{"disabled":35,"type":36},[39,93946,2255],{},[66,93948,93949,93951,93958],{},[69,93950,71],{},[73,93952,93953,93955,93956],{},[76,93954,78],{}," C — Raises ",[39,93957,827],{},[73,93959,93960,355,93962,93964,93965,93967,93968,93970,93971,446,93974,10044,93977,93979,93980,93983],{},[76,93961,84],{},[76,93963,88175],{}," — Python 3 refuses to order-compare incompatible types: ",[39,93966,87646],{}," has no defined ordering against ",[39,93969,17109],{},", both types' ",[39,93972,93973],{},"__lt__",[39,93975,93976],{},"__gt__",[39,93978,93072],{}," for each other, so Python raises ",[39,93981,93982],{},"TypeError: '\u003C' not supported between instances of 'int' and 'str'",". This is a deliberate break from Python 2, which allowed cross-type comparisons using an arbitrary-but-consistent rule — code ported from Python 2 that relied on sorting mixed-type lists can crash outright in Python 3.",[15,93985,93986,93990,94030,94061],{"language":87455},[18,93987,93989],{"id":93988},"q20-what-does-the-following-print","Q20. What does the following print?",[257,93991,93992],{"language":87455},[260,93993,93995],{"className":87467,"code":93994,"language":87455,"meta":264,"style":264},"nan = float('nan')\nprint(nan == nan, nan is nan)\n",[39,93996,93997,94013],{"__ignoreMap":264},[268,93998,93999,94002,94004,94006,94008,94011],{"class":270,"line":271},[268,94000,94001],{"class":282},"nan ",[268,94003,302],{"class":274},[268,94005,90145],{"class":305},[268,94007,622],{"class":282},[268,94009,94010],{"class":289},"'nan'",[268,94012,20702],{"class":282},[268,94014,94015,94017,94020,94022,94025,94027],{"class":270,"line":286},[268,94016,84797],{"class":305},[268,94018,94019],{"class":282},"(nan ",[268,94021,3197],{"class":274},[268,94023,94024],{"class":282}," nan, nan ",[268,94026,4447],{"class":274},[268,94028,94029],{"class":282}," nan)\n",[23,94031,94033,94040,94047,94054],{"className":94032},[26],[28,94034,94036,355,94038],{"className":94035},[31],[33,94037],{"disabled":35,"type":36},[39,94039,92428],{},[28,94041,94043,355,94045],{"className":94042},[31],[33,94044],{"disabled":35,"type":36},[39,94046,92444],{},[28,94048,94050,355,94052],{"className":94049},[31],[33,94051],{"disabled":35,"type":36},[39,94053,92436],{},[28,94055,94057,355,94059],{"className":94056},[31],[33,94058],{"disabled":35,"type":36},[39,94060,92452],{},[66,94062,94063,94065,94071],{},[69,94064,71],{},[73,94066,94067,6901,94069],{},[76,94068,78],{},[39,94070,92452],{},[73,94072,94073,355,94075,94077,94078,830,94081,94083,94084,94087,94088,830,94091,94093,94094,94096,94097,94099],{},[76,94074,84],{},[76,94076,16523],{}," — IEEE-754 defines NaN as unordered and unequal to everything, including itself, so ",[39,94079,94080],{},"nan == nan",[39,94082,88449],{}," even though both sides are literally the same object — ",[39,94085,94086],{},"float.__eq__"," follows the IEEE rule rather than special-casing identical operands. ",[39,94089,94090],{},"nan is nan",[39,94092,89285],{}," simply because both names refer to the exact same object; identity is trivially reflexive and unaffected by IEEE semantics. Practical implication: a NaN value can silently fail ",[39,94095,3197],{},"-based lookups or filters, but CPython's dict\u002Fset implementation checks identity before falling back to equality, so the ",[104,94098,22779],{}," NaN object can still be found again as a dict key — a different, merely equal-valued NaN object cannot.",[2107,94101,94102],{},"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 .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}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 .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}",{"title":264,"searchDepth":286,"depth":286,"links":94104},[94105,94106,94107,94108,94109,94110,94111,94112,94113,94114,94115,94116,94117,94118,94119,94120,94121,94122,94123,94124],{"id":91659,"depth":296,"text":91660},{"id":91780,"depth":296,"text":91781},{"id":91882,"depth":296,"text":91883},{"id":91995,"depth":296,"text":91996},{"id":92145,"depth":296,"text":92146},{"id":92242,"depth":296,"text":92243},{"id":92358,"depth":296,"text":92359},{"id":92508,"depth":296,"text":92509},{"id":92600,"depth":296,"text":92601},{"id":92698,"depth":296,"text":92699},{"id":92801,"depth":296,"text":92802},{"id":92911,"depth":296,"text":92912},{"id":93095,"depth":296,"text":93096},{"id":93280,"depth":296,"text":93281},{"id":93387,"depth":296,"text":93388},{"id":93486,"depth":296,"text":93487},{"id":93631,"depth":296,"text":93632},{"id":93772,"depth":296,"text":93773},{"id":93893,"depth":296,"text":93894},{"id":93988,"depth":296,"text":93989},{},"\u002Fpython\u002F03-operators-and-expressions",{"title":5211,"description":264},"python\u002F03-operators-and-expressions","CwF6upKHPbsEAhm6XhdgPsoLpv1x45YFnknAvZ0FNXI",{"id":94131,"title":94132,"body":94133,"description":264,"extension":2144,"meta":96784,"navigation":35,"path":96785,"seo":96786,"stem":96787,"__hash__":96788},"content\u002Fpython\u002F11-closures-and-decorators.md","11 — Closures & Decorators",{"type":8,"value":94134,"toc":96753},[94135,94138,94192,94251,94323,94407,94525,94595,94650,94795,94881,95026,95231,95469,95663,95918,96152,96226,96291,96356,96612,96750],[11,94136,94132],{"id":94137},"_11-closures-decorators",[15,94139,94140,94144,94174],{},[18,94141,94143],{"id":94142},"q1-what-is-a-closure-in-python","Q1. What is a closure in Python?",[23,94145,94147,94153,94159,94165],{"className":94146},[26],[28,94148,94150,94152],{"className":94149},[31],[33,94151],{"disabled":35,"type":36}," A function that has access to variables from its enclosing lexical scope, even after the enclosing function has finished executing",[28,94154,94156,94158],{"className":94155},[31],[33,94157],{"disabled":35,"type":36}," Any function defined inside a class body",[28,94160,94162,94164],{"className":94161},[31],[33,94163],{"disabled":35,"type":36}," A function that automatically closes open file handles when it returns",[28,94166,94168,94170,94171],{"className":94167},[31],[33,94169],{"disabled":35,"type":36}," A function decorated with ",[39,94172,94173],{},"@staticmethod",[66,94175,94176,94178,94183],{},[69,94177,71],{},[73,94179,94180,94182],{},[76,94181,78],{}," A — A function that has access to variables from its enclosing lexical scope, even after the enclosing function has finished executing",[73,94184,94185,94187,94188,94191],{},[76,94186,84],{}," A closure is an inner function that \"remembers\" the variables from its enclosing scope via a cell object, so it can still read (and with ",[39,94189,94190],{},"nonlocal",", write) them long after the outer function has returned. It has nothing to do with classes or file handles — those are unrelated meanings of \"closing\" that beginners sometimes conflate with the term.",[15,94193,94194,94201,94228],{},[18,94195,94197,94198,94200],{"id":94196},"q2-what-does-the-nonlocal-keyword-do","Q2. What does the ",[39,94199,94190],{}," keyword do?",[23,94202,94204,94210,94216,94222],{"className":94203},[26],[28,94205,94207,94209],{"className":94206},[31],[33,94208],{"disabled":35,"type":36}," Lets an inner function assign to a variable defined in its nearest enclosing (non-global) function scope",[28,94211,94213,94215],{"className":94212},[31],[33,94214],{"disabled":35,"type":36}," Lets an inner function assign to a variable in the module's global scope",[28,94217,94219,94221],{"className":94218},[31],[33,94220],{"disabled":35,"type":36}," Declares a variable that is shared across all instances of a class",[28,94223,94225,94227],{"className":94224},[31],[33,94226],{"disabled":35,"type":36}," Makes a variable visible to every thread without a lock",[66,94229,94230,94232,94237],{},[69,94231,71],{},[73,94233,94234,94236],{},[76,94235,78],{}," A — Lets an inner function assign to a variable defined in its nearest enclosing (non-global) function scope",[73,94238,94239,94241,94242,94244,94245,94247,94248,94250],{},[76,94240,84],{}," Without ",[39,94243,94190],{},", assigning to a name inside a nested function creates a brand-new local variable that shadows the outer one instead of modifying it. ",[39,94246,94190],{}," tells Python to bind to the enclosing function's variable instead. ",[39,94249,71866],{}," (option B) is the different keyword for module-level scope — mixing the two up is a common mistake.",[15,94252,94253,94265,94300],{},[18,94254,94256,94257,94260,94261,94264],{"id":94255},"q3-my_decorator-placed-above-def-func-is-syntactic-sugar-for-which-statement","Q3. ",[39,94258,94259],{},"@my_decorator"," placed above ",[39,94262,94263],{},"def func(): ..."," is syntactic sugar for which statement?",[23,94266,94268,94276,94284,94292],{"className":94267},[26],[28,94269,94271,355,94273],{"className":94270},[31],[33,94272],{"disabled":35,"type":36},[39,94274,94275],{},"func = my_decorator(func)",[28,94277,94279,355,94281],{"className":94278},[31],[33,94280],{"disabled":35,"type":36},[39,94282,94283],{},"func = my_decorator()(func)",[28,94285,94287,355,94289],{"className":94286},[31],[33,94288],{"disabled":35,"type":36},[39,94290,94291],{},"my_decorator.func = func",[28,94293,94295,355,94297],{"className":94294},[31],[33,94296],{"disabled":35,"type":36},[39,94298,94299],{},"func = my_decorator",[66,94301,94302,94304,94310],{},[69,94303,71],{},[73,94305,94306,3459,94308],{},[76,94307,78],{},[39,94309,94275],{},[73,94311,94312,94314,94315,94318,94319,94322],{},[76,94313,84],{}," A plain decorator is just a function that takes the decorated function as its single argument and returns a (usually different) callable, which is rebound to the original name. Option B is the expansion for a decorator ",[104,94316,94317],{},"factory"," called with arguments, like ",[39,94320,94321],{},"@my_decorator(arg)",", not a plain decorator.",[15,94324,94325,94332,94374],{},[18,94326,87554,94328,94331],{"id":94327},"q4-what-does-functoolswraps-do-when-applied-inside-a-decorators-wrapper-function",[39,94329,94330],{},"functools.wraps"," do when applied inside a decorator's wrapper function?",[23,94333,94335,94348,94359,94368],{"className":94334},[26],[28,94336,94338,94340,94341,42,94344,94347],{"className":94337},[31],[33,94339],{"disabled":35,"type":36}," Copies ",[39,94342,94343],{},"__name__",[39,94345,94346],{},"__doc__",", and other metadata from the original function onto the wrapper",[28,94349,94351,94353,94354,446,94356,94358],{"className":94350},[31],[33,94352],{"disabled":35,"type":36}," Wraps the return value of the function in a ",[39,94355,23142],{},[39,94357,91317],{}," block automatically",[28,94360,94362,94364,94365],{"className":94361},[31],[33,94363],{"disabled":35,"type":36}," Caches the function's return value like ",[39,94366,94367],{},"lru_cache",[28,94369,94371,94373],{"className":94370},[31],[33,94372],{"disabled":35,"type":36}," Converts a regular function into a coroutine",[66,94375,94376,94378,94387],{},[69,94377,71],{},[73,94379,94380,94382,94383,42,94385,94347],{},[76,94381,78],{}," A — Copies ",[39,94384,94343],{},[39,94386,94346],{},[73,94388,94389,94241,94391,94394,94395,94398,94399,94402,94403,94406],{},[76,94390,84],{},[39,94392,94393],{},"@functools.wraps(func)"," on the inner ",[39,94396,94397],{},"wrapper",", introspection tools, debuggers, and ",[39,94400,94401],{},"help()"," will report the wrapper's own name (typically ",[39,94404,94405],{},"\"wrapper\"",") and lose the original docstring, which makes stack traces and documentation confusing. It does not add error handling or caching — those are unrelated decorator patterns.",[15,94408,94409,94413,94442,94450,94489],{"language":87455},[18,94410,94412],{"id":94411},"q5-given-stacked-decorators","Q5. Given stacked decorators:",[257,94414,94415],{"language":87455},[260,94416,94418],{"className":87467,"code":94417,"language":87455,"meta":264,"style":264},"@first\n@second\ndef handler():\n    ...\n",[39,94419,94420,94425,94430,94438],{"__ignoreMap":264},[268,94421,94422],{"class":270,"line":271},[268,94423,94424],{"class":278},"@first\n",[268,94426,94427],{"class":270,"line":286},[268,94428,94429],{"class":278},"@second\n",[268,94431,94432,94434,94436],{"class":270,"line":296},[268,94433,88976],{"class":274},[268,94435,39898],{"class":278},[268,94437,92012],{"class":282},[268,94439,94440],{"class":270,"line":311},[268,94441,90877],{"class":305},[73,94443,94444,94445,30040,94447,39124],{},"Which decorator's wrapping logic executes ",[104,94446,12590],{},[39,94448,94449],{},"handler()",[23,94451,94453,94463,94471,94477],{"className":94452},[26],[28,94454,94456,355,94458,94460,94461],{"className":94455},[31],[33,94457],{"disabled":35,"type":36},[39,94459,47797],{},"'s, because it wraps the original function directly and runs on the way in before control reaches ",[39,94462,12590],{},[28,94464,94466,355,94468,94470],{"className":94465},[31],[33,94467],{"disabled":35,"type":36},[39,94469,12590],{},"'s, because it's listed first in the source",[28,94472,94474,94476],{"className":94473},[31],[33,94475],{"disabled":35,"type":36}," Both run simultaneously",[28,94478,94480,94482,94483,94485,94486,94488],{"className":94479},[31],[33,94481],{"disabled":35,"type":36}," Neither — only ",[39,94484,12590],{}," applies; ",[39,94487,47797],{}," is silently discarded",[66,94490,94491,94493,94501],{},[69,94492,71],{},[73,94494,94495,3459,94497,94460,94499],{},[76,94496,78],{},[39,94498,47797],{},[39,94500,12590],{},[73,94502,94503,94505,94506,1179,94509,94511,94512,94514,94515,94517,94518,94520,94521,94524],{},[76,94504,84],{}," Decorators apply bottom-up but execute outside-in: ",[39,94507,94508],{},"handler = first(second(handler))",[39,94510,12590],{},"'s wrapper is the outermost call, but its body typically calls the thing it wraps (",[39,94513,47797],{},"'s wrapper) before that call returns — so on entry, ",[39,94516,12590],{},"'s pre-call code runs, then ",[39,94519,47797],{},"'s pre-call code, then the real function. The naive assumption that \"top decorator runs first in every sense\" is the beginner trap; it's true for ",[104,94522,94523],{},"application order",", not necessarily for every line of runtime behavior.",[15,94526,94527,94535,94562],{},[18,94528,94530,94531,94534],{"id":94529},"q6-a-decorator-that-itself-accepts-arguments-eg-retrytimes3-requires-how-many-levels-of-nested-functions","Q6. A decorator that itself accepts arguments, e.g. ",[39,94532,94533],{},"@retry(times=3)",", requires how many levels of nested functions?",[23,94536,94538,94544,94550,94556],{"className":94537},[26],[28,94539,94541,94543],{"className":94540},[31],[33,94542],{"disabled":35,"type":36}," Three — an outer factory taking the decorator's arguments, a middle decorator taking the function, and an inner wrapper taking the function's call arguments",[28,94545,94547,94549],{"className":94546},[31],[33,94548],{"disabled":35,"type":36}," One — the decorator function itself takes both the decorator arguments and the function",[28,94551,94553,94555],{"className":94552},[31],[33,94554],{"disabled":35,"type":36}," Two — a decorator taking the function, and a wrapper taking call arguments",[28,94557,94559,94561],{"className":94558},[31],[33,94560],{"disabled":35,"type":36}," Four — Python requires a separate factory for each keyword argument",[66,94563,94564,94566,94571],{},[69,94565,71],{},[73,94567,94568,94570],{},[76,94569,78],{}," A — Three — an outer factory taking the decorator's arguments, a middle decorator taking the function, and an inner wrapper taking the function's call arguments",[73,94572,94573,355,94575,94578,94579,94582,94583,94586,94587,14552,94589,355,94592,94594],{},[76,94574,84],{},[39,94576,94577],{},"retry(times=3)"," must first return an actual decorator (level 2), which is then called with the function (",[39,94580,94581],{},"func","), which must return a ",[39,94584,94585],{},"wrapper(*args, **kwargs)"," (level 3) that does the real work. Beginners often try to collapse this into two levels (option C), which works for plain decorators but not parameterized ones, since ",[39,94588,94533],{},[39,94590,94591],{},"retry",[104,94593,11314],{}," decoration even begins.",[15,94596,94597,94601,94631],{},[18,94598,94600],{"id":94599},"q7-what-does-a-python-closure-actually-capture-from-the-enclosing-scope","Q7. What does a Python closure actually capture from the enclosing scope?",[23,94602,94604,94613,94619,94625],{"className":94603},[26],[28,94605,94607,94609,94610,94612],{"className":94606},[31],[33,94608],{"disabled":35,"type":36}," A reference to the variable's cell, so the closure always sees the variable's ",[104,94611,28182],{}," value, not a snapshot taken at definition time",[28,94614,94616,94618],{"className":94615},[31],[33,94617],{"disabled":35,"type":36}," A deep copy of the variable's value at the moment the inner function is defined",[28,94620,94622,94624],{"className":94621},[31],[33,94623],{"disabled":35,"type":36}," A shallow copy of the value, copied only if the value is mutable",[28,94626,94628,94630],{"className":94627},[31],[33,94629],{"disabled":35,"type":36}," Nothing — closures re-evaluate the enclosing function's source code on each call",[66,94632,94633,94635,94642],{},[69,94634,71],{},[73,94636,94637,94639,94640,94612],{},[76,94638,78],{}," A — A reference to the variable's cell, so the closure always sees the variable's ",[104,94641,28182],{},[73,94643,94644,94646,94647,94649],{},[76,94645,84],{}," Python closures bind by reference to a shared cell object, not by value. This is exactly why the late-binding loop-variable gotcha exists: every closure created in a loop shares the ",[104,94648,22779],{}," cell for the loop variable, so they all observe whatever that variable holds when they're eventually called, not when they were created.",[15,94651,94652,94656,94723,94758],{"language":87455},[18,94653,94655],{"id":94654},"q8-what-does-this-print","Q8. What does this print?",[257,94657,94658],{"language":87455},[260,94659,94661],{"className":87467,"code":94660,"language":87455,"meta":264,"style":264},"callbacks = []\nfor i in range(3):\n    callbacks.append(lambda: i)\n\nprint([cb() for cb in callbacks])\n",[39,94662,94663,94673,94691,94702,94706],{"__ignoreMap":264},[268,94664,94665,94668,94670],{"class":270,"line":271},[268,94666,94667],{"class":282},"callbacks ",[268,94669,302],{"class":274},[268,94671,94672],{"class":282}," []\n",[268,94674,94675,94677,94679,94681,94684,94686,94688],{"class":270,"line":286},[268,94676,6926],{"class":274},[268,94678,9384],{"class":282},[268,94680,20749],{"class":274},[268,94682,94683],{"class":305}," range",[268,94685,622],{"class":282},[268,94687,3423],{"class":305},[268,94689,94690],{"class":282},"):\n",[268,94692,94693,94696,94699],{"class":270,"line":296},[268,94694,94695],{"class":282},"    callbacks.append(",[268,94697,94698],{"class":274},"lambda",[268,94700,94701],{"class":282},": i)\n",[268,94703,94704],{"class":270,"line":311},[268,94705,5033],{"emptyLinePlaceholder":35},[268,94707,94708,94710,94713,94715,94718,94720],{"class":270,"line":788},[268,94709,84797],{"class":305},[268,94711,94712],{"class":282},"([cb() ",[268,94714,6926],{"class":274},[268,94716,94717],{"class":282}," cb ",[268,94719,20749],{"class":274},[268,94721,94722],{"class":282}," callbacks])\n",[23,94724,94726,94734,94742,94750],{"className":94725},[26],[28,94727,94729,355,94731],{"className":94728},[31],[33,94730],{"disabled":35,"type":36},[39,94732,94733],{},"[2, 2, 2]",[28,94735,94737,355,94739],{"className":94736},[31],[33,94738],{"disabled":35,"type":36},[39,94740,94741],{},"[0, 1, 2]",[28,94743,94745,355,94747],{"className":94744},[31],[33,94746],{"disabled":35,"type":36},[39,94748,94749],{},"[0, 0, 0]",[28,94751,94753,355,94755],{"className":94752},[31],[33,94754],{"disabled":35,"type":36},[39,94756,94757],{},"RuntimeError: variable modified during iteration",[66,94759,94760,94762,94768],{},[69,94761,71],{},[73,94763,94764,3459,94766],{},[76,94765,78],{},[39,94767,94733],{},[73,94769,94770,355,94772,94774,94775,94777,94778,94780,94781,94783,94784,94786,94787,23794,94789,94791,94792,94794],{},[76,94771,84],{},[76,94773,16523],{}," — All three lambdas close over the ",[104,94776,22779],{}," variable ",[39,94779,9509],{},", not three independent copies. By the time the list comprehension calls them, the ",[39,94782,6926],{}," loop has already finished and ",[39,94785,9509],{}," holds its final value, ",[39,94788,2258],{},[39,94790,94741],{}," answer assumes each lambda captures the value of ",[39,94793,9509],{}," at the point it was created, which is how closures work in some other languages but not in Python's late-binding model.",[15,94796,94797,94803,94849],{},[18,94798,94800,94801,1685],{"id":94799},"q9-which-change-correctly-fixes-the-late-binding-bug-from-q8-so-the-output-is-0-1-2","Q9. Which change correctly fixes the late-binding bug from Q8 so the output is ",[39,94802,94741],{},[23,94804,94806,94818,94830,94840],{"className":94805},[26],[28,94807,94809,355,94811,94814,94815,94817],{"className":94808},[31],[33,94810],{"disabled":35,"type":36},[39,94812,94813],{},"callbacks.append(lambda i=i: i)"," — bind ",[39,94816,9509],{},"'s current value as a default argument at lambda-creation time",[28,94819,94821,355,94823,94826,94827,94829],{"className":94820},[31],[33,94822],{"disabled":35,"type":36},[39,94824,94825],{},"callbacks.append(lambda: int(i))"," — wrapping in ",[39,94828,91356],{}," forces early evaluation",[28,94831,94833,81123,94835,94837,94838,11426],{"className":94832},[31],[33,94834],{"disabled":35,"type":36},[39,94836,6926],{}," loop with a ",[39,94839,11160],{},[28,94841,94843,355,94845,94848],{"className":94842},[31],[33,94844],{"disabled":35,"type":36},[39,94846,94847],{},"callbacks.append(lambda: i.copy())"," — copy the integer before storing it",[66,94850,94851,94853,94861],{},[69,94852,71],{},[73,94854,94855,3459,94857,94814,94859,94817],{},[76,94856,78],{},[39,94858,94813],{},[39,94860,9509],{},[73,94862,94863,94865,94866,94868,94869,94872,94873,94876,94877,94880],{},[76,94864,84],{}," Default argument values ",[104,94867,70614],{}," evaluated once, at function-definition time, so ",[39,94870,94871],{},"i=i"," captures the loop variable's value on each iteration into a fresh, per-lambda default. ",[39,94874,94875],{},"int(i)"," (option B) still reads the shared cell at call time, so it doesn't help; integers have no ",[39,94878,94879],{},".copy()"," method (option D), and switching loop constructs (option C) doesn't change how closures bind names.",[15,94882,94883,94885,94939,94988],{"language":87455},[18,94884,27954],{"id":27953},[257,94886,94887],{"language":87455},[260,94888,94890],{"className":87467,"code":94889,"language":87455,"meta":264,"style":264},"def outer():\n    def inner():\n        nonlocal missing\n        missing = 1\n    inner()\n\nouter()\n",[39,94891,94892,94900,94908,94916,94925,94930,94934],{"__ignoreMap":264},[268,94893,94894,94896,94898],{"class":270,"line":271},[268,94895,88976],{"class":274},[268,94897,9700],{"class":278},[268,94899,92012],{"class":282},[268,94901,94902,94904,94906],{"class":270,"line":286},[268,94903,92933],{"class":274},[268,94905,15153],{"class":278},[268,94907,92012],{"class":282},[268,94909,94910,94913],{"class":270,"line":296},[268,94911,94912],{"class":274},"        nonlocal",[268,94914,94915],{"class":282}," missing\n",[268,94917,94918,94921,94923],{"class":270,"line":311},[268,94919,94920],{"class":282},"        missing ",[268,94922,302],{"class":274},[268,94924,84787],{"class":305},[268,94926,94927],{"class":270,"line":788},[268,94928,94929],{"class":282},"    inner()\n",[268,94931,94932],{"class":270,"line":1951},[268,94933,5033],{"emptyLinePlaceholder":35},[268,94935,94936],{"class":270,"line":8955},[268,94937,94938],{"class":282},"outer()\n",[23,94940,94942,94954,94966,94975],{"className":94941},[26],[28,94943,94945,355,94947,94950,94951,94953],{"className":94944},[31],[33,94946],{"disabled":35,"type":36},[39,94948,94949],{},"SyntaxError: no binding for nonlocal 'missing' found"," — raised at compile time, before ",[39,94952,37562],{}," is ever called",[28,94955,94957,355,94959,94962,94963,94965],{"className":94956},[31],[33,94958],{"disabled":35,"type":36},[39,94960,94961],{},"UnboundLocalError"," raised when ",[39,94964,55205],{}," executes",[28,94967,94969,85094,94971,94974],{"className":94968},[31],[33,94970],{"disabled":35,"type":36},[39,94972,94973],{},"missing"," becomes a new global variable",[28,94976,94978,85094,94980,94982,94983,2018,94985,94987],{"className":94977},[31],[33,94979],{"disabled":35,"type":36},[39,94981,94190],{}," silently creates ",[39,94984,94973],{},[39,94986,9628],{},"'s scope",[66,94989,94990,94992,95000],{},[69,94991,71],{},[73,94993,94994,3459,94996,94950,94998,94953],{},[76,94995,78],{},[39,94997,94949],{},[39,94999,37562],{},[73,95001,95002,4030,95004,95006,95007,95009,95010,95013,95014,95016,95017,95019,95020,95022,95023,95025],{},[76,95003,84],{},[39,95005,71866],{},", which will happily create a new module-level name if one doesn't exist, ",[39,95008,94190],{}," requires that some enclosing function scope ",[104,95011,95012],{},"already"," bind that name (e.g., via assignment) — Python checks this at compile time. Since ",[39,95015,9628],{}," never assigns ",[39,95018,94973],{}," anywhere, the whole module fails to compile with a ",[39,95021,1274],{},", not a runtime error, which surprises people who expect the failure to happen only when ",[39,95024,55205],{}," is called.",[15,95027,95028,95032,95153,95190],{"language":87455},[18,95029,95031],{"id":95030},"q11-a-shared-mutable-counter-is-implemented-two-ways-which-one-actually-works-in-python-3-without-extra-tricks","Q11. A shared mutable counter is implemented two ways. Which one actually works in Python 3 without extra tricks?",[257,95033,95034],{"language":87455},[260,95035,95037],{"className":87467,"code":95036,"language":87455,"meta":264,"style":264},"# Version A\ndef make_counter_a():\n    count = 0\n    def increment():\n        nonlocal count\n        count += 1\n        return count\n    return increment\n\n# Version B\ndef make_counter_b():\n    count = 0\n    def increment():\n        count += 1\n        return count\n    return increment\n",[39,95038,95039,95044,95053,95062,95070,95077,95086,95092,95099,95103,95108,95117,95125,95133,95141,95147],{"__ignoreMap":264},[268,95040,95041],{"class":270,"line":271},[268,95042,95043],{"class":29390},"# Version A\n",[268,95045,95046,95048,95051],{"class":270,"line":286},[268,95047,88976],{"class":274},[268,95049,95050],{"class":278}," make_counter_a",[268,95052,92012],{"class":282},[268,95054,95055,95058,95060],{"class":270,"line":296},[268,95056,95057],{"class":282},"    count ",[268,95059,302],{"class":274},[268,95061,86318],{"class":305},[268,95063,95064,95066,95068],{"class":270,"line":311},[268,95065,92933],{"class":274},[268,95067,37313],{"class":278},[268,95069,92012],{"class":282},[268,95071,95072,95074],{"class":270,"line":788},[268,95073,94912],{"class":274},[268,95075,95076],{"class":282}," count\n",[268,95078,95079,95082,95084],{"class":270,"line":1951},[268,95080,95081],{"class":282},"        count ",[268,95083,14575],{"class":274},[268,95085,84787],{"class":305},[268,95087,95088,95090],{"class":270,"line":8955},[268,95089,11956],{"class":274},[268,95091,95076],{"class":282},[268,95093,95094,95096],{"class":270,"line":8966},[268,95095,9871],{"class":274},[268,95097,95098],{"class":282}," increment\n",[268,95100,95101],{"class":270,"line":8974},[268,95102,5033],{"emptyLinePlaceholder":35},[268,95104,95105],{"class":270,"line":8985},[268,95106,95107],{"class":29390},"# Version B\n",[268,95109,95110,95112,95115],{"class":270,"line":8990},[268,95111,88976],{"class":274},[268,95113,95114],{"class":278}," make_counter_b",[268,95116,92012],{"class":282},[268,95118,95119,95121,95123],{"class":270,"line":8997},[268,95120,95057],{"class":282},[268,95122,302],{"class":274},[268,95124,86318],{"class":305},[268,95126,95127,95129,95131],{"class":270,"line":9002},[268,95128,92933],{"class":274},[268,95130,37313],{"class":278},[268,95132,92012],{"class":282},[268,95134,95135,95137,95139],{"class":270,"line":14676},[268,95136,95081],{"class":282},[268,95138,14575],{"class":274},[268,95140,84787],{"class":305},[268,95142,95143,95145],{"class":270,"line":14681},[268,95144,11956],{"class":274},[268,95146,95076],{"class":282},[268,95148,95149,95151],{"class":270,"line":31051},[268,95150,9871],{"class":274},[268,95152,95098],{"class":282},[23,95154,95156,95167,95175,95181],{"className":95155},[26],[28,95157,95159,95161,95162,95164,95165],{"className":95158},[31],[33,95160],{"disabled":35,"type":36}," Only Version A works; Version B raises ",[39,95163,94961],{}," on the first call to ",[39,95166,44633],{},[28,95168,95170,95172,95173],{"className":95169},[31],[33,95171],{"disabled":35,"type":36}," Only Version B works; Version A raises a ",[39,95174,1274],{},[28,95176,95178,95180],{"className":95177},[31],[33,95179],{"disabled":35,"type":36}," Both versions work identically",[28,95182,95184,95186,95187,95189],{"className":95183},[31],[33,95185],{"disabled":35,"type":36}," Neither works; both need a ",[39,95188,71866],{}," declaration",[66,95191,95192,95194,95203],{},[69,95193,71],{},[73,95195,95196,95198,95199,95164,95201],{},[76,95197,78],{}," A — Only Version A works; Version B raises ",[39,95200,94961],{},[39,95202,44633],{},[73,95204,95205,355,95207,95210,95211,95214,95215,95217,95218,95220,95221,95223,95224,95226,95227,95230],{},[76,95206,84],{},[39,95208,95209],{},"count += 1"," is equivalent to ",[39,95212,95213],{},"count = count + 1",", and the presence of that assignment makes Python treat ",[39,95216,10191],{}," as local to ",[39,95219,34969],{}," at compile time — so the read on the right-hand side happens before any local ",[39,95222,10191],{}," has been assigned, raising ",[39,95225,94961],{},". Version A's ",[39,95228,95229],{},"nonlocal count"," tells Python to use the enclosing cell instead of creating a new local, which is exactly the fix this pattern needs.",[15,95232,95233,95244,95399,95439],{"language":87455},[18,95234,95236,95237,5992,95240,95243],{"id":95235},"q12-a-decorator-wraps-an-instance-method-but-the-wrapper-is-defined-as-def-wrapperargs-no-kwargs-what-breaks","Q12. A decorator wraps an instance method but the wrapper is defined as ",[39,95238,95239],{},"def wrapper(*args): ...",[39,95241,95242],{},"**kwargs","). What breaks?",[257,95245,95246],{"language":87455},[260,95247,95249],{"className":87467,"code":95248,"language":87455,"meta":264,"style":264},"def log_call(func):\n    def wrapper(*args):\n        print(f\"Calling {func.__name__}\")\n        return func(*args)\n    return wrapper\n\nclass Service:\n    @log_call\n    def fetch(self, url, timeout=5):\n        return f\"{url} in {timeout}s\"\n\nService().fetch(\"\u002Fapi\", timeout=2)\n",[39,95250,95251,95261,95275,95300,95311,95318,95322,95331,95336,95351,95377,95381],{"__ignoreMap":264},[268,95252,95253,95255,95258],{"class":270,"line":271},[268,95254,88976],{"class":274},[268,95256,95257],{"class":278}," log_call",[268,95259,95260],{"class":282},"(func):\n",[268,95262,95263,95265,95268,95270,95272],{"class":270,"line":286},[268,95264,92933],{"class":274},[268,95266,95267],{"class":278}," wrapper",[268,95269,622],{"class":282},[268,95271,6134],{"class":274},[268,95273,95274],{"class":282},"args):\n",[268,95276,95277,95280,95282,95284,95287,95290,95293,95296,95298],{"class":270,"line":296},[268,95278,95279],{"class":305},"        print",[268,95281,622],{"class":282},[268,95283,35286],{"class":274},[268,95285,95286],{"class":289},"\"Calling ",[268,95288,95289],{"class":305},"{",[268,95291,95292],{"class":282},"func.",[268,95294,95295],{"class":305},"__name__}",[268,95297,85220],{"class":289},[268,95299,20702],{"class":282},[268,95301,95302,95304,95307,95309],{"class":270,"line":311},[268,95303,11956],{"class":274},[268,95305,95306],{"class":282}," func(",[268,95308,6134],{"class":274},[268,95310,40305],{"class":282},[268,95312,95313,95315],{"class":270,"line":788},[268,95314,9871],{"class":274},[268,95316,95317],{"class":282}," wrapper\n",[268,95319,95320],{"class":270,"line":1951},[268,95321,5033],{"emptyLinePlaceholder":35},[268,95323,95324,95326,95329],{"class":270,"line":8955},[268,95325,1468],{"class":274},[268,95327,95328],{"class":278}," Service",[268,95330,8931],{"class":282},[268,95332,95333],{"class":270,"line":8966},[268,95334,95335],{"class":278},"    @log_call\n",[268,95337,95338,95340,95342,95345,95347,95349],{"class":270,"line":8974},[268,95339,92933],{"class":274},[268,95341,53875],{"class":278},[268,95343,95344],{"class":282},"(self, url, timeout",[268,95346,302],{"class":274},[268,95348,2429],{"class":305},[268,95350,94690],{"class":282},[268,95352,95353,95355,95357,95359,95361,95363,95366,95368,95370,95372,95374],{"class":270,"line":8985},[268,95354,11956],{"class":274},[268,95356,35259],{"class":274},[268,95358,85220],{"class":289},[268,95360,95289],{"class":305},[268,95362,15524],{"class":282},[268,95364,95365],{"class":305},"}",[268,95367,2018],{"class":289},[268,95369,95289],{"class":305},[268,95371,7414],{"class":282},[268,95373,95365],{"class":305},[268,95375,95376],{"class":289},"s\"\n",[268,95378,95379],{"class":270,"line":8990},[268,95380,5033],{"emptyLinePlaceholder":35},[268,95382,95383,95386,95389,95391,95393,95395,95397],{"class":270,"line":8997},[268,95384,95385],{"class":282},"Service().fetch(",[268,95387,95388],{"class":289},"\"\u002Fapi\"",[268,95390,42],{"class":282},[268,95392,7414],{"class":1222},[268,95394,302],{"class":274},[268,95396,2258],{"class":305},[268,95398,20702],{"class":282},[23,95400,95402,95410,95420,95431],{"className":95401},[26],[28,95403,95405,355,95407],{"className":95404},[31],[33,95406],{"disabled":35,"type":36},[39,95408,95409],{},"TypeError: wrapper() got an unexpected keyword argument 'timeout'",[28,95411,95413,95415,95416,95419],{"className":95412},[31],[33,95414],{"disabled":35,"type":36}," It works fine; ",[39,95417,95418],{},"*args"," silently absorbs keyword arguments too",[28,95421,95423,355,95425,95427,95428,95430],{"className":95422},[31],[33,95424],{"disabled":35,"type":36},[39,95426,87099],{}," is dropped and ",[39,95429,47324],{}," is called as a static method",[28,95432,95434,355,95436],{"className":95433},[31],[33,95435],{"disabled":35,"type":36},[39,95437,95438],{},"AttributeError: 'Service' object has no attribute 'fetch'",[66,95440,95441,95443,95449],{},[69,95442,71],{},[73,95444,95445,3459,95447],{},[76,95446,78],{},[39,95448,95409],{},[73,95450,95451,355,95453,95455,95456,95459,95460,95462,95463,95465,95466,95468],{},[76,95452,84],{},[39,95454,95418],{}," only collects positional arguments; a caller passing ",[39,95457,95458],{},"timeout=2"," as a keyword argument has nothing to bind to, so Python raises ",[39,95461,827],{},". A decorator meant to be transparent for arbitrary wrapped callables must define ",[39,95464,94585],{}," and forward both. Beginners assume ",[39,95467,95418],{}," is a catch-all for \"anything,\" which is the trap here.",[15,95470,95471,95475,95579,95612],{"language":87455},[18,95472,95474],{"id":95473},"q13-what-does-this-print","Q13. What does this print?",[257,95476,95477],{"language":87455},[260,95478,95480],{"className":87467,"code":95479,"language":87455,"meta":264,"style":264},"def broken_decorator(func):\n    def wrapper(*args, **kwargs):\n        result = func(*args, **kwargs)\n        # forgot to return wrapper\n\n@broken_decorator\ndef add(a, b):\n    return a + b\n\nprint(add(2, 3))\n",[39,95481,95482,95491,95508,95526,95531,95535,95540,95549,95560,95564],{"__ignoreMap":264},[268,95483,95484,95486,95489],{"class":270,"line":271},[268,95485,88976],{"class":274},[268,95487,95488],{"class":278}," broken_decorator",[268,95490,95260],{"class":282},[268,95492,95493,95495,95497,95499,95501,95503,95505],{"class":270,"line":286},[268,95494,92933],{"class":274},[268,95496,95267],{"class":278},[268,95498,622],{"class":282},[268,95500,6134],{"class":274},[268,95502,40331],{"class":282},[268,95504,6231],{"class":274},[268,95506,95507],{"class":282},"kwargs):\n",[268,95509,95510,95513,95515,95517,95519,95521,95523],{"class":270,"line":296},[268,95511,95512],{"class":282},"        result ",[268,95514,302],{"class":274},[268,95516,95306],{"class":282},[268,95518,6134],{"class":274},[268,95520,40331],{"class":282},[268,95522,6231],{"class":274},[268,95524,95525],{"class":282},"kwargs)\n",[268,95527,95528],{"class":270,"line":311},[268,95529,95530],{"class":29390},"        # forgot to return wrapper\n",[268,95532,95533],{"class":270,"line":788},[268,95534,5033],{"emptyLinePlaceholder":35},[268,95536,95537],{"class":270,"line":1951},[268,95538,95539],{"class":278},"@broken_decorator\n",[268,95541,95542,95544,95546],{"class":270,"line":8955},[268,95543,88976],{"class":274},[268,95545,1217],{"class":278},[268,95547,95548],{"class":282},"(a, b):\n",[268,95550,95551,95553,95555,95557],{"class":270,"line":8966},[268,95552,9871],{"class":274},[268,95554,1243],{"class":282},[268,95556,1246],{"class":274},[268,95558,95559],{"class":282}," b\n",[268,95561,95562],{"class":270,"line":8974},[268,95563,5033],{"emptyLinePlaceholder":35},[268,95565,95566,95568,95571,95573,95575,95577],{"class":270,"line":8985},[268,95567,84797],{"class":305},[268,95569,95570],{"class":282},"(add(",[268,95572,2258],{"class":305},[268,95574,42],{"class":282},[268,95576,3423],{"class":305},[268,95578,47690],{"class":282},[23,95580,95582,95590,95597,95604],{"className":95581},[26],[28,95583,95585,355,95587],{"className":95584},[31],[33,95586],{"disabled":35,"type":36},[39,95588,95589],{},"TypeError: 'NoneType' object is not callable",[28,95591,95593,355,95595],{"className":95592},[31],[33,95594],{"disabled":35,"type":36},[39,95596,2429],{},[28,95598,95600,355,95602],{"className":95599},[31],[33,95601],{"disabled":35,"type":36},[39,95603,90944],{},[28,95605,95607,355,95609],{"className":95606},[31],[33,95608],{"disabled":35,"type":36},[39,95610,95611],{},"NameError: name 'add' is not defined",[66,95613,95614,95616,95622],{},[69,95615,71],{},[73,95617,95618,3459,95620],{},[76,95619,78],{},[39,95621,95589],{},[73,95623,95624,355,95626,3990,95628,95631,95632,95634,95635,7474,95637,95640,95641,95643,95644,12867,95646,95649,95650,95652,95653,95655,95656,95659,95660,95662],{},[76,95625,84],{},[76,95627,16523],{},[39,95629,95630],{},"broken_decorator"," never returns ",[39,95633,94397],{}," (or anything), so it implicitly returns ",[39,95636,90944],{},[39,95638,95639],{},"add = broken_decorator(add)",", the name ",[39,95642,41889],{}," is rebound to ",[39,95645,90944],{},[39,95647,95648],{},"add(2, 3)"," tries to call ",[39,95651,90944],{},", which raises ",[39,95654,827],{},". The fix is to always ",[39,95657,95658],{},"return wrapper"," from the decorator — a missing ",[39,95661,9151],{}," is one of the most common real-world decorator bugs, and it fails at the call site, far from the actual mistake.",[15,95664,95665,95669,95839,95874],{"language":87455},[18,95666,95668],{"id":95667},"q14-what-is-printed-by-this-decorator-with-arguments-code","Q14. What is printed by this decorator-with-arguments code?",[257,95670,95671],{"language":87455},[260,95672,95674],{"className":87467,"code":95673,"language":87455,"meta":264,"style":264},"import functools\n\ndef repeat(times):\n    def decorator(func):\n        @functools.wraps(func)\n        def wrapper(*args, **kwargs):\n            results = []\n            for _ in range(times):\n                results.append(func(*args, **kwargs))\n            return results\n        return wrapper\n    return decorator\n\n@repeat(times=2)\ndef shout(word):\n    return word.upper()\n\nprint(shout(\"hi\"))\n",[39,95675,95676,95683,95687,95697,95706,95714,95731,95740,95753,95767,95775,95781,95788,95792,95808,95817,95824,95828],{"__ignoreMap":264},[268,95677,95678,95680],{"class":270,"line":271},[268,95679,662],{"class":274},[268,95681,95682],{"class":282}," functools\n",[268,95684,95685],{"class":270,"line":286},[268,95686,5033],{"emptyLinePlaceholder":35},[268,95688,95689,95691,95694],{"class":270,"line":296},[268,95690,88976],{"class":274},[268,95692,95693],{"class":278}," repeat",[268,95695,95696],{"class":282},"(times):\n",[268,95698,95699,95701,95704],{"class":270,"line":311},[268,95700,92933],{"class":274},[268,95702,95703],{"class":278}," decorator",[268,95705,95260],{"class":282},[268,95707,95708,95711],{"class":270,"line":788},[268,95709,95710],{"class":278},"        @functools.wraps",[268,95712,95713],{"class":282},"(func)\n",[268,95715,95716,95719,95721,95723,95725,95727,95729],{"class":270,"line":1951},[268,95717,95718],{"class":274},"        def",[268,95720,95267],{"class":278},[268,95722,622],{"class":282},[268,95724,6134],{"class":274},[268,95726,40331],{"class":282},[268,95728,6231],{"class":274},[268,95730,95507],{"class":282},[268,95732,95733,95736,95738],{"class":270,"line":8955},[268,95734,95735],{"class":282},"            results ",[268,95737,302],{"class":274},[268,95739,94672],{"class":282},[268,95741,95742,95745,95747,95749,95751],{"class":270,"line":8966},[268,95743,95744],{"class":274},"            for",[268,95746,83633],{"class":282},[268,95748,20749],{"class":274},[268,95750,94683],{"class":305},[268,95752,95696],{"class":282},[268,95754,95755,95758,95760,95762,95764],{"class":270,"line":8974},[268,95756,95757],{"class":282},"                results.append(func(",[268,95759,6134],{"class":274},[268,95761,40331],{"class":282},[268,95763,6231],{"class":274},[268,95765,95766],{"class":282},"kwargs))\n",[268,95768,95769,95772],{"class":270,"line":8985},[268,95770,95771],{"class":274},"            return",[268,95773,95774],{"class":282}," results\n",[268,95776,95777,95779],{"class":270,"line":8990},[268,95778,11956],{"class":274},[268,95780,95317],{"class":282},[268,95782,95783,95785],{"class":270,"line":8997},[268,95784,9871],{"class":274},[268,95786,95787],{"class":282}," decorator\n",[268,95789,95790],{"class":270,"line":9002},[268,95791,5033],{"emptyLinePlaceholder":35},[268,95793,95794,95797,95799,95802,95804,95806],{"class":270,"line":14676},[268,95795,95796],{"class":278},"@repeat",[268,95798,622],{"class":282},[268,95800,95801],{"class":1222},"times",[268,95803,302],{"class":274},[268,95805,2258],{"class":305},[268,95807,20702],{"class":282},[268,95809,95810,95812,95814],{"class":270,"line":14681},[268,95811,88976],{"class":274},[268,95813,16162],{"class":278},[268,95815,95816],{"class":282},"(word):\n",[268,95818,95819,95821],{"class":270,"line":31051},[268,95820,9871],{"class":274},[268,95822,95823],{"class":282}," word.upper()\n",[268,95825,95826],{"class":270,"line":31071},[268,95827,5033],{"emptyLinePlaceholder":35},[268,95829,95830,95832,95835,95837],{"class":270,"line":33819},[268,95831,84797],{"class":305},[268,95833,95834],{"class":282},"(shout(",[268,95836,85975],{"class":289},[268,95838,47690],{"class":282},[23,95840,95842,95850,95858,95866],{"className":95841},[26],[28,95843,95845,355,95847],{"className":95844},[31],[33,95846],{"disabled":35,"type":36},[39,95848,95849],{},"['HI', 'HI']",[28,95851,95853,355,95855],{"className":95852},[31],[33,95854],{"disabled":35,"type":36},[39,95856,95857],{},"'HIHI'",[28,95859,95861,355,95863],{"className":95860},[31],[33,95862],{"disabled":35,"type":36},[39,95864,95865],{},"TypeError: decorator() missing 1 required positional argument: 'func'",[28,95867,95869,355,95871],{"className":95868},[31],[33,95870],{"disabled":35,"type":36},[39,95872,95873],{},"['hi', 'hi']",[66,95875,95876,95878,95884],{},[69,95877,71],{},[73,95879,95880,3459,95882],{},[76,95881,78],{},[39,95883,95849],{},[73,95885,95886,355,95888,4912,95891,95894,95895,95897,95898,15108,95900,95903,95904,95907,95908,95910,95911,73737,95914,95917],{},[76,95887,84],{},[39,95889,95890],{},"repeat(times=2)",[39,95892,95893],{},"decorator",", which is then applied to ",[39,95896,16226],{},", producing ",[39,95899,94397],{},[39,95901,95902],{},"shout(\"hi\")"," actually calls ",[39,95905,95906],{},"wrapper(\"hi\")",", which invokes the original ",[39,95909,95902],{}," twice and collects the (already-uppercased) results into a list. Option C is the mistake of thinking ",[39,95912,95913],{},"@repeat(times=2)",[39,95915,95916],{},"repeat"," directly to the function instead of first calling it to get a decorator.",[15,95919,95920,95924,96056,96109],{"language":87455},[18,95921,95923],{"id":95922},"q15-which-is-the-idiomatic-most-robust-way-to-write-a-decorator-that-is-meant-to-work-on-any-function-signature","Q15. Which is the idiomatic, most robust way to write a decorator that is meant to work on any function signature?",[257,95925,95926],{"language":87455},[260,95927,95929],{"className":87467,"code":95928,"language":87455,"meta":264,"style":264},"import functools\n\ndef timed(func):\n    @functools.wraps(func)\n    def wrapper(*args, **kwargs):\n        start = time.perf_counter()\n        try:\n            return func(*args, **kwargs)\n        finally:\n            print(f\"{func.__name__} took {time.perf_counter() - start:.4f}s\")\n    return wrapper\n",[39,95930,95931,95937,95941,95950,95957,95973,95983,95990,96004,96011,96050],{"__ignoreMap":264},[268,95932,95933,95935],{"class":270,"line":271},[268,95934,662],{"class":274},[268,95936,95682],{"class":282},[268,95938,95939],{"class":270,"line":286},[268,95940,5033],{"emptyLinePlaceholder":35},[268,95942,95943,95945,95948],{"class":270,"line":296},[268,95944,88976],{"class":274},[268,95946,95947],{"class":278}," timed",[268,95949,95260],{"class":282},[268,95951,95952,95955],{"class":270,"line":311},[268,95953,95954],{"class":278},"    @functools.wraps",[268,95956,95713],{"class":282},[268,95958,95959,95961,95963,95965,95967,95969,95971],{"class":270,"line":788},[268,95960,92933],{"class":274},[268,95962,95267],{"class":278},[268,95964,622],{"class":282},[268,95966,6134],{"class":274},[268,95968,40331],{"class":282},[268,95970,6231],{"class":274},[268,95972,95507],{"class":282},[268,95974,95975,95978,95980],{"class":270,"line":1951},[268,95976,95977],{"class":282},"        start ",[268,95979,302],{"class":274},[268,95981,95982],{"class":282}," time.perf_counter()\n",[268,95984,95985,95988],{"class":270,"line":8955},[268,95986,95987],{"class":274},"        try",[268,95989,8931],{"class":282},[268,95991,95992,95994,95996,95998,96000,96002],{"class":270,"line":8966},[268,95993,95771],{"class":274},[268,95995,95306],{"class":282},[268,95997,6134],{"class":274},[268,95999,40331],{"class":282},[268,96001,6231],{"class":274},[268,96003,95525],{"class":282},[268,96005,96006,96009],{"class":270,"line":8974},[268,96007,96008],{"class":274},"        finally",[268,96010,8931],{"class":282},[268,96012,96013,96016,96018,96020,96022,96024,96026,96028,96031,96033,96036,96038,96040,96043,96045,96048],{"class":270,"line":8985},[268,96014,96015],{"class":305},"            print",[268,96017,622],{"class":282},[268,96019,35286],{"class":274},[268,96021,85220],{"class":289},[268,96023,95289],{"class":305},[268,96025,95292],{"class":282},[268,96027,95295],{"class":305},[268,96029,96030],{"class":289}," took ",[268,96032,95289],{"class":305},[268,96034,96035],{"class":282},"time.perf_counter() ",[268,96037,6244],{"class":274},[268,96039,70103],{"class":282},[268,96041,96042],{"class":274},":.4f",[268,96044,95365],{"class":305},[268,96046,96047],{"class":289},"s\"",[268,96049,20702],{"class":282},[268,96051,96052,96054],{"class":270,"line":8990},[268,96053,9871],{"class":274},[268,96055,95317],{"class":282},[23,96057,96059,96078,96090,96100],{"className":96058},[26],[28,96060,96062,96064,96065,96068,96069,96071,96072,96074,96075,96077],{"className":96061},[31],[33,96063],{"disabled":35,"type":36}," This version — ",[39,96066,96067],{},"*args, **kwargs"," forwards any signature, ",[39,96070,94330],{}," preserves metadata, and ",[39,96073,51954],{}," ensures timing prints even if ",[39,96076,94581],{}," raises",[28,96079,96081,96083,96084,96086,96087,96089],{"className":96080},[31],[33,96082],{"disabled":35,"type":36}," Same, but without ",[39,96085,94330],{},", since it only affects ",[39,96088,94401],{}," output and nothing functional",[28,96091,96093,96083,96095,446,96097,96099],{"className":96092},[31],[33,96094],{"disabled":35,"type":36},[39,96096,23142],{},[39,96098,51954],{},", since decorators shouldn't handle control flow",[28,96101,96103,96105,96106,96108],{"className":96102},[31],[33,96104],{"disabled":35,"type":36}," Same, but replacing ",[39,96107,96067],{}," with the wrapped function's exact named parameters for clarity",[66,96110,96111,96113,96126],{},[69,96112,71],{},[73,96114,96115,96117,96118,96068,96120,96071,96122,96074,96124,96077],{},[76,96116,78],{}," A — This version — ",[39,96119,96067],{},[39,96121,94330],{},[39,96123,51954],{},[39,96125,94581],{},[73,96127,96128,355,96130,96132,96133,96135,96136,96138,96139,96141,96142,96145,96146,446,96148,96151],{},[76,96129,84],{},[76,96131,17307],{}," — A general-purpose decorator must accept and forward an arbitrary signature (",[39,96134,96067],{},"), preserve introspection metadata (",[39,96137,94330],{},"), and use ",[39,96140,51954],{}," so cleanup\u002Flogging code runs even when the wrapped function raises. Skipping ",[39,96143,96144],{},"wraps"," (option B) is a real bug in production code — it breaks tools that rely on ",[39,96147,94343],{},[39,96149,96150],{},"__qualname__",", such as API routers and test discovery. Hardcoding named parameters (option D) makes the decorator unreusable for any other function.",[15,96153,96154,96166,96202],{},[18,96155,96157,96158,96161,96162,96165],{"id":96156},"q16-a-decorator-needs-to-work-both-as-cache-no-parentheses-and-cachemaxsize100-with-parentheses-what-is-the-idiomatic-way-to-support-both-forms","Q16. A decorator needs to work both as ",[39,96159,96160],{},"@cache"," (no parentheses) and ",[39,96163,96164],{},"@cache(maxsize=100)"," (with parentheses). What is the idiomatic way to support both forms?",[23,96167,96169,96175,96184,96194],{"className":96168},[26],[28,96170,96172,96174],{"className":96171},[31],[33,96173],{"disabled":35,"type":36}," Detect whether the single positional argument is callable: if so, treat it as the direct-decoration case and decorate immediately; otherwise treat it as configuration and return a real decorator",[28,96176,96178,96180,96181,96183],{"className":96177},[31],[33,96179],{"disabled":35,"type":36}," Always require parentheses and document that ",[39,96182,96160],{}," alone is unsupported",[28,96185,96187,96189,96190,96193],{"className":96186},[31],[33,96188],{"disabled":35,"type":36}," Overload the function name with two different ",[39,96191,96192],{},"def cache"," definitions",[28,96195,96197,4353,96199,96201],{"className":96196},[31],[33,96198],{"disabled":35,"type":36},[39,96200,95418],{}," and assume the first argument is always the function",[66,96203,96204,96206,96211],{},[69,96205,71],{},[73,96207,96208,96210],{},[76,96209,78],{}," A — Detect whether the single positional argument is callable: if so, treat it as the direct-decoration case and decorate immediately; otherwise treat it as configuration and return a real decorator",[73,96212,96213,355,96215,96217,96218,96221,96222,96225],{},[76,96214,84],{},[76,96216,17307],{}," — Libraries like ",[39,96219,96220],{},"functools.lru_cache"," (Python 3.8+) support this dual-mode pattern by checking ",[39,96223,96224],{},"callable(arg) and not kwargs"," to distinguish \"I was called directly on a function\" from \"I was called with configuration and need to return a decorator.\" Requiring parentheses always (option B) is simpler but breaks compatibility with existing dual-mode decorators users expect to work either way; redefining a function twice (option C) simply overwrites the first definition rather than overloading it.",[15,96227,96228,96232,96264],{},[18,96229,96231],{"id":96230},"q17-for-simple-memoization-of-a-pure-function-keyed-on-its-arguments-which-is-the-best-practice-choice","Q17. For simple memoization of a pure function keyed on its arguments, which is the best-practice choice?",[23,96233,96235,96243,96252,96258],{"className":96234},[26],[28,96236,96238,355,96240,96242],{"className":96237},[31],[33,96239],{"disabled":35,"type":36},[39,96241,96220],{},", since it's a battle-tested, thread-safe-for-reads standard-library decorator with eviction support",[28,96244,96246,96248,96249,96251],{"className":96245},[31],[33,96247],{"disabled":35,"type":36}," A hand-rolled decorator using a plain ",[39,96250,89385],{}," with no size limit, since it gives identical behavior with less import overhead",[28,96253,96255,96257],{"className":96254},[31],[33,96256],{"disabled":35,"type":36}," A global mutable list scanned linearly for matching arguments on every call",[28,96259,96261,96263],{"className":96260},[31],[33,96262],{"disabled":35,"type":36}," Re-running the function every time, since memoization is rarely worth the complexity",[66,96265,96266,96268,96274],{},[69,96267,71],{},[73,96269,96270,3459,96272,96242],{},[76,96271,78],{},[39,96273,96220],{},[73,96275,96276,355,96278,3990,96280,96282,96283,96286,96287,96290],{},[76,96277,84],{},[76,96279,17307],{},[39,96281,96220],{}," handles hashable-argument caching, an optional ",[39,96284,96285],{},"maxsize"," for bounded memory, and ",[39,96288,96289],{},"cache_info()"," for introspection, all without extra code. A hand-rolled unbounded dict cache (option B) is a memory-leak risk in long-running processes since entries are never evicted; a linear-scan list (option C) is both slower and more error-prone at determining argument equality.",[15,96292,96293,96297,96334],{},[18,96294,96296],{"id":96295},"q18-in-modern-python-3-code-which-is-the-preferred-way-to-maintain-a-mutable-counter-shared-between-an-outer-function-and-its-inner-closures","Q18. In modern Python 3 code, which is the preferred way to maintain a mutable counter shared between an outer function and its inner closures?",[23,96298,96300,96308,96322,96328],{"className":96299},[26],[28,96301,96303,355,96305,96307],{"className":96302},[31],[33,96304],{"disabled":35,"type":36},[39,96306,94190],{},", since it clearly expresses intent and avoids indirection through a container object",[28,96309,96311,96313,96314,96317,96318,96321],{"className":96310},[31],[33,96312],{"disabled":35,"type":36}," A single-element list, e.g. ",[39,96315,96316],{},"count = [0]",", mutated via ",[39,96319,96320],{},"count[0] += 1",", because closures can't rebind outer names at all",[28,96323,96325,96327],{"className":96324},[31],[33,96326],{"disabled":35,"type":36}," A global variable, since it's simplest",[28,96329,96331,96333],{"className":96330},[31],[33,96332],{"disabled":35,"type":36}," A mutable default argument on the inner function",[66,96335,96336,96338,96344],{},[69,96337,71],{},[73,96339,96340,3459,96342,96307],{},[76,96341,78],{},[39,96343,94190],{},[73,96345,96346,355,96348,3990,96350,96352,96353,96355],{},[76,96347,84],{},[76,96349,17307],{},[39,96351,94190],{}," (Python 3+) directly and readably rebinds an enclosing-scope variable. The list-mutation trick (option B) was a common workaround in Python 2, which lacked ",[39,96354,94190],{},", but it's now considered a code smell — it mutates a container instead of rebinding a name, which is harder to read and easy to mix up with genuinely shared mutable state. A global (option C) unnecessarily widens scope beyond the closure's own use case.",[15,96357,96358,96366,96508,96567],{"language":87455},[18,96359,96361,96362,96365],{"id":96360},"q19-a-class-based-decorator-is-implemented-using-__call__-which-statement-about-it-is-correct","Q19. A class-based decorator is implemented using ",[39,96363,96364],{},"__call__",". Which statement about it is correct?",[257,96367,96368],{"language":87455},[260,96369,96371],{"className":87467,"code":96370,"language":87455,"meta":264,"style":264},"import functools\n\nclass CountCalls:\n    def __init__(self, func):\n        functools.update_wrapper(self, func)\n        self.func = func\n        self.calls = 0\n\n    def __call__(self, *args, **kwargs):\n        self.calls += 1\n        return self.func(*args, **kwargs)\n\n@CountCalls\ndef greet():\n    return \"hi\"\n",[39,96372,96373,96379,96383,96392,96401,96411,96423,96434,96438,96456,96466,96484,96488,96493,96501],{"__ignoreMap":264},[268,96374,96375,96377],{"class":270,"line":271},[268,96376,662],{"class":274},[268,96378,95682],{"class":282},[268,96380,96381],{"class":270,"line":286},[268,96382,5033],{"emptyLinePlaceholder":35},[268,96384,96385,96387,96390],{"class":270,"line":296},[268,96386,1468],{"class":274},[268,96388,96389],{"class":278}," CountCalls",[268,96391,8931],{"class":282},[268,96393,96394,96396,96398],{"class":270,"line":311},[268,96395,92933],{"class":274},[268,96397,92936],{"class":305},[268,96399,96400],{"class":282},"(self, func):\n",[268,96402,96403,96406,96408],{"class":270,"line":788},[268,96404,96405],{"class":282},"        functools.update_wrapper(",[268,96407,87099],{"class":305},[268,96409,96410],{"class":282},", func)\n",[268,96412,96413,96415,96418,96420],{"class":270,"line":1951},[268,96414,92944],{"class":305},[268,96416,96417],{"class":282},".func ",[268,96419,302],{"class":274},[268,96421,96422],{"class":282}," func\n",[268,96424,96425,96427,96430,96432],{"class":270,"line":8955},[268,96426,92944],{"class":305},[268,96428,96429],{"class":282},".calls ",[268,96431,302],{"class":274},[268,96433,86318],{"class":305},[268,96435,96436],{"class":270,"line":8966},[268,96437,5033],{"emptyLinePlaceholder":35},[268,96439,96440,96442,96445,96448,96450,96452,96454],{"class":270,"line":8974},[268,96441,92933],{"class":274},[268,96443,96444],{"class":305}," __call__",[268,96446,96447],{"class":282},"(self, ",[268,96449,6134],{"class":274},[268,96451,40331],{"class":282},[268,96453,6231],{"class":274},[268,96455,95507],{"class":282},[268,96457,96458,96460,96462,96464],{"class":270,"line":8985},[268,96459,92944],{"class":305},[268,96461,96429],{"class":282},[268,96463,14575],{"class":274},[268,96465,84787],{"class":305},[268,96467,96468,96470,96473,96476,96478,96480,96482],{"class":270,"line":8990},[268,96469,11956],{"class":274},[268,96471,96472],{"class":305}," self",[268,96474,96475],{"class":282},".func(",[268,96477,6134],{"class":274},[268,96479,40331],{"class":282},[268,96481,6231],{"class":274},[268,96483,95525],{"class":282},[268,96485,96486],{"class":270,"line":8997},[268,96487,5033],{"emptyLinePlaceholder":35},[268,96489,96490],{"class":270,"line":9002},[268,96491,96492],{"class":278},"@CountCalls\n",[268,96494,96495,96497,96499],{"class":270,"line":14676},[268,96496,88976],{"class":274},[268,96498,3679],{"class":278},[268,96500,92012],{"class":282},[268,96502,96503,96505],{"class":270,"line":14681},[268,96504,9871],{"class":274},[268,96506,96507],{"class":289}," \"hi\"\n",[23,96509,96511,96538,96544,96553],{"className":96510},[26],[28,96512,96514,355,96516,96519,96520,96522,96523,446,96525,20968,96527,96529,96530,96533,96534,96537],{"className":96513},[31],[33,96515],{"disabled":35,"type":36},[39,96517,96518],{},"functools.update_wrapper"," is needed here (the class-based equivalent of ",[39,96521,94330],{},") to copy ",[39,96524,94343],{},[39,96526,94346],{},[39,96528,94581],{}," onto the ",[39,96531,96532],{},"CountCalls"," instance, and ",[39,96535,96536],{},"greet.calls"," is now readable state that a plain closure-based decorator can't expose as cleanly",[28,96539,96541,96543],{"className":96540},[31],[33,96542],{"disabled":35,"type":36}," Class-based decorators can never preserve the original function's metadata, unlike function-based ones",[28,96545,96547,355,96549,96552],{"className":96546},[31],[33,96548],{"disabled":35,"type":36},[39,96550,96551],{},"@CountCalls"," is invalid syntax because decorators must be functions, not classes",[28,96554,96556,355,96558,96561,96562,96564,96565],{"className":96555},[31],[33,96557],{"disabled":35,"type":36},[39,96559,96560],{},"self.calls"," resets to ",[39,96563,3307],{}," on every call to ",[39,96566,12870],{},[66,96568,96569,96571,96589],{},[69,96570,71],{},[73,96572,96573,3459,96575,96519,96577,96522,96579,446,96581,20968,96583,96529,96585,96533,96587,96537],{},[76,96574,78],{},[39,96576,96518],{},[39,96578,94330],{},[39,96580,94343],{},[39,96582,94346],{},[39,96584,94581],{},[39,96586,96532],{},[39,96588,96536],{},[73,96590,96591,355,96593,96595,96596,96598,96599,96601,96602,96604,96605,96607,96608,96611],{},[76,96592,84],{},[76,96594,17307],{}," — Any callable object can be a decorator; a class implementing ",[39,96597,96364],{}," is a common pattern when the decorator needs to hold persistent, easily-inspectable state (like a call counter) rather than hiding it in a closure cell. ",[39,96600,96518],{}," is the underlying function that ",[39,96603,94330],{}," calls internally, applicable to any object, not just nested functions. ",[39,96606,96560],{}," persists across calls precisely because ",[39,96609,96610],{},"__init__"," runs once, at decoration time, not on every invocation.",[15,96613,96614,96626,96663,96710],{"language":87455},[18,96615,96617,96618,96621,96622,96625],{"id":96616},"q20-a-web-framework-uses-approuteusers-above-login_required-above-the-view-function-what-does-the-ordering-imply-and-why-does-it-matter","Q20. A web framework uses ",[39,96619,96620],{},"@app.route(\"\u002Fusers\")"," above ",[39,96623,96624],{},"@login_required"," above the view function. What does the ordering imply, and why does it matter?",[257,96627,96628],{"language":87455},[260,96629,96631],{"className":87467,"code":96630,"language":87455,"meta":264,"style":264},"@app.route(\"\u002Fusers\")\n@login_required\ndef list_users():\n    ...\n",[39,96632,96633,96645,96650,96659],{"__ignoreMap":264},[268,96634,96635,96638,96640,96643],{"class":270,"line":271},[268,96636,96637],{"class":278},"@app.route",[268,96639,622],{"class":282},[268,96641,96642],{"class":289},"\"\u002Fusers\"",[268,96644,20702],{"class":282},[268,96646,96647],{"class":270,"line":286},[268,96648,96649],{"class":278},"@login_required\n",[268,96651,96652,96654,96657],{"class":270,"line":296},[268,96653,88976],{"class":274},[268,96655,96656],{"class":278}," list_users",[268,96658,92012],{"class":282},[268,96660,96661],{"class":270,"line":311},[268,96662,90877],{"class":305},[23,96664,96666,96687,96693,96704],{"className":96665},[26],[28,96667,96669,355,96671,96674,96675,96678,96679,96682,96683,96686],{"className":96668},[31],[33,96670],{"disabled":35,"type":36},[39,96672,96673],{},"login_required"," wraps ",[39,96676,96677],{},"list_users"," first (closest decorator), so the auth check runs on every request before the route even reaches the view logic; reversing the order would let ",[39,96680,96681],{},"app.route"," register the ",[104,96684,96685],{},"unwrapped"," view, bypassing the auth check entirely",[28,96688,96690,96692],{"className":96689},[31],[33,96691],{"disabled":35,"type":36}," The order is purely stylistic; Python decorators are commutative regardless of which one is listed first",[28,96694,96696,355,96698,96700,96701,96703],{"className":96695},[31],[33,96697],{"disabled":35,"type":36},[39,96699,96681],{}," always executes before ",[39,96702,96673],{}," no matter the order written, because routing decorators have special priority",[28,96705,96707,96709],{"className":96706},[31],[33,96708],{"disabled":35,"type":36}," Both decorators wrap independently and neither can see the other's effect",[66,96711,96712,96714,96726],{},[69,96713,71],{},[73,96715,96716,3459,96718,96674,96720,96678,96722,96682,96724,96686],{},[76,96717,78],{},[39,96719,96673],{},[39,96721,96677],{},[39,96723,96681],{},[104,96725,96685],{},[73,96727,96728,355,96730,96732,96733,42,96736,96738,96739,96741,96742,96744,96745,137,96747,96749],{},[76,96729,84],{},[76,96731,17307],{}," — Since decoration is ",[39,96734,96735],{},"list_users = app.route(\"\u002Fusers\")(login_required(list_users))",[39,96737,96673],{}," produces the auth-checking wrapper first, and ",[104,96740,7690],{}," wrapper is what gets registered as the route handler. If the order were flipped, ",[39,96743,96681],{}," would register the raw ",[39,96746,96677],{},[39,96748,96673],{}," would wrap a function that's no longer connected to any route — a real, security-relevant bug that decorator-order mistakes can cause in production frameworks like Flask.",[2107,96751,96752],{},"html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}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}",{"title":264,"searchDepth":286,"depth":286,"links":96754},[96755,96756,96758,96760,96762,96763,96765,96766,96767,96769,96770,96771,96773,96774,96775,96776,96778,96779,96780,96782],{"id":94142,"depth":296,"text":94143},{"id":94196,"depth":296,"text":96757},"Q2. What does the nonlocal keyword do?",{"id":94255,"depth":296,"text":96759},"Q3. @my_decorator placed above def func(): ... is syntactic sugar for which statement?",{"id":94327,"depth":296,"text":96761},"Q4. What does functools.wraps do when applied inside a decorator's wrapper function?",{"id":94411,"depth":296,"text":94412},{"id":94529,"depth":296,"text":96764},"Q6. A decorator that itself accepts arguments, e.g. @retry(times=3), requires how many levels of nested functions?",{"id":94599,"depth":296,"text":94600},{"id":94654,"depth":296,"text":94655},{"id":94799,"depth":296,"text":96768},"Q9. Which change correctly fixes the late-binding bug from Q8 so the output is [0, 1, 2]?",{"id":27953,"depth":296,"text":27954},{"id":95030,"depth":296,"text":95031},{"id":95235,"depth":296,"text":96772},"Q12. A decorator wraps an instance method but the wrapper is defined as def wrapper(*args): ... (no **kwargs). What breaks?",{"id":95473,"depth":296,"text":95474},{"id":95667,"depth":296,"text":95668},{"id":95922,"depth":296,"text":95923},{"id":96156,"depth":296,"text":96777},"Q16. A decorator needs to work both as @cache (no parentheses) and @cache(maxsize=100) (with parentheses). What is the idiomatic way to support both forms?",{"id":96230,"depth":296,"text":96231},{"id":96295,"depth":296,"text":96296},{"id":96360,"depth":296,"text":96781},"Q19. A class-based decorator is implemented using __call__. Which statement about it is correct?",{"id":96616,"depth":296,"text":96783},"Q20. A web framework uses @app.route(\"\u002Fusers\") above @login_required above the view function. What does the ordering imply, and why does it matter?",{},"\u002Fpython\u002F11-closures-and-decorators",{"title":94132,"description":264},"python\u002F11-closures-and-decorators","t5aAd1jgmmSn4Z331F__BeogoSDggABhvVISnQish7Q",{"id":96790,"title":96791,"body":96792,"description":264,"extension":2144,"meta":99204,"navigation":35,"path":99205,"seo":99206,"stem":99207,"__hash__":99208},"content\u002Fpython\u002F12-classes-and-objects.md","12 — Classes & Objects",{"type":8,"value":96793,"toc":99168},[96794,96797,96864,96973,97049,97156,97218,97281,97381,97542,97686,97925,98085,98286,98446,98649,98736,98824,98916,98994,99064,99165],[11,96795,96791],{"id":96796},"_12-classes-objects",[15,96798,96799,96803,96840],{},[18,96800,96802],{"id":96801},"q1-what-is-the-difference-between-a-class-attribute-and-an-instance-attribute","Q1. What is the difference between a class attribute and an instance attribute?",[23,96804,96806,96816,96822,96831],{"className":96805},[26],[28,96807,96809,96811,96812,2018,96814],{"className":96808},[31],[33,96810],{"disabled":35,"type":36}," A class attribute is defined in the class body and shared by all instances unless overridden; an instance attribute is set per-object, usually via ",[39,96813,87099],{},[39,96815,96610],{},[28,96817,96819,96821],{"className":96818},[31],[33,96820],{"disabled":35,"type":36}," A class attribute can only hold integers or strings; an instance attribute can hold any type",[28,96823,96825,96827,96828],{"className":96824},[31],[33,96826],{"disabled":35,"type":36}," There is no functional difference — both are stored identically in every object's ",[39,96829,96830],{},"__dict__",[28,96832,96834,96836,96837,96839],{"className":96833},[31],[33,96835],{"disabled":35,"type":36}," A class attribute is only visible inside ",[39,96838,96610],{},", while an instance attribute is visible everywhere",[66,96841,96842,96844,96853],{},[69,96843,71],{},[73,96845,96846,96848,96849,2018,96851],{},[76,96847,78],{}," A — A class attribute is defined in the class body and shared by all instances unless overridden; an instance attribute is set per-object, usually via ",[39,96850,87099],{},[39,96852,96610],{},[73,96854,96855,96857,96858,96860,96861,96863],{},[76,96856,84],{}," Class attributes live in the class's own ",[39,96859,96830],{}," and are looked up via the class if an instance doesn't have its own copy. Instance attributes live in each object's own ",[39,96862,96830],{}," and take precedence over a class attribute of the same name. They are stored differently, not identically (option C) — this distinction is exactly what causes the shared-mutable-default bug covered later in this quiz.",[15,96865,96866,96875,96926],{},[18,96867,96869,96870,186,96872,1685],{"id":96868},"q2-what-is-the-difference-between-__init__-and-__new__","Q2. What is the difference between ",[39,96871,96610],{},[39,96873,96874],{},"__new__",[23,96876,96878,96898,96904,96915],{"className":96877},[26],[28,96879,96881,355,96883,96885,96886,96889,96890,355,96892,96895,96896],{"className":96880},[31],[33,96882],{"disabled":35,"type":36},[39,96884,96874],{}," is responsible for ",[104,96887,96888],{},"creating"," and returning a new instance (called before the object exists); ",[39,96891,96610],{},[104,96893,96894],{},"initializes"," an already-created instance and returns ",[39,96897,90944],{},[28,96899,96901,96903],{"className":96900},[31],[33,96902],{"disabled":35,"type":36}," They are aliases for the same method; Python calls whichever one is defined",[28,96905,96907,355,96909,96911,96912,96914],{"className":96906},[31],[33,96908],{"disabled":35,"type":36},[39,96910,96610],{}," creates the object; ",[39,96913,96874],{}," only runs for subclasses of built-in immutable types",[28,96916,96918,355,96920,96922,96923,96925],{"className":96917},[31],[33,96919],{"disabled":35,"type":36},[39,96921,96874],{}," runs after ",[39,96924,96610],{}," to finalize attribute defaults",[66,96927,96928,96930,96944],{},[69,96929,71],{},[73,96931,96932,3459,96934,96885,96936,96889,96938,355,96940,96895,96942],{},[76,96933,78],{},[39,96935,96874],{},[104,96937,96888],{},[39,96939,96610],{},[104,96941,96894],{},[39,96943,90944],{},[73,96945,96946,355,96948,96950,96951,96954,96955,96957,96958,96961,96962,96964,96965,183,96967,96969,96970,96972],{},[76,96947,84],{},[39,96949,96874],{}," is a static method (implicitly) that allocates and returns the object — it's what actually calls ",[39,96952,96953],{},"object.__new__(cls)"," under the hood. Only after ",[39,96956,96874],{}," returns an instance of ",[39,96959,96960],{},"cls"," (or a subclass) does Python call ",[39,96963,96610],{}," on it to set up its initial state. Most classes never override ",[39,96966,96874],{},[39,96968,96610],{}," is sufficient; overriding ",[39,96971,96874],{}," matters for immutable types and patterns like singletons, covered later in this quiz.",[15,96974,96975,96982,97020],{},[18,96976,96978,96979,96981],{"id":96977},"q3-is-self-a-reserved-keyword-in-python","Q3. Is ",[39,96980,87099],{}," a reserved keyword in Python?",[23,96983,96985,96991,97000,97011],{"className":96984},[26],[28,96986,96988,96990],{"className":96987},[31],[33,96989],{"disabled":35,"type":36}," No — it's just a strong convention; any valid identifier could be used for the first parameter of an instance method",[28,96992,96994,96996,96997,96999],{"className":96993},[31],[33,96995],{"disabled":35,"type":36}," Yes — Python's parser specifically recognizes ",[39,96998,87099],{}," and treats it as the instance reference",[28,97001,97003,97005,97006,97008,97009],{"className":97002},[31],[33,97004],{"disabled":35,"type":36}," No, but using anything other than ",[39,97007,87099],{}," causes a ",[39,97010,1274],{},[28,97012,97014,97016,97017,97019],{"className":97013},[31],[33,97015],{"disabled":35,"type":36}," Yes, but only inside ",[39,97018,96610],{},"; other methods may use any name",[66,97021,97022,97024,97029],{},[69,97023,71],{},[73,97025,97026,97028],{},[76,97027,78],{}," A — No — it's just a strong convention; any valid identifier could be used for the first parameter of an instance method",[73,97030,97031,97033,97034,97037,97038,97041,97042,97044,97045,97048],{},[76,97032,84],{}," When you call ",[39,97035,97036],{},"obj.method(args)",", Python translates it to ",[39,97039,97040],{},"ClassName.method(obj, args)"," — the first positional parameter always receives the instance, regardless of what it's named. ",[39,97043,87099],{}," is PEP 8 convention (and nearly universal in the ecosystem), but writing ",[39,97046,97047],{},"def method(this, ...)"," is perfectly legal and behaves identically. It only becomes a real problem when it breaks readability or violates a linter's expectations, not because Python enforces the name.",[15,97050,97051,97065,97107],{},[18,97052,97054,97055,97058,97059,97061,97062,1685],{"id":97053},"q4-in-class-foo-def-barself-x-what-gets-passed-as-self-when-you-call-foobar5","Q4. In ",[39,97056,97057],{},"class Foo: def bar(self, x): ...",", what gets passed as ",[39,97060,87099],{}," when you call ",[39,97063,97064],{},"Foo().bar(5)",[23,97066,97068,97080,97088,97096],{"className":97067},[26],[28,97069,97071,4396,97073,97075,97076,97079],{"className":97070},[31],[33,97072],{"disabled":35,"type":36},[39,97074,29570],{}," instance created by ",[39,97077,97078],{},"Foo()",", automatically supplied by Python's attribute-lookup\u002Fbinding machinery",[28,97081,97083,4396,97085,97087],{"className":97082},[31],[33,97084],{"disabled":35,"type":36},[39,97086,29570],{}," class itself",[28,97089,97091,355,97093,97095],{"className":97090},[31],[33,97092],{"disabled":35,"type":36},[39,97094,90944],{},", unless explicitly passed",[28,97097,97099,97101,97102,90722,97104,97106],{"className":97098},[31],[33,97100],{"disabled":35,"type":36}," The integer ",[39,97103,2429],{},[39,97105,2403],{}," left unbound",[66,97108,97109,97111,97119],{},[69,97110,71],{},[73,97112,97113,43363,97115,97075,97117,97079],{},[76,97114,78],{},[39,97116,29570],{},[39,97118,97078],{},[73,97120,97121,97123,97124,97127,97128,97131,97132,97135,97136,1179,97139,97141,97142,97144,97145,97147,97148,97150,97151,97153,97154,462],{},[76,97122,84],{}," Accessing ",[39,97125,97126],{},"instance.bar"," produces a ",[104,97129,97130],{},"bound method"," — a callable that has already captured the instance as its first argument. ",[39,97133,97134],{},"bar(5)"," on that bound method is equivalent to ",[39,97137,97138],{},"Foo.bar(instance, 5)",[39,97140,87099],{}," gets the instance and ",[39,97143,2403],{}," gets ",[39,97146,2429],{},". Confusing ",[39,97149,87099],{}," with the class itself (option B) is what ",[39,97152,96960],{}," in classmethods is for, not ",[39,97155,87099],{},[15,97157,97158,97166,97196],{},[18,97159,97161,97162,97165],{"id":97160},"q5-what-distinguishes-a-classmethod-from-a-regular-instance-method","Q5. What distinguishes a ",[39,97163,97164],{},"@classmethod"," from a regular instance method?",[23,97167,97169,97178,97184,97190],{"className":97168},[26],[28,97170,97172,97174,97175,97177],{"className":97171},[31],[33,97173],{"disabled":35,"type":36}," It receives the class (",[39,97176,96960],{},") as its first argument instead of the instance, and can be called on the class itself without an instance",[28,97179,97181,97183],{"className":97180},[31],[33,97182],{"disabled":35,"type":36}," It cannot access any attributes at all",[28,97185,97187,97189],{"className":97186},[31],[33,97188],{"disabled":35,"type":36}," It automatically becomes private (name-mangled)",[28,97191,97193,97195],{"className":97192},[31],[33,97194],{"disabled":35,"type":36}," It runs at import time instead of when explicitly called",[66,97197,97198,97200,97207],{},[69,97199,71],{},[73,97201,97202,97204,97205,97177],{},[76,97203,78],{}," A — It receives the class (",[39,97206,96960],{},[73,97208,97209,355,97211,97213,97214,97217],{},[76,97210,84],{},[39,97212,97164],{}," binds the first parameter to the class the method was accessed through (which, importantly, is the ",[104,97215,97216],{},"actual"," subclass when called via a subclass — not necessarily the class where the method was defined). This makes classmethods the idiomatic tool for alternative constructors, covered later in this quiz.",[15,97219,97220,97227,97261],{},[18,97221,97223,97224,97226],{"id":97222},"q6-what-distinguishes-a-staticmethod-from-both-instance-and-class-methods","Q6. What distinguishes a ",[39,97225,94173],{}," from both instance and class methods?",[23,97228,97230,97236,97247,97253],{"className":97229},[26],[28,97231,97233,97235],{"className":97232},[31],[33,97234],{"disabled":35,"type":36}," It receives no implicit first argument at all — it behaves like a plain function that simply happens to live in the class's namespace",[28,97237,97239,97241,97242,97244,97245],{"className":97238},[31],[33,97240],{"disabled":35,"type":36}," It receives ",[39,97243,87099],{}," but not ",[39,97246,96960],{},[28,97248,97250,97252],{"className":97249},[31],[33,97251],{"disabled":35,"type":36}," It can only be called before any instance of the class is created",[28,97254,97256,97258,97259],{"className":97255},[31],[33,97257],{"disabled":35,"type":36}," It is automatically cached like ",[39,97260,96220],{},[66,97262,97263,97265,97270],{},[69,97264,71],{},[73,97266,97267,97269],{},[76,97268,78],{}," A — It receives no implicit first argument at all — it behaves like a plain function that simply happens to live in the class's namespace",[73,97271,97272,355,97274,97276,97277,99,97279,462],{},[76,97273,84],{},[39,97275,94173],{}," opts a method out of both instance-binding and class-binding; it gets exactly the arguments you pass it, nothing more. It's used purely for namespacing a helper function under a class for organizational reasons, not because it needs ",[39,97278,87099],{},[39,97280,96960],{},[15,97282,97283,97295,97337],{},[18,97284,97286,97287,186,97289,97291,97292,1685],{"id":97285},"q7-in-what-order-does-python-call-__new__-and-__init__-when-you-write-foox-y","Q7. In what order does Python call ",[39,97288,96874],{},[39,97290,96610],{}," when you write ",[39,97293,97294],{},"Foo(x, y)",[23,97296,97298,97311,97322,97331],{"className":97297},[26],[28,97299,97301,355,97303,97306,97307,97310],{"className":97300},[31],[33,97302],{"disabled":35,"type":36},[39,97304,97305],{},"Foo.__new__(Foo, x, y)"," is called first to create the instance; then ",[39,97308,97309],{},"Foo.__init__(instance, x, y)"," is called on the result",[28,97312,97314,355,97316,97318,97319,97321],{"className":97313},[31],[33,97315],{"disabled":35,"type":36},[39,97317,96610],{}," runs first to set defaults, then ",[39,97320,96874],{}," finalizes the object",[28,97323,97325,97327,97328],{"className":97324},[31],[33,97326],{"disabled":35,"type":36}," Only one of them runs, depending on whether the class defines ",[39,97329,97330],{},"__slots__",[28,97332,97334,97336],{"className":97333},[31],[33,97335],{"disabled":35,"type":36}," They run concurrently in separate threads",[66,97338,97339,97341,97349],{},[69,97340,71],{},[73,97342,97343,3459,97345,97306,97347,97310],{},[76,97344,78],{},[39,97346,97305],{},[39,97348,97309],{},[73,97350,97351,97353,97354,97357,97358,97361,97362,97364,97365,97368,97369,97371,97372,97374,97375,97377,97378,97380],{},[76,97352,84],{}," Object construction is a two-step protocol: ",[39,97355,97356],{},"type.__call__"," (invoked implicitly by ",[39,97359,97360],{},"Foo(...)",") first calls ",[39,97363,96874],{}," to obtain an instance, then — ",[104,97366,97367],{},"only if"," the returned object is an instance of ",[39,97370,29570],{}," (or a subclass) — calls ",[39,97373,96610],{}," on it with the same arguments. This conditional call is itself a gotcha covered later: if ",[39,97376,96874],{}," returns something of an unrelated type, ",[39,97379,96610],{}," is skipped entirely.",[15,97382,97383,97385,97468,97502],{"language":87455},[18,97384,94655],{"id":94654},[257,97386,97387],{"language":87455},[260,97388,97390],{"className":87467,"code":97389,"language":87455,"meta":264,"style":264},"class ShoppingCart:\n    items = []\n\n    def add(self, item):\n        self.items.append(item)\n\ncart_a = ShoppingCart()\ncart_b = ShoppingCart()\ncart_a.add(\"apple\")\nprint(cart_b.items)\n",[39,97391,97392,97401,97409,97413,97422,97429,97433,97443,97452,97461],{"__ignoreMap":264},[268,97393,97394,97396,97399],{"class":270,"line":271},[268,97395,1468],{"class":274},[268,97397,97398],{"class":278}," ShoppingCart",[268,97400,8931],{"class":282},[268,97402,97403,97405,97407],{"class":270,"line":286},[268,97404,90431],{"class":282},[268,97406,302],{"class":274},[268,97408,94672],{"class":282},[268,97410,97411],{"class":270,"line":296},[268,97412,5033],{"emptyLinePlaceholder":35},[268,97414,97415,97417,97419],{"class":270,"line":311},[268,97416,92933],{"class":274},[268,97418,1217],{"class":278},[268,97420,97421],{"class":282},"(self, item):\n",[268,97423,97424,97426],{"class":270,"line":788},[268,97425,92944],{"class":305},[268,97427,97428],{"class":282},".items.append(item)\n",[268,97430,97431],{"class":270,"line":1951},[268,97432,5033],{"emptyLinePlaceholder":35},[268,97434,97435,97438,97440],{"class":270,"line":8955},[268,97436,97437],{"class":282},"cart_a ",[268,97439,302],{"class":274},[268,97441,97442],{"class":282}," ShoppingCart()\n",[268,97444,97445,97448,97450],{"class":270,"line":8966},[268,97446,97447],{"class":282},"cart_b ",[268,97449,302],{"class":274},[268,97451,97442],{"class":282},[268,97453,97454,97457,97459],{"class":270,"line":8974},[268,97455,97456],{"class":282},"cart_a.add(",[268,97458,14842],{"class":289},[268,97460,20702],{"class":282},[268,97462,97463,97465],{"class":270,"line":8985},[268,97464,84797],{"class":305},[268,97466,97467],{"class":282},"(cart_b.items)\n",[23,97469,97471,97479,97486,97494],{"className":97470},[26],[28,97472,97474,355,97476],{"className":97473},[31],[33,97475],{"disabled":35,"type":36},[39,97477,97478],{},"['apple']",[28,97480,97482,355,97484],{"className":97481},[31],[33,97483],{"disabled":35,"type":36},[39,97485,3290],{},[28,97487,97489,355,97491],{"className":97488},[31],[33,97490],{"disabled":35,"type":36},[39,97492,97493],{},"AttributeError: 'ShoppingCart' object has no attribute 'items'",[28,97495,97497,355,97499],{"className":97496},[31],[33,97498],{"disabled":35,"type":36},[39,97500,97501],{},"['apple', 'apple']",[66,97503,97504,97506,97512],{},[69,97505,71],{},[73,97507,97508,3459,97510],{},[76,97509,78],{},[39,97511,97478],{},[73,97513,97514,355,97516,3990,97518,358,97521,97523,97524,97527,97528,97531,97532,186,97535,97538,97539,97541],{},[76,97515,84],{},[76,97517,16523],{},[39,97519,97520],{},"items = []",[104,97522,1468],{}," attribute, created once when the class body executes, not a fresh list per instance. ",[39,97525,97526],{},"self.items.append(...)"," doesn't reassign ",[39,97529,97530],{},"self.items"," (which would create a new instance attribute); it mutates the single list object in place, and since both ",[39,97533,97534],{},"cart_a",[39,97536,97537],{},"cart_b"," look up ",[39,97540,56380],{}," through the same class (neither has its own instance attribute), they see the same shared list. This is one of Python's most infamous shared-mutable-state footguns — structurally identical to the mutable-default-argument trap.",[15,97543,97544,97555,97608,97658],{"language":87455},[18,97545,97547,97548,97551,97552,97554],{"id":97546},"q9-which-fix-correctly-gives-each-shoppingcart-instance-its-own-independent-items-list","Q9. Which fix correctly gives each ",[39,97549,97550],{},"ShoppingCart"," instance its own independent ",[39,97553,56380],{}," list?",[257,97556,97557],{"language":87455},[260,97558,97560],{"className":87467,"code":97559,"language":87455,"meta":264,"style":264},"class ShoppingCart:\n    def __init__(self):\n        self.items = []\n\n    def add(self, item):\n        self.items.append(item)\n",[39,97561,97562,97570,97579,97590,97594,97602],{"__ignoreMap":264},[268,97563,97564,97566,97568],{"class":270,"line":271},[268,97565,1468],{"class":274},[268,97567,97398],{"class":278},[268,97569,8931],{"class":282},[268,97571,97572,97574,97576],{"class":270,"line":286},[268,97573,92933],{"class":274},[268,97575,92936],{"class":305},[268,97577,97578],{"class":282},"(self):\n",[268,97580,97581,97583,97586,97588],{"class":270,"line":296},[268,97582,92944],{"class":305},[268,97584,97585],{"class":282},".items ",[268,97587,302],{"class":274},[268,97589,94672],{"class":282},[268,97591,97592],{"class":270,"line":311},[268,97593,5033],{"emptyLinePlaceholder":35},[268,97595,97596,97598,97600],{"class":270,"line":788},[268,97597,92933],{"class":274},[268,97599,1217],{"class":278},[268,97601,97421],{"class":282},[268,97603,97604,97606],{"class":270,"line":1951},[268,97605,92944],{"class":305},[268,97607,97428],{"class":282},[23,97609,97611,97626,97636,97648],{"className":97610},[26],[28,97612,97614,97616,97617,23506,97620,97622,97623,97625],{"className":97613},[31],[33,97615],{"disabled":35,"type":36}," This version — assigning ",[39,97618,97619],{},"self.items = []",[39,97621,96610],{}," creates a brand-new list object as an instance attribute for every ",[39,97624,97550],{}," created",[28,97627,97629,97631,97632,97635],{"className":97628},[31],[33,97630],{"disabled":35,"type":36}," Declaring ",[39,97633,97634],{},"items: list = []"," as a type-annotated class attribute instead",[28,97637,97639,97641,97642,23506,97645,97647],{"className":97638},[31],[33,97640],{"disabled":35,"type":36}," Using ",[39,97643,97644],{},"self.items = list(ShoppingCart.items)",[39,97646,41889],{}," before every append",[28,97649,97651,97653,97654,97657],{"className":97650},[31],[33,97652],{"disabled":35,"type":36}," The original code was already correct; the bug in Q8 was caused by calling ",[39,97655,97656],{},".add()"," twice",[66,97659,97660,97662,97673],{},[69,97661,71],{},[73,97663,97664,97666,97667,23506,97669,97622,97671,97625],{},[76,97665,78],{}," A — This version — assigning ",[39,97668,97619],{},[39,97670,96610],{},[39,97672,97550],{},[73,97674,97675,12848,97677,97679,97680,97682,97683,97685],{},[76,97676,84],{},[39,97678,96610],{}," runs once per instance, ",[39,97681,97619],{}," executes fresh for every object, producing a distinct list each time and shadowing any class-level attribute of the same name. Adding a type annotation (option B) doesn't change the fundamental problem — it's still one shared list evaluated once at class-definition time. This is the general fix pattern: any mutable default (list, dict, set) should be created inside ",[39,97684,96610],{},", never as a bare class attribute meant to be per-instance state.",[15,97687,97688,97692,97809,97875],{"language":87455},[18,97689,97691],{"id":97690},"q10-what-happens-here","Q10. What happens here?",[257,97693,97694],{"language":87455},[260,97695,97697],{"className":87467,"code":97696,"language":87455,"meta":264,"style":264},"class Singleton:\n    _instance = None\n\n    def __new__(cls):\n        return cls._instance or object.__new__(cls)\n\n    def __init__(self):\n        print(\"init ran\")\n\ns1 = Singleton()\nSingleton._instance = s1\ns2 = Singleton()\n",[39,97698,97699,97708,97717,97721,97731,97755,97759,97767,97778,97782,97791,97801],{"__ignoreMap":264},[268,97700,97701,97703,97706],{"class":270,"line":271},[268,97702,1468],{"class":274},[268,97704,97705],{"class":278}," Singleton",[268,97707,8931],{"class":282},[268,97709,97710,97713,97715],{"class":270,"line":286},[268,97711,97712],{"class":282},"    _instance ",[268,97714,302],{"class":274},[268,97716,91331],{"class":305},[268,97718,97719],{"class":270,"line":296},[268,97720,5033],{"emptyLinePlaceholder":35},[268,97722,97723,97725,97728],{"class":270,"line":311},[268,97724,92933],{"class":274},[268,97726,97727],{"class":305}," __new__",[268,97729,97730],{"class":282},"(cls):\n",[268,97732,97733,97735,97738,97741,97743,97745,97747,97749,97751,97753],{"class":270,"line":788},[268,97734,11956],{"class":274},[268,97736,97737],{"class":305}," cls",[268,97739,97740],{"class":282},"._instance ",[268,97742,93462],{"class":274},[268,97744,67652],{"class":305},[268,97746,462],{"class":282},[268,97748,96874],{"class":305},[268,97750,622],{"class":282},[268,97752,96960],{"class":305},[268,97754,20702],{"class":282},[268,97756,97757],{"class":270,"line":1951},[268,97758,5033],{"emptyLinePlaceholder":35},[268,97760,97761,97763,97765],{"class":270,"line":8955},[268,97762,92933],{"class":274},[268,97764,92936],{"class":305},[268,97766,97578],{"class":282},[268,97768,97769,97771,97773,97776],{"class":270,"line":8966},[268,97770,95279],{"class":305},[268,97772,622],{"class":282},[268,97774,97775],{"class":289},"\"init ran\"",[268,97777,20702],{"class":282},[268,97779,97780],{"class":270,"line":8974},[268,97781,5033],{"emptyLinePlaceholder":35},[268,97783,97784,97786,97788],{"class":270,"line":8985},[268,97785,89960],{"class":282},[268,97787,302],{"class":274},[268,97789,97790],{"class":282}," Singleton()\n",[268,97792,97793,97796,97798],{"class":270,"line":8990},[268,97794,97795],{"class":282},"Singleton._instance ",[268,97797,302],{"class":274},[268,97799,97800],{"class":282}," s1\n",[268,97802,97803,97805,97807],{"class":270,"line":8997},[268,97804,89970],{"class":282},[268,97806,302],{"class":274},[268,97808,97790],{"class":282},[23,97810,97812,97839,97850,97861],{"className":97811},[26],[28,97813,97815,355,97817,97819,97820,97823,97824,20766,97827,2833,97830,97832,97833,97835,97836,67669],{"className":97814},[31],[33,97816],{"disabled":35,"type":36},[39,97818,97775],{}," prints twice — once for ",[39,97821,97822],{},"s1",", and again for ",[39,97825,97826],{},"s2",[39,97828,97829],{},"s2 is s1",[39,97831,96610],{}," is called whenever ",[39,97834,96874],{}," returns an instance of the class, regardless of whether it's a ",[104,97837,97838],{},"reused",[28,97840,97842,355,97844,97846,97847,97849],{"className":97841},[31],[33,97843],{"disabled":35,"type":36},[39,97845,97775],{}," prints once, because Python detects that ",[39,97848,97829],{}," and skips re-initialization",[28,97851,97853,355,97855,97857,97858,97860],{"className":97852},[31],[33,97854],{"disabled":35,"type":36},[39,97856,827],{}," is raised because ",[39,97859,96874],{}," doesn't accept extra arguments",[28,97862,97864,355,97866,97868,97869,830,97872,97874],{"className":97863},[31],[33,97865],{"disabled":35,"type":36},[39,97867,97775],{}," never prints because ",[39,97870,97871],{},"_instance",[39,97873,90944],{}," initially",[66,97876,97877,97879,97897],{},[69,97878,71],{},[73,97880,97881,3459,97883,97819,97885,97823,97887,20766,97889,2833,97891,97832,97893,97835,97895,67669],{},[76,97882,78],{},[39,97884,97775],{},[39,97886,97822],{},[39,97888,97826],{},[39,97890,97829],{},[39,97892,96610],{},[39,97894,96874],{},[104,97896,97838],{},[73,97898,97899,355,97901,97903,97904,96957,97906,97908,97909,97911,97912,97914,97915,97917,97918,97920,97921,97924],{},[76,97900,84],{},[76,97902,16523],{}," — Python's rule is purely type-based: if ",[39,97905,96874],{},[39,97907,96960],{}," (or a subclass), ",[39,97910,96610],{}," runs on it — Python does not check whether the object is \"new\" versus recycled. This is exactly why naive singleton implementations that only override ",[39,97913,96874],{}," still re-run ",[39,97916,96610],{}," on every \"construction,\" silently resetting state each time unless ",[39,97919,96610],{}," is guarded (e.g., with an ",[39,97922,97923],{},"if self._initialized:"," check).",[15,97926,97927,97931,97996,98031],{"language":87455},[18,97928,97930],{"id":97929},"q11-what-does-this-print","Q11. What does this print?",[257,97932,97933],{"language":87455},[260,97934,97936],{"className":87467,"code":97935,"language":87455,"meta":264,"style":264},"class Config:\n    debug = False\n\nc1 = Config()\nc2 = Config()\nc1.debug = True\nprint(c1.debug, c2.debug, Config.debug)\n",[39,97937,97938,97947,97957,97961,97971,97980,97989],{"__ignoreMap":264},[268,97939,97940,97942,97945],{"class":270,"line":271},[268,97941,1468],{"class":274},[268,97943,97944],{"class":278}," Config",[268,97946,8931],{"class":282},[268,97948,97949,97952,97954],{"class":270,"line":286},[268,97950,97951],{"class":282},"    debug ",[268,97953,302],{"class":274},[268,97955,97956],{"class":305}," False\n",[268,97958,97959],{"class":270,"line":296},[268,97960,5033],{"emptyLinePlaceholder":35},[268,97962,97963,97966,97968],{"class":270,"line":311},[268,97964,97965],{"class":282},"c1 ",[268,97967,302],{"class":274},[268,97969,97970],{"class":282}," Config()\n",[268,97972,97973,97976,97978],{"class":270,"line":788},[268,97974,97975],{"class":282},"c2 ",[268,97977,302],{"class":274},[268,97979,97970],{"class":282},[268,97981,97982,97985,97987],{"class":270,"line":1951},[268,97983,97984],{"class":282},"c1.debug ",[268,97986,302],{"class":274},[268,97988,91509],{"class":305},[268,97990,97991,97993],{"class":270,"line":8955},[268,97992,84797],{"class":305},[268,97994,97995],{"class":282},"(c1.debug, c2.debug, Config.debug)\n",[23,97997,97999,98007,98015,98023],{"className":97998},[26],[28,98000,98002,355,98004],{"className":98001},[31],[33,98003],{"disabled":35,"type":36},[39,98005,98006],{},"True False False",[28,98008,98010,355,98012],{"className":98009},[31],[33,98011],{"disabled":35,"type":36},[39,98013,98014],{},"True True True",[28,98016,98018,355,98020],{"className":98017},[31],[33,98019],{"disabled":35,"type":36},[39,98021,98022],{},"False False False",[28,98024,98026,355,98028],{"className":98025},[31],[33,98027],{"disabled":35,"type":36},[39,98029,98030],{},"AttributeError",[66,98032,98033,98035,98041],{},[69,98034,71],{},[73,98036,98037,3459,98039],{},[76,98038,78],{},[39,98040,98006],{},[73,98042,98043,355,98045,3990,98047,34860,98050,98052,98053,98055,98056,98059,98060,98063,98064,98067,98068,3277,98070,186,98073,98076,98077,98080,98081,98084],{},[76,98044,84],{},[76,98046,16523],{},[39,98048,98049],{},"c1.debug = True",[104,98051,95],{}," mutate the class attribute; because ",[39,98054,89412],{}," is immutable, this assignment creates a brand-new ",[104,98057,98058],{},"instance"," attribute on ",[39,98061,98062],{},"c1"," that shadows ",[39,98065,98066],{},"Config.debug"," when accessed through ",[39,98069,98062],{},[39,98071,98072],{},"c2",[39,98074,98075],{},"Config"," itself are unaffected, since they still resolve ",[39,98078,98079],{},"debug"," via the class attribute. This is the crucial contrast with Q8: reassigning a name creates an instance attribute (isolated), while mutating a shared mutable object in place (like ",[39,98082,98083],{},".append()",") affects everyone who shares that object — the same operation (\"set an attribute on self\") behaves completely differently depending on whether you assign or mutate.",[15,98086,98087,98091,98204,98255],{"language":87455},[18,98088,98090],{"id":98089},"q12-is-this-class-valid-and-does-it-behave-normally","Q12. Is this class valid, and does it behave normally?",[257,98092,98093],{"language":87455},[260,98094,98096],{"className":87467,"code":98095,"language":87455,"meta":264,"style":264},"class Point:\n    def __init__(this, x, y):\n        this.x = x\n        this.y = y\n\n    def distance_from_origin(this):\n        return (this.x ** 2 + this.y ** 2) ** 0.5\n\np = Point(3, 4)\nprint(p.distance_from_origin())\n",[39,98097,98098,98106,98115,98124,98134,98138,98148,98175,98179,98197],{"__ignoreMap":264},[268,98099,98100,98102,98104],{"class":270,"line":271},[268,98101,1468],{"class":274},[268,98103,30134],{"class":278},[268,98105,8931],{"class":282},[268,98107,98108,98110,98112],{"class":270,"line":286},[268,98109,92933],{"class":274},[268,98111,92936],{"class":305},[268,98113,98114],{"class":282},"(this, x, y):\n",[268,98116,98117,98120,98122],{"class":270,"line":296},[268,98118,98119],{"class":282},"        this.x ",[268,98121,302],{"class":274},[268,98123,93160],{"class":282},[268,98125,98126,98129,98131],{"class":270,"line":311},[268,98127,98128],{"class":282},"        this.y ",[268,98130,302],{"class":274},[268,98132,98133],{"class":282}," y\n",[268,98135,98136],{"class":270,"line":788},[268,98137,5033],{"emptyLinePlaceholder":35},[268,98139,98140,98142,98145],{"class":270,"line":1951},[268,98141,92933],{"class":274},[268,98143,98144],{"class":278}," distance_from_origin",[268,98146,98147],{"class":282},"(this):\n",[268,98149,98150,98152,98155,98157,98159,98161,98164,98166,98168,98170,98172],{"class":270,"line":8955},[268,98151,11956],{"class":274},[268,98153,98154],{"class":282}," (this.x ",[268,98156,6231],{"class":274},[268,98158,2214],{"class":305},[268,98160,3350],{"class":274},[268,98162,98163],{"class":282}," this.y ",[268,98165,6231],{"class":274},[268,98167,2214],{"class":305},[268,98169,6131],{"class":282},[268,98171,6231],{"class":274},[268,98173,98174],{"class":305}," 0.5\n",[268,98176,98177],{"class":270,"line":8966},[268,98178,5033],{"emptyLinePlaceholder":35},[268,98180,98181,98184,98186,98189,98191,98193,98195],{"class":270,"line":8974},[268,98182,98183],{"class":282},"p ",[268,98185,302],{"class":274},[268,98187,98188],{"class":282}," Point(",[268,98190,3423],{"class":305},[268,98192,42],{"class":282},[268,98194,15049],{"class":305},[268,98196,20702],{"class":282},[268,98198,98199,98201],{"class":270,"line":8985},[268,98200,84797],{"class":305},[268,98202,98203],{"class":282},"(p.distance_from_origin())\n",[23,98205,98207,98222,98232,98247],{"className":98206},[26],[28,98208,98210,98212,98213,2272,98216,98218,98219,98221],{"className":98209},[31],[33,98211],{"disabled":35,"type":36}," Yes — it prints ",[39,98214,98215],{},"5.0",[39,98217,950],{}," works exactly like ",[39,98220,87099],{}," would, since the first parameter name is not special to Python",[28,98223,98225,355,98227,98229,98230],{"className":98224},[31],[33,98226],{"disabled":35,"type":36},[39,98228,1274],{},", since instance methods must name their first parameter ",[39,98231,87099],{},[28,98233,98235,98237,98238,186,98241,98244,98245],{"className":98234},[31],[33,98236],{"disabled":35,"type":36}," It runs but ",[39,98239,98240],{},"this.x",[39,98242,98243],{},"this.y"," are never actually attached to ",[39,98246,73],{},[28,98248,98250,355,98252],{"className":98249},[31],[33,98251],{"disabled":35,"type":36},[39,98253,98254],{},"TypeError: __init__() takes 3 positional arguments but 4 were given",[66,98256,98257,98259,98270],{},[69,98258,71],{},[73,98260,98261,98263,98264,2272,98266,98218,98268,98221],{},[76,98262,78],{}," A — Yes — it prints ",[39,98265,98215],{},[39,98267,950],{},[39,98269,87099],{},[73,98271,98272,98274,98275,98278,98279,98282,98283,98285],{},[76,98273,84],{}," As established in Q3, Python's method-binding mechanism only cares about parameter ",[104,98276,98277],{},"position",", not name — whichever name occupies the first slot receives the bound instance. The code is fully functional and computes ",[39,98280,98281],{},"sqrt(3² + 4²) = 5.0","; it's simply unconventional and would likely fail code review for violating the near-universal ",[39,98284,87099],{}," naming convention, not because of anything the interpreter enforces.",[15,98287,98288,98295,98374,98418],{"language":87455},[18,98289,98291,98292,98294],{"id":98290},"q13-calling-a-staticmethod-through-an-instance-versus-through-the-class-whats-the-difference-in-behavior","Q13. Calling a ",[39,98293,94173],{}," through an instance versus through the class — what's the difference in behavior?",[257,98296,98297],{"language":87455},[260,98298,98300],{"className":87467,"code":98299,"language":87455,"meta":264,"style":264},"class MathUtils:\n    @staticmethod\n    def add(a, b):\n        return a + b\n\nm = MathUtils()\nprint(MathUtils.add(2, 3), m.add(2, 3))\n",[39,98301,98302,98310,98318,98326,98336,98340,98350],{"__ignoreMap":264},[268,98303,98304,98306,98308],{"class":270,"line":271},[268,98305,1468],{"class":274},[268,98307,31428],{"class":278},[268,98309,8931],{"class":282},[268,98311,98312,98315],{"class":270,"line":286},[268,98313,98314],{"class":278},"    @",[268,98316,98317],{"class":305},"staticmethod\n",[268,98319,98320,98322,98324],{"class":270,"line":296},[268,98321,92933],{"class":274},[268,98323,1217],{"class":278},[268,98325,95548],{"class":282},[268,98327,98328,98330,98332,98334],{"class":270,"line":311},[268,98329,11956],{"class":274},[268,98331,1243],{"class":282},[268,98333,1246],{"class":274},[268,98335,95559],{"class":282},[268,98337,98338],{"class":270,"line":788},[268,98339,5033],{"emptyLinePlaceholder":35},[268,98341,98342,98345,98347],{"class":270,"line":1951},[268,98343,98344],{"class":282},"m ",[268,98346,302],{"class":274},[268,98348,98349],{"class":282}," MathUtils()\n",[268,98351,98352,98354,98357,98359,98361,98363,98366,98368,98370,98372],{"class":270,"line":8955},[268,98353,84797],{"class":305},[268,98355,98356],{"class":282},"(MathUtils.add(",[268,98358,2258],{"class":305},[268,98360,42],{"class":282},[268,98362,3423],{"class":305},[268,98364,98365],{"class":282},"), m.add(",[268,98367,2258],{"class":305},[268,98369,42],{"class":282},[268,98371,3423],{"class":305},[268,98373,47690],{"class":282},[23,98375,98377,98386,98401,98410],{"className":98376},[26],[28,98378,98380,98382,98383,98385],{"className":98379},[31],[33,98381],{"disabled":35,"type":36}," No difference — both print ",[39,98384,2429],{},"; a static method never receives an implicit instance argument no matter how it's accessed",[28,98387,98389,355,98391,91357,98394,98396,98397,98400],{"className":98388},[31],[33,98390],{"disabled":35,"type":36},[39,98392,98393],{},"m.add(2, 3)",[39,98395,827],{}," because it implicitly passes ",[39,98398,98399],{},"m"," as an extra argument",[28,98402,98404,355,98406,98409],{"className":98403},[31],[33,98405],{"disabled":35,"type":36},[39,98407,98408],{},"MathUtils.add(2, 3)"," fails because static methods require an instance to be called",[28,98411,98413,98415,98416],{"className":98412},[31],[33,98414],{"disabled":35,"type":36}," The class-level call returns an unbound method object instead of ",[39,98417,2429],{},[66,98419,98420,98422,98429],{},[69,98421,71],{},[73,98423,98424,98426,98427,98385],{},[76,98425,78],{}," A — No difference — both print ",[39,98428,2429],{},[73,98430,98431,355,98433,98435,98436,34860,98439,98441,98442,98445],{},[76,98432,84],{},[39,98434,94173],{}," explicitly opts out of the descriptor-based instance-binding that normal methods get, so accessing it via ",[39,98437,98438],{},"m.add",[104,98440,95],{}," produce a bound method the way ",[39,98443,98444],{},"m.instance_method"," would — it returns the plain underlying function either way. This is exactly why static methods are safe to call from either the class or an instance with identical results.",[15,98447,98448,98455,98575,98610],{"language":87455},[18,98449,98451,98452,98454],{"id":98450},"q14-alternative-constructors-via-classmethod-in-a-subclass-what-prints","Q14. Alternative constructors via ",[39,98453,97164],{}," in a subclass — what prints?",[257,98456,98457],{"language":87455},[260,98458,98460],{"className":87467,"code":98459,"language":87455,"meta":264,"style":264},"class Animal:\n    def __init__(self, name):\n        self.name = name\n\n    @classmethod\n    def from_upper(cls, name):\n        return cls(name.upper())\n\nclass Dog(Animal):\n    pass\n\nd = Dog.from_upper(\"rex\")\nprint(type(d).__name__, d.name)\n",[39,98461,98462,98470,98479,98490,98494,98501,98511,98520,98524,98536,98541,98545,98559],{"__ignoreMap":264},[268,98463,98464,98466,98468],{"class":270,"line":271},[268,98465,1468],{"class":274},[268,98467,29687],{"class":278},[268,98469,8931],{"class":282},[268,98471,98472,98474,98476],{"class":270,"line":286},[268,98473,92933],{"class":274},[268,98475,92936],{"class":305},[268,98477,98478],{"class":282},"(self, name):\n",[268,98480,98481,98483,98485,98487],{"class":270,"line":296},[268,98482,92944],{"class":305},[268,98484,30956],{"class":282},[268,98486,302],{"class":274},[268,98488,98489],{"class":282}," name\n",[268,98491,98492],{"class":270,"line":311},[268,98493,5033],{"emptyLinePlaceholder":35},[268,98495,98496,98498],{"class":270,"line":788},[268,98497,98314],{"class":278},[268,98499,98500],{"class":305},"classmethod\n",[268,98502,98503,98505,98508],{"class":270,"line":1951},[268,98504,92933],{"class":274},[268,98506,98507],{"class":278}," from_upper",[268,98509,98510],{"class":282},"(cls, name):\n",[268,98512,98513,98515,98517],{"class":270,"line":8955},[268,98514,11956],{"class":274},[268,98516,97737],{"class":305},[268,98518,98519],{"class":282},"(name.upper())\n",[268,98521,98522],{"class":270,"line":8966},[268,98523,5033],{"emptyLinePlaceholder":35},[268,98525,98526,98528,98530,98532,98534],{"class":270,"line":8974},[268,98527,1468],{"class":274},[268,98529,30493],{"class":278},[268,98531,622],{"class":282},[268,98533,29893],{"class":278},[268,98535,94690],{"class":282},[268,98537,98538],{"class":270,"line":8985},[268,98539,98540],{"class":274},"    pass\n",[268,98542,98543],{"class":270,"line":8990},[268,98544,5033],{"emptyLinePlaceholder":35},[268,98546,98547,98549,98551,98554,98557],{"class":270,"line":8997},[268,98548,89555],{"class":282},[268,98550,302],{"class":274},[268,98552,98553],{"class":282}," Dog.from_upper(",[268,98555,98556],{"class":289},"\"rex\"",[268,98558,20702],{"class":282},[268,98560,98561,98563,98565,98567,98570,98572],{"class":270,"line":9002},[268,98562,84797],{"class":305},[268,98564,622],{"class":282},[268,98566,8623],{"class":305},[268,98568,98569],{"class":282},"(d).",[268,98571,94343],{"class":305},[268,98573,98574],{"class":282},", d.name)\n",[23,98576,98578,98586,98594,98602],{"className":98577},[26],[28,98579,98581,355,98583],{"className":98580},[31],[33,98582],{"disabled":35,"type":36},[39,98584,98585],{},"Dog REX",[28,98587,98589,355,98591],{"className":98588},[31],[33,98590],{"disabled":35,"type":36},[39,98592,98593],{},"Animal REX",[28,98595,98597,355,98599],{"className":98596},[31],[33,98598],{"disabled":35,"type":36},[39,98600,98601],{},"Dog rex",[28,98603,98605,355,98607],{"className":98604},[31],[33,98606],{"disabled":35,"type":36},[39,98608,98609],{},"TypeError: from_upper() is not inherited by subclasses",[66,98611,98612,98614,98620],{},[69,98613,71],{},[73,98615,98616,3459,98618],{},[76,98617,78],{},[39,98619,98585],{},[73,98621,98622,98624,98625,98627,98628,98630,98631,98633,98634,14552,98637,98640,98641,98643,98644,46957,98646,98648],{},[76,98623,84],{}," Inside a classmethod, ",[39,98626,96960],{}," is bound to whichever class the method was actually accessed through — here, ",[39,98629,30602],{}," — not the class where the method was defined (",[39,98632,29893],{},"). So ",[39,98635,98636],{},"cls(name.upper())",[39,98638,98639],{},"Dog(\"REX\")",", correctly producing a ",[39,98642,30602],{}," instance. This polymorphic behavior is precisely why ",[39,98645,97164],{},[39,98647,94173],{},") is the right tool for alternative constructors meant to be inheritance-friendly.",[15,98650,98651,98655,98701],{},[18,98652,98654],{"id":98653},"q15-for-a-class-that-needs-a-mutable-default-like-a-list-or-dict-as-part-of-an-instances-state-what-is-the-best-practice-approach","Q15. For a class that needs a mutable default (like a list or dict) as part of an instance's state, what is the best-practice approach?",[23,98656,98658,98677,98683,98695],{"className":98657},[26],[28,98659,98661,98663,98664,26085,98666,65140,98669,98672,98673,98676],{"className":98660},[31],[33,98662],{"disabled":35,"type":36}," Initialize it inside ",[39,98665,96610],{},[39,98667,98668],{},"self.attr = []",[39,98670,98671],{},"dataclasses.field(default_factory=list)"," if using ",[39,98674,98675],{},"@dataclass","), never as a bare mutable class attribute",[28,98678,98680,98682],{"className":98679},[31],[33,98681],{"disabled":35,"type":36}," Declare it as a class attribute for efficiency, since it avoids re-allocating a list per instance",[28,98684,98686,98688,98689,98691,98692],{"className":98685},[31],[33,98687],{"disabled":35,"type":36}," Use a mutable default argument in ",[39,98690,96610],{},", e.g. ",[39,98693,98694],{},"def __init__(self, items=[]):",[28,98696,98698,98700],{"className":98697},[31],[33,98699],{"disabled":35,"type":36}," Store it as a class attribute and document that callers must not mutate it",[66,98702,98703,98705,98718],{},[69,98704,71],{},[73,98706,98707,98709,98710,26085,98712,65140,98714,98672,98716,98676],{},[76,98708,78],{}," A — Initialize it inside ",[39,98711,96610],{},[39,98713,98668],{},[39,98715,98671],{},[39,98717,98675],{},[73,98719,98720,355,98722,98724,98725,98727,98728,98731,98732,98735],{},[76,98721,84],{},[76,98723,17307],{}," — This is the direct fix for the Q8\u002FQ9 gotcha, generalized: any per-instance mutable state belongs in ",[39,98726,96610],{}," (or a ",[39,98729,98730],{},"default_factory"," for dataclasses), so each instance gets its own object. A mutable default ",[104,98733,98734],{},"argument"," (option C) is a related but distinct footgun — default argument values are evaluated once at function-definition time and shared across all calls that don't override them, causing the exact same kind of cross-instance leakage.",[15,98737,98738,98749,98789],{},[18,98739,98741,98742,42,98745,98748],{"id":98740},"q16-when-designing-alternative-ways-to-construct-an-object-eg-configfrom_filepath-configfrom_env-whats-the-idiomatic-choice","Q16. When designing alternative ways to construct an object (e.g., ",[39,98743,98744],{},"Config.from_file(path)",[39,98746,98747],{},"Config.from_env()","), what's the idiomatic choice?",[23,98750,98752,98763,98771,98780],{"className":98751},[26],[28,98753,98755,355,98757,1179,98759,98762],{"className":98754},[31],[33,98756],{"disabled":35,"type":36},[39,98758,97164],{},[39,98760,98761],{},"cls(...)"," is used internally, keeping the constructors correct for subclasses too",[28,98764,98766,355,98768,98770],{"className":98765},[31],[33,98767],{"disabled":35,"type":36},[39,98769,94173],{},", since these are just utility functions that don't need class state",[28,98772,98774,98776,98777,13454],{"className":98773},[31],[33,98775],{"disabled":35,"type":36}," A plain module-level function that returns a hardcoded ",[39,98778,98779],{},"Config(...)",[28,98781,98783,98785,98786,98788],{"className":98782},[31],[33,98784],{"disabled":35,"type":36}," Overloading ",[39,98787,96610],{}," with many optional parameters instead of separate constructors",[66,98790,98791,98793,98801],{},[69,98792,71],{},[73,98794,98795,3459,98797,1179,98799,98762],{},[76,98796,78],{},[39,98798,97164],{},[39,98800,98761],{},[73,98802,98803,355,98805,98807,98808,98810,98811,98813,98814,98816,98817,42,98820,98823],{},[76,98804,84],{},[76,98806,17307],{}," — As shown in Q14, a ",[39,98809,97164],{}," that calls ",[39,98812,98761],{}," automatically does the right thing for subclasses, while a ",[39,98815,94173],{}," (option B) would have to hardcode the concrete class name, silently breaking for any subclass that calls the \"constructor.\" This is the standard pattern behind ",[39,98818,98819],{},"dict.fromkeys",[39,98821,98822],{},"datetime.fromtimestamp",", and similar APIs in the standard library.",[15,98825,98826,98835,98876],{},[18,98827,98829,98830,98832,98833,1685],{"id":98828},"q17-when-is-it-actually-necessary-to-override-__new__-instead-of-just-using-__init__","Q17. When is it actually necessary to override ",[39,98831,96874],{}," instead of just using ",[39,98834,96610],{},[23,98836,98838,98853,98861,98867],{"className":98837},[26],[28,98839,98841,98843,98844,98847,98848,99,98850,98852],{"className":98840},[31],[33,98842],{"disabled":35,"type":36}," When you need to control instance ",[104,98845,98846],{},"creation"," itself — e.g., returning a cached\u002Fsingleton instance, or subclassing an immutable built-in type like ",[39,98849,17109],{},[39,98851,89379],{}," where state must be set during creation",[28,98854,98856,98858,98859,40843],{"className":98855},[31],[33,98857],{"disabled":35,"type":36}," Whenever a class defines more than one ",[39,98860,96610],{},[28,98862,98864,98866],{"className":98863},[31],[33,98865],{"disabled":35,"type":36}," Every time a class is used with inheritance",[28,98868,98870,98872,98873,98875],{"className":98869},[31],[33,98871],{"disabled":35,"type":36}," Never — ",[39,98874,96874],{}," is a legacy hook with no valid modern use case",[66,98877,98878,98880,98891],{},[69,98879,71],{},[73,98881,98882,98884,98885,98847,98887,99,98889,98852],{},[76,98883,78],{}," A — When you need to control instance ",[104,98886,98846],{},[39,98888,17109],{},[39,98890,89379],{},[73,98892,98893,355,98895,3990,98897,98899,98900,98903,98904,98906,98907,98909,98910,98912,98913,98915],{},[76,98894,84],{},[76,98896,17307],{},[39,98898,96610],{}," can only ",[104,98901,98902],{},"mutate"," an already-created instance, which doesn't work for immutable types (you can't \"mutate\" a ",[39,98905,17109],{}," after creation) or for patterns where you might want to return an existing object instead of a new one (singletons, object pools, memoized value types). For ordinary mutable classes, overriding ",[39,98908,96874],{}," is unnecessary complexity — ",[39,98911,96610],{}," alone is the idiomatic choice, which is why it's rare to see ",[39,98914,96874],{}," overrides in typical application code.",[15,98917,98918,98929,98966],{},[18,98919,98921,98922,98925,98926,98928],{"id":98920},"q18-a-team-debates-whether-max_retries-3-should-be-a-class-attribute-or-set-in-__init__-given-its-an-immutable-shared-constant-that-instances-never-need-to-override-individually-whats-the-best-practice","Q18. A team debates whether ",[39,98923,98924],{},"MAX_RETRIES = 3"," should be a class attribute or set in ",[39,98927,96610],{},". Given it's an immutable, shared constant that instances never need to override individually, what's the best practice?",[23,98930,98932,98941,98950,98956],{"className":98931},[26],[28,98933,98935,98937,98938],{"className":98934},[31],[33,98936],{"disabled":35,"type":36}," Keep it as a class attribute — it's immutable, so there's no shared-mutation risk, and instances can still override it individually if ever needed via ",[39,98939,98940],{},"self.MAX_RETRIES = ...",[28,98942,98944,98946,98947,98949],{"className":98943},[31],[33,98945],{"disabled":35,"type":36}," Always move every attribute into ",[39,98948,96610],{},", regardless of mutability, to avoid any confusion",[28,98951,98953,98955],{"className":98952},[31],[33,98954],{"disabled":35,"type":36}," Store it in a global module-level variable instead of attaching it to the class at all",[28,98957,98959,98961,98962,98965],{"className":98958},[31],[33,98960],{"disabled":35,"type":36}," Make it a ",[39,98963,98964],{},"@property"," that returns a hardcoded value",[66,98967,98968,98970,98977],{},[69,98969,71],{},[73,98971,98972,98974,98975],{},[76,98973,78],{}," A — Keep it as a class attribute — it's immutable, so there's no shared-mutation risk, and instances can still override it individually if ever needed via ",[39,98976,98940],{},[73,98978,98979,355,98981,98983,98984,98987,98988,98990,98991,98993],{},[76,98980,84],{},[76,98982,17307],{}," — The Q8 gotcha specifically concerns ",[104,98985,98986],{},"mutable"," class attributes (lists, dicts, sets) being mutated in place and shared unexpectedly. An immutable constant like an ",[39,98989,87646],{}," has no such risk: any attempt to \"change\" it on an instance creates a new instance attribute (as in Q11) rather than corrupting shared state, so class-level placement is both idiomatic and efficient (one shared object instead of a per-instance copy). The rule isn't \"never use class attributes\" — it's \"don't use ",[104,98992,98986],{}," class attributes for per-instance state.\"",[15,98995,98996,99002,99031],{},[18,98997,98999,99000,1685],{"id":98998},"q19-which-situation-makes-a-plain-module-level-function-more-appropriate-than-a-staticmethod","Q19. Which situation makes a plain module-level function more appropriate than a ",[39,99001,94173],{},[23,99003,99005,99011,99019,99025],{"className":99004},[26],[28,99006,99008,99010],{"className":99007},[31],[33,99009],{"disabled":35,"type":36}," When the function has no meaningful connection to the class's purpose or namespace, and grouping it under the class only adds indirection without organizational benefit",[28,99012,99014,99016,99017],{"className":99013},[31],[33,99015],{"disabled":35,"type":36}," Whenever the function doesn't use ",[39,99018,87099],{},[28,99020,99022,99024],{"className":99021},[31],[33,99023],{"disabled":35,"type":36}," Whenever the function is longer than a few lines",[28,99026,99028,99030],{"className":99027},[31],[33,99029],{"disabled":35,"type":36}," Static methods are always better than module functions because they're faster to call",[66,99032,99033,99035,99040],{},[69,99034,71],{},[73,99036,99037,99039],{},[76,99038,78],{}," A — When the function has no meaningful connection to the class's purpose or namespace, and grouping it under the class only adds indirection without organizational benefit",[73,99041,99042,355,99044,3990,99046,99048,99049,99052,99053,99056,99057,99060,99061,99063],{},[76,99043,84],{},[76,99045,17307],{},[39,99047,94173],{}," exists purely for ",[104,99050,99051],{},"namespacing"," — grouping a helper under a class because it's conceptually related (e.g., ",[39,99054,99055],{},"Vector.from_polar","-style helpers, or validation helpers tightly coupled to the class's data). If a function is genuinely general-purpose and unrelated to the class, forcing it into the class as a static method just adds an extra ",[39,99058,99059],{},"ClassName."," prefix everywhere it's used, with no benefit — a plain module function is more discoverable and idiomatic in that case. \"Doesn't use ",[39,99062,87099],{},"\" (option B) is necessary but not sufficient justification on its own.",[15,99065,99066,99078,99120],{},[18,99067,99069,99070,99073,99074,99077],{"id":99068},"q20-reviewing-a-pull-request-you-see-typeobj-foo-used-to-check-an-objects-type-instead-of-isinstanceobj-foo-why-is-this-flagged-as-a-best-practice-issue","Q20. Reviewing a pull request, you see ",[39,99071,99072],{},"type(obj) == Foo"," used to check an object's type instead of ",[39,99075,99076],{},"isinstance(obj, Foo)",". Why is this flagged as a best-practice issue?",[23,99079,99081,99094,99102,99108],{"className":99080},[26],[28,99082,99084,355,99086,99088,99089,99091,99092],{"className":99083},[31],[33,99085],{"disabled":35,"type":36},[39,99087,89591],{}," respects inheritance (so subclass instances are correctly recognized) and works with virtual base classes\u002FABCs, while ",[39,99090,99072],{}," fails for any subclass instance even though it's substitutable for ",[39,99093,29570],{},[28,99095,99097,355,99099,99101],{"className":99096},[31],[33,99098],{"disabled":35,"type":36},[39,99100,99072],{}," is slower in every case and should never be used for performance reasons",[28,99103,99105,99107],{"className":99104},[31],[33,99106],{"disabled":35,"type":36}," They are functionally identical; the difference is purely stylistic",[28,99109,99111,355,99113,99115,99116,99,99118],{"className":99110},[31],[33,99112],{"disabled":35,"type":36},[39,99114,89591],{}," cannot check against built-in types like ",[39,99117,87646],{},[39,99119,17109],{},[66,99121,99122,99124,99134],{},[69,99123,71],{},[73,99125,99126,3459,99128,99088,99130,99091,99132],{},[76,99127,78],{},[39,99129,89591],{},[39,99131,99072],{},[39,99133,29570],{},[73,99135,99136,355,99138,99140,99141,42,99144,830,99147,99149,99150,830,99153,4387,99155,99157,99158,99161,99162,99164],{},[76,99137,84],{},[76,99139,17307],{}," — Given ",[39,99142,99143],{},"class Dog(Animal): ...",[39,99145,99146],{},"isinstance(Dog(), Animal)",[39,99148,89285],{}," (correctly honoring polymorphism), but ",[39,99151,99152],{},"type(Dog()) == Animal",[39,99154,88449],{},[39,99156,89656],{}," returns the ",[104,99159,99160],{},"exact"," class, not considering the MRO. Code that relies on exact-type checks silently breaks the moment someone introduces a reasonable subclass, which is precisely the kind of duck-typing\u002Fpolymorphism violation ",[39,99163,89591],{}," is designed to avoid. This ties directly into duck typing and explicit type checks covered in the next quiz on inheritance.",[2107,99166,99167],{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-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 .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);}",{"title":264,"searchDepth":286,"depth":286,"links":99169},[99170,99171,99173,99175,99177,99179,99181,99183,99184,99186,99187,99188,99189,99191,99193,99194,99196,99198,99200,99202],{"id":96801,"depth":296,"text":96802},{"id":96868,"depth":296,"text":99172},"Q2. What is the difference between __init__ and __new__?",{"id":96977,"depth":296,"text":99174},"Q3. Is self a reserved keyword in Python?",{"id":97053,"depth":296,"text":99176},"Q4. In class Foo: def bar(self, x): ..., what gets passed as self when you call Foo().bar(5)?",{"id":97160,"depth":296,"text":99178},"Q5. What distinguishes a @classmethod from a regular instance method?",{"id":97222,"depth":296,"text":99180},"Q6. What distinguishes a @staticmethod from both instance and class methods?",{"id":97285,"depth":296,"text":99182},"Q7. In what order does Python call __new__ and __init__ when you write Foo(x, y)?",{"id":94654,"depth":296,"text":94655},{"id":97546,"depth":296,"text":99185},"Q9. Which fix correctly gives each ShoppingCart instance its own independent items list?",{"id":97690,"depth":296,"text":97691},{"id":97929,"depth":296,"text":97930},{"id":98089,"depth":296,"text":98090},{"id":98290,"depth":296,"text":99190},"Q13. Calling a @staticmethod through an instance versus through the class — what's the difference in behavior?",{"id":98450,"depth":296,"text":99192},"Q14. Alternative constructors via @classmethod in a subclass — what prints?",{"id":98653,"depth":296,"text":98654},{"id":98740,"depth":296,"text":99195},"Q16. When designing alternative ways to construct an object (e.g., Config.from_file(path), Config.from_env()), what's the idiomatic choice?",{"id":98828,"depth":296,"text":99197},"Q17. When is it actually necessary to override __new__ instead of just using __init__?",{"id":98920,"depth":296,"text":99199},"Q18. A team debates whether MAX_RETRIES = 3 should be a class attribute or set in __init__. Given it's an immutable, shared constant that instances never need to override individually, what's the best practice?",{"id":98998,"depth":296,"text":99201},"Q19. Which situation makes a plain module-level function more appropriate than a @staticmethod?",{"id":99068,"depth":296,"text":99203},"Q20. Reviewing a pull request, you see type(obj) == Foo used to check an object's type instead of isinstance(obj, Foo). Why is this flagged as a best-practice issue?",{},"\u002Fpython\u002F12-classes-and-objects",{"title":96791,"description":264},"python\u002F12-classes-and-objects","ye736CW0dJKaw4b0y8zt8uTyM-vawgrxo5GM1AG_HYI",{"id":99210,"title":99211,"body":99212,"description":264,"extension":2144,"meta":101865,"navigation":35,"path":101866,"seo":101867,"stem":101868,"__hash__":101869},"content\u002Fpython\u002F13-inheritance-and-polymorphism.md","13 — Inheritance & Polymorphism",{"type":8,"value":99213,"toc":101832},[99214,99217,99271,99349,99462,99528,99596,99790,99867,100186,100354,100450,100666,100846,101022,101305,101390,101448,101529,101632,101735,101829],[11,99215,99211],{"id":99216},"_13-inheritance-polymorphism",[15,99218,99219,99223,99250],{},[18,99220,99222],{"id":99221},"q1-what-is-the-method-resolution-order-mro","Q1. What is the Method Resolution Order (MRO)?",[23,99224,99226,99232,99238,99244],{"className":99225},[26],[28,99227,99229,99231],{"className":99228},[31],[33,99230],{"disabled":35,"type":36}," The specific, linear order in which Python searches base classes for a method or attribute when it's not found on the instance or its own class",[28,99233,99235,99237],{"className":99234},[31],[33,99236],{"disabled":35,"type":36}," The order in which a class's methods are defined in the source file",[28,99239,99241,99243],{"className":99240},[31],[33,99242],{"disabled":35,"type":36}," The order in which methods execute when an instance is created",[28,99245,99247,99249],{"className":99246},[31],[33,99248],{"disabled":35,"type":36}," A runtime cache of the most recently called methods, for performance",[66,99251,99252,99254,99259],{},[69,99253,71],{},[73,99255,99256,99258],{},[76,99257,78],{}," A — The specific, linear order in which Python searches base classes for a method or attribute when it's not found on the instance or its own class",[73,99260,99261,99263,99264,99,99267,99270],{},[76,99262,84],{}," Every class has a computed MRO (viewable via ",[39,99265,99266],{},"ClassName.__mro__",[39,99268,99269],{},"ClassName.mro()",") that linearizes the entire inheritance graph into a single, deterministic sequence. Attribute and method lookups walk this sequence in order and stop at the first match. It has nothing to do with source-code definition order or a runtime cache — it's a static property computed when the class is created.",[15,99272,99273,99283,99322],{},[18,99274,99276,99277,99280,99281,65680],{"id":99275},"q2-in-single-inheritance-what-does-super__init__args-inside-a-subclasss-__init__-do","Q2. In single inheritance, what does ",[39,99278,99279],{},"super().__init__(*args)"," inside a subclass's ",[39,99282,96610],{},[23,99284,99286,99295,99305,99314],{"className":99285},[26],[28,99287,99289,99291,99292,99294],{"className":99288},[31],[33,99290],{"disabled":35,"type":36}," Calls the immediate parent class's ",[39,99293,96610],{},", passing along the given arguments, using the instance's actual MRO",[28,99296,99298,99300,99301,99304],{"className":99297},[31],[33,99299],{"disabled":35,"type":36}," Calls ",[39,99302,99303],{},"object.__init__"," directly, skipping any intermediate parent classes",[28,99306,99308,99310,99311,99313],{"className":99307},[31],[33,99309],{"disabled":35,"type":36}," Re-runs the subclass's own ",[39,99312,96610],{}," recursively",[28,99315,99317,99319,99320],{"className":99316},[31],[33,99318],{"disabled":35,"type":36}," Creates a brand-new parent-class instance separate from ",[39,99321,87099],{},[66,99323,99324,99326,99333],{},[69,99325,71],{},[73,99327,99328,99330,99331,99294],{},[76,99329,78],{}," A — Calls the immediate parent class's ",[39,99332,96610],{},[73,99334,99335,355,99337,99339,99340,99342,99343,99345,99346,99348],{},[76,99336,84],{},[39,99338,30889],{}," (zero-argument form, Python 3+) returns a proxy object bound to the current class and instance, and delegates attribute lookup to the ",[104,99341,16949],{}," class in ",[39,99344,87099],{},"'s MRO after the current one. In simple single inheritance, that next class is just the immediate parent — but as covered later in this quiz, in multiple inheritance \"next in the MRO\" is not always the same as \"the literal parent class in the ",[39,99347,1468],{}," statement.\"",[15,99350,99351,99355,99410],{},[18,99352,99354],{"id":99353},"q3-what-is-diamond-inheritance","Q3. What is \"diamond inheritance\"?",[23,99356,99358,99380,99386,99400],{"className":99357},[26],[28,99359,99361,99363,99364,186,99366,99368,99369,99371,99372,99374,99375,186,99377,99379],{"className":99360},[31],[33,99362],{"disabled":35,"type":36}," A class hierarchy where two classes ",[39,99365,47807],{},[39,99367,47793],{}," both inherit from a common base ",[39,99370,47783],{},", and a class ",[39,99373,47803],{}," inherits from both ",[39,99376,47807],{},[39,99378,47793],{},", forming a diamond shape",[28,99381,99383,99385],{"className":99382},[31],[33,99384],{"disabled":35,"type":36}," A class that inherits from four or more base classes",[28,99387,99389,99391,99392,90681,99394,186,99396,90681,99398],{"className":99388},[31],[33,99390],{"disabled":35,"type":36}," A circular inheritance chain where ",[39,99393,47783],{},[39,99395,47807],{},[39,99397,47807],{},[39,99399,47783],{},[28,99401,99403,99405,99406,99,99408],{"className":99402},[31],[33,99404],{"disabled":35,"type":36}," Inheriting from a built-in type like ",[39,99407,89385],{},[39,99409,14924],{},[66,99411,99412,99414,99431],{},[69,99413,71],{},[73,99415,99416,99418,99419,186,99421,99368,99423,99371,99425,99374,99427,186,99429,99379],{},[76,99417,78],{}," A — A class hierarchy where two classes ",[39,99420,47807],{},[39,99422,47793],{},[39,99424,47783],{},[39,99426,47803],{},[39,99428,47807],{},[39,99430,47793],{},[73,99432,99433,99435,99436,99438,99439,186,99441,99443,99444,99446,99447,99449,99450,99452,99453,99455,99456,99458,99459,99461],{},[76,99434,84],{}," Diagrammed, ",[39,99437,47783],{}," sits at the top, ",[39,99440,47807],{},[39,99442,47793],{}," branch off it, and ",[39,99445,47803],{}," sits at the bottom pointing to both — a diamond. The classic question this raises is: when ",[39,99448,47803],{}," calls a method defined on ",[39,99451,47783],{}," (and possibly overridden in ",[39,99454,47807],{}," and\u002For ",[39,99457,47793],{},"), which version runs, and does ",[39,99460,47783],{},"'s code run once or twice? Python's C3 linearization (covered next) exists specifically to answer this unambiguously.",[15,99463,99464,99468,99504],{},[18,99465,99467],{"id":99466},"q4-what-guarantee-does-pythons-c3-linearization-algorithm-provide-when-computing-a-classs-mro","Q4. What guarantee does Python's C3 linearization algorithm provide when computing a class's MRO?",[23,99469,99471,99480,99486,99498],{"className":99470},[26],[28,99472,99474,99476,99477,99479],{"className":99473},[31],[33,99475],{"disabled":35,"type":36}," Every class appears exactly once in the MRO, a subclass always precedes its own base classes, and the relative order of base classes as listed in the ",[39,99478,1468],{}," statement is preserved",[28,99481,99483,99485],{"className":99482},[31],[33,99484],{"disabled":35,"type":36}," It guarantees the MRO always matches simple depth-first, left-to-right traversal of the inheritance tree, as in old-style classes",[28,99487,99489,99491,99492,99494,99495,99497],{"className":99488},[31],[33,99490],{"disabled":35,"type":36}," It guarantees every base class's ",[39,99493,96610],{}," runs automatically, even without ",[39,99496,30889],{}," calls",[28,99499,99501,99503],{"className":99500},[31],[33,99502],{"disabled":35,"type":36}," It only applies to classes that inherit from exactly two base classes",[66,99505,99506,99508,99515],{},[69,99507,71],{},[73,99509,99510,99512,99513,99479],{},[76,99511,78],{}," A — Every class appears exactly once in the MRO, a subclass always precedes its own base classes, and the relative order of base classes as listed in the ",[39,99514,1468],{},[73,99516,99517,355,99519,99521,99522,99524,99525,99527],{},[76,99518,84],{},[76,99520,16523],{}," — Python 2's old-style classes used naive depth-first-left-to-right (DFLR) search, which could visit a common ancestor multiple times or in an inconsistent order for diamond hierarchies. C3 linearization (used by all classes in Python 3, since they all implicitly inherit from ",[39,99523,2664],{},") fixes this by merging each base's own MRO plus the base list itself, guaranteeing monotonicity and local precedence. If no consistent order can be computed, Python raises ",[39,99526,827],{}," at class-creation time rather than silently picking an ambiguous order (covered in Q9).",[15,99529,99530,99534,99567],{},[18,99531,99533],{"id":99532},"q5-what-is-duck-typing","Q5. What is \"duck typing\"?",[23,99535,99537,99543,99549,99561],{"className":99536},[26],[28,99538,99540,99542],{"className":99539},[31],[33,99541],{"disabled":35,"type":36}," Relying on an object's behavior (which methods\u002Fattributes it supports) rather than its actual type or class hierarchy to decide if it's usable in a given context",[28,99544,99546,99548],{"className":99545},[31],[33,99547],{"disabled":35,"type":36}," A typing style where every variable must have an explicit type hint",[28,99550,99552,97641,99554,99557,99558,99560],{"className":99551},[31],[33,99553],{"disabled":35,"type":36},[39,99555,99556],{},"isinstance()"," checks exclusively instead of ",[39,99559,89656],{}," comparisons",[28,99562,99564,99566],{"className":99563},[31],[33,99565],{"disabled":35,"type":36}," A Python 2-only feature removed in Python 3",[66,99568,99569,99571,99576],{},[69,99570,71],{},[73,99572,99573,99575],{},[76,99574,78],{}," A — Relying on an object's behavior (which methods\u002Fattributes it supports) rather than its actual type or class hierarchy to decide if it's usable in a given context",[73,99577,99578,99580,99581,99584,99585,99588,99589,99592,99593,99595],{},[76,99579,84],{}," \"If it walks like a duck and quacks like a duck, it's a duck\" — Python code that does ",[39,99582,99583],{},"obj.read()"," without checking ",[39,99586,99587],{},"isinstance(obj, SomeFileType)"," first is duck typing: any object with a compatible ",[39,99590,99591],{},".read()"," method works, regardless of its actual class or inheritance chain. This is central to Python's idiomatic style and is contrasted with rigid, explicit ",[39,99594,89591],{}," gatekeeping later in this quiz.",[15,99597,99598,99607,99708,99759],{"language":87455},[18,99599,99601,99602,66778,99604,1685],{"id":99600},"q6-what-happens-if-a-subclass-overrides-__init__-but-never-calls-super__init__","Q6. What happens if a subclass overrides ",[39,99603,96610],{},[39,99605,99606],{},"super().__init__()",[257,99608,99609],{"language":87455},[260,99610,99612],{"className":87467,"code":99611,"language":87455,"meta":264,"style":264},"class Vehicle:\n    def __init__(self, wheels):\n        self.wheels = wheels\n\nclass Car(Vehicle):\n    def __init__(self, brand):\n        self.brand = brand  # forgot super().__init__(wheels)\n\nc = Car(\"Toyota\")\nprint(c.wheels)\n",[39,99613,99614,99622,99631,99643,99647,99660,99669,99684,99688,99701],{"__ignoreMap":264},[268,99615,99616,99618,99620],{"class":270,"line":271},[268,99617,1468],{"class":274},[268,99619,30704],{"class":278},[268,99621,8931],{"class":282},[268,99623,99624,99626,99628],{"class":270,"line":286},[268,99625,92933],{"class":274},[268,99627,92936],{"class":305},[268,99629,99630],{"class":282},"(self, wheels):\n",[268,99632,99633,99635,99638,99640],{"class":270,"line":296},[268,99634,92944],{"class":305},[268,99636,99637],{"class":282},".wheels ",[268,99639,302],{"class":274},[268,99641,99642],{"class":282}," wheels\n",[268,99644,99645],{"class":270,"line":311},[268,99646,5033],{"emptyLinePlaceholder":35},[268,99648,99649,99651,99653,99655,99658],{"class":270,"line":788},[268,99650,1468],{"class":274},[268,99652,30748],{"class":278},[268,99654,622],{"class":282},[268,99656,99657],{"class":278},"Vehicle",[268,99659,94690],{"class":282},[268,99661,99662,99664,99666],{"class":270,"line":1951},[268,99663,92933],{"class":274},[268,99665,92936],{"class":305},[268,99667,99668],{"class":282},"(self, brand):\n",[268,99670,99671,99673,99676,99678,99681],{"class":270,"line":8955},[268,99672,92944],{"class":305},[268,99674,99675],{"class":282},".brand ",[268,99677,302],{"class":274},[268,99679,99680],{"class":282}," brand  ",[268,99682,99683],{"class":29390},"# forgot super().__init__(wheels)\n",[268,99685,99686],{"class":270,"line":8966},[268,99687,5033],{"emptyLinePlaceholder":35},[268,99689,99690,99692,99694,99697,99699],{"class":270,"line":8974},[268,99691,92387],{"class":282},[268,99693,302],{"class":274},[268,99695,99696],{"class":282}," Car(",[268,99698,30818],{"class":289},[268,99700,20702],{"class":282},[268,99702,99703,99705],{"class":270,"line":8985},[268,99704,84797],{"class":305},[268,99706,99707],{"class":282},"(c.wheels)\n",[23,99709,99711,99727,99738,99748],{"className":99710},[26],[28,99712,99714,355,99716,99719,99720,99722,99723,99726],{"className":99713},[31],[33,99715],{"disabled":35,"type":36},[39,99717,99718],{},"AttributeError: 'Car' object has no attribute 'wheels'"," — the parent's ",[39,99721,96610],{}," never runs, so ",[39,99724,99725],{},"self.wheels"," is never set",[28,99728,99730,355,99732,99734,99735],{"className":99729},[31],[33,99731],{"disabled":35,"type":36},[39,99733,15049],{}," — Python automatically infers a default value for ",[39,99736,99737],{},"wheels",[28,99739,99741,355,99743,99745,99746],{"className":99740},[31],[33,99742],{"disabled":35,"type":36},[39,99744,90944],{}," — uninitialized attributes default to ",[39,99747,90944],{},[28,99749,99751,355,99753,99755,99756,58241],{"className":99750},[31],[33,99752],{"disabled":35,"type":36},[39,99754,827],{}," is raised immediately when ",[39,99757,99758],{},"Car(\"Toyota\")",[66,99760,99761,99763,99773],{},[69,99762,71],{},[73,99764,99765,3459,99767,99719,99769,99722,99771,99726],{},[76,99766,78],{},[39,99768,99718],{},[39,99770,96610],{},[39,99772,99725],{},[73,99774,99775,355,99777,99779,99780,99782,99783,99786,99787,99789],{},[76,99776,84],{},[76,99778,16523],{}," — Overriding ",[39,99781,96610],{}," completely replaces the parent's version unless the subclass explicitly calls it via ",[39,99784,99785],{},"super().__init__(...)",". There is no automatic chaining — Python does not run every ",[39,99788,96610],{}," up the MRO unless the code says so. This is one of the most common real-world inheritance bugs: a subclass \"loses\" attributes the parent was responsible for setting up, and the failure only surfaces later when that attribute is accessed, far from the actual mistake.",[15,99791,99792,99796,99834],{},[18,99793,99795],{"id":99794},"q7-how-can-you-inspect-a-classs-actual-mro-at-runtime","Q7. How can you inspect a class's actual MRO at runtime?",[23,99797,99799,99810,99819,99828],{"className":99798},[26],[28,99800,99802,355,99804,99806,99807,99809],{"className":99801},[31],[33,99803],{"disabled":35,"type":36},[39,99805,99266],{}," (a tuple) or ",[39,99808,99269],{}," (a list)",[28,99811,99813,355,99815,99818],{"className":99812},[31],[33,99814],{"disabled":35,"type":36},[39,99816,99817],{},"ClassName.__bases__"," gives the full MRO, including indirect ancestors",[28,99820,99822,355,99824,99827],{"className":99821},[31],[33,99823],{"disabled":35,"type":36},[39,99825,99826],{},"dir(ClassName)"," returns the MRO in order",[28,99829,99831,99833],{"className":99830},[31],[33,99832],{"disabled":35,"type":36}," MRO cannot be inspected; it's only used internally by the interpreter",[66,99835,99836,99838,99846],{},[69,99837,71],{},[73,99839,99840,3459,99842,99806,99844,99809],{},[76,99841,78],{},[39,99843,99266],{},[39,99845,99269],{},[73,99847,99848,355,99850,99853,99854,99857,99858,99860,99861,99863,99864,99866],{},[76,99849,84],{},[39,99851,99852],{},"__mro__"," is the linearized order computed by C3 at class-creation time. ",[39,99855,99856],{},"__bases__"," (option B) is a common point of confusion — it only lists the ",[104,99859,72942],{}," parents named in the ",[39,99862,1468],{}," statement, not the full linearized ancestor chain, so it's insufficient for understanding how ",[39,99865,30889],{}," will actually resolve calls in a multi-level or multiple-inheritance hierarchy.",[15,99868,99869,99873,100045,100112],{"language":87455},[18,99870,99872],{"id":99871},"q8-given-cooperative-multiple-inheritance-what-does-this-print","Q8. Given cooperative multiple inheritance, what does this print?",[257,99874,99875],{"language":87455},[260,99876,99878],{"className":87467,"code":99877,"language":87455,"meta":264,"style":264},"class A:\n    def greet(self):\n        print(\"A\")\n\nclass B(A):\n    def greet(self):\n        print(\"B\")\n        super().greet()\n\nclass C(A):\n    def greet(self):\n        print(\"C\")\n        super().greet()\n\nclass D(B, C):\n    def greet(self):\n        print(\"D\")\n        super().greet()\n\nD().greet()\n",[39,99879,99880,99889,99897,99907,99911,99924,99932,99942,99950,99954,99967,99975,99985,99991,99995,100012,100020,100030,100036,100040],{"__ignoreMap":264},[268,99881,99882,99884,99887],{"class":270,"line":271},[268,99883,1468],{"class":274},[268,99885,99886],{"class":278}," A",[268,99888,8931],{"class":282},[268,99890,99891,99893,99895],{"class":270,"line":286},[268,99892,92933],{"class":274},[268,99894,3679],{"class":278},[268,99896,97578],{"class":282},[268,99898,99899,99901,99903,99905],{"class":270,"line":296},[268,99900,95279],{"class":305},[268,99902,622],{"class":282},[268,99904,47625],{"class":289},[268,99906,20702],{"class":282},[268,99908,99909],{"class":270,"line":311},[268,99910,5033],{"emptyLinePlaceholder":35},[268,99912,99913,99915,99918,99920,99922],{"class":270,"line":788},[268,99914,1468],{"class":274},[268,99916,99917],{"class":278}," B",[268,99919,622],{"class":282},[268,99921,47783],{"class":278},[268,99923,94690],{"class":282},[268,99925,99926,99928,99930],{"class":270,"line":1951},[268,99927,92933],{"class":274},[268,99929,3679],{"class":278},[268,99931,97578],{"class":282},[268,99933,99934,99936,99938,99940],{"class":270,"line":8955},[268,99935,95279],{"class":305},[268,99937,622],{"class":282},[268,99939,26749],{"class":289},[268,99941,20702],{"class":282},[268,99943,99944,99947],{"class":270,"line":8966},[268,99945,99946],{"class":305},"        super",[268,99948,99949],{"class":282},"().greet()\n",[268,99951,99952],{"class":270,"line":8974},[268,99953,5033],{"emptyLinePlaceholder":35},[268,99955,99956,99958,99961,99963,99965],{"class":270,"line":8985},[268,99957,1468],{"class":274},[268,99959,99960],{"class":278}," C",[268,99962,622],{"class":282},[268,99964,47783],{"class":278},[268,99966,94690],{"class":282},[268,99968,99969,99971,99973],{"class":270,"line":8990},[268,99970,92933],{"class":274},[268,99972,3679],{"class":278},[268,99974,97578],{"class":282},[268,99976,99977,99979,99981,99983],{"class":270,"line":8997},[268,99978,95279],{"class":305},[268,99980,622],{"class":282},[268,99982,47687],{"class":289},[268,99984,20702],{"class":282},[268,99986,99987,99989],{"class":270,"line":9002},[268,99988,99946],{"class":305},[268,99990,99949],{"class":282},[268,99992,99993],{"class":270,"line":14676},[268,99994,5033],{"emptyLinePlaceholder":35},[268,99996,99997,99999,100002,100004,100006,100008,100010],{"class":270,"line":14681},[268,99998,1468],{"class":274},[268,100000,100001],{"class":278}," D",[268,100003,622],{"class":282},[268,100005,47807],{"class":278},[268,100007,42],{"class":282},[268,100009,47793],{"class":278},[268,100011,94690],{"class":282},[268,100013,100014,100016,100018],{"class":270,"line":31051},[268,100015,92933],{"class":274},[268,100017,3679],{"class":278},[268,100019,97578],{"class":282},[268,100021,100022,100024,100026,100028],{"class":270,"line":31071},[268,100023,95279],{"class":305},[268,100025,622],{"class":282},[268,100027,47709],{"class":289},[268,100029,20702],{"class":282},[268,100031,100032,100034],{"class":270,"line":33819},[268,100033,99946],{"class":305},[268,100035,99949],{"class":282},[268,100037,100038],{"class":270,"line":33824},[268,100039,5033],{"emptyLinePlaceholder":35},[268,100041,100042],{"class":270,"line":33829},[268,100043,100044],{"class":282},"D().greet()\n",[23,100046,100048,100065,100083,100098],{"className":100047},[26],[28,100049,100051,355,100053,42,100055,42,100057,42,100059,100061,100062,100064],{"className":100050},[31],[33,100052],{"disabled":35,"type":36},[39,100054,47803],{},[39,100056,47807],{},[39,100058,47793],{},[39,100060,47783],{}," — each class's ",[39,100063,12761],{}," runs exactly once, in MRO order",[28,100066,100068,355,100070,42,100072,42,100074,42,100076,42,100078,3990,100080,100082],{"className":100067},[31],[33,100069],{"disabled":35,"type":36},[39,100071,47803],{},[39,100073,47807],{},[39,100075,47783],{},[39,100077,47793],{},[39,100079,47783],{},[39,100081,47783],{}," runs twice, once via each branch of the diamond",[28,100084,100086,355,100088,42,100090,42,100092,100094,100095,100097],{"className":100085},[31],[33,100087],{"disabled":35,"type":36},[39,100089,47803],{},[39,100091,47807],{},[39,100093,47783],{}," only — ",[39,100096,47793],{}," is never reached",[28,100099,100101,355,100103,42,100105,42,100107,42,100109,100111],{"className":100100},[31],[33,100102],{"disabled":35,"type":36},[39,100104,47803],{},[39,100106,47793],{},[39,100108,47807],{},[39,100110,47783],{}," — multiple inheritance always resolves right-to-left",[66,100113,100114,100116,100130],{},[69,100115,71],{},[73,100117,100118,3459,100120,42,100122,42,100124,42,100126,100061,100128,100064],{},[76,100119,78],{},[39,100121,47803],{},[39,100123,47807],{},[39,100125,47793],{},[39,100127,47783],{},[39,100129,12761],{},[73,100131,100132,355,100134,3990,100136,100138,100139,100142,100143,21200,100145,100147,100148,100151,100152,100155,100156,1179,100159,9057,100161,14552,100163,100165,100166,100168,100169,9057,100171,100173,100174,100176,100177,100179,100180,100182,100183,100185],{},[76,100133,84],{},[76,100135,16523],{},[39,100137,47803],{},"'s MRO is ",[39,100140,100141],{},"[D, B, C, A, object]"," (computed by C3, preserving ",[39,100144,47807],{},[39,100146,47793],{}," since that's their order in ",[39,100149,100150],{},"class D(B, C)","). Each ",[39,100153,100154],{},"super().greet()"," call doesn't jump straight to that class's own literal parent — it advances to the ",[104,100157,100158],{},"next class in the shared MRO",[39,100160,47807],{},[39,100162,100154],{},[39,100164,47793],{},"'s (not ",[39,100167,47783],{},"'s directly), and only ",[39,100170,47793],{},[39,100172,100154],{}," finally reaches ",[39,100175,47783],{},". This is exactly why naive assumptions like \"each branch of the diamond calls ",[39,100178,47783],{}," independently\" (option B, ",[39,100181,47783],{}," running twice) are wrong — C3 linearization guarantees ",[39,100184,47783],{}," is visited exactly once.",[15,100187,100188,100192,100259,100304],{"language":87455},[18,100189,100191],{"id":100190},"q9-what-happens-when-you-try-to-define-this-class","Q9. What happens when you try to define this class?",[257,100193,100194],{"language":87455},[260,100195,100197],{"className":87467,"code":100196,"language":87455,"meta":264,"style":264},"class X:\n    pass\n\nclass Y(X):\n    pass\n\nclass Z(X, Y):\n    pass\n",[39,100198,100199,100208,100212,100216,100229,100233,100237,100255],{"__ignoreMap":264},[268,100200,100201,100203,100206],{"class":270,"line":271},[268,100202,1468],{"class":274},[268,100204,100205],{"class":278}," X",[268,100207,8931],{"class":282},[268,100209,100210],{"class":270,"line":286},[268,100211,98540],{"class":274},[268,100213,100214],{"class":270,"line":296},[268,100215,5033],{"emptyLinePlaceholder":35},[268,100217,100218,100220,100223,100225,100227],{"class":270,"line":311},[268,100219,1468],{"class":274},[268,100221,100222],{"class":278}," Y",[268,100224,622],{"class":282},[268,100226,93621],{"class":278},[268,100228,94690],{"class":282},[268,100230,100231],{"class":270,"line":788},[268,100232,98540],{"class":274},[268,100234,100235],{"class":270,"line":1951},[268,100236,5033],{"emptyLinePlaceholder":35},[268,100238,100239,100241,100244,100246,100248,100250,100253],{"class":270,"line":8955},[268,100240,1468],{"class":274},[268,100242,100243],{"class":278}," Z",[268,100245,622],{"class":282},[268,100247,93621],{"class":278},[268,100249,42],{"class":282},[268,100251,100252],{"class":278},"Y",[268,100254,94690],{"class":282},[268,100256,100257],{"class":270,"line":8966},[268,100258,98540],{"class":274},[23,100260,100262,100270,100281,100291],{"className":100261},[26],[28,100263,100265,355,100267],{"className":100264},[31],[33,100266],{"disabled":35,"type":36},[39,100268,100269],{},"TypeError: Cannot create a consistent method resolution order (MRO) for bases X, Y",[28,100271,100273,95415,100275,100138,100278],{"className":100272},[31],[33,100274],{"disabled":35,"type":36},[39,100276,100277],{},"Z",[39,100279,100280],{},"[Z, X, Y, object]",[28,100282,100284,95415,100286,100138,100288],{"className":100283},[31],[33,100285],{"disabled":35,"type":36},[39,100287,100277],{},[39,100289,100290],{},"[Z, Y, X, object]",[28,100292,100294,355,100296,100298,100299,5887,100301,100303],{"className":100293},[31],[33,100295],{"disabled":35,"type":36},[39,100297,100277],{}," silently ignores ",[39,100300,93621],{},[39,100302,100252],{}," already inherits from it",[66,100305,100306,100308,100314],{},[69,100307,71],{},[73,100309,100310,3459,100312],{},[76,100311,78],{},[39,100313,100269],{},[73,100315,100316,355,100318,3990,100320,100323,100324,100326,100327,100329,100330,100332,100333,100335,100336,21200,100338,100340,100341,100343,100344,100347,100348,100350,100351,100353],{},[76,100317,84],{},[76,100319,16523],{},[39,100321,100322],{},"class Z(X, Y)"," demands that ",[39,100325,93621],{}," precede ",[39,100328,100252],{}," (as listed), but ",[39,100331,100252],{}," already inherits from ",[39,100334,93621],{},", which means any valid MRO must place ",[39,100337,100252],{},[39,100339,93621],{}," (subclasses must precede their own bases — a rule from Q4). These two requirements directly contradict each other, so C3 linearization has no valid solution, and Python raises ",[39,100342,827],{}," at class-definition time rather than guessing. The fix is to list bases in an order consistent with the existing hierarchy: ",[39,100345,100346],{},"class Z(Y, X)"," would work, since ",[39,100349,100252],{}," already implies ",[39,100352,93621],{}," comes after it.",[15,100355,100356,100369,100413],{},[18,100357,100359,100360,186,100362,100365,100366,1685],{"id":100358},"q10-in-python-3-is-there-any-behavioral-difference-between-super-and-supercurrentclass-self-when-called-inside-a-normal-instance-method-of-currentclass","Q10. In Python 3, is there any behavioral difference between ",[39,100361,30889],{},[39,100363,100364],{},"super(CurrentClass, self)"," when called inside a normal instance method of ",[39,100367,100368],{},"CurrentClass",[23,100370,100372,100384,100393,100402],{"className":100371},[26],[28,100373,100375,100377,100378,100380,100381,100383],{"className":100374},[31],[33,100376],{"disabled":35,"type":36}," No — Python 3's zero-argument ",[39,100379,30889],{}," is compiler-assisted sugar that resolves to exactly ",[39,100382,100364],{}," in that context",[28,100385,100387,100389,100390,100392],{"className":100386},[31],[33,100388],{"disabled":35,"type":36}," Yes — the zero-argument form always uses ",[39,100391,2664],{}," as the starting point, skipping intermediate classes",[28,100394,100396,100398,100399,100401],{"className":100395},[31],[33,100397],{"disabled":35,"type":36}," Yes — the zero-argument form only works in ",[39,100400,96610],{},", not other methods",[28,100403,100405,88213,100407,100409,100410,100412],{"className":100404},[31],[33,100406],{"disabled":35,"type":36},[39,100408,30889],{}," without arguments raises ",[39,100411,827],{}," in Python 3",[66,100414,100415,100417,100426],{},[69,100416,71],{},[73,100418,100419,100421,100422,100380,100424,100383],{},[76,100420,78],{}," A — No — Python 3's zero-argument ",[39,100423,30889],{},[39,100425,100364],{},[73,100427,100428,100430,100431,100434,100435,100437,100438,100440,100441,100443,100444,100446,100447,100449],{},[76,100429,84],{}," The compiler injects a hidden ",[39,100432,100433],{},"__class__"," cell reference so that bare ",[39,100436,30889],{}," inside a method knows both the class it was defined in and the instance (",[39,100439,87099],{},") it's being called on, letting it reconstruct the explicit two-argument form automatically. The explicit ",[39,100442,100364],{}," form (Python 2 style) still works in Python 3 and is occasionally still needed — e.g., inside a ",[39,100445,94173],{}," or a nested function where the implicit ",[39,100448,100433],{}," cell isn't available — but for ordinary methods, the two are equivalent.",[15,100451,100452,100458,100557,100617],{"language":87455},[18,100453,100455,100456,1685],{"id":100454},"q11-a-mixin-is-meant-to-add-caching-to-any-class-in-a-cooperative-multiple-inheritance-hierarchy-whats-wrong-with-this-__init__","Q11. A mixin is meant to add caching to any class in a cooperative multiple-inheritance hierarchy. What's wrong with this ",[39,100457,96610],{},[257,100459,100460],{"language":87455},[260,100461,100463],{"className":87467,"code":100462,"language":87455,"meta":264,"style":264},"class CacheMixin:\n    def __init__(self, *args, **kwargs):\n        self.cache = {}\n        super().__init__()  # note: no args\u002Fkwargs forwarded\n\nclass Repository(CacheMixin, Base):\n    def __init__(self, db_url):\n        super().__init__(db_url)\n",[39,100464,100465,100474,100490,100501,100515,100519,100537,100546],{"__ignoreMap":264},[268,100466,100467,100469,100472],{"class":270,"line":271},[268,100468,1468],{"class":274},[268,100470,100471],{"class":278}," CacheMixin",[268,100473,8931],{"class":282},[268,100475,100476,100478,100480,100482,100484,100486,100488],{"class":270,"line":286},[268,100477,92933],{"class":274},[268,100479,92936],{"class":305},[268,100481,96447],{"class":282},[268,100483,6134],{"class":274},[268,100485,40331],{"class":282},[268,100487,6231],{"class":274},[268,100489,95507],{"class":282},[268,100491,100492,100494,100497,100499],{"class":270,"line":296},[268,100493,92944],{"class":305},[268,100495,100496],{"class":282},".cache ",[268,100498,302],{"class":274},[268,100500,30486],{"class":282},[268,100502,100503,100505,100507,100509,100512],{"class":270,"line":311},[268,100504,99946],{"class":305},[268,100506,19341],{"class":282},[268,100508,96610],{"class":305},[268,100510,100511],{"class":282},"()  ",[268,100513,100514],{"class":29390},"# note: no args\u002Fkwargs forwarded\n",[268,100516,100517],{"class":270,"line":788},[268,100518,5033],{"emptyLinePlaceholder":35},[268,100520,100521,100523,100526,100528,100531,100533,100535],{"class":270,"line":1951},[268,100522,1468],{"class":274},[268,100524,100525],{"class":278}," Repository",[268,100527,622],{"class":282},[268,100529,100530],{"class":278},"CacheMixin",[268,100532,42],{"class":282},[268,100534,20597],{"class":278},[268,100536,94690],{"class":282},[268,100538,100539,100541,100543],{"class":270,"line":8955},[268,100540,92933],{"class":274},[268,100542,92936],{"class":305},[268,100544,100545],{"class":282},"(self, db_url):\n",[268,100547,100548,100550,100552,100554],{"class":270,"line":8966},[268,100549,99946],{"class":305},[268,100551,19341],{"class":282},[268,100553,96610],{"class":305},[268,100555,100556],{"class":282},"(db_url)\n",[23,100558,100560,100585,100594,100605],{"className":100559},[26],[28,100561,100563,355,100565,100568,100569,100571,100572,100574,100575,100577,100578,100581,100582,100584],{"className":100562},[31],[33,100564],{"disabled":35,"type":36},[39,100566,100567],{},"CacheMixin.__init__"," drops ",[39,100570,96067],{}," when calling ",[39,100573,99606],{},", so the next class in the MRO (",[39,100576,20597],{},") never receives ",[39,100579,100580],{},"db_url",", breaking ",[39,100583,20597],{},"'s own initialization",[28,100586,100588,100590,100591,100593],{"className":100587},[31],[33,100589],{"disabled":35,"type":36}," Mixins can never define ",[39,100592,96610],{},"; only the final concrete class can",[28,100595,100597,355,100599,100601,100602,100604],{"className":100596},[31],[33,100598],{"disabled":35,"type":36},[39,100600,99606],{}," inside a mixin always raises ",[39,100603,827],{}," since mixins have no base class",[28,100606,100608,100610,100611,100614,100615,15926],{"className":100607},[31],[33,100609],{"disabled":35,"type":36}," Nothing is wrong; ",[39,100612,100613],{},"Base.__init__"," will still receive ",[39,100616,100580],{},[66,100618,100619,100621,100637],{},[69,100620,71],{},[73,100622,100623,3459,100625,100568,100627,100571,100629,100574,100631,100577,100633,100581,100635,100584],{},[76,100624,78],{},[39,100626,100567],{},[39,100628,96067],{},[39,100630,99606],{},[39,100632,20597],{},[39,100634,100580],{},[39,100636,20597],{},[73,100638,100639,355,100641,100643,100644,100647,100648,100650,100651,100653,100654,100656,100657,100659,100660,100662,100663,100665],{},[76,100640,84],{},[76,100642,16523],{}," — In cooperative multiple inheritance, every class in the chain must forward whatever arguments it doesn't consume itself to ",[39,100645,100646],{},"super().__init__(*args, **kwargs)",", so the call correctly propagates down the entire MRO to whichever class ultimately needs them. Here, ",[39,100649,100530],{}," accepts ",[39,100652,96067],{}," but then calls ",[39,100655,99606],{}," with nothing, silently swallowing ",[39,100658,100580],{}," before it ever reaches ",[39,100661,20597],{},". The fix is ",[39,100664,100646],{}," in the mixin, ensuring the cooperative chain stays intact.",[15,100667,100668,100672,100768,100800],{"language":87455},[18,100669,100671],{"id":100670},"q12-what-does-this-print","Q12. What does this print?",[257,100673,100674],{"language":87455},[260,100675,100677],{"className":87467,"code":100676,"language":87455,"meta":264,"style":264},"class Base:\n    def __init__(self):\n        self.value = self.compute()\n\n    def compute(self):\n        return 1\n\nclass Derived(Base):\n    def compute(self):\n        return 2\n\nprint(Derived().value)\n",[39,100678,100679,100687,100695,100709,100713,100721,100727,100731,100743,100751,100757,100761],{"__ignoreMap":264},[268,100680,100681,100683,100685],{"class":270,"line":271},[268,100682,1468],{"class":274},[268,100684,20590],{"class":278},[268,100686,8931],{"class":282},[268,100688,100689,100691,100693],{"class":270,"line":286},[268,100690,92933],{"class":274},[268,100692,92936],{"class":305},[268,100694,97578],{"class":282},[268,100696,100697,100699,100702,100704,100706],{"class":270,"line":296},[268,100698,92944],{"class":305},[268,100700,100701],{"class":282},".value ",[268,100703,302],{"class":274},[268,100705,96472],{"class":305},[268,100707,100708],{"class":282},".compute()\n",[268,100710,100711],{"class":270,"line":311},[268,100712,5033],{"emptyLinePlaceholder":35},[268,100714,100715,100717,100719],{"class":270,"line":788},[268,100716,92933],{"class":274},[268,100718,13542],{"class":278},[268,100720,97578],{"class":282},[268,100722,100723,100725],{"class":270,"line":1951},[268,100724,11956],{"class":274},[268,100726,84787],{"class":305},[268,100728,100729],{"class":270,"line":8955},[268,100730,5033],{"emptyLinePlaceholder":35},[268,100732,100733,100735,100737,100739,100741],{"class":270,"line":8966},[268,100734,1468],{"class":274},[268,100736,31665],{"class":278},[268,100738,622],{"class":282},[268,100740,20597],{"class":278},[268,100742,94690],{"class":282},[268,100744,100745,100747,100749],{"class":270,"line":8974},[268,100746,92933],{"class":274},[268,100748,13542],{"class":278},[268,100750,97578],{"class":282},[268,100752,100753,100755],{"class":270,"line":8985},[268,100754,11956],{"class":274},[268,100756,85329],{"class":305},[268,100758,100759],{"class":270,"line":8990},[268,100760,5033],{"emptyLinePlaceholder":35},[268,100762,100763,100765],{"class":270,"line":8997},[268,100764,84797],{"class":305},[268,100766,100767],{"class":282},"(Derived().value)\n",[23,100769,100771,100778,100785,100793],{"className":100770},[26],[28,100772,100774,355,100776],{"className":100773},[31],[33,100775],{"disabled":35,"type":36},[39,100777,2258],{},[28,100779,100781,355,100783],{"className":100780},[31],[33,100782],{"disabled":35,"type":36},[39,100784,2255],{},[28,100786,100788,355,100790],{"className":100787},[31],[33,100789],{"disabled":35,"type":36},[39,100791,100792],{},"AttributeError: 'Derived' object has no attribute 'compute'",[28,100794,100796,355,100798],{"className":100795},[31],[33,100797],{"disabled":35,"type":36},[39,100799,90944],{},[66,100801,100802,100804,100810],{},[69,100803,71],{},[73,100805,100806,3459,100808],{},[76,100807,78],{},[39,100809,2258],{},[73,100811,100812,355,100814,100816,100817,830,100820,100822,100823,100825,100826,44798,100829,2182,100831,100833,100834,100836,100837,89923,100839,100841,100842,14552,100844,462],{},[76,100813,84],{},[76,100815,16523],{}," — Even though ",[39,100818,100819],{},"compute()",[104,100821,55334],{}," from within ",[39,100824,100613],{},", method lookup is always based on the ",[104,100827,100828],{},"actual runtime type",[39,100830,87099],{},[39,100832,31719],{},"), not on which class's code is currently executing. This is polymorphism working correctly, but it's a common surprise for developers coming from languages with static dispatch — it also means calling overridable methods from ",[39,100835,96610],{}," is risky if the override depends on subclass attributes that haven't been set up yet, since ",[39,100838,96610],{},[39,100840,31719],{}," hasn't necessarily finished running its own setup by the time ",[39,100843,100613],{},[39,100845,100819],{},[15,100847,100848,100855,100931,100982],{"language":87455},[18,100849,100851,100852,100854],{"id":100850},"q13-a-function-accepts-any-file-like-object-and-calls-read-on-it-which-approach-is-duck-typing-and-which-is-its-rigid-alternative","Q13. A function accepts any \"file-like\" object and calls ",[39,100853,99591],{}," on it. Which approach is duck typing, and which is its rigid alternative?",[257,100856,100857],{"language":87455},[260,100858,100860],{"className":87467,"code":100859,"language":87455,"meta":264,"style":264},"# Version A\ndef load(source):\n    return source.read()\n\n# Version B\ndef load(source):\n    if not isinstance(source, io.IOBase):\n        raise TypeError(\"source must be a file\")\n    return source.read()\n",[39,100861,100862,100866,100876,100883,100887,100891,100899,100911,100925],{"__ignoreMap":264},[268,100863,100864],{"class":270,"line":271},[268,100865,95043],{"class":29390},[268,100867,100868,100870,100873],{"class":270,"line":286},[268,100869,88976],{"class":274},[268,100871,100872],{"class":278}," load",[268,100874,100875],{"class":282},"(source):\n",[268,100877,100878,100880],{"class":270,"line":296},[268,100879,9871],{"class":274},[268,100881,100882],{"class":282}," source.read()\n",[268,100884,100885],{"class":270,"line":311},[268,100886,5033],{"emptyLinePlaceholder":35},[268,100888,100889],{"class":270,"line":788},[268,100890,95107],{"class":29390},[268,100892,100893,100895,100897],{"class":270,"line":1951},[268,100894,88976],{"class":274},[268,100896,100872],{"class":278},[268,100898,100875],{"class":282},[268,100900,100901,100903,100906,100908],{"class":270,"line":8955},[268,100902,9686],{"class":274},[268,100904,100905],{"class":274}," not",[268,100907,90869],{"class":305},[268,100909,100910],{"class":282},"(source, io.IOBase):\n",[268,100912,100913,100916,100918,100920,100923],{"class":270,"line":8966},[268,100914,100915],{"class":274},"        raise",[268,100917,60015],{"class":305},[268,100919,622],{"class":282},[268,100921,100922],{"class":289},"\"source must be a file\"",[268,100924,20702],{"class":282},[268,100926,100927,100929],{"class":270,"line":8974},[268,100928,9871],{"class":274},[268,100930,100882],{"class":282},[23,100932,100934,100953,100961,100976],{"className":100933},[26],[28,100935,100937,100939,100940,62227,100942,100945,100946,100949,100950],{"className":100936},[31],[33,100938],{"disabled":35,"type":36}," Version A is duck typing — it works with any object that implements ",[39,100941,99591],{},[39,100943,100944],{},"io.StringIO",", sockets wrapped in ",[39,100947,100948],{},"makefile()",", or test doubles; Version B rejects perfectly valid file-like objects that don't literally subclass ",[39,100951,100952],{},"io.IOBase",[28,100954,100956,100958,100959],{"className":100955},[31],[33,100957],{"disabled":35,"type":36}," Version B is duck typing, since it explicitly checks the file's \"shape\" via ",[39,100960,89591],{},[28,100962,100964,100966,100967,100969,100970,100972,100973,100975],{"className":100963},[31],[33,100965],{"disabled":35,"type":36}," Both versions are equally flexible; ",[39,100968,89591],{}," checks against ",[39,100971,100952],{}," accept any object with a ",[39,100974,99591],{}," method",[28,100977,100979,100981],{"className":100978},[31],[33,100980],{"disabled":35,"type":36}," Version A is unsafe and should never be used in production code",[66,100983,100984,100986,100999],{},[69,100985,71],{},[73,100987,100988,100990,100991,62227,100993,100945,100995,100949,100997],{},[76,100989,78],{}," A — Version A is duck typing — it works with any object that implements ",[39,100992,99591],{},[39,100994,100944],{},[39,100996,100948],{},[39,100998,100952],{},[73,101000,101001,101003,101004,101007,101008,101010,101011,101013,101014,90262,101016,101018,101019,101021],{},[76,101002,84],{}," Duck typing (Version A) trusts that if ",[39,101005,101006],{},"source"," has a working ",[39,101009,99591],{},", it's usable — this is precisely what makes Python code composable with third-party and test objects that were never designed to subclass anything in particular. Version B's ",[39,101012,89591],{}," check is overly rigid: plenty of legitimate file-like objects (certain mocks, custom wrappers, some third-party libraries) don't inherit from ",[39,101015,100952],{},[39,101017,99591],{}," works perfectly, so the check produces false-negative ",[39,101020,827],{},"s for valid input — a real production bug pattern, not just a style nitpick.",[15,101023,101024,101028,101172,101234],{"language":87455},[18,101025,101027],{"id":101026},"q14-what-does-this-print-and-why","Q14. What does this print, and why?",[257,101029,101030],{"language":87455},[260,101031,101033],{"className":87467,"code":101032,"language":87455,"meta":264,"style":264},"class Base:\n    def __init__(self, name):\n        self.name = name\n        print(\"Base init\")\n\nclass Mixin:\n    def __init__(self, *a, **kw):\n        print(\"Mixin init\")\n        super().__init__(*a, **kw)\n\nclass Combined(Mixin, Base):\n    pass\n\nCombined(\"x\")\n",[39,101034,101035,101043,101051,101061,101072,101076,101085,101103,101114,101133,101137,101155,101159,101163],{"__ignoreMap":264},[268,101036,101037,101039,101041],{"class":270,"line":271},[268,101038,1468],{"class":274},[268,101040,20590],{"class":278},[268,101042,8931],{"class":282},[268,101044,101045,101047,101049],{"class":270,"line":286},[268,101046,92933],{"class":274},[268,101048,92936],{"class":305},[268,101050,98478],{"class":282},[268,101052,101053,101055,101057,101059],{"class":270,"line":296},[268,101054,92944],{"class":305},[268,101056,30956],{"class":282},[268,101058,302],{"class":274},[268,101060,98489],{"class":282},[268,101062,101063,101065,101067,101070],{"class":270,"line":311},[268,101064,95279],{"class":305},[268,101066,622],{"class":282},[268,101068,101069],{"class":289},"\"Base init\"",[268,101071,20702],{"class":282},[268,101073,101074],{"class":270,"line":788},[268,101075,5033],{"emptyLinePlaceholder":35},[268,101077,101078,101080,101083],{"class":270,"line":1951},[268,101079,1468],{"class":274},[268,101081,101082],{"class":278}," Mixin",[268,101084,8931],{"class":282},[268,101086,101087,101089,101091,101093,101095,101098,101100],{"class":270,"line":8955},[268,101088,92933],{"class":274},[268,101090,92936],{"class":305},[268,101092,96447],{"class":282},[268,101094,6134],{"class":274},[268,101096,101097],{"class":282},"a, ",[268,101099,6231],{"class":274},[268,101101,101102],{"class":282},"kw):\n",[268,101104,101105,101107,101109,101112],{"class":270,"line":8966},[268,101106,95279],{"class":305},[268,101108,622],{"class":282},[268,101110,101111],{"class":289},"\"Mixin init\"",[268,101113,20702],{"class":282},[268,101115,101116,101118,101120,101122,101124,101126,101128,101130],{"class":270,"line":8974},[268,101117,99946],{"class":305},[268,101119,19341],{"class":282},[268,101121,96610],{"class":305},[268,101123,622],{"class":282},[268,101125,6134],{"class":274},[268,101127,101097],{"class":282},[268,101129,6231],{"class":274},[268,101131,101132],{"class":282},"kw)\n",[268,101134,101135],{"class":270,"line":8985},[268,101136,5033],{"emptyLinePlaceholder":35},[268,101138,101139,101141,101144,101146,101149,101151,101153],{"class":270,"line":8990},[268,101140,1468],{"class":274},[268,101142,101143],{"class":278}," Combined",[268,101145,622],{"class":282},[268,101147,101148],{"class":278},"Mixin",[268,101150,42],{"class":282},[268,101152,20597],{"class":278},[268,101154,94690],{"class":282},[268,101156,101157],{"class":270,"line":8997},[268,101158,98540],{"class":274},[268,101160,101161],{"class":270,"line":9002},[268,101162,5033],{"emptyLinePlaceholder":35},[268,101164,101165,101168,101170],{"class":270,"line":14676},[268,101166,101167],{"class":282},"Combined(",[268,101169,22248],{"class":289},[268,101171,20702],{"class":282},[23,101173,101175,101202,101212,101222],{"className":101174},[26],[28,101176,101178,355,101180,1133,101183,3990,101186,100138,101189,1179,101192,101195,101196,101199,101200],{"className":101177},[31],[33,101179],{"disabled":35,"type":36},[39,101181,101182],{},"Mixin init",[39,101184,101185],{},"Base init",[39,101187,101188],{},"Combined",[39,101190,101191],{},"[Combined, Mixin, Base, object]",[39,101193,101194],{},"Mixin.__init__"," runs first and its ",[39,101197,101198],{},"super().__init__"," correctly forwards to ",[39,101201,20597],{},[28,101203,101205,355,101207,1133,101209,101211],{"className":101204},[31],[33,101206],{"disabled":35,"type":36},[39,101208,101185],{},[39,101210,101182],{}," — base classes always initialize before mixins",[28,101213,101215,50010,101217,101219,101220,100097],{"className":101214},[31],[33,101216],{"disabled":35,"type":36},[39,101218,101182],{}," prints; ",[39,101221,100613],{},[28,101223,101225,355,101227,2833,101229,101231,101232],{"className":101224},[31],[33,101226],{"disabled":35,"type":36},[39,101228,827],{},[39,101230,101188],{}," doesn't define its own ",[39,101233,96610],{},[66,101235,101236,101238,101256],{},[69,101237,71],{},[73,101239,101240,3459,101242,1133,101244,3990,101246,100138,101248,1179,101250,101195,101252,101199,101254],{},[76,101241,78],{},[39,101243,101182],{},[39,101245,101185],{},[39,101247,101188],{},[39,101249,101191],{},[39,101251,101194],{},[39,101253,101198],{},[39,101255,20597],{},[73,101257,101258,69024,101260,101262,101263,101265,101266,101269,101270,101272,101273,101275,101276,101278,101279,2018,101281,101284,101285,101287,101288,5425,101291,101294,101295,101297,101298,101301,101302,101304],{},[76,101259,84],{},[39,101261,101188],{}," defines no ",[39,101264,96610],{}," of its own, calling ",[39,101267,101268],{},"Combined(\"x\")"," resolves ",[39,101271,96610],{}," via the MRO, finding ",[39,101274,101194],{}," first (because ",[39,101277,101148],{}," is listed before ",[39,101280,20597],{},[39,101282,101283],{},"class Combined(Mixin, Base)","). Because ",[39,101286,101194],{}," properly forwards ",[39,101289,101290],{},"*a, **kw",[39,101292,101293],{},"super().__init__(*a, **kw)"," (the fix from Q11), the chain continues correctly into ",[39,101296,100613],{},", which prints and sets ",[39,101299,101300],{},"self.name",". This demonstrates why mixins are conventionally listed ",[104,101303,11314],{}," the \"real\" base class — covered as a best practice later in this quiz.",[15,101306,101307,101318,101351],{},[18,101308,101310,101311,101313,101314,101317],{"id":101309},"q15-when-should-you-prefer-duck-typing-isinstance-checks-against-an-abstract-base-class-abc-or-collectionsabc-protocol-over-an-explicit-concrete-type-check","Q15. When should you prefer duck typing \u002F ",[39,101312,89591],{}," checks against an Abstract Base Class (ABC) or ",[39,101315,101316],{},"collections.abc"," protocol over an explicit concrete-type check?",[23,101319,101321,101330,101339,101345],{"className":101320},[26],[28,101322,101324,101326,101327,101329],{"className":101323},[31],[33,101325],{"disabled":35,"type":36}," When you only care that the object supports the required behavior (e.g., iteration, ",[39,101328,99591],{},", comparison), since this maximizes compatibility with any conforming object, including ones from third-party code or tests",[28,101331,101333,101335,101336,101338],{"className":101332},[31],[33,101334],{"disabled":35,"type":36}," Always avoid ",[39,101337,89591],{}," entirely; type checks are never appropriate in idiomatic Python",[28,101340,101342,101344],{"className":101341},[31],[33,101343],{"disabled":35,"type":36}," Only when performance is not a concern, since duck typing is always slower",[28,101346,101348,101350],{"className":101347},[31],[33,101349],{"disabled":35,"type":36}," Only in Python 2 code; Python 3 favors strict type checks exclusively",[66,101352,101353,101355,101362],{},[69,101354,71],{},[73,101356,101357,101359,101360,101329],{},[76,101358,78],{}," A — When you only care that the object supports the required behavior (e.g., iteration, ",[39,101361,99591],{},[73,101363,101364,355,101366,3990,101368,101371,101372,101375,101376,101378,101379,101381,101382,101385,101386,101389],{},[76,101365,84],{},[76,101367,17307],{},[39,101369,101370],{},"isinstance(x, collections.abc.Iterable)"," or simply trying ",[39,101373,101374],{},"iter(x)"," and catching ",[39,101377,827],{}," (EAFP style) accepts any object that behaves correctly, regardless of its concrete class — this is far more Pythonic than requiring a specific concrete base class. ",[39,101380,89591],{}," isn't inherently un-Pythonic (option B overstates it); checking against a ",[104,101383,101384],{},"behavioral"," ABC\u002Fprotocol is fine, while checking against one specific ",[104,101387,101388],{},"concrete"," implementation class (as in Q13's Version B) is the anti-pattern.",[15,101391,101392,101402,101429],{},[18,101393,101395,101396,101398,101399,101401],{"id":101394},"q16-what-is-the-best-practice-rule-about-calling-super__init__-when-overriding-__init__-in-a-subclass","Q16. What is the best-practice rule about calling ",[39,101397,99606],{}," when overriding ",[39,101400,96610],{}," in a subclass?",[23,101403,101405,101411,101417,101423],{"className":101404},[26],[28,101406,101408,101410],{"className":101407},[31],[33,101409],{"disabled":35,"type":36}," Call it (typically as the first statement) unless you have a deliberate, documented reason to fully replace the parent's initialization behavior",[28,101412,101414,101416],{"className":101413},[31],[33,101415],{"disabled":35,"type":36}," Never call it — each class should be responsible for setting up only its own attributes independently",[28,101418,101420,101422],{"className":101419},[31],[33,101421],{"disabled":35,"type":36}," Only call it if the parent class defines more than one attribute",[28,101424,101426,101428],{"className":101425},[31],[33,101427],{"disabled":35,"type":36}," Call it only in multiple inheritance, never in single inheritance",[66,101430,101431,101433,101438],{},[69,101432,71],{},[73,101434,101435,101437],{},[76,101436,78],{}," A — Call it (typically as the first statement) unless you have a deliberate, documented reason to fully replace the parent's initialization behavior",[73,101439,101440,355,101442,101444,101445,101447],{},[76,101441,84],{},[76,101443,17307],{}," — This directly prevents the Q6 bug (missing attributes) and the Q11 bug (broken cooperative chains). Skipping ",[39,101446,99606],{}," should be a conscious, rare decision — e.g., when a subclass genuinely needs to bypass the parent's setup entirely — not the default, since forgetting it silently produces incompletely-initialized objects that only fail later when a missing attribute is accessed.",[15,101449,101450,101457,101503],{},[18,101451,101453,101454,101456],{"id":101452},"q17-for-mixins-designed-to-be-combined-with-other-classes-via-multiple-inheritance-whats-the-best-practice-pattern-for-their-__init__-methods","Q17. For mixins designed to be combined with other classes via multiple inheritance, what's the best-practice pattern for their ",[39,101455,96610],{}," methods?",[23,101458,101460,101472,101481,101492],{"className":101459},[26],[28,101461,101463,101465,101466,101468,101469,101471],{"className":101462},[31],[33,101464],{"disabled":35,"type":36}," Accept ",[39,101467,96067],{},", do the mixin's own setup, then call ",[39,101470,100646],{}," to forward everything else down the MRO chain",[28,101473,101475,101477,101478,101480],{"className":101474},[31],[33,101476],{"disabled":35,"type":36}," Never define ",[39,101479,96610],{}," in a mixin at all",[28,101482,101484,39927,101486,101489,101490],{"className":101483},[31],[33,101485],{"disabled":35,"type":36},[39,101487,101488],{},"Base.__init__(self)"," directly by name instead of using ",[39,101491,30889],{},[28,101493,101495,101497,101498,101500,101501],{"className":101494},[31],[33,101496],{"disabled":35,"type":36}," Require every consumer of the mixin to manually call the mixin's ",[39,101499,96610],{}," separately from the class's own ",[39,101502,96610],{},[66,101504,101505,101507,101516],{},[69,101506,71],{},[73,101508,101509,101511,101512,101468,101514,101471],{},[76,101510,78],{}," A — Accept ",[39,101513,96067],{},[39,101515,100646],{},[73,101517,101518,355,101520,101522,101523,101525,101526,101528],{},[76,101519,84],{},[76,101521,17307],{}," — This is the cooperative multiple inheritance pattern demonstrated correctly in Q14: every participant in the chain must both do its own work ",[104,101524,31781],{}," pass along whatever it doesn't personally need, using ",[39,101527,30889],{}," rather than a hardcoded class name (option C), since a hardcoded name breaks the MRO-based dispatch entirely and can call the wrong class or the same class twice in complex hierarchies.",[15,101530,101531,101549,101604],{},[18,101532,101534,101535,101537,101538,101541,101542,101545,101546,101548],{"id":101533},"q18-a-design-needs-a-car-to-have-engine-like-behavior-and-gps-like-behavior-but-these-are-unrelated-capabilities-with-no-natural-is-a-relationship-to-car-whats-the-best-practice-design-choice","Q18. A design needs a ",[39,101536,30893],{}," to have ",[39,101539,101540],{},"Engine","-like behavior and ",[39,101543,101544],{},"GPS","-like behavior, but these are unrelated capabilities with no natural \"is-a\" relationship to ",[39,101547,30893],{},". What's the best-practice design choice?",[23,101550,101552,101576,101586,101595],{"className":101551},[26],[28,101553,101555,101557,101558,101560,101561,186,101564,101567,101568,101570,101571,101573,101574],{"className":101554},[31],[33,101556],{"disabled":35,"type":36}," Favor composition — give ",[39,101559,30893],{}," an ",[39,101562,101563],{},"self.engine = Engine()",[39,101565,101566],{},"self.gps = GPS()"," attribute — over multiple inheritance, since ",[39,101569,30893],{}," \"has-a\" engine and GPS, it isn't \"an\" ",[39,101572,101540],{}," or \"a\" ",[39,101575,101544],{},[28,101577,101579,101581,101582,101585],{"className":101578},[31],[33,101580],{"disabled":35,"type":36}," Always use multiple inheritance (",[39,101583,101584],{},"class Car(Engine, GPS)",") since it's more concise",[28,101587,101589,101591,101592,101594],{"className":101588},[31],[33,101590],{"disabled":35,"type":36}," Duplicate the engine and GPS logic directly inside ",[39,101593,30893],{}," to avoid any inheritance complexity",[28,101596,101598,101600,101601,101603],{"className":101597},[31],[33,101599],{"disabled":35,"type":36}," Use multiple inheritance but avoid calling ",[39,101602,30889],{}," anywhere to keep things simple",[66,101605,101606,101608,101625],{},[69,101607,71],{},[73,101609,101610,101612,101613,101560,101615,186,101617,101567,101619,101570,101621,101573,101623],{},[76,101611,78],{}," A — Favor composition — give ",[39,101614,30893],{},[39,101616,101563],{},[39,101618,101566],{},[39,101620,30893],{},[39,101622,101540],{},[39,101624,101544],{},[73,101626,101627,355,101629,101631],{},[76,101628,84],{},[76,101630,17307],{}," — \"Favor composition over inheritance\" is a core OOP design principle: multiple inheritance is powerful but adds real MRO complexity (as this whole quiz demonstrates) for relationships that aren't genuinely \"is-a.\" Reserving multiple inheritance for true mixins (small, focused, cooperative classes explicitly designed to be combined) and using composition for unrelated capabilities keeps hierarchies shallow, predictable, and far easier to reason about and test.",[15,101633,101634,101641,101686],{},[18,101635,101637,101638,101640],{"id":101636},"q19-when-multiple-concrete-types-should-be-accepted-by-one-isinstance-check-whats-the-idiomatic-way-to-write-it","Q19. When multiple concrete types should be accepted by one ",[39,101639,89591],{}," check, what's the idiomatic way to write it?",[23,101642,101644,101653,101665,101677],{"className":101643},[26],[28,101645,101647,355,101649,101652],{"className":101646},[31],[33,101648],{"disabled":35,"type":36},[39,101650,101651],{},"isinstance(x, (int, float))"," — pass a tuple of types as the second argument",[28,101654,101656,355,101658,101661,101662,101664],{"className":101655},[31],[33,101657],{"disabled":35,"type":36},[39,101659,101660],{},"isinstance(x, int) or isinstance(x, float)"," — always spelled out with ",[39,101663,93462],{},", since tuples aren't supported",[28,101666,101668,355,101670,101673,101674,101676],{"className":101667},[31],[33,101669],{"disabled":35,"type":36},[39,101671,101672],{},"type(x) in (int, float)"," — using ",[39,101675,89656],{}," is preferred since it's more explicit",[28,101678,101680,355,101682,101685],{"className":101679},[31],[33,101681],{"disabled":35,"type":36},[39,101683,101684],{},"isinstance(x, int, float)"," — pass each type as a separate positional argument",[66,101687,101688,101690,101696],{},[69,101689,71],{},[73,101691,101692,3459,101694,101652],{},[76,101693,78],{},[39,101695,101651],{},[73,101697,101698,355,101700,3990,101702,101704,101705,101707,101708,101710,101711,101713,101714,101716,101717,22334,101720,101723,101724,2758,101727,10819,101729,101731,101732,101734],{},[76,101699,84],{},[76,101701,17307],{},[39,101703,89591],{}," natively accepts a tuple of types (or classes) as its second argument and returns ",[39,101706,89285],{}," if the object matches any of them, which is both more concise and, unlike ",[39,101709,101672],{},", still correctly honors subclasses (e.g., a ",[39,101712,89412],{},", which subclasses ",[39,101715,87646],{},", matches ",[39,101718,101719],{},"isinstance(x, int)",[39,101721,101722],{},"type(x) in (int,)"," would reject it since ",[39,101725,101726],{},"type(True) is bool",[39,101728,87646],{},[39,101730,101684],{}," (option D) raises ",[39,101733,827],{}," — that's not valid syntax for multiple types.",[15,101736,101737,101748,101783],{},[18,101738,101740,101741,101744,101745,101747],{"id":101739},"q20-when-writing-class-combinedmixin-base-why-do-style-guides-recommend-listing-mixins-before-the-primary-base-class","Q20. When writing ",[39,101742,101743],{},"class Combined(Mixin, Base):",", why do style guides recommend listing mixins ",[104,101746,11314],{}," the primary base class?",[23,101749,101751,101760,101768,101774],{"className":101750},[26],[28,101752,101754,101756,101757,101759],{"className":101753},[31],[33,101755],{"disabled":35,"type":36}," Because Python's left-to-right MRO ordering means earlier-listed classes take precedence for overridden methods, and mixins are meant to \"layer on top of\" the base's behavior, intercepting calls via ",[39,101758,30889],{}," before they reach the base",[28,101761,101763,101765,101766],{"className":101762},[31],[33,101764],{"disabled":35,"type":36}," Because Python requires mixins to be listed first or it raises a ",[39,101767,827],{},[28,101769,101771,101773],{"className":101770},[31],[33,101772],{"disabled":35,"type":36}," The order of base classes has no effect on behavior, only readability",[28,101775,101777,101779,101780,101782],{"className":101776},[31],[33,101778],{"disabled":35,"type":36}," Because mixins must always be defined before the base class in the source file, and ",[39,101781,1468],{}," statement order must match definition order",[66,101784,101785,101787,101794],{},[69,101786,71],{},[73,101788,101789,101791,101792,101759],{},[76,101790,78],{}," A — Because Python's left-to-right MRO ordering means earlier-listed classes take precedence for overridden methods, and mixins are meant to \"layer on top of\" the base's behavior, intercepting calls via ",[39,101793,30889],{},[73,101795,101796,355,101798,101800,101801,101803,101804,1179,101806,101808,101809,101811,101812,355,101814,101816,101817,3801,101819,101821,101822,101825,101826,101828],{},[76,101797,84],{},[76,101799,17307],{}," — As demonstrated in Q14, ",[39,101802,101283],{}," produces the MRO ",[39,101805,101191],{},[39,101807,101148],{},"'s methods (including ",[39,101810,96610],{},") run ",[104,101813,11314],{},[39,101815,20597],{},"'s and can add behavior around calls that eventually reach ",[39,101818,20597],{},[39,101820,30889],{},". Reversing the order (",[39,101823,101824],{},"Base, Mixin",") would mean ",[39,101827,20597],{},"'s methods take precedence instead, likely defeating the mixin's entire purpose of augmenting or intercepting behavior. This ordering convention is why nearly every mixin-based library (e.g., Django class-based views) documents \"mixins go first, left of the base class.\"",[2107,101830,101831],{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-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 .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);}",{"title":264,"searchDepth":286,"depth":286,"links":101833},[101834,101835,101837,101838,101839,101840,101842,101843,101844,101845,101847,101849,101850,101852,101853,101855,101857,101859,101861,101863],{"id":99221,"depth":296,"text":99222},{"id":99275,"depth":296,"text":101836},"Q2. In single inheritance, what does super().__init__(*args) inside a subclass's __init__ do?",{"id":99353,"depth":296,"text":99354},{"id":99466,"depth":296,"text":99467},{"id":99532,"depth":296,"text":99533},{"id":99600,"depth":296,"text":101841},"Q6. What happens if a subclass overrides __init__ but never calls super().__init__()?",{"id":99794,"depth":296,"text":99795},{"id":99871,"depth":296,"text":99872},{"id":100190,"depth":296,"text":100191},{"id":100358,"depth":296,"text":101846},"Q10. In Python 3, is there any behavioral difference between super() and super(CurrentClass, self) when called inside a normal instance method of CurrentClass?",{"id":100454,"depth":296,"text":101848},"Q11. A mixin is meant to add caching to any class in a cooperative multiple-inheritance hierarchy. What's wrong with this __init__?",{"id":100670,"depth":296,"text":100671},{"id":100850,"depth":296,"text":101851},"Q13. A function accepts any \"file-like\" object and calls .read() on it. Which approach is duck typing, and which is its rigid alternative?",{"id":101026,"depth":296,"text":101027},{"id":101309,"depth":296,"text":101854},"Q15. When should you prefer duck typing \u002F isinstance checks against an Abstract Base Class (ABC) or collections.abc protocol over an explicit concrete-type check?",{"id":101394,"depth":296,"text":101856},"Q16. What is the best-practice rule about calling super().__init__() when overriding __init__ in a subclass?",{"id":101452,"depth":296,"text":101858},"Q17. For mixins designed to be combined with other classes via multiple inheritance, what's the best-practice pattern for their __init__ methods?",{"id":101533,"depth":296,"text":101860},"Q18. A design needs a Car to have Engine-like behavior and GPS-like behavior, but these are unrelated capabilities with no natural \"is-a\" relationship to Car. What's the best-practice design choice?",{"id":101636,"depth":296,"text":101862},"Q19. When multiple concrete types should be accepted by one isinstance check, what's the idiomatic way to write it?",{"id":101739,"depth":296,"text":101864},"Q20. When writing class Combined(Mixin, Base):, why do style guides recommend listing mixins before the primary base class?",{},"\u002Fpython\u002F13-inheritance-and-polymorphism",{"title":99211,"description":264},"python\u002F13-inheritance-and-polymorphism","gSCxefWeTLWl6YSf_UWfAUbfIhbNQb8du-mR4Y7YNi4",{"id":101871,"title":101872,"body":101873,"description":264,"extension":2144,"meta":105095,"navigation":35,"path":105096,"seo":105097,"stem":105098,"__hash__":105099},"content\u002Fpython\u002F20-type-hints-and-typing.md","20 — Type Hints & Typing",{"type":8,"value":101874,"toc":105057},[101875,101878,102028,102184,102365,102554,102629,102729,102828,102973,103116,103298,103498,103683,103757,103924,104093,104273,104392,104567,104761,105055],[11,101876,101872],{"id":101877},"_20-type-hints-typing",[15,101879,101880,101884,101941,101984],{"language":87455},[18,101881,101883],{"id":101882},"q1-what-happens-when-the-following-code-is-run-with-plain-cpython-no-external-tool","Q1. What happens when the following code is run with plain CPython (no external tool)?",[257,101885,101886],{"language":87455},[260,101887,101889],{"className":87467,"code":101888,"language":87455,"meta":264,"style":264},"def add(a: int, b: int) -> int:\n    return a + b\n\nprint(add(\"3\", \"4\"))\n",[39,101890,101891,101913,101923,101927],{"__ignoreMap":264},[268,101892,101893,101895,101897,101900,101902,101904,101906,101909,101911],{"class":270,"line":271},[268,101894,88976],{"class":274},[268,101896,1217],{"class":278},[268,101898,101899],{"class":282},"(a: ",[268,101901,87646],{"class":305},[268,101903,10279],{"class":282},[268,101905,87646],{"class":305},[268,101907,101908],{"class":282},") -> ",[268,101910,87646],{"class":305},[268,101912,8931],{"class":282},[268,101914,101915,101917,101919,101921],{"class":270,"line":286},[268,101916,9871],{"class":274},[268,101918,1243],{"class":282},[268,101920,1246],{"class":274},[268,101922,95559],{"class":282},[268,101924,101925],{"class":270,"line":296},[268,101926,5033],{"emptyLinePlaceholder":35},[268,101928,101929,101931,101933,101935,101937,101939],{"class":270,"line":311},[268,101930,84797],{"class":305},[268,101932,95570],{"class":282},[268,101934,50483],{"class":289},[268,101936,42],{"class":282},[268,101938,50527],{"class":289},[268,101940,47690],{"class":282},[23,101942,101944,101957,101967,101976],{"className":101943},[26],[28,101945,101947,101949,101950,183,101952,101954,101955],{"className":101946},[31],[33,101948],{"disabled":35,"type":36}," Raises a ",[39,101951,827],{},[39,101953,50483],{}," is not an ",[39,101956,87646],{},[28,101958,101960,101949,101962,101964,101965],{"className":101959},[31],[33,101961],{"disabled":35,"type":36},[39,101963,827],{}," because the return value doesn't match ",[39,101966,87646],{},[28,101968,101970,85345,101972,101975],{"className":101969},[31],[33,101971],{"disabled":35,"type":36},[39,101973,101974],{},"\"34\""," with no error at all",[28,101977,101979,101949,101981,101983],{"className":101978},[31],[33,101980],{"disabled":35,"type":36},[39,101982,1274],{}," at import time because the annotations are violated",[66,101985,101986,101988,101995],{},[69,101987,71],{},[73,101989,101990,101992,101993,101975],{},[76,101991,78],{}," C — Prints ",[39,101994,101974],{},[73,101996,101997,355,101999,102001,102002,6033,102004,186,102006,102008,102009,102012,102013,102016,102017,102020,102021,102023,102024,102027],{},[76,101998,84],{},[76,102000,582],{}," Python's type hints are not enforced at runtime by the interpreter. ",[39,102003,87646],{},[39,102005,1223],{},[39,102007,1232],{}," is purely documentation\u002Fmetadata (stored in ",[39,102010,102011],{},"__annotations__",") unless a separate tool checks it. Since ",[39,102014,102015],{},"str + str"," is valid Python, ",[39,102018,102019],{},"add(\"3\", \"4\")"," just concatenates and returns ",[39,102022,101974],{},". The tempting answers assume CPython behaves like a statically typed language and raises on mismatched types — it does not; only static checkers like mypy or pyright, or runtime validators like ",[39,102025,102026],{},"pydantic",", would flag this.",[15,102029,102030,102034,102102,102144],{"language":87455},[18,102031,102033],{"id":102032},"q2-which-two-type-hints-are-exactly-equivalent","Q2. Which two type hints are exactly equivalent?",[257,102035,102036],{"language":87455},[260,102037,102039],{"className":87467,"code":102038,"language":87455,"meta":264,"style":264},"from typing import Optional, Union\n\ndef f(x: Optional[str]) -> None: ...\ndef g(x: Union[str, None]) -> None: ...\n",[39,102040,102041,102053,102057,102078],{"__ignoreMap":264},[268,102042,102043,102045,102048,102050],{"class":270,"line":271},[268,102044,44539],{"class":274},[268,102046,102047],{"class":282}," typing ",[268,102049,662],{"class":274},[268,102051,102052],{"class":282}," Optional, Union\n",[268,102054,102055],{"class":270,"line":286},[268,102056,5033],{"emptyLinePlaceholder":35},[268,102058,102059,102061,102063,102066,102068,102071,102073,102075],{"class":270,"line":296},[268,102060,88976],{"class":274},[268,102062,35259],{"class":278},[268,102064,102065],{"class":282},"(x: Optional[",[268,102067,17109],{"class":305},[268,102069,102070],{"class":282},"]) -> ",[268,102072,90944],{"class":305},[268,102074,1783],{"class":282},[268,102076,102077],{"class":305},"...\n",[268,102079,102080,102082,102085,102088,102090,102092,102094,102096,102098,102100],{"class":270,"line":311},[268,102081,88976],{"class":274},[268,102083,102084],{"class":278}," g",[268,102086,102087],{"class":282},"(x: Union[",[268,102089,17109],{"class":305},[268,102091,42],{"class":282},[268,102093,90944],{"class":305},[268,102095,102070],{"class":282},[268,102097,90944],{"class":305},[268,102099,1783],{"class":282},[268,102101,102077],{"class":305},[23,102103,102105,102118,102127,102138],{"className":102104},[26],[28,102106,102108,102110,102111,102114,102115],{"className":102107},[31],[33,102109],{"disabled":35,"type":36}," They are equivalent — ",[39,102112,102113],{},"Optional[str]"," is defined as ",[39,102116,102117],{},"Union[str, None]",[28,102119,102121,102123,102124,102126],{"className":102120},[31],[33,102122],{"disabled":35,"type":36}," They are different — ",[39,102125,102113],{}," also allows omitting the argument entirely",[28,102128,102130,102123,102132,102134,102135,102137],{"className":102129},[31],[33,102131],{"disabled":35,"type":36},[39,102133,102117],{}," allows ",[39,102136,87646],{}," too, by widening",[28,102139,102141,102143],{"className":102140},[31],[33,102142],{"disabled":35,"type":36}," They are equivalent only under Python 3.11+",[66,102145,102146,102148,102157],{},[69,102147,71],{},[73,102149,102150,102152,102153,102114,102155],{},[76,102151,78],{}," A — They are equivalent — ",[39,102154,102113],{},[39,102156,102117],{},[73,102158,102159,355,102161,102164,102165,102168,102169,102172,102173,102176,102177,102180,102181,102183],{},[76,102160,84],{},[39,102162,102163],{},"Optional[X]"," is literally shorthand in the ",[39,102166,102167],{},"typing"," module for ",[39,102170,102171],{},"Union[X, None]"," — nothing more. A very common misconception (option B) is that ",[39,102174,102175],{},"Optional"," makes an argument optional in the sense of having a default value; it does not — you still must pass something explicitly unless you separately give the parameter a default like ",[39,102178,102179],{},"= None",". This equivalence has held since ",[39,102182,102175],{}," was introduced and is not a 3.11 change.",[15,102185,102186,102195,102262,102311],{"language":87455},[18,102187,102189,102190,64118,102193,1685],{"id":102188},"q3-what-is-the-key-practical-difference-between-annotating-a-parameter-as-any-versus-object","Q3. What is the key practical difference between annotating a parameter as ",[39,102191,102192],{},"Any",[39,102194,2664],{},[257,102196,102197],{"language":87455},[260,102198,102200],{"className":87467,"code":102199,"language":87455,"meta":264,"style":264},"from typing import Any\n\ndef handle_any(x: Any) -> None:\n    x.whatever_method()\n\ndef handle_object(x: object) -> None:\n    x.whatever_method()\n",[39,102201,102202,102213,102217,102231,102236,102240,102258],{"__ignoreMap":264},[268,102203,102204,102206,102208,102210],{"class":270,"line":271},[268,102205,44539],{"class":274},[268,102207,102047],{"class":282},[268,102209,662],{"class":274},[268,102211,102212],{"class":282}," Any\n",[268,102214,102215],{"class":270,"line":286},[268,102216,5033],{"emptyLinePlaceholder":35},[268,102218,102219,102221,102224,102227,102229],{"class":270,"line":296},[268,102220,88976],{"class":274},[268,102222,102223],{"class":278}," handle_any",[268,102225,102226],{"class":282},"(x: Any) -> ",[268,102228,90944],{"class":305},[268,102230,8931],{"class":282},[268,102232,102233],{"class":270,"line":311},[268,102234,102235],{"class":282},"    x.whatever_method()\n",[268,102237,102238],{"class":270,"line":788},[268,102239,5033],{"emptyLinePlaceholder":35},[268,102241,102242,102244,102247,102250,102252,102254,102256],{"class":270,"line":1951},[268,102243,88976],{"class":274},[268,102245,102246],{"class":278}," handle_object",[268,102248,102249],{"class":282},"(x: ",[268,102251,2664],{"class":305},[268,102253,101908],{"class":282},[268,102255,90944],{"class":305},[268,102257,8931],{"class":282},[268,102259,102260],{"class":270,"line":8955},[268,102261,102235],{"class":282},[23,102263,102265,102273,102284,102298],{"className":102264},[26],[28,102266,102268,102270,102271],{"className":102267},[31],[33,102269],{"disabled":35,"type":36}," There is no difference — both disable all static type checking on ",[39,102272,2403],{},[28,102274,102276,355,102278,102280,102281,102283],{"className":102275},[31],[33,102277],{"disabled":35,"type":36},[39,102279,2664],{}," disables checking, ",[39,102282,102192],{}," is checked strictly",[28,102285,102287,355,102289,102291,102292,102294,102295,102297],{"className":102286},[31],[33,102288],{"disabled":35,"type":36},[39,102290,102192],{}," tells the checker to skip checking on ",[39,102293,2403],{}," entirely; ",[39,102296,2664],{}," is a real type, so calling an arbitrary method on it is a static type error",[28,102299,102301,355,102303,186,102305,102307,102308,102310],{"className":102300},[31],[33,102302],{"disabled":35,"type":36},[39,102304,102192],{},[39,102306,2664],{}," both restrict ",[39,102309,2403],{}," to have no methods at all",[66,102312,102313,102315,102325],{},[69,102314,71],{},[73,102316,102317,1004,102319,102291,102321,102294,102323,102297],{},[76,102318,78],{},[39,102320,102192],{},[39,102322,2403],{},[39,102324,2664],{},[73,102326,102327,355,102329,355,102331,102333,102334,102336,102337,102339,102340,42,102342,102345,102346,102349,102350,3277,102353,102355,102356,102358,102359,102361,102362,102364],{},[76,102328,84],{},[76,102330,930],{},[39,102332,2664],{}," is the actual root of Python's type hierarchy — every value is an ",[39,102335,2664],{},", but a static checker only knows about the methods ",[39,102338,2664],{}," itself defines (",[39,102341,89232],{},[39,102343,102344],{},"__repr__",", etc.), so ",[39,102347,102348],{},"handle_object"," would fail a mypy check on ",[39,102351,102352],{},"x.whatever_method()",[39,102354,102192],{}," is special-cased by type checkers to be compatible with everything in both directions, effectively opting ",[39,102357,2403],{}," out of static checking. Beginners often assume ",[39,102360,2664],{}," is the \"accept anything, no checks\" type since it's the base of everything — that's actually what ",[39,102363,102192],{}," is for.",[15,102366,102367,102371,102457,102508],{"language":87455},[18,102368,102370],{"id":102369},"q4-what-does-this-generic-function-signature-guarantee-to-a-static-type-checker","Q4. What does this generic function signature guarantee to a static type checker?",[257,102372,102373],{"language":87455},[260,102374,102376],{"className":87467,"code":102375,"language":87455,"meta":264,"style":264},"from typing import TypeVar\n\nT = TypeVar(\"T\")\n\ndef first(items: list[T]) -> T:\n    return items[0]\n\nresult = first([1, 2, 3])\n",[39,102377,102378,102389,102393,102408,102412,102421,102432,102436],{"__ignoreMap":264},[268,102379,102380,102382,102384,102386],{"class":270,"line":271},[268,102381,44539],{"class":274},[268,102383,102047],{"class":282},[268,102385,662],{"class":274},[268,102387,102388],{"class":282}," TypeVar\n",[268,102390,102391],{"class":270,"line":286},[268,102392,5033],{"emptyLinePlaceholder":35},[268,102394,102395,102398,102400,102403,102406],{"class":270,"line":296},[268,102396,102397],{"class":282},"T ",[268,102399,302],{"class":274},[268,102401,102402],{"class":282}," TypeVar(",[268,102404,102405],{"class":289},"\"T\"",[268,102407,20702],{"class":282},[268,102409,102410],{"class":270,"line":311},[268,102411,5033],{"emptyLinePlaceholder":35},[268,102413,102414,102416,102418],{"class":270,"line":788},[268,102415,88976],{"class":274},[268,102417,47835],{"class":278},[268,102419,102420],{"class":282},"(items: list[T]) -> T:\n",[268,102422,102423,102425,102428,102430],{"class":270,"line":1951},[268,102424,9871],{"class":274},[268,102426,102427],{"class":282}," items[",[268,102429,3307],{"class":305},[268,102431,89183],{"class":282},[268,102433,102434],{"class":270,"line":8955},[268,102435,5033],{"emptyLinePlaceholder":35},[268,102437,102438,102440,102442,102445,102447,102449,102451,102453,102455],{"class":270,"line":8966},[268,102439,87569],{"class":282},[268,102441,302],{"class":274},[268,102443,102444],{"class":282}," first([",[268,102446,2255],{"class":305},[268,102448,42],{"class":282},[268,102450,2258],{"class":305},[268,102452,42],{"class":282},[268,102454,3423],{"class":305},[268,102456,85493],{"class":282},[23,102458,102460,102474,102490,102500],{"className":102459},[26],[28,102461,102463,355,102465,102467,102468,183,102470,102473],{"className":102462},[31],[33,102464],{"disabled":35,"type":36},[39,102466,5631],{}," is inferred as ",[39,102469,102192],{},[39,102471,102472],{},"TypeVar"," can't track concrete types",[28,102475,102477,355,102479,102467,102481,102483,102484,5425,102487,102489],{"className":102476},[31],[33,102478],{"disabled":35,"type":36},[39,102480,5631],{},[39,102482,87646],{},", because the checker binds ",[39,102485,102486],{},"T",[39,102488,87646],{}," from the call site",[28,102491,102493,355,102495,102467,102497],{"className":102492},[31],[33,102494],{"disabled":35,"type":36},[39,102496,5631],{},[39,102498,102499],{},"list[int]",[28,102501,102503,355,102505,102507],{"className":102502},[31],[33,102504],{"disabled":35,"type":36},[39,102506,102472],{}," forces a runtime check that all list items share the same type",[66,102509,102510,102512,102524],{},[69,102511,71],{},[73,102513,102514,1727,102516,102467,102518,102483,102520,5425,102522,102489],{},[76,102515,78],{},[39,102517,5631],{},[39,102519,87646],{},[39,102521,102486],{},[39,102523,87646],{},[73,102525,102526,812,102528,102530,102531,42,102533,102535,102536,102538,102539,4912,102542,102544,102545,102547,102548,102550,102551,102553],{},[76,102527,84],{},[39,102529,102472],{}," lets a static checker propagate a concrete type through a generic function: given ",[39,102532,102499],{},[39,102534,102486],{}," is bound to ",[39,102537,87646],{}," for that call, so the checker infers ",[39,102540,102541],{},"first(...)",[39,102543,87646],{},". Nothing about this is enforced by CPython at runtime (option D is wrong — no runtime check ever happens); ",[39,102546,102472],{}," is a pure static-analysis construct. Option A is the common mistake of assuming generics degrade to ",[39,102549,102192],{},", when in fact the whole point of ",[39,102552,102472],{}," is to preserve the specific type through the call.",[15,102555,102556,102564,102605],{},[18,102557,102559,102560,102563],{"id":102558},"q5-which-statement-correctly-describes-how-mypy-relates-to-running-your-program","Q5. Which statement correctly describes how ",[39,102561,102562],{},"mypy"," relates to running your program?",[23,102565,102567,102578,102586,102597],{"className":102566},[26],[28,102568,102570,355,102572,102574,102575],{"className":102569},[31],[33,102571],{"disabled":35,"type":36},[39,102573,102562],{}," is a runtime import that Python executes automatically before ",[39,102576,102577],{},"main()",[28,102579,102581,355,102583,102585],{"className":102580},[31],[33,102582],{"disabled":35,"type":36},[39,102584,102562],{}," is a separate static-analysis tool you run against your source files; it reports type errors but does not change how the code executes",[28,102587,102589,355,102591,102593,102594,102596],{"className":102588},[31],[33,102590],{"disabled":35,"type":36},[39,102592,102562],{}," patches the CPython interpreter to raise ",[39,102595,827],{}," on hint violations",[28,102598,102600,355,102602,102604],{"className":102599},[31],[33,102601],{"disabled":35,"type":36},[39,102603,102562],{}," and type hints are required for Python code to run at all",[66,102606,102607,102609,102615],{},[69,102608,71],{},[73,102610,102611,1727,102613,102585],{},[76,102612,78],{},[39,102614,102562],{},[73,102616,102617,355,102619,24617,102621,102624,102625,102628],{},[76,102618,84],{},[39,102620,102562],{},[39,102622,102623],{},"pyright",") reads your source, checks annotations for consistency, and reports diagnostics — completely separately from ",[39,102626,102627],{},"python script.py",". It never modifies runtime behavior or the interpreter. Options A, C, and D describe a form of enforcement Python simply does not have out of the box; type hints are always optional documentation to CPython itself.",[15,102630,102631,102635,102676],{},[18,102632,102634],{"id":102633},"q6-in-modern-python-39-which-is-the-recommended-way-to-annotate-a-list-of-integers-without-importing-anything-extra","Q6. In modern Python (3.9+), which is the recommended way to annotate \"a list of integers\" without importing anything extra?",[23,102636,102638,102649,102660,102668],{"className":102637},[26],[28,102639,102641,355,102643,20968,102646,102648],{"className":102640},[31],[33,102642],{"disabled":35,"type":36},[39,102644,102645],{},"List[int]",[39,102647,102167],{},", always",[28,102650,102652,355,102654,102656,102657,102659],{"className":102651},[31],[33,102653],{"disabled":35,"type":36},[39,102655,102499],{},", using the built-in ",[39,102658,14924],{}," directly as a generic",[28,102661,102663,355,102665],{"className":102662},[31],[33,102664],{"disabled":35,"type":36},[39,102666,102667],{},"list(int)",[28,102669,102671,355,102673],{"className":102670},[31],[33,102672],{"disabled":35,"type":36},[39,102674,102675],{},"list\u003Cint>",[66,102677,102678,102680,102688],{},[69,102679,71],{},[73,102681,102682,1727,102684,102656,102686,102659],{},[76,102683,78],{},[39,102685,102499],{},[39,102687,14924],{},[73,102689,102690,355,102692,102694,102695,42,102697,42,102699,42,102701,102703,102704,102706,102707,3277,102710,102713,102714,102716,102717,102719,102720,102722,102723,102725,102726,102728],{},[76,102691,84],{},[76,102693,930],{}," PEP 585 (Python 3.9+) made the built-in collection types (",[39,102696,14924],{},[39,102698,89385],{},[39,102700,37910],{},[39,102702,89379],{},", etc.) directly subscriptable for annotations, so ",[39,102705,102499],{}," works without importing ",[39,102708,102709],{},"typing.List",[39,102711,102712],{},"typing.List[int]"," (option A) still works for backward compatibility but is now considered legacy style. ",[39,102715,102667],{}," (option C) is actually a runtime call to the ",[39,102718,14924],{}," constructor with ",[39,102721,87646],{}," as an argument — not an annotation at all, and it would raise ",[39,102724,827],{}," if actually executed since ",[39,102727,87646],{}," isn't iterable.",[15,102730,102731,102738,102791],{},[18,102732,3000,102734,102737],{"id":102733},"q7-what-does-callableint-str-bool-describe",[39,102735,102736],{},"Callable[[int, str], bool]"," describe?",[23,102739,102741,102753,102767,102779],{"className":102740},[26],[28,102742,102744,102746,102747,42,102749,383,102751],{"className":102743},[31],[33,102745],{"disabled":35,"type":36}," A callable that takes any two positional arguments and returns either an ",[39,102748,87646],{},[39,102750,17109],{},[39,102752,89412],{},[28,102754,102756,102758,102759,102761,102762,102764,102765],{"className":102755},[31],[33,102757],{"disabled":35,"type":36}," A callable taking exactly one ",[39,102760,87646],{}," argument and one ",[39,102763,17109],{}," argument (positionally) and returning a ",[39,102766,89412],{},[28,102768,102770,102772,102773,42,102775,137,102777],{"className":102769},[31],[33,102771],{"disabled":35,"type":36}," A tuple of three types: ",[39,102774,87646],{},[39,102776,17109],{},[39,102778,89412],{},[28,102780,102782,102784,102785,99,102787,17040,102789],{"className":102781},[31],[33,102783],{"disabled":35,"type":36}," A callable that takes an ",[39,102786,87646],{},[39,102788,17109],{},[39,102790,89412],{},[66,102792,102793,102795,102806],{},[69,102794,71],{},[73,102796,102797,102799,102800,102761,102802,102764,102804],{},[76,102798,78],{}," B — A callable taking exactly one ",[39,102801,87646],{},[39,102803,17109],{},[39,102805,89412],{},[73,102807,102808,355,102810,102813,102814,102816,102817,102820,102821,102823,102824,102827],{},[76,102809,84],{},[39,102811,102812],{},"Callable[[ArgTypes...], ReturnType]"," uses a list of the parameter types (positional-only, in order) as the first element and the return type as the second. So ",[39,102815,102736],{}," means \"call it with ",[39,102818,102819],{},"(some_int, some_str)"," and get a ",[39,102822,89412],{}," back.\" Option A misreads the union-like syntax that doesn't apply here; ",[39,102825,102826],{},"Callable","'s argument list is positional and ordered, not a set of alternatives.",[15,102829,102830,102840,102903,102946],{"language":87455},[18,102831,102833,102834,102836,102837,1685],{"id":102832},"q8-a-class-needs-to-reference-its-own-type-in-a-method-signature-before-the-class-body-finishes-executing-which-approach-avoids-a-nameerror-at-class-definition-time-on-python-versions-before-310-without-from-__future__-import-annotations","Q8. A class needs to reference its own type in a method signature before the class body finishes executing. Which approach avoids a ",[39,102835,87958],{}," at class-definition time on Python versions before 3.10 without ",[39,102838,102839],{},"from __future__ import annotations",[257,102841,102842],{"language":87455},[260,102843,102845],{"className":87467,"code":102844,"language":87455,"meta":264,"style":264},"class Node:\n    def __init__(self, value: int) -> None:\n        self.value = value\n        self.next: \"Node\" | None = None\n",[39,102846,102847,102856,102873,102884],{"__ignoreMap":264},[268,102848,102849,102851,102854],{"class":270,"line":271},[268,102850,1468],{"class":274},[268,102852,102853],{"class":278}," Node",[268,102855,8931],{"class":282},[268,102857,102858,102860,102862,102865,102867,102869,102871],{"class":270,"line":286},[268,102859,92933],{"class":274},[268,102861,92936],{"class":305},[268,102863,102864],{"class":282},"(self, value: ",[268,102866,87646],{"class":305},[268,102868,101908],{"class":282},[268,102870,90944],{"class":305},[268,102872,8931],{"class":282},[268,102874,102875,102877,102879,102881],{"class":270,"line":296},[268,102876,92944],{"class":305},[268,102878,100701],{"class":282},[268,102880,302],{"class":274},[268,102882,102883],{"class":282}," value\n",[268,102885,102886,102888,102891,102894,102897,102899,102901],{"class":270,"line":311},[268,102887,92944],{"class":305},[268,102889,102890],{"class":282},".next: ",[268,102892,102893],{"class":289},"\"Node\"",[268,102895,102896],{"class":274}," |",[268,102898,90962],{"class":305},[268,102900,616],{"class":274},[268,102902,91331],{"class":305},[23,102904,102906,102915,102928,102937],{"className":102905},[26],[28,102907,102909,102911,102912,102914],{"className":102908},[31],[33,102910],{"disabled":35,"type":36}," It will always raise ",[39,102913,87958],{}," regardless of quoting",[28,102916,102918,102920,102921,102923,102924,102927],{"className":102917},[31],[33,102919],{"disabled":35,"type":36}," Quoting the type as a string forward reference (",[39,102922,102893],{},") defers evaluation so it works even though ",[39,102925,102926],{},"Node"," isn't fully defined yet",[28,102929,102931,102933,102934,102936],{"className":102930},[31],[33,102932],{"disabled":35,"type":36}," You must define ",[39,102935,102926],{}," twice — once as a stub, once for real",[28,102938,102940,102942,102943,102945],{"className":102939},[31],[33,102941],{"disabled":35,"type":36}," Forward references only work inside ",[39,102944,98675],{}," classes",[66,102947,102948,102950,102959],{},[69,102949,71],{},[73,102951,102952,102954,102955,102923,102957,102927],{},[76,102953,78],{}," B — Quoting the type as a string forward reference (",[39,102956,102893],{},[39,102958,102926],{},[73,102960,102961,355,102963,102965,102966,102968,102969,102972],{},[76,102962,84],{},[76,102964,365],{}," Annotations are normally evaluated at function-definition time by default in older Python, so referencing the enclosing class by name before its ",[39,102967,1468],{}," statement completes would fail. Wrapping the reference in quotes makes it a forward reference — a string that a type checker parses lazily instead of the interpreter evaluating it immediately. Note the snippet mixes syntaxes for illustration (the ",[39,102970,102971],{},"\"Node\" | None"," union-with-string form needs care), but the core mechanism being tested is that string annotations sidestep the ordering problem, unlike option A's assumption that it always fails.",[15,102974,102975,102983,103051,103087],{"language":87455},[18,102976,102978,102979,102982],{"id":102977},"q9-why-would-a-codebase-use-if-type_checking-around-an-import","Q9. Why would a codebase use ",[39,102980,102981],{},"if TYPE_CHECKING:"," around an import?",[257,102984,102985],{"language":87455},[260,102986,102988],{"className":87467,"code":102987,"language":87455,"meta":264,"style":264},"from typing import TYPE_CHECKING\n\nif TYPE_CHECKING:\n    from mymodule import HeavyClass\n\ndef process(item: \"HeavyClass\") -> None: ...\n",[39,102989,102990,103001,103005,103014,103027,103031],{"__ignoreMap":264},[268,102991,102992,102994,102996,102998],{"class":270,"line":271},[268,102993,44539],{"class":274},[268,102995,102047],{"class":282},[268,102997,662],{"class":274},[268,102999,103000],{"class":305}," TYPE_CHECKING\n",[268,103002,103003],{"class":270,"line":286},[268,103004,5033],{"emptyLinePlaceholder":35},[268,103006,103007,103009,103012],{"class":270,"line":296},[268,103008,2179],{"class":274},[268,103010,103011],{"class":305}," TYPE_CHECKING",[268,103013,8931],{"class":282},[268,103015,103016,103019,103022,103024],{"class":270,"line":311},[268,103017,103018],{"class":274},"    from",[268,103020,103021],{"class":282}," mymodule ",[268,103023,662],{"class":274},[268,103025,103026],{"class":282}," HeavyClass\n",[268,103028,103029],{"class":270,"line":788},[268,103030,5033],{"emptyLinePlaceholder":35},[268,103032,103033,103035,103037,103040,103043,103045,103047,103049],{"class":270,"line":1951},[268,103034,88976],{"class":274},[268,103036,10851],{"class":278},[268,103038,103039],{"class":282},"(item: ",[268,103041,103042],{"class":289},"\"HeavyClass\"",[268,103044,101908],{"class":282},[268,103046,90944],{"class":305},[268,103048,1783],{"class":282},[268,103050,102077],{"class":305},[23,103052,103054,103060,103071,103081],{"className":103053},[26],[28,103055,103057,103059],{"className":103056},[31],[33,103058],{"disabled":35,"type":36}," To make the import faster by caching it",[28,103061,103063,355,103065,4453,103068,103070],{"className":103062},[31],[33,103064],{"disabled":35,"type":36},[39,103066,103067],{},"TYPE_CHECKING",[39,103069,89285],{},", so this is identical to a normal import",[28,103072,103074,355,103076,830,103078,103080],{"className":103073},[31],[33,103075],{"disabled":35,"type":36},[39,103077,103067],{},[39,103079,88449],{}," at runtime, so the import (which might cause a circular import or unnecessary runtime cost) is skipped when the program actually executes, while static checkers still see it and validate the annotation",[28,103082,103084,103086],{"className":103083},[31],[33,103085],{"disabled":35,"type":36}," It silences all mypy errors in the module",[66,103088,103089,103091,103100],{},[69,103090,71],{},[73,103092,103093,1004,103095,830,103097,103099],{},[76,103094,78],{},[39,103096,103067],{},[39,103098,88449],{}," at runtime, so the import is skipped when the program executes, while static checkers still see it and validate the annotation",[73,103101,103102,355,103104,830,103107,103109,103110,103112,103113,103115],{},[76,103103,84],{},[39,103105,103106],{},"typing.TYPE_CHECKING",[39,103108,88449],{}," during normal interpretation and treated as ",[39,103111,89285],{}," by static analyzers like mypy. This lets you import a class purely for annotation purposes — avoiding a circular import or a heavy\u002Foptional dependency at runtime — while the checker still resolves the forward-referenced type string. Assuming it's always ",[39,103114,89285],{}," (option B) would mean the import always executes, defeating the entire purpose of the pattern.",[15,103117,103118,103126,103198,103248],{"language":87455},[18,103119,103121,103122,103125],{"id":103120},"q10-what-does-userid-newtypeuserid-int-actually-produce-at-runtime","Q10. What does ",[39,103123,103124],{},"UserId = NewType(\"UserId\", int)"," actually produce at runtime?",[257,103127,103128],{"language":87455},[260,103129,103131],{"className":87467,"code":103130,"language":87455,"meta":264,"style":264},"from typing import NewType\n\nUserId = NewType(\"UserId\", int)\nuid = UserId(42)\nprint(type(uid), uid + 1)\n",[39,103132,103133,103144,103148,103167,103181],{"__ignoreMap":264},[268,103134,103135,103137,103139,103141],{"class":270,"line":271},[268,103136,44539],{"class":274},[268,103138,102047],{"class":282},[268,103140,662],{"class":274},[268,103142,103143],{"class":282}," NewType\n",[268,103145,103146],{"class":270,"line":286},[268,103147,5033],{"emptyLinePlaceholder":35},[268,103149,103150,103153,103155,103158,103161,103163,103165],{"class":270,"line":296},[268,103151,103152],{"class":282},"UserId ",[268,103154,302],{"class":274},[268,103156,103157],{"class":282}," NewType(",[268,103159,103160],{"class":289},"\"UserId\"",[268,103162,42],{"class":282},[268,103164,87646],{"class":305},[268,103166,20702],{"class":282},[268,103168,103169,103172,103174,103177,103179],{"class":270,"line":311},[268,103170,103171],{"class":282},"uid ",[268,103173,302],{"class":274},[268,103175,103176],{"class":282}," UserId(",[268,103178,4659],{"class":305},[268,103180,20702],{"class":282},[268,103182,103183,103185,103187,103189,103192,103194,103196],{"class":270,"line":788},[268,103184,84797],{"class":305},[268,103186,622],{"class":282},[268,103188,8623],{"class":305},[268,103190,103191],{"class":282},"(uid), uid ",[268,103193,1246],{"class":274},[268,103195,2199],{"class":305},[268,103197,20702],{"class":282},[23,103199,103201,103213,103228,103239],{"className":103200},[26],[28,103202,103204,103206,103207,2029,103209,103212],{"className":103203},[31],[33,103205],{"disabled":35,"type":36}," A new subclass of ",[39,103208,87646],{},[39,103210,103211],{},"UserId"," as its runtime type",[28,103214,103216,103218,103219,830,103222,137,103224,103227],{"className":103215},[31],[33,103217],{"disabled":35,"type":36}," A callable that at runtime just returns its argument unchanged — ",[39,103220,103221],{},"type(uid)",[39,103223,87646],{},[39,103225,103226],{},"uid + 1"," works as plain int arithmetic; the distinctness only exists for static checkers",[28,103229,103231,812,103233,2833,103235,103238],{"className":103230},[31],[33,103232],{"disabled":35,"type":36},[39,103234,827],{},[39,103236,103237],{},"NewType"," requires a class, not a builtin",[28,103240,103242,103244,103245,35800],{"className":103241},[31],[33,103243],{"disabled":35,"type":36}," A dataclass wrapping the int with a ",[39,103246,103247],{},".value",[66,103249,103250,103252,103257],{},[69,103251,71],{},[73,103253,103254,103256],{},[76,103255,78],{}," B — A callable that at runtime just returns its argument unchanged; the distinctness only exists for static checkers",[73,103258,103259,355,103261,355,103263,103265,103266,103269,103270,137,103272,64333,103274,103277,103278,103280,103281,103283,103284,103286,103287,103289,103290,103292,103293,103295,103296,462],{},[76,103260,84],{},[76,103262,930],{},[39,103264,103237],{}," creates a lightweight identity function at runtime — calling ",[39,103267,103268],{},"UserId(42)"," just returns ",[39,103271,4659],{},[39,103273,103221],{},[39,103275,103276],{},"\u003Cclass 'int'>",", not some special ",[39,103279,103211],{}," type. Its entire purpose is to let a static checker treat ",[39,103282,103211],{}," and plain ",[39,103285,87646],{}," as distinct (so you can't accidentally pass a raw ",[39,103288,87646],{}," where a ",[39,103291,103211],{}," is expected) without any runtime wrapping cost. Believing it creates a real subclass (option A) is the most common misunderstanding — that's what subclassing ",[39,103294,87646],{}," directly would do, not ",[39,103297,103237],{},[15,103299,103300,103308,103399,103457],{"language":87455},[18,103301,103303,103304,103307],{"id":103302},"q11-what-runtime-guarantee-does-a-typeddict-provide","Q11. What runtime guarantee does a ",[39,103305,103306],{},"TypedDict"," provide?",[257,103309,103310],{"language":87455},[260,103311,103313],{"className":87467,"code":103312,"language":87455,"meta":264,"style":264},"from typing import TypedDict\n\nclass Movie(TypedDict):\n    title: str\n    year: int\n\nm: Movie = {\"title\": \"Arrival\", \"year\": \"2016\"}\nprint(m)\n",[39,103314,103315,103326,103330,103343,103351,103359,103363,103392],{"__ignoreMap":264},[268,103316,103317,103319,103321,103323],{"class":270,"line":271},[268,103318,44539],{"class":274},[268,103320,102047],{"class":282},[268,103322,662],{"class":274},[268,103324,103325],{"class":282}," TypedDict\n",[268,103327,103328],{"class":270,"line":286},[268,103329,5033],{"emptyLinePlaceholder":35},[268,103331,103332,103334,103337,103339,103341],{"class":270,"line":296},[268,103333,1468],{"class":274},[268,103335,103336],{"class":278}," Movie",[268,103338,622],{"class":282},[268,103340,103306],{"class":278},[268,103342,94690],{"class":282},[268,103344,103345,103348],{"class":270,"line":311},[268,103346,103347],{"class":282},"    title: ",[268,103349,103350],{"class":305},"str\n",[268,103352,103353,103356],{"class":270,"line":788},[268,103354,103355],{"class":282},"    year: ",[268,103357,103358],{"class":305},"int\n",[268,103360,103361],{"class":270,"line":1951},[268,103362,5033],{"emptyLinePlaceholder":35},[268,103364,103365,103368,103370,103372,103375,103377,103380,103382,103385,103387,103390],{"class":270,"line":8955},[268,103366,103367],{"class":282},"m: Movie ",[268,103369,302],{"class":274},[268,103371,85460],{"class":282},[268,103373,103374],{"class":289},"\"title\"",[268,103376,1783],{"class":282},[268,103378,103379],{"class":289},"\"Arrival\"",[268,103381,42],{"class":282},[268,103383,103384],{"class":289},"\"year\"",[268,103386,1783],{"class":282},[268,103388,103389],{"class":289},"\"2016\"",[268,103391,314],{"class":282},[268,103393,103394,103396],{"class":270,"line":8966},[268,103395,84797],{"class":305},[268,103397,103398],{"class":282},"(m)\n",[23,103400,103402,103420,103434,103447],{"className":103401},[26],[28,103403,103405,103407,103408,103410,103411,2464,103413,103416,103417,103419],{"className":103404},[31],[33,103406],{"disabled":35,"type":36}," None — at runtime ",[39,103409,98399],{}," is a plain ",[39,103412,89385],{},[39,103414,103415],{},"\"year\": \"2016\""," string instead of ",[39,103418,87646],{}," will not raise anything, and this only shows up as an error under a static checker",[28,103421,103423,812,103425,103427,103428,103431,103432],{"className":103422},[31],[33,103424],{"disabled":35,"type":36},[39,103426,827],{}," is raised immediately because ",[39,103429,103430],{},"year"," should be an ",[39,103433,87646],{},[28,103435,103437,355,103439,103441,103442,5425,103444],{"className":103436},[31],[33,103438],{"disabled":35,"type":36},[39,103440,103306],{}," automatically coerces ",[39,103443,103389],{},[39,103445,103446],{},"2016",[28,103448,103450,103452,103453,103456],{"className":103449},[31],[33,103451],{"disabled":35,"type":36}," Missing required keys raise a ",[39,103454,103455],{},"KeyError"," at construction time",[66,103458,103459,103461,103471],{},[69,103460,71],{},[73,103462,103463,103465,103466,103410,103468,103470],{},[76,103464,78],{}," A — None — at runtime ",[39,103467,98399],{},[39,103469,89385],{},"; the string year does not raise, and only a static checker flags it",[73,103472,103473,355,103475,103477,103478,103480,103481,103484,103485,103487,103488,7507,103490,103492,103493,103495,103496,462],{},[76,103474,84],{},[39,103476,103306],{}," exists purely to give static checkers shape information about a ",[39,103479,89385],{},"'s expected keys and value types; at runtime, ",[39,103482,103483],{},"Movie"," instances are ordinary ",[39,103486,89385],{}," objects with zero validation, coercion, or enforcement. Both the type mismatch (",[39,103489,103389],{},[39,103491,87646],{},") and even a missing required key would run without error — only tools like mypy catch them. For actual runtime validation, you'd reach for something like ",[39,103494,102026],{}," or manual checks, not ",[39,103497,103306],{},[15,103499,103500,103508,103604,103646],{"language":87455},[18,103501,103503,103504,103507],{"id":103502},"q12-what-happens-if-you-call-a-function-decorated-with-multiple-overload-signatures-using-arguments-that-dont-match-any-of-the-declared-overloads-when-running-the-actual-script-not-a-type-checker","Q12. What happens if you call a function decorated with multiple ",[39,103505,103506],{},"@overload"," signatures using arguments that don't match any of the declared overloads, when running the actual script (not a type checker)?",[257,103509,103510],{"language":87455},[260,103511,103513],{"className":87467,"code":103512,"language":87455,"meta":264,"style":264},"from typing import overload\n\n@overload\ndef process(x: int) -> int: ...\n@overload\ndef process(x: str) -> str: ...\ndef process(x):\n    return x\n\nprocess(3.14)\n",[39,103514,103515,103526,103530,103535,103553,103557,103575,103584,103590,103594],{"__ignoreMap":264},[268,103516,103517,103519,103521,103523],{"class":270,"line":271},[268,103518,44539],{"class":274},[268,103520,102047],{"class":282},[268,103522,662],{"class":274},[268,103524,103525],{"class":282}," overload\n",[268,103527,103528],{"class":270,"line":286},[268,103529,5033],{"emptyLinePlaceholder":35},[268,103531,103532],{"class":270,"line":296},[268,103533,103534],{"class":278},"@overload\n",[268,103536,103537,103539,103541,103543,103545,103547,103549,103551],{"class":270,"line":311},[268,103538,88976],{"class":274},[268,103540,10851],{"class":278},[268,103542,102249],{"class":282},[268,103544,87646],{"class":305},[268,103546,101908],{"class":282},[268,103548,87646],{"class":305},[268,103550,1783],{"class":282},[268,103552,102077],{"class":305},[268,103554,103555],{"class":270,"line":788},[268,103556,103534],{"class":278},[268,103558,103559,103561,103563,103565,103567,103569,103571,103573],{"class":270,"line":1951},[268,103560,88976],{"class":274},[268,103562,10851],{"class":278},[268,103564,102249],{"class":282},[268,103566,17109],{"class":305},[268,103568,101908],{"class":282},[268,103570,17109],{"class":305},[268,103572,1783],{"class":282},[268,103574,102077],{"class":305},[268,103576,103577,103579,103581],{"class":270,"line":8955},[268,103578,88976],{"class":274},[268,103580,10851],{"class":278},[268,103582,103583],{"class":282},"(x):\n",[268,103585,103586,103588],{"class":270,"line":8966},[268,103587,9871],{"class":274},[268,103589,93160],{"class":282},[268,103591,103592],{"class":270,"line":8974},[268,103593,5033],{"emptyLinePlaceholder":35},[268,103595,103596,103599,103602],{"class":270,"line":8985},[268,103597,103598],{"class":282},"process(",[268,103600,103601],{"class":305},"3.14",[268,103603,20702],{"class":282},[23,103605,103607,103617,103629,103638],{"className":103606},[26],[28,103608,103610,91837,103612,73433,103614,103616],{"className":103609},[31],[33,103611],{"disabled":35,"type":36},[39,103613,827],{},[39,103615,87642],{}," matches no overload",[28,103618,103620,103622,103623,103625,103626,103628],{"className":103619},[31],[33,103621],{"disabled":35,"type":36}," Runs fine at runtime — only the final, un-decorated implementation actually executes, and ",[39,103624,103506],{}," stubs are ignored by the interpreter; only a static checker would flag the ",[39,103627,87642],{}," argument as invalid",[28,103630,103632,103634,103635,103637],{"className":103631},[31],[33,103633],{"disabled":35,"type":36}," Silently returns ",[39,103636,90944],{}," because no overload matched",[28,103639,103641,4396,103643,103645],{"className":103640},[31],[33,103642],{"disabled":35,"type":36},[39,103644,103506],{}," decorator dispatches to the closest matching stub automatically",[66,103647,103648,103650,103658],{},[69,103649,71],{},[73,103651,103652,103654,103655,103657],{},[76,103653,78],{}," B — Runs fine at runtime; ",[39,103656,103506],{}," stubs are ignored by the interpreter and only the real implementation executes",[73,103659,103660,355,103662,355,103664,103666,103667,103669,103670,103673,103674,103676,103677,103269,103680,103682],{},[76,103661,84],{},[76,103663,365],{},[39,103665,103506],{},"-decorated stub bodies (the ",[39,103668,15329],{}," ones) are never actually called — Python discards them, and only the final non-decorated ",[39,103671,103672],{},"process(x): return x"," implementation runs. ",[39,103675,103506],{}," exists solely so a static checker can offer precise per-signature type checking and autocompletion; there is no runtime dispatch mechanism at all (option D is a common false assumption — Python has no built-in multiple dispatch). Since the concrete implementation accepts anything, ",[39,103678,103679],{},"process(3.14)",[39,103681,103601],{}," with no error.",[15,103684,103685,103697,103736],{},[18,103686,103688,103689,103692,103693,103696],{"id":103687},"q13-a-function-is-annotated-def-get_ids-listint-but-its-body-is-return-is-this-a-problem-at-runtime","Q13. A function is annotated ",[39,103690,103691],{},"def get_ids() -> list[int]:"," but its body is ",[39,103694,103695],{},"return []",". Is this a problem at runtime?",[23,103698,103700,103712,103721,103727],{"className":103699},[26],[28,103701,103703,103705,103706,103708,103709,103711],{"className":103702},[31],[33,103704],{"disabled":35,"type":36}," Yes — an empty list can never satisfy ",[39,103707,102499],{},", so this raises ",[39,103710,827],{}," on return",[28,103713,103715,103717,103718,103720],{"className":103714},[31],[33,103716],{"disabled":35,"type":36}," No — an empty list contains no elements to contradict ",[39,103719,87646],{},", and since hints aren't enforced at runtime anyway, this runs without any error regardless",[28,103722,103724,103726],{"className":103723},[31],[33,103725],{"disabled":35,"type":36}," Yes, but only in Python 3.12+",[28,103728,103730,103732,103733],{"className":103729},[31],[33,103731],{"disabled":35,"type":36}," No, but it silently converts to ",[39,103734,103735],{},"[0]",[66,103737,103738,103740,103745],{},[69,103739,71],{},[73,103741,103742,103744],{},[76,103743,78],{}," B — No; an empty list vacuously satisfies the hint, and runtime never checks it anyway",[73,103746,103747,103749,103750,103752,103753,103756],{},[76,103748,84],{}," Two separate reasons both point to \"no error\": logically, ",[39,103751,102499],{}," is satisfied vacuously by an empty list since there's no element violating the constraint, and practically, CPython never inspects the return annotation at runtime regardless. Even returning ",[39,103754,103755],{},"[\"not\", \"an\", \"int\"]"," from this function would run without any exception — the mismatch would only surface as a static type error under mypy.",[15,103758,103759,103767,103825,103880],{"language":87455},[18,103760,103762,103763,103766],{"id":103761},"q14-what-is-the-correct-type-hint-safe-way-to-give-a-dataclass-field-a-mutable-default-value","Q14. What is the correct, type-hint-safe way to give a ",[39,103764,103765],{},"dataclass"," field a mutable default value?",[257,103768,103769],{"language":87455},[260,103770,103772],{"className":87467,"code":103771,"language":87455,"meta":264,"style":264},"from dataclasses import dataclass, field\n\n@dataclass\nclass Config:\n    tags: list[str] = field(default_factory=list)\n",[39,103773,103774,103786,103790,103795,103803],{"__ignoreMap":264},[268,103775,103776,103778,103781,103783],{"class":270,"line":271},[268,103777,44539],{"class":274},[268,103779,103780],{"class":282}," dataclasses ",[268,103782,662],{"class":274},[268,103784,103785],{"class":282}," dataclass, field\n",[268,103787,103788],{"class":270,"line":286},[268,103789,5033],{"emptyLinePlaceholder":35},[268,103791,103792],{"class":270,"line":296},[268,103793,103794],{"class":278},"@dataclass\n",[268,103796,103797,103799,103801],{"class":270,"line":311},[268,103798,1468],{"class":274},[268,103800,97944],{"class":278},[268,103802,8931],{"class":282},[268,103804,103805,103808,103810,103812,103814,103817,103819,103821,103823],{"class":270,"line":788},[268,103806,103807],{"class":282},"    tags: list[",[268,103809,17109],{"class":305},[268,103811,19897],{"class":282},[268,103813,302],{"class":274},[268,103815,103816],{"class":282}," field(",[268,103818,98730],{"class":1222},[268,103820,302],{"class":274},[268,103822,14924],{"class":305},[268,103824,20702],{"class":282},[23,103826,103828,103837,103857,103871],{"className":103827},[26],[28,103829,103831,355,103833,103836],{"className":103830},[31],[33,103832],{"disabled":35,"type":36},[39,103834,103835],{},"tags: list[str] = []"," — dataclasses handle mutable defaults safely, unlike plain functions",[28,103838,103840,103842,103843,103846,103847,103850,103851,103853,103854,103856],{"className":103839},[31],[33,103841],{"disabled":35,"type":36}," The shown ",[39,103844,103845],{},"field(default_factory=list)"," form — a bare mutable literal default (",[39,103848,103849],{},"= []",") raises ",[39,103852,91360],{}," at class-definition time, and ",[39,103855,98730],{}," calls the factory fresh for each new instance",[28,103858,103860,355,103862,103865,103866,2018,103868],{"className":103859},[31],[33,103861],{"disabled":35,"type":36},[39,103863,103864],{},"tags: list[str] = None"," and check for ",[39,103867,90944],{},[39,103869,103870],{},"__post_init__",[28,103872,103874,355,103876,103879],{"className":103873},[31],[33,103875],{"disabled":35,"type":36},[39,103877,103878],{},"tags: List[str] = list"," without calling it",[66,103881,103882,103884,103897],{},[69,103883,71],{},[73,103885,103886,1727,103888,103890,103891,103893,103894,103896],{},[76,103887,78],{},[39,103889,103845],{},"; a bare ",[39,103892,103849],{}," default raises ",[39,103895,91360],{}," at class-definition time",[73,103898,103899,355,103901,355,103903,103905,103906,42,103908,42,103910,103912,103913,103916,103917,103919,103920,103923],{},[76,103900,84],{},[76,103902,582],{},[39,103904,98675],{}," explicitly detects a mutable literal default (",[39,103907,14924],{},[39,103909,89385],{},[39,103911,37910],{},") for a field and raises ",[39,103914,103915],{},"ValueError: mutable default \u003Cclass 'list'> for field tags is not allowed"," at class-definition time — dataclasses deliberately guard against the classic Python mutable-default-argument footgun rather than silently sharing one list across instances. ",[39,103918,103845],{}," tells it to call ",[39,103921,103922],{},"list()"," fresh per instance instead. Option A is the tempting mistake because dataclasses look like they might \"fix\" the mutable-default problem automatically — they instead refuse to let you make it.",[15,103925,103926,103937,103993,104044],{"language":87455},[18,103927,7723,103929,103932,103933,103936],{"id":103928},"q15-what-is-the-idiomatic-reason-to-prefer-optionalstr-none-over-just-writing-str-none-for-a-parameter-default",[39,103930,103931],{},"Optional[str] = None"," over just writing ",[39,103934,103935],{},"str = None"," for a parameter default?",[257,103938,103939],{"language":87455},[260,103940,103942],{"className":87467,"code":103941,"language":87455,"meta":264,"style":264},"def greet(name: str = None) -> None: ...\ndef greet2(name: Optional[str] = None) -> None: ...\n",[39,103943,103944,103967],{"__ignoreMap":264},[268,103945,103946,103948,103950,103953,103955,103957,103959,103961,103963,103965],{"class":270,"line":271},[268,103947,88976],{"class":274},[268,103949,3679],{"class":278},[268,103951,103952],{"class":282},"(name: ",[268,103954,17109],{"class":305},[268,103956,616],{"class":274},[268,103958,90962],{"class":305},[268,103960,101908],{"class":282},[268,103962,90944],{"class":305},[268,103964,1783],{"class":282},[268,103966,102077],{"class":305},[268,103968,103969,103971,103974,103977,103979,103981,103983,103985,103987,103989,103991],{"class":270,"line":286},[268,103970,88976],{"class":274},[268,103972,103973],{"class":278}," greet2",[268,103975,103976],{"class":282},"(name: Optional[",[268,103978,17109],{"class":305},[268,103980,19897],{"class":282},[268,103982,302],{"class":274},[268,103984,90962],{"class":305},[268,103986,101908],{"class":282},[268,103988,90944],{"class":305},[268,103990,1783],{"class":282},[268,103992,102077],{"class":305},[23,103994,103996,104005,104026,104036],{"className":103995},[26],[28,103997,103999,355,104001,358,104003],{"className":103998},[31],[33,104000],{"disabled":35,"type":36},[39,104002,103935],{},[39,104004,1274],{},[28,104006,104008,104010,104011,104013,104014,104016,104017,104019,104020,104022,104023,104025],{"className":104007},[31],[33,104009],{"disabled":35,"type":36}," They behave identically at runtime, but ",[39,104012,103935],{}," is a lie to static checkers — ",[39,104015,90944],{}," isn't a ",[39,104018,17109],{},", so mypy flags it, while ",[39,104021,103931],{}," accurately documents that ",[39,104024,90944],{}," is a valid value",[28,104027,104029,355,104031,104033,104034,5302],{"className":104028},[31],[33,104030],{"disabled":35,"type":36},[39,104032,102113],{}," makes the parameter itself optional to omit, while ",[39,104035,103935],{},[28,104037,104039,355,104041,104043],{"className":104038},[31],[33,104040],{"disabled":35,"type":36},[39,104042,103931],{}," is slower because it wraps the value in a union object at call time",[66,104045,104046,104048,104062],{},[69,104047,71],{},[73,104049,104050,104052,104053,104055,104056,104058,104059,104061],{},[76,104051,78],{}," B — They behave identically at runtime; ",[39,104054,103935],{}," is inaccurate to static checkers, while ",[39,104057,102113],{}," documents that ",[39,104060,90944],{}," is valid",[73,104063,104064,355,104066,104068,104069,104072,104073,104075,104076,104078,104079,104081,104082,99,104084,104086,104087,104089,104090,104092],{},[76,104065,84],{},[76,104067,930],{}," Both run identically since CPython ignores hints, but a strict type checker treats ",[39,104070,104071],{},"name: str = None"," as an error because ",[39,104074,90944],{}," is not a ",[39,104077,17109],{}," and the annotation says nothing about it being optional. ",[39,104080,102113],{}," correctly communicates \"this can be a ",[39,104083,17109],{},[39,104085,90944],{},"\" to both the checker and human readers. Runtime \"optionality\" (whether you can omit the argument) comes purely from the ",[39,104088,102179],{}," default, not from ",[39,104091,102175],{}," — that's a separate, commonly conflated concept (option C).",[15,104094,104095,104107,104182,104234],{"language":87455},[18,104096,104098,104099,104102,104103,104106],{"id":104097},"q16-when-should-you-prefer-typingprotocol-over-an-abstract-base-class-abcabc-for-defining-an-interface","Q16. When should you prefer ",[39,104100,104101],{},"typing.Protocol"," over an abstract base class (",[39,104104,104105],{},"abc.ABC",") for defining an interface?",[257,104108,104109],{"language":87455},[260,104110,104112],{"className":87467,"code":104111,"language":87455,"meta":264,"style":264},"from typing import Protocol\n\nclass SupportsClose(Protocol):\n    def close(self) -> None: ...\n\ndef cleanup(resource: SupportsClose) -> None:\n    resource.close()\n",[39,104113,104114,104125,104129,104143,104159,104163,104177],{"__ignoreMap":264},[268,104115,104116,104118,104120,104122],{"class":270,"line":271},[268,104117,44539],{"class":274},[268,104119,102047],{"class":282},[268,104121,662],{"class":274},[268,104123,104124],{"class":282}," Protocol\n",[268,104126,104127],{"class":270,"line":286},[268,104128,5033],{"emptyLinePlaceholder":35},[268,104130,104131,104133,104136,104138,104141],{"class":270,"line":296},[268,104132,1468],{"class":274},[268,104134,104135],{"class":278}," SupportsClose",[268,104137,622],{"class":282},[268,104139,104140],{"class":278},"Protocol",[268,104142,94690],{"class":282},[268,104144,104145,104147,104150,104153,104155,104157],{"class":270,"line":311},[268,104146,92933],{"class":274},[268,104148,104149],{"class":278}," close",[268,104151,104152],{"class":282},"(self) -> ",[268,104154,90944],{"class":305},[268,104156,1783],{"class":282},[268,104158,102077],{"class":305},[268,104160,104161],{"class":270,"line":788},[268,104162,5033],{"emptyLinePlaceholder":35},[268,104164,104165,104167,104170,104173,104175],{"class":270,"line":1951},[268,104166,88976],{"class":274},[268,104168,104169],{"class":278}," cleanup",[268,104171,104172],{"class":282},"(resource: SupportsClose) -> ",[268,104174,90944],{"class":305},[268,104176,8931],{"class":282},[268,104178,104179],{"class":270,"line":8955},[268,104180,104181],{"class":282},"    resource.close()\n",[23,104183,104185,104196,104212,104226],{"className":104184},[26],[28,104186,104188,98872,104190,104192,104193],{"className":104187},[31],[33,104189],{"disabled":35,"type":36},[39,104191,104140],{}," is strictly worse and slower than ",[39,104194,104195],{},"ABC",[28,104197,104199,104201,104202,104205,104206,61987,104209,104211],{"className":104198},[31],[33,104200],{"disabled":35,"type":36}," When you want structural (\"duck\") typing — any object with a matching ",[39,104203,104204],{},"close()"," method satisfies the type statically without explicitly inheriting from ",[39,104207,104208],{},"SupportsClose",[39,104210,104195],{}," which requires nominal subclassing",[28,104213,104215,355,104217,104219,104220,104223,104224],{"className":104214},[31],[33,104216],{"disabled":35,"type":36},[39,104218,104140],{}," requires runtime registration via ",[39,104221,104222],{},"register()",", same as ",[39,104225,104195],{},[28,104227,104229,355,104231,104233],{"className":104228},[31],[33,104230],{"disabled":35,"type":36},[39,104232,104140],{}," can only be used for dataclasses",[66,104235,104236,104238,104248],{},[69,104237,71],{},[73,104239,104240,4409,104242,104244,104245,104247],{},[76,104241,78],{},[39,104243,104140],{}," for structural typing; any object with a matching method satisfies it without explicit inheritance, unlike ",[39,104246,104195],{},"'s nominal typing",[73,104249,104250,355,104252,355,104254,104256,104257,104259,104260,104263,104264,104266,104267,104269,104270,104272],{},[76,104251,84],{},[76,104253,930],{},[39,104255,104140],{}," implements structural subtyping (PEP 544) — a static checker considers any class that happens to implement the right methods\u002Fattributes as compatible, with zero inheritance relationship required. ",[39,104258,104195],{}," requires explicit ",[39,104261,104262],{},"class Foo(SupportsClose):"," nominal subclassing (or ",[39,104265,104222],{},") to be recognized. This makes ",[39,104268,104140],{}," a good fit for third-party classes you can't modify to add a base class, which is a common real-world constraint ",[39,104271,104195],{}," can't satisfy as cleanly.",[15,104274,104275,104283,104324,104360],{"language":87455},[18,104276,104278,104279,104282],{"id":104277},"q17-what-does-marking-a-variable-with-final-actually-do","Q17. What does marking a variable with ",[39,104280,104281],{},"Final"," actually do?",[257,104284,104285],{"language":87455},[260,104286,104288],{"className":87467,"code":104287,"language":87455,"meta":264,"style":264},"from typing import Final\n\nMAX_RETRIES: Final = 3\nMAX_RETRIES = 5\n",[39,104289,104290,104301,104305,104316],{"__ignoreMap":264},[268,104291,104292,104294,104296,104298],{"class":270,"line":271},[268,104293,44539],{"class":274},[268,104295,102047],{"class":282},[268,104297,662],{"class":274},[268,104299,104300],{"class":282}," Final\n",[268,104302,104303],{"class":270,"line":286},[268,104304,5033],{"emptyLinePlaceholder":35},[268,104306,104307,104309,104312,104314],{"class":270,"line":296},[268,104308,88532],{"class":305},[268,104310,104311],{"class":282},": Final ",[268,104313,302],{"class":274},[268,104315,86757],{"class":305},[268,104317,104318,104320,104322],{"class":270,"line":311},[268,104319,88532],{"class":305},[268,104321,616],{"class":274},[268,104323,85072],{"class":305},[23,104325,104327,104336,104346,104352],{"className":104326},[26],[28,104328,104330,104332,104333,104335],{"className":104329},[31],[33,104331],{"disabled":35,"type":36}," It raises ",[39,104334,827],{}," immediately on the reassignment line",[28,104337,104339,104341,104342,7083,104344],{"className":104338},[31],[33,104340],{"disabled":35,"type":36}," It is purely a static-analysis hint — mypy will flag the reassignment as an error, but CPython executes the second line without complaint and ",[39,104343,88532],{},[39,104345,2429],{},[28,104347,104349,104351],{"className":104348},[31],[33,104350],{"disabled":35,"type":36}," It makes the name read-only via the C-level immutability flag",[28,104353,104355,355,104357,104359],{"className":104354},[31],[33,104356],{"disabled":35,"type":36},[39,104358,104281],{}," only works inside classes, not at module level",[66,104361,104362,104364,104373],{},[69,104363,71],{},[73,104365,104366,104368,104369,7083,104371],{},[76,104367,78],{}," B — It's purely a static-analysis hint; CPython executes the reassignment fine and ",[39,104370,88532],{},[39,104372,2429],{},[73,104374,104375,355,104377,104379,104380,104382,104383,104385,104386,446,104388,104391],{},[76,104376,84],{},[76,104378,582],{}," Like all typing constructs, ",[39,104381,104281],{}," carries zero runtime enforcement — it tells a checker \"treat this as a constant; flag any rebinding,\" but the interpreter has no concept of a ",[39,104384,104281],{},"-protected name and simply rebinds it. Developers coming from languages with real ",[39,104387,243],{},[39,104389,104390],{},"final"," keywords (option C) often expect actual immutability enforcement, which Python's typing system deliberately does not provide — runtime constant-protection would need a different mechanism entirely (e.g., a custom descriptor or just convention).",[15,104393,104394,104402,104471,104529],{"language":87455},[18,104395,104397,104398,104401],{"id":104396},"q18-what-is-the-purpose-of-classvar-in-this-dataclass","Q18. What is the purpose of ",[39,104399,104400],{},"ClassVar"," in this dataclass?",[257,104403,104404],{"language":87455},[260,104405,104407],{"className":87467,"code":104406,"language":87455,"meta":264,"style":264},"from typing import ClassVar\nfrom dataclasses import dataclass\n\n@dataclass\nclass Counter:\n    count: int = 0\n    total_instances: ClassVar[int] = 0\n",[39,104408,104409,104420,104431,104435,104439,104447,104458],{"__ignoreMap":264},[268,104410,104411,104413,104415,104417],{"class":270,"line":271},[268,104412,44539],{"class":274},[268,104414,102047],{"class":282},[268,104416,662],{"class":274},[268,104418,104419],{"class":282}," ClassVar\n",[268,104421,104422,104424,104426,104428],{"class":270,"line":286},[268,104423,44539],{"class":274},[268,104425,103780],{"class":282},[268,104427,662],{"class":274},[268,104429,104430],{"class":282}," dataclass\n",[268,104432,104433],{"class":270,"line":296},[268,104434,5033],{"emptyLinePlaceholder":35},[268,104436,104437],{"class":270,"line":311},[268,104438,103794],{"class":278},[268,104440,104441,104443,104445],{"class":270,"line":788},[268,104442,1468],{"class":274},[268,104444,32656],{"class":278},[268,104446,8931],{"class":282},[268,104448,104449,104452,104454,104456],{"class":270,"line":1951},[268,104450,104451],{"class":282},"    count: ",[268,104453,87646],{"class":305},[268,104455,616],{"class":274},[268,104457,86318],{"class":305},[268,104459,104460,104463,104465,104467,104469],{"class":270,"line":8955},[268,104461,104462],{"class":282},"    total_instances: ClassVar[",[268,104464,87646],{"class":305},[268,104466,19897],{"class":282},[268,104468,302],{"class":274},[268,104470,86318],{"class":305},[23,104472,104474,104489,104509,104518],{"className":104473},[26],[28,104475,104477,104479,104480,104483,104484,104486,104487],{"className":104476},[31],[33,104478],{"disabled":35,"type":36}," It marks ",[39,104481,104482],{},"total_instances"," as a per-instance field with default ",[39,104485,3307],{},", identical to ",[39,104488,10191],{},[28,104490,104492,104494,104495,104497,104498,104500,104501,104503,104504,104506,104507,40843],{"className":104491},[31],[33,104493],{"disabled":35,"type":36}," It tells both static checkers and ",[39,104496,98675],{}," itself to treat ",[39,104499,104482],{}," as a class-level attribute, excluding it from the generated ",[39,104502,96610],{}," and instance fields — unlike ",[39,104505,10191],{},", which becomes a normal ",[39,104508,96610],{},[28,104510,104512,104514,104515,104517],{"className":104511},[31],[33,104513],{"disabled":35,"type":36}," It makes ",[39,104516,104482],{}," thread-safe automatically",[28,104519,104521,355,104523,104525,104526,104528],{"className":104520},[31],[33,104522],{"disabled":35,"type":36},[39,104524,104400],{}," has no effect on ",[39,104527,98675],{},"'s generated code; it's purely cosmetic",[66,104530,104531,104533,104544],{},[69,104532,71],{},[73,104534,104535,104537,104538,104540,104541,104543],{},[76,104536,78],{}," B — It marks ",[39,104539,104482],{}," as class-level, excluded from the generated ",[39,104542,96610],{}," and instance fields",[73,104545,104546,355,104548,355,104550,104552,104553,104555,104556,42,104558,137,104560,104562,104563,104566],{},[76,104547,84],{},[76,104549,930],{},[39,104551,98675],{}," specifically inspects annotations for ",[39,104554,104400],{}," and, unlike ordinary fields, excludes those attributes from the auto-generated ",[39,104557,96610],{},[39,104559,102344],{},[39,104561,89232],{}," — they remain shared class attributes, exactly like a normal class-body assignment without a dataclass. This is one of the few typing constructs that a real library (",[39,104564,104565],{},"dataclasses",") actually inspects at runtime rather than ignoring, which trips people up (option D) since most other hints genuinely are inert to runtime code.",[15,104568,104569,104577,104650,104712],{"language":87455},[18,104570,104572,104573,104576],{"id":104571},"q19-what-is-cast-for-and-what-does-it-do-at-runtime","Q19. What is ",[39,104574,104575],{},"cast()"," for, and what does it do at runtime?",[257,104578,104579],{"language":87455},[260,104580,104582],{"className":87467,"code":104581,"language":87455,"meta":264,"style":264},"from typing import cast\n\ndef get_config() -> dict:\n    ...\n\nraw = get_config()\nport = cast(int, raw[\"port\"])\n",[39,104583,104584,104595,104599,104613,104617,104621,104630],{"__ignoreMap":264},[268,104585,104586,104588,104590,104592],{"class":270,"line":271},[268,104587,44539],{"class":274},[268,104589,102047],{"class":282},[268,104591,662],{"class":274},[268,104593,104594],{"class":282}," cast\n",[268,104596,104597],{"class":270,"line":286},[268,104598,5033],{"emptyLinePlaceholder":35},[268,104600,104601,104603,104606,104609,104611],{"class":270,"line":296},[268,104602,88976],{"class":274},[268,104604,104605],{"class":278}," get_config",[268,104607,104608],{"class":282},"() -> ",[268,104610,89385],{"class":305},[268,104612,8931],{"class":282},[268,104614,104615],{"class":270,"line":311},[268,104616,90877],{"class":305},[268,104618,104619],{"class":270,"line":788},[268,104620,5033],{"emptyLinePlaceholder":35},[268,104622,104623,104625,104627],{"class":270,"line":1951},[268,104624,91282],{"class":282},[268,104626,302],{"class":274},[268,104628,104629],{"class":282}," get_config()\n",[268,104631,104632,104635,104637,104640,104642,104645,104648],{"class":270,"line":8955},[268,104633,104634],{"class":282},"port ",[268,104636,302],{"class":274},[268,104638,104639],{"class":282}," cast(",[268,104641,87646],{"class":305},[268,104643,104644],{"class":282},", raw[",[268,104646,104647],{"class":289},"\"port\"",[268,104649,85493],{"class":282},[23,104651,104653,104670,104684,104701],{"className":104652},[26],[28,104654,104656,355,104658,104661,104662,91268,104664,12714,104666,104669],{"className":104655},[31],[33,104657],{"disabled":35,"type":36},[39,104659,104660],{},"cast(int, x)"," converts ",[39,104663,2403],{},[39,104665,87646],{},[39,104667,104668],{},"int(x)",", and raises if conversion fails",[28,104671,104673,355,104675,104677,104678,104680,104681,104683],{"className":104672},[31],[33,104674],{"disabled":35,"type":36},[39,104676,104575],{}," is a pure no-op at runtime — it returns ",[39,104679,2403],{}," completely unchanged; it exists only to tell the static checker \"trust me, treat this expression as ",[39,104682,87646],{},"\" when the checker can't infer it itself",[28,104685,104687,355,104689,104691,104692,104694,104695,104697,104698,104700],{"className":104686},[31],[33,104688],{"disabled":35,"type":36},[39,104690,104575],{}," validates that ",[39,104693,2403],{}," is already an ",[39,104696,87646],{}," and raises ",[39,104699,827],{}," otherwise",[28,104702,104704,355,104706,104708,104709,104711],{"className":104703},[31],[33,104705],{"disabled":35,"type":36},[39,104707,104575],{}," deep-copies ",[39,104710,2403],{}," before returning it",[66,104713,104714,104716,104723],{},[69,104715,71],{},[73,104717,104718,1727,104720,104722],{},[76,104719,78],{},[39,104721,104575],{}," is a pure no-op at runtime; it only tells the static checker to treat the expression as the given type",[73,104724,104725,355,104727,355,104729,104732,104733,104736,104737,104739,104740,104743,104744,42,104747,104750,104751,104753,104754,104756,104757,104760],{},[76,104726,84],{},[76,104728,365],{},[39,104730,104731],{},"typing.cast(TypeHint, value)"," is implemented essentially as ",[39,104734,104735],{},"return value"," — it performs no conversion, no validation, nothing. It exists purely to override a static checker's inferred type when you know something the checker can't (e.g., after runtime validation it doesn't understand). Confusing it with ",[39,104738,104668],{}," (option A) is a common and dangerous mistake: if ",[39,104741,104742],{},"raw[\"port\"]"," is actually the string ",[39,104745,104746],{},"\"8080\"",[39,104748,104749],{},"cast(int, raw[\"port\"])"," happily returns the string unchanged, and a later arithmetic operation on ",[39,104752,14248],{}," will fail with a ",[39,104755,827],{}," far from where the real bug is — the correct fix is to actually convert\u002Fvalidate the value, e.g. ",[39,104758,104759],{},"port = int(raw[\"port\"])",", not just cast it.",[15,104762,104763,104777,104937,104990],{"language":87455},[18,104764,104766,104767,104769,104770,104773,104774,104776],{"id":104765},"q20-what-does-declaring-a-typevar-as-covariant-typevart_co-covarianttrue-enable-that-an-invariant-typevar-does-not","Q20. What does declaring a ",[39,104768,102472],{}," as covariant (",[39,104771,104772],{},"TypeVar(\"T_co\", covariant=True)",") enable that an invariant ",[39,104775,102472],{}," does not?",[257,104778,104779],{"language":87455},[260,104780,104782],{"className":87467,"code":104781,"language":87455,"meta":264,"style":264},"from typing import TypeVar, Generic\n\nT_co = TypeVar(\"T_co\", covariant=True)\n\nclass ReadOnlyBox(Generic[T_co]):\n    def __init__(self, item: T_co) -> None:\n        self._item = item\n    def get(self) -> T_co:\n        return self._item\n\ndef print_box(box: \"ReadOnlyBox[object]\") -> None:\n    print(box.get())\n\nint_box: ReadOnlyBox[int] = ReadOnlyBox(42)\nprint_box(int_box)\n",[39,104783,104784,104795,104799,104822,104826,104836,104849,104861,104871,104880,104884,104903,104910,104914,104932],{"__ignoreMap":264},[268,104785,104786,104788,104790,104792],{"class":270,"line":271},[268,104787,44539],{"class":274},[268,104789,102047],{"class":282},[268,104791,662],{"class":274},[268,104793,104794],{"class":282}," TypeVar, Generic\n",[268,104796,104797],{"class":270,"line":286},[268,104798,5033],{"emptyLinePlaceholder":35},[268,104800,104801,104804,104806,104808,104811,104813,104816,104818,104820],{"class":270,"line":296},[268,104802,104803],{"class":282},"T_co ",[268,104805,302],{"class":274},[268,104807,102402],{"class":282},[268,104809,104810],{"class":289},"\"T_co\"",[268,104812,42],{"class":282},[268,104814,104815],{"class":1222},"covariant",[268,104817,302],{"class":274},[268,104819,89285],{"class":305},[268,104821,20702],{"class":282},[268,104823,104824],{"class":270,"line":311},[268,104825,5033],{"emptyLinePlaceholder":35},[268,104827,104828,104830,104833],{"class":270,"line":788},[268,104829,1468],{"class":274},[268,104831,104832],{"class":278}," ReadOnlyBox",[268,104834,104835],{"class":282},"(Generic[T_co]):\n",[268,104837,104838,104840,104842,104845,104847],{"class":270,"line":1951},[268,104839,92933],{"class":274},[268,104841,92936],{"class":305},[268,104843,104844],{"class":282},"(self, item: T_co) -> ",[268,104846,90944],{"class":305},[268,104848,8931],{"class":282},[268,104850,104851,104853,104856,104858],{"class":270,"line":8955},[268,104852,92944],{"class":305},[268,104854,104855],{"class":282},"._item ",[268,104857,302],{"class":274},[268,104859,104860],{"class":282}," item\n",[268,104862,104863,104865,104868],{"class":270,"line":8966},[268,104864,92933],{"class":274},[268,104866,104867],{"class":278}," get",[268,104869,104870],{"class":282},"(self) -> T_co:\n",[268,104872,104873,104875,104877],{"class":270,"line":8974},[268,104874,11956],{"class":274},[268,104876,96472],{"class":305},[268,104878,104879],{"class":282},"._item\n",[268,104881,104882],{"class":270,"line":8985},[268,104883,5033],{"emptyLinePlaceholder":35},[268,104885,104886,104888,104891,104894,104897,104899,104901],{"class":270,"line":8990},[268,104887,88976],{"class":274},[268,104889,104890],{"class":278}," print_box",[268,104892,104893],{"class":282},"(box: ",[268,104895,104896],{"class":289},"\"ReadOnlyBox[object]\"",[268,104898,101908],{"class":282},[268,104900,90944],{"class":305},[268,104902,8931],{"class":282},[268,104904,104905,104907],{"class":270,"line":8997},[268,104906,92017],{"class":305},[268,104908,104909],{"class":282},"(box.get())\n",[268,104911,104912],{"class":270,"line":9002},[268,104913,5033],{"emptyLinePlaceholder":35},[268,104915,104916,104919,104921,104923,104925,104928,104930],{"class":270,"line":14676},[268,104917,104918],{"class":282},"int_box: ReadOnlyBox[",[268,104920,87646],{"class":305},[268,104922,19897],{"class":282},[268,104924,302],{"class":274},[268,104926,104927],{"class":282}," ReadOnlyBox(",[268,104929,4659],{"class":305},[268,104931,20702],{"class":282},[268,104933,104934],{"class":270,"line":14681},[268,104935,104936],{"class":282},"print_box(int_box)\n",[23,104938,104940,104946,104972,104982],{"className":104939},[26],[28,104941,104943,104945],{"className":104942},[31],[33,104944],{"disabled":35,"type":36}," Covariance has a runtime performance cost proportional to the number of subtypes",[28,104947,104949,104951,104952,104955,104956,104959,104960,104963,104964,91972,104966,104968,104969,104971],{"className":104948},[31],[33,104950],{"disabled":35,"type":36}," With a covariant ",[39,104953,104954],{},"T_co",", a static checker allows ",[39,104957,104958],{},"ReadOnlyBox[int]"," to be used wherever ",[39,104961,104962],{},"ReadOnlyBox[object]"," is expected (since ",[39,104965,87646],{},[39,104967,2664],{},"), matching the intuitive subtyping of read-only containers; an invariant ",[39,104970,102472],{}," would reject this assignment as a type error even though it works fine at runtime",[28,104973,104975,104977,104978,104981],{"className":104974},[31],[33,104976],{"disabled":35,"type":36}," Covariance lets you mutate ",[39,104979,104980],{},"_item"," to any type at runtime without restriction",[28,104983,104985,104987,104988],{"className":104984},[31],[33,104986],{"disabled":35,"type":36}," Covariant TypeVars are required for any class that uses ",[39,104989,96610],{},[66,104991,104992,104994,105005],{},[69,104993,71],{},[73,104995,104996,104998,104999,105001,105002,105004],{},[76,104997,78],{}," B — Covariance lets a static checker treat ",[39,105000,104958],{}," as compatible with ",[39,105003,104962],{},", matching real subtyping for read-only containers; invariant would reject it",[73,105006,105007,355,105009,105011,105012,105014,105015,186,105017,105019,105020,105022,105023,105025,105026,105028,105029,105031,105032,105035,105036,105038,105039,358,105042,105045,105046,105048,105049,7152,105052,105054],{},[76,105008,84],{},[76,105010,930],{}," By default, ",[39,105013,102472],{},"s are invariant — a checker treats ",[39,105016,104958],{},[39,105018,104962],{}," as unrelated types even though ",[39,105021,87646],{}," is an ",[39,105024,2664],{},". Marking ",[39,105027,104954],{}," covariant tells the checker it's safe to treat the relationship like the underlying type relationship ",[104,105030,10057],{}," the box is read-only (",[39,105033,105034],{},"get()"," only, never accepts a new ",[39,105037,104954],{}," from outside after construction) — this mirrors why ",[39,105040,105041],{},"Sequence[int]",[39,105043,105044],{},"Sequence[object]"," in typeshed but ",[39,105047,102499],{}," is intentionally not treated as a ",[39,105050,105051],{},"list[object]",[39,105053,14924],{}," is mutable and allows appending, which invariance protects against). None of this variance machinery has any runtime effect at all — it exists solely to make static checking of generic containers match real-world expectations.",[2107,105056,81839],{},{"title":264,"searchDepth":286,"depth":286,"links":105058},[105059,105060,105061,105063,105064,105066,105067,105069,105071,105073,105075,105077,105079,105081,105083,105085,105087,105089,105091,105093],{"id":101882,"depth":296,"text":101883},{"id":102032,"depth":296,"text":102033},{"id":102188,"depth":296,"text":105062},"Q3. What is the key practical difference between annotating a parameter as Any versus object?",{"id":102369,"depth":296,"text":102370},{"id":102558,"depth":296,"text":105065},"Q5. Which statement correctly describes how mypy relates to running your program?",{"id":102633,"depth":296,"text":102634},{"id":102733,"depth":296,"text":105068},"Q7. What does Callable[[int, str], bool] describe?",{"id":102832,"depth":296,"text":105070},"Q8. A class needs to reference its own type in a method signature before the class body finishes executing. Which approach avoids a NameError at class-definition time on Python versions before 3.10 without from __future__ import annotations?",{"id":102977,"depth":296,"text":105072},"Q9. Why would a codebase use if TYPE_CHECKING: around an import?",{"id":103120,"depth":296,"text":105074},"Q10. What does UserId = NewType(\"UserId\", int) actually produce at runtime?",{"id":103302,"depth":296,"text":105076},"Q11. What runtime guarantee does a TypedDict provide?",{"id":103502,"depth":296,"text":105078},"Q12. What happens if you call a function decorated with multiple @overload signatures using arguments that don't match any of the declared overloads, when running the actual script (not a type checker)?",{"id":103687,"depth":296,"text":105080},"Q13. A function is annotated def get_ids() -> list[int]: but its body is return []. Is this a problem at runtime?",{"id":103761,"depth":296,"text":105082},"Q14. What is the correct, type-hint-safe way to give a dataclass field a mutable default value?",{"id":103928,"depth":296,"text":105084},"Q15. What is the idiomatic reason to prefer Optional[str] = None over just writing str = None for a parameter default?",{"id":104097,"depth":296,"text":105086},"Q16. When should you prefer typing.Protocol over an abstract base class (abc.ABC) for defining an interface?",{"id":104277,"depth":296,"text":105088},"Q17. What does marking a variable with Final actually do?",{"id":104396,"depth":296,"text":105090},"Q18. What is the purpose of ClassVar in this dataclass?",{"id":104571,"depth":296,"text":105092},"Q19. What is cast() for, and what does it do at runtime?",{"id":104765,"depth":296,"text":105094},"Q20. What does declaring a TypeVar as covariant (TypeVar(\"T_co\", covariant=True)) enable that an invariant TypeVar does not?",{},"\u002Fpython\u002F20-type-hints-and-typing",{"title":101872,"description":264},"python\u002F20-type-hints-and-typing","HBIbjotG8WeO_IhzXo7xFEweB5xLy3y-mxqmaw5GP_4",{"id":105101,"title":105102,"body":105103,"description":264,"extension":2144,"meta":107959,"navigation":35,"path":107960,"seo":107961,"stem":107962,"__hash__":107963},"content\u002Fpython\u002F21-concurrency-threading-and-multiprocessing.md","21 — Concurrency: Threading & Multiprocessing",{"type":8,"value":105104,"toc":107928},[105105,105108,105263,105401,105615,105711,105782,106014,106177,106338,106565,106741,106952,107114,107286,107336,107532,107591,107769,107925],[11,105106,105102],{"id":105107},"_21-concurrency-threading-multiprocessing",[15,105109,105110,105114,105220,105247],{"language":87455},[18,105111,105113],{"id":105112},"q1-what-does-the-cpython-global-interpreter-lock-gil-actually-restrict","Q1. What does the CPython Global Interpreter Lock (GIL) actually restrict?",[257,105115,105116],{"language":87455},[260,105117,105119],{"className":87467,"code":105118,"language":87455,"meta":264,"style":264},"import threading\n\ndef cpu_heavy():\n    total = 0\n    for i in range(50_000_000):\n        total += i\n\nt1 = threading.Thread(target=cpu_heavy)\nt2 = threading.Thread(target=cpu_heavy)\nt1.start(); t2.start()\nt1.join(); t2.join()\n",[39,105120,105121,105128,105132,105141,105149,105166,105176,105180,105196,105210,105215],{"__ignoreMap":264},[268,105122,105123,105125],{"class":270,"line":271},[268,105124,662],{"class":274},[268,105126,105127],{"class":282}," threading\n",[268,105129,105130],{"class":270,"line":286},[268,105131,5033],{"emptyLinePlaceholder":35},[268,105133,105134,105136,105139],{"class":270,"line":296},[268,105135,88976],{"class":274},[268,105137,105138],{"class":278}," cpu_heavy",[268,105140,92012],{"class":282},[268,105142,105143,105145,105147],{"class":270,"line":311},[268,105144,86343],{"class":282},[268,105146,302],{"class":274},[268,105148,86318],{"class":305},[268,105150,105151,105153,105155,105157,105159,105161,105164],{"class":270,"line":788},[268,105152,80840],{"class":274},[268,105154,9384],{"class":282},[268,105156,20749],{"class":274},[268,105158,94683],{"class":305},[268,105160,622],{"class":282},[268,105162,105163],{"class":305},"50_000_000",[268,105165,94690],{"class":282},[268,105167,105168,105171,105173],{"class":270,"line":1951},[268,105169,105170],{"class":282},"        total ",[268,105172,14575],{"class":274},[268,105174,105175],{"class":282}," i\n",[268,105177,105178],{"class":270,"line":8955},[268,105179,5033],{"emptyLinePlaceholder":35},[268,105181,105182,105184,105186,105189,105191,105193],{"class":270,"line":8966},[268,105183,90301],{"class":282},[268,105185,302],{"class":274},[268,105187,105188],{"class":282}," threading.Thread(",[268,105190,65414],{"class":1222},[268,105192,302],{"class":274},[268,105194,105195],{"class":282},"cpu_heavy)\n",[268,105197,105198,105200,105202,105204,105206,105208],{"class":270,"line":8974},[268,105199,90311],{"class":282},[268,105201,302],{"class":274},[268,105203,105188],{"class":282},[268,105205,65414],{"class":1222},[268,105207,302],{"class":274},[268,105209,105195],{"class":282},[268,105211,105212],{"class":270,"line":8985},[268,105213,105214],{"class":282},"t1.start(); t2.start()\n",[268,105216,105217],{"class":270,"line":8990},[268,105218,105219],{"class":282},"t1.join(); t2.join()\n",[23,105221,105223,105229,105235,105241],{"className":105222},[26],[28,105224,105226,105228],{"className":105225},[31],[33,105227],{"disabled":35,"type":36}," It prevents more than one thread from existing in a process at all",[28,105230,105232,105234],{"className":105231},[31],[33,105233],{"disabled":35,"type":36}," It allows only one thread to execute Python bytecode at a time, so this two-thread CPU-bound loop runs no faster (often slightly slower) than doing the work in one thread sequentially",[28,105236,105238,105240],{"className":105237},[31],[33,105239],{"disabled":35,"type":36}," It only restricts I\u002FO operations, so this CPU-bound example runs fully in parallel",[28,105242,105244,105246],{"className":105243},[31],[33,105245],{"disabled":35,"type":36}," It was removed in Python 3.12, so this now runs on two cores",[66,105248,105249,105251,105256],{},[69,105250,71],{},[73,105252,105253,105255],{},[76,105254,78],{}," B — Only one thread executes Python bytecode at a time; this CPU-bound loop gets no real speedup from two threads",[73,105257,105258,355,105260,105262],{},[76,105259,84],{},[76,105261,438],{}," The GIL ensures only one OS thread runs Python bytecode at any instant, even on a multi-core machine. Threads still exist and get scheduled (option A is wrong), but for a pure-Python CPU-bound loop like this, the two threads take turns on a single core, so total wall-clock time is roughly the same as — or worse than, due to context-switch overhead — running both loops sequentially. As of the environment's cutoff, the GIL is still the default in mainline CPython 3.12; an optional free-threaded (\"no-GIL\") build exists as of 3.13 but is not the default, so option D's blanket claim is wrong for standard installs.",[15,105264,105265,105273,105345,105378],{"language":87455},[18,105266,105268,105269,105272],{"id":105267},"q2-for-which-of-these-workloads-does-threading-typically-give-a-real-measurable-speedup-in-cpython","Q2. For which of these workloads does ",[39,105270,105271],{},"threading"," typically give a real, measurable speedup in CPython?",[257,105274,105275],{"language":87455},[260,105276,105278],{"className":87467,"code":105277,"language":87455,"meta":264,"style":264},"import threading, requests\n\ndef fetch(url):\n    return requests.get(url).text\n\nthreads = [threading.Thread(target=fetch, args=(u,)) for u in urls]\n",[39,105279,105280,105287,105291,105300,105307,105311],{"__ignoreMap":264},[268,105281,105282,105284],{"class":270,"line":271},[268,105283,662],{"class":274},[268,105285,105286],{"class":282}," threading, requests\n",[268,105288,105289],{"class":270,"line":286},[268,105290,5033],{"emptyLinePlaceholder":35},[268,105292,105293,105295,105297],{"class":270,"line":296},[268,105294,88976],{"class":274},[268,105296,53875],{"class":278},[268,105298,105299],{"class":282},"(url):\n",[268,105301,105302,105304],{"class":270,"line":311},[268,105303,9871],{"class":274},[268,105305,105306],{"class":282}," requests.get(url).text\n",[268,105308,105309],{"class":270,"line":788},[268,105310,5033],{"emptyLinePlaceholder":35},[268,105312,105313,105316,105318,105321,105323,105325,105328,105330,105332,105335,105337,105340,105342],{"class":270,"line":1951},[268,105314,105315],{"class":282},"threads ",[268,105317,302],{"class":274},[268,105319,105320],{"class":282}," [threading.Thread(",[268,105322,65414],{"class":1222},[268,105324,302],{"class":274},[268,105326,105327],{"class":282},"fetch, ",[268,105329,40270],{"class":1222},[268,105331,302],{"class":274},[268,105333,105334],{"class":282},"(u,)) ",[268,105336,6926],{"class":274},[268,105338,105339],{"class":282}," u ",[268,105341,20749],{"class":274},[268,105343,105344],{"class":282}," urls]\n",[23,105346,105348,105354,105360,105369],{"className":105347},[26],[28,105349,105351,105353],{"className":105350},[31],[33,105352],{"disabled":35,"type":36}," Computing the SHA-256 hash of a 10 GB file in pure Python",[28,105355,105357,105359],{"className":105356},[31],[33,105358],{"disabled":35,"type":36}," Fetching 50 URLs over the network concurrently, as shown above",[28,105361,105363,105365,105366,105368],{"className":105362},[31],[33,105364],{"disabled":35,"type":36}," Multiplying two large matrices with nested Python ",[39,105367,6926],{}," loops",[28,105370,105372,105374,105375,105377],{"className":105371},[31],[33,105373],{"disabled":35,"type":36}," Parsing a large JSON file with the pure-Python ",[39,105376,1751],{}," module",[66,105379,105380,105382,105387],{},[69,105381,71],{},[73,105383,105384,105386],{},[76,105385,78],{}," B — Fetching 50 URLs over the network concurrently",[73,105388,105389,355,105391,105393,105394,105397,105398,105400],{},[76,105390,84],{},[76,105392,438],{}," Threading shines for I\u002FO-bound work because CPython releases the GIL around blocking I\u002FO calls (socket reads, file I\u002FO, ",[39,105395,105396],{},"time.sleep","), letting other threads run while one waits on the network. The other three options are CPU-bound pure-Python work, where the GIL prevents any of the threads from running Python bytecode simultaneously — you'd see little to no speedup, and possibly a slowdown from thread-switching overhead. The common beginner mistake is reaching for ",[39,105399,105271],{}," for CPU-heavy loops expecting linear speedup with thread count.",[15,105402,105403,105413,105546,105588],{"language":87455},[18,105404,105406,105407,105410,105411,104776],{"id":105405},"q3-why-does-multiprocessing-achieve-real-parallel-speedup-for-cpu-bound-work-where-threading-does-not","Q3. Why does ",[39,105408,105409],{},"multiprocessing"," achieve real parallel speedup for CPU-bound work where ",[39,105412,105271],{},[257,105414,105415],{"language":87455},[260,105416,105418],{"className":87467,"code":105417,"language":87455,"meta":264,"style":264},"from multiprocessing import Process\n\ndef cpu_heavy():\n    total = sum(i * i for i in range(20_000_000))\n\nif __name__ == \"__main__\":\n    procs = [Process(target=cpu_heavy) for _ in range(4)]\n    for p in procs: p.start()\n    for p in procs: p.join()\n",[39,105419,105420,105432,105436,105444,105474,105478,105492,105524,105535],{"__ignoreMap":264},[268,105421,105422,105424,105427,105429],{"class":270,"line":271},[268,105423,44539],{"class":274},[268,105425,105426],{"class":282}," multiprocessing ",[268,105428,662],{"class":274},[268,105430,105431],{"class":282}," Process\n",[268,105433,105434],{"class":270,"line":286},[268,105435,5033],{"emptyLinePlaceholder":35},[268,105437,105438,105440,105442],{"class":270,"line":296},[268,105439,88976],{"class":274},[268,105441,105138],{"class":278},[268,105443,92012],{"class":282},[268,105445,105446,105448,105450,105452,105455,105457,105459,105461,105463,105465,105467,105469,105472],{"class":270,"line":311},[268,105447,86343],{"class":282},[268,105449,302],{"class":274},[268,105451,28469],{"class":305},[268,105453,105454],{"class":282},"(i ",[268,105456,6134],{"class":274},[268,105458,9384],{"class":282},[268,105460,6926],{"class":274},[268,105462,9384],{"class":282},[268,105464,20749],{"class":274},[268,105466,94683],{"class":305},[268,105468,622],{"class":282},[268,105470,105471],{"class":305},"20_000_000",[268,105473,47690],{"class":282},[268,105475,105476],{"class":270,"line":788},[268,105477,5033],{"emptyLinePlaceholder":35},[268,105479,105480,105482,105485,105487,105490],{"class":270,"line":1951},[268,105481,2179],{"class":274},[268,105483,105484],{"class":305}," __name__",[268,105486,3165],{"class":274},[268,105488,105489],{"class":289}," \"__main__\"",[268,105491,8931],{"class":282},[268,105493,105494,105497,105499,105502,105504,105506,105509,105511,105513,105515,105517,105519,105521],{"class":270,"line":8955},[268,105495,105496],{"class":282},"    procs ",[268,105498,302],{"class":274},[268,105500,105501],{"class":282}," [Process(",[268,105503,65414],{"class":1222},[268,105505,302],{"class":274},[268,105507,105508],{"class":282},"cpu_heavy) ",[268,105510,6926],{"class":274},[268,105512,83633],{"class":282},[268,105514,20749],{"class":274},[268,105516,94683],{"class":305},[268,105518,622],{"class":282},[268,105520,15049],{"class":305},[268,105522,105523],{"class":282},")]\n",[268,105525,105526,105528,105530,105532],{"class":270,"line":8966},[268,105527,80840],{"class":274},[268,105529,40997],{"class":282},[268,105531,20749],{"class":274},[268,105533,105534],{"class":282}," procs: p.start()\n",[268,105536,105537,105539,105541,105543],{"class":270,"line":8974},[268,105538,80840],{"class":274},[268,105540,40997],{"class":282},[268,105542,20749],{"class":274},[268,105544,105545],{"class":282}," procs: p.join()\n",[23,105547,105549,105558,105566,105574],{"className":105548},[26],[28,105550,105552,17028,105554,105557],{"className":105551},[31],[33,105553],{"disabled":35,"type":36},[39,105555,105556],{},"Process"," is a separate OS process with its own Python interpreter and its own GIL, so four processes can genuinely run on four cores simultaneously",[28,105559,105561,355,105563,105565],{"className":105560},[31],[33,105562],{"disabled":35,"type":36},[39,105564,105409],{}," disables the GIL globally for the whole machine",[28,105567,105569,355,105571,105573],{"className":105568},[31],[33,105570],{"disabled":35,"type":36},[39,105572,105556],{}," objects share the same GIL but are scheduled with higher OS priority than threads",[28,105575,105577,105579,105580,105583,105584,105587],{"className":105576},[31],[33,105578],{"disabled":35,"type":36}," There's no real difference; ",[39,105581,105582],{},"multiprocessing.Process"," is just an alias for ",[39,105585,105586],{},"threading.Thread"," under the hood",[66,105589,105590,105592,105600],{},[69,105591,71],{},[73,105593,105594,105596,105597,105599],{},[76,105595,78],{}," A — Each ",[39,105598,105556],{}," is a separate OS process with its own interpreter and its own GIL, so multiple processes can run truly in parallel",[73,105601,105602,355,105604,355,105606,105608,105609,105611,105612,105614],{},[76,105603,84],{},[76,105605,438],{},[39,105607,105409],{}," sidesteps the GIL entirely by spawning independent OS processes, each with its own Python interpreter, memory space, and GIL — there is no single lock shared across processes, so four processes really can use four CPU cores concurrently. This is the fundamental reason ",[39,105610,105409],{}," is the standard recommendation for CPU-bound parallelism in pure Python, unlike ",[39,105613,105271],{},". The trade-off (covered later in this quiz) is the overhead of inter-process communication, since memory is not shared by default.",[15,105616,105617,105625,105644,105684],{"language":87455},[18,105618,105620,105621,105624],{"id":105619},"q4-given-concurrentfutures-which-executor-should-you-pick-for-a-downloading-200-files-over-http-and-b-computing-200-independent-cpu-heavy-fibonacci-like-calculations-in-pure-python","Q4. Given ",[39,105622,105623],{},"concurrent.futures",", which executor should you pick for (a) downloading 200 files over HTTP and (b) computing 200 independent CPU-heavy Fibonacci-like calculations in pure Python?",[257,105626,105627],{"language":87455},[260,105628,105630],{"className":87467,"code":105629,"language":87455,"meta":264,"style":264},"from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor\n",[39,105631,105632],{"__ignoreMap":264},[268,105633,105634,105636,105639,105641],{"class":270,"line":271},[268,105635,44539],{"class":274},[268,105637,105638],{"class":282}," concurrent.futures ",[268,105640,662],{"class":274},[268,105642,105643],{"class":282}," ThreadPoolExecutor, ProcessPoolExecutor\n",[23,105645,105647,105659,105670,105678],{"className":105646},[26],[28,105648,105650,355,105652,105655,105656],{"className":105649},[31],[33,105651],{"disabled":35,"type":36},[39,105653,105654],{},"ProcessPoolExecutor"," for both, since it's always faster than ",[39,105657,105658],{},"ThreadPoolExecutor",[28,105660,105662,355,105664,105666,105667,105669],{"className":105661},[31],[33,105663],{"disabled":35,"type":36},[39,105665,105658],{}," for the downloads (I\u002FO-bound), ",[39,105668,105654],{}," for the CPU-heavy computation (bypasses the GIL for true parallelism)",[28,105671,105673,355,105675,105677],{"className":105672},[31],[33,105674],{"disabled":35,"type":36},[39,105676,105658],{}," for both, since threads are lighter-weight and that outweighs GIL contention",[28,105679,105681,105683],{"className":105680},[31],[33,105682],{"disabled":35,"type":36}," It doesn't matter — both executors use the same underlying worker model",[66,105685,105686,105688,105698],{},[69,105687,71],{},[73,105689,105690,1727,105692,105694,105695,105697],{},[76,105691,78],{},[39,105693,105658],{}," for I\u002FO-bound downloads, ",[39,105696,105654],{}," for CPU-bound computation",[73,105699,105700,355,105702,105704,105705,105707,105708,105710],{},[76,105701,84],{},[76,105703,930],{}," This is the standard rule of thumb: I\u002FO-bound tasks spend most of their time waiting (network, disk), so lightweight threads are sufficient and avoid process-spawn\u002FIPC overhead. CPU-bound pure-Python tasks are limited by the GIL under threads, so ",[39,105706,105654],{}," is needed to actually use multiple cores. Defaulting to ",[39,105709,105654],{}," \"because it's always faster\" (option A) is wrong — for I\u002FO-bound work, process overhead (spawning, pickling task arguments\u002Fresults) usually makes it slower than threads for the same job.",[15,105712,105713,105724,105756],{},[18,105714,105716,105717,99,105720,105723],{"id":105715},"q5-why-does-a-network-call-like-socketrecv-or-requestsget-allow-other-python-threads-to-make-progress-even-though-the-gil-normally-lets-only-one-thread-run-at-a-time","Q5. Why does a network call like ",[39,105718,105719],{},"socket.recv()",[39,105721,105722],{},"requests.get()"," allow other Python threads to make progress, even though the GIL normally lets only one thread run at a time?",[23,105725,105727,105733,105739,105745],{"className":105726},[26],[28,105728,105730,105732],{"className":105729},[31],[33,105731],{"disabled":35,"type":36}," It doesn't — network calls block all threads until they return",[28,105734,105736,105738],{"className":105735},[31],[33,105737],{"disabled":35,"type":36}," Blocking I\u002FO calls in CPython release the GIL while waiting on the OS\u002Fkernel for data, allowing other threads to acquire it and run Python bytecode in the meantime",[28,105740,105742,105744],{"className":105741},[31],[33,105743],{"disabled":35,"type":36}," Network calls are implemented entirely in a separate process automatically",[28,105746,105748,50010,105750,2758,105753,105755],{"className":105747},[31],[33,105749],{"disabled":35,"type":36},[39,105751,105752],{},"asyncio",[39,105754,105271],{},", gets this benefit",[66,105757,105758,105760,105765],{},[69,105759,71],{},[73,105761,105762,105764],{},[76,105763,78],{}," B — Blocking I\u002FO calls release the GIL while waiting on the OS, letting other threads run meanwhile",[73,105766,105767,105769,105770,105772,105773,105775,105776,105778,105779,105781],{},[76,105768,84],{}," CPython's C implementations of blocking I\u002FO operations explicitly release the GIL before making the blocking system call and re-acquire it afterward. This is precisely why ",[39,105771,105271],{}," is effective for I\u002FO-bound concurrency: while one thread is parked waiting on the kernel for socket data, the GIL is free for another thread to run actual Python code. This release\u002Freacquire dance is unrelated to ",[39,105774,105752],{}," (option D) — it's a ",[39,105777,105271],{},"-level mechanism that predates ",[39,105780,105752],{}," entirely.",[15,105783,105784,105795,105933,105973],{"language":87455},[18,105785,105787,105788,105790,105791,105794],{"id":105786},"q6-despite-the-gil-serializing-bytecode-execution-this-code-can-still-print-a-final-counter-value-less-than-200000-why","Q6. Despite the GIL serializing bytecode execution, this code can still print a final ",[39,105789,35037],{}," value less than ",[39,105792,105793],{},"200000",". Why?",[257,105796,105797],{"language":87455},[260,105798,105800],{"className":87467,"code":105799,"language":87455,"meta":264,"style":264},"import threading\n\ncounter = 0\n\ndef increment():\n    global counter\n    for _ in range(100_000):\n        counter += 1\n\nthreads = [threading.Thread(target=increment) for _ in range(2)]\nfor t in threads: t.start()\nfor t in threads: t.join()\n\nprint(counter)\n",[39,105801,105802,105808,105812,105821,105825,105833,105841,105858,105867,105871,105900,105911,105922,105926],{"__ignoreMap":264},[268,105803,105804,105806],{"class":270,"line":271},[268,105805,662],{"class":274},[268,105807,105127],{"class":282},[268,105809,105810],{"class":270,"line":286},[268,105811,5033],{"emptyLinePlaceholder":35},[268,105813,105814,105817,105819],{"class":270,"line":296},[268,105815,105816],{"class":282},"counter ",[268,105818,302],{"class":274},[268,105820,86318],{"class":305},[268,105822,105823],{"class":270,"line":311},[268,105824,5033],{"emptyLinePlaceholder":35},[268,105826,105827,105829,105831],{"class":270,"line":788},[268,105828,88976],{"class":274},[268,105830,37313],{"class":278},[268,105832,92012],{"class":282},[268,105834,105835,105838],{"class":270,"line":1951},[268,105836,105837],{"class":274},"    global",[268,105839,105840],{"class":282}," counter\n",[268,105842,105843,105845,105847,105849,105851,105853,105856],{"class":270,"line":8955},[268,105844,80840],{"class":274},[268,105846,83633],{"class":282},[268,105848,20749],{"class":274},[268,105850,94683],{"class":305},[268,105852,622],{"class":282},[268,105854,105855],{"class":305},"100_000",[268,105857,94690],{"class":282},[268,105859,105860,105863,105865],{"class":270,"line":8966},[268,105861,105862],{"class":282},"        counter ",[268,105864,14575],{"class":274},[268,105866,84787],{"class":305},[268,105868,105869],{"class":270,"line":8974},[268,105870,5033],{"emptyLinePlaceholder":35},[268,105872,105873,105875,105877,105879,105881,105883,105886,105888,105890,105892,105894,105896,105898],{"class":270,"line":8985},[268,105874,105315],{"class":282},[268,105876,302],{"class":274},[268,105878,105320],{"class":282},[268,105880,65414],{"class":1222},[268,105882,302],{"class":274},[268,105884,105885],{"class":282},"increment) ",[268,105887,6926],{"class":274},[268,105889,83633],{"class":282},[268,105891,20749],{"class":274},[268,105893,94683],{"class":305},[268,105895,622],{"class":282},[268,105897,2258],{"class":305},[268,105899,105523],{"class":282},[268,105901,105902,105904,105906,105908],{"class":270,"line":8990},[268,105903,6926],{"class":274},[268,105905,85455],{"class":282},[268,105907,20749],{"class":274},[268,105909,105910],{"class":282}," threads: t.start()\n",[268,105912,105913,105915,105917,105919],{"class":270,"line":8997},[268,105914,6926],{"class":274},[268,105916,85455],{"class":282},[268,105918,20749],{"class":274},[268,105920,105921],{"class":282}," threads: t.join()\n",[268,105923,105924],{"class":270,"line":9002},[268,105925,5033],{"emptyLinePlaceholder":35},[268,105927,105928,105930],{"class":270,"line":14676},[268,105929,84797],{"class":305},[268,105931,105932],{"class":282},"(counter)\n",[23,105934,105936,105947,105956,105964],{"className":105935},[26],[28,105937,105939,105941,105942,105944,105945],{"className":105938},[31],[33,105940],{"disabled":35,"type":36}," It's impossible — the GIL guarantees ",[39,105943,35037],{}," is always exactly ",[39,105946,105793],{},[28,105948,105950,355,105952,105955],{"className":105949},[31],[33,105951],{"disabled":35,"type":36},[39,105953,105954],{},"counter += 1"," is not a single atomic bytecode operation; the GIL can switch threads mid-sequence (between the read, add, and store steps), so increments from the two threads can be lost to a race condition",[28,105957,105959,355,105961,105963],{"className":105958},[31],[33,105960],{"disabled":35,"type":36},[39,105962,105586],{}," silently drops some loop iterations for performance",[28,105965,105967,355,105969,105972],{"className":105966},[31],[33,105968],{"disabled":35,"type":36},[39,105970,105971],{},"global counter"," desynchronizes the variable between threads",[66,105974,105975,105977,105984],{},[69,105976,71],{},[73,105978,105979,1727,105981,105983],{},[76,105980,78],{},[39,105982,105954],{}," isn't atomic; the GIL can switch threads between the read\u002Fadd\u002Fstore steps, losing increments to a race condition",[73,105985,105986,355,105988,105990,105991,105993,105994,105997,105998,106000,106001,106003,106004,106006,106007,106010,106011,462],{},[76,105987,84],{},[76,105989,582],{}," A very common misconception is that the GIL makes all Python code thread-safe — it does not. ",[39,105992,105954],{}," compiles to multiple bytecode instructions (load, add, store), and CPython's scheduler can switch to another thread between any of them. If thread A reads ",[39,105995,105996],{},"counter=5",", thread B also reads ",[39,105999,2429],{}," before A writes back ",[39,106002,13663],{},", both compute ",[39,106005,13663],{},", and one increment is lost. The correct fix is a ",[39,106008,106009],{},"threading.Lock"," (or an atomic structure) around the read-modify-write: ",[39,106012,106013],{},"with lock: counter += 1",[15,106015,106016,106026,106109,106144],{"language":87455},[18,106017,106019,106020,106022,106023,106025],{"id":106018},"q7-what-overhead-does-multiprocessing-introduce-that-threading-does-not-when-passing-data-to-and-from-worker-processes","Q7. What overhead does ",[39,106021,105409],{}," introduce that ",[39,106024,105271],{}," does not, when passing data to and from worker processes?",[257,106027,106028],{"language":87455},[260,106029,106031],{"className":87467,"code":106030,"language":87455,"meta":264,"style":264},"from multiprocessing import Pool\n\ndef process_item(item):\n    return item.upper()\n\nif __name__ == \"__main__\":\n    with Pool(4) as pool:\n        results = pool.map(process_item, large_list_of_strings)\n",[39,106032,106033,106044,106048,106058,106065,106069,106081,106099],{"__ignoreMap":264},[268,106034,106035,106037,106039,106041],{"class":270,"line":271},[268,106036,44539],{"class":274},[268,106038,105426],{"class":282},[268,106040,662],{"class":274},[268,106042,106043],{"class":282}," Pool\n",[268,106045,106046],{"class":270,"line":286},[268,106047,5033],{"emptyLinePlaceholder":35},[268,106049,106050,106052,106055],{"class":270,"line":296},[268,106051,88976],{"class":274},[268,106053,106054],{"class":278}," process_item",[268,106056,106057],{"class":282},"(item):\n",[268,106059,106060,106062],{"class":270,"line":311},[268,106061,9871],{"class":274},[268,106063,106064],{"class":282}," item.upper()\n",[268,106066,106067],{"class":270,"line":788},[268,106068,5033],{"emptyLinePlaceholder":35},[268,106070,106071,106073,106075,106077,106079],{"class":270,"line":1951},[268,106072,2179],{"class":274},[268,106074,105484],{"class":305},[268,106076,3165],{"class":274},[268,106078,105489],{"class":289},[268,106080,8931],{"class":282},[268,106082,106083,106086,106089,106091,106093,106096],{"class":270,"line":8955},[268,106084,106085],{"class":274},"    with",[268,106087,106088],{"class":282}," Pool(",[268,106090,15049],{"class":305},[268,106092,6131],{"class":282},[268,106094,106095],{"class":274},"as",[268,106097,106098],{"class":282}," pool:\n",[268,106100,106101,106104,106106],{"class":270,"line":8966},[268,106102,106103],{"class":282},"        results ",[268,106105,302],{"class":274},[268,106107,106108],{"class":282}," pool.map(process_item, large_list_of_strings)\n",[23,106110,106112,106118,106124,106138],{"className":106111},[26],[28,106113,106115,106117],{"className":106114},[31],[33,106116],{"disabled":35,"type":36}," None — memory is automatically shared between processes just like threads",[28,106119,106121,106123],{"className":106120},[31],[33,106122],{"disabled":35,"type":36}," Arguments and return values must be pickled (serialized) to cross the process boundary and unpickled on the other side, which costs CPU time and can dominate runtime for large or many small objects",[28,106125,106127,355,106129,106132,106133,2758,106135],{"className":106126},[31],[33,106128],{"disabled":35,"type":36},[39,106130,106131],{},"multiprocessing.Pool"," uses shared memory exclusively, so this overhead only applies to ",[39,106134,105556],{},[39,106136,106137],{},"Pool",[28,106139,106141,106143],{"className":106140},[31],[33,106142],{"disabled":35,"type":36}," The overhead only applies to the return values, not the input arguments",[66,106145,106146,106148,106153],{},[69,106147,71],{},[73,106149,106150,106152],{},[76,106151,78],{}," B — Arguments and return values must be pickled\u002Funpickled to cross the process boundary, costing CPU time",[73,106154,106155,355,106157,106159,106160,106163,106164,106167,106168,106170,106171,106173,106174,106176],{},[76,106156,84],{},[76,106158,438],{}," Unlike threads, which share the same process memory space, separate processes do not share memory by default. ",[39,106161,106162],{},"Pool.map"," serializes each argument with ",[39,106165,106166],{},"pickle",", sends it through an OS pipe to a worker process, and pickles the result back. For workloads with many small, fast tasks, this serialization overhead can exceed the actual computation time, sometimes making ",[39,106169,105409],{}," slower than a single-threaded loop — a frequent surprise for people expecting free parallelism. ",[39,106172,106137],{}," uses the same pickling mechanism as ",[39,106175,105556],{}," (option C is wrong); it does not get free shared memory.",[15,106178,106179,106185,106264,106294],{"language":87455},[18,106180,106182,106183,1685],{"id":106181},"q8-what-happens-when-you-try-to-pass-this-to-a-multiprocessingpool","Q8. What happens when you try to pass this to a ",[39,106184,106131],{},[257,106186,106187],{"language":87455},[260,106188,106190],{"className":87467,"code":106189,"language":87455,"meta":264,"style":264},"from multiprocessing import Pool\n\nif __name__ == \"__main__\":\n    with Pool(4) as pool:\n        results = pool.map(lambda x: x * 2, [1, 2, 3])\n",[39,106191,106192,106202,106206,106218,106232],{"__ignoreMap":264},[268,106193,106194,106196,106198,106200],{"class":270,"line":271},[268,106195,44539],{"class":274},[268,106197,105426],{"class":282},[268,106199,662],{"class":274},[268,106201,106043],{"class":282},[268,106203,106204],{"class":270,"line":286},[268,106205,5033],{"emptyLinePlaceholder":35},[268,106207,106208,106210,106212,106214,106216],{"class":270,"line":296},[268,106209,2179],{"class":274},[268,106211,105484],{"class":305},[268,106213,3165],{"class":274},[268,106215,105489],{"class":289},[268,106217,8931],{"class":282},[268,106219,106220,106222,106224,106226,106228,106230],{"class":270,"line":311},[268,106221,106085],{"class":274},[268,106223,106088],{"class":282},[268,106225,15049],{"class":305},[268,106227,6131],{"class":282},[268,106229,106095],{"class":274},[268,106231,106098],{"class":282},[268,106233,106234,106236,106238,106241,106243,106246,106248,106250,106252,106254,106256,106258,106260,106262],{"class":270,"line":788},[268,106235,106103],{"class":282},[268,106237,302],{"class":274},[268,106239,106240],{"class":282}," pool.map(",[268,106242,94698],{"class":274},[268,106244,106245],{"class":282}," x: x ",[268,106247,6134],{"class":274},[268,106249,2214],{"class":305},[268,106251,25183],{"class":282},[268,106253,2255],{"class":305},[268,106255,42],{"class":282},[268,106257,2258],{"class":305},[268,106259,42],{"class":282},[268,106261,3423],{"class":305},[268,106263,85493],{"class":282},[23,106265,106267,106273,106282,106288],{"className":106266},[26],[28,106268,106270,106272],{"className":106269},[31],[33,106271],{"disabled":35,"type":36}," It runs fine — lambdas are pickled by value automatically",[28,106274,106276,91837,106278,106281],{"className":106275},[31],[33,106277],{"disabled":35,"type":36},[39,106279,106280],{},"PicklingError"," (or similar) because lambda functions cannot be pickled — only module-level (importable) functions and objects can cross the process boundary this way",[28,106283,106285,106287],{"className":106284},[31],[33,106286],{"disabled":35,"type":36}," It silently falls back to running single-threaded",[28,106289,106291,106293],{"className":106290},[31],[33,106292],{"disabled":35,"type":36}," It works, but only on Linux, never on any other OS",[66,106295,106296,106298,106303],{},[69,106297,71],{},[73,106299,106300,106302],{},[76,106301,78],{}," B — Raises a pickling error because lambdas can't be pickled; only importable, module-level functions\u002Fobjects can be sent to worker processes",[73,106304,106305,355,106307,355,106309,106311,106312,106314,106315,106317,106318,106321,106322,106325,106326,106328,106329,106331,106332,99,106334,106337],{},[76,106306,84],{},[76,106308,365],{},[39,106310,106166],{}," (the mechanism ",[39,106313,105409],{}," uses to send work to worker processes) serializes callables by reference — it stores the module and qualified name and re-imports them in the worker. A ",[39,106316,94698],{}," has no importable name (",[39,106319,106320],{},"\u003Clambda>","), so pickling fails with something like ",[39,106323,106324],{},"AttributeError: Can't pickle local object",". The fix is to define the function at module level with ",[39,106327,88976],{}," instead of as a ",[39,106330,94698],{},". This is a frequent gotcha for people used to ",[39,106333,105271],{},[39,106335,106336],{},"concurrent.futures.ThreadPoolExecutor",", where lambdas work fine since no pickling ever happens.",[15,106339,106340,106344,106463,106517],{"language":87455},[18,106341,106343],{"id":106342},"q9-two-worker-processes-need-to-update-a-shared-counter-why-wont-this-work-as-expected-and-whats-the-fix","Q9. Two worker processes need to update a shared counter. Why won't this work as expected, and what's the fix?",[257,106345,106346],{"language":87455},[260,106347,106349],{"className":87467,"code":106348,"language":87455,"meta":264,"style":264},"from multiprocessing import Process\n\ncounter = 0\n\ndef increment():\n    global counter\n    counter += 1\n\nprocs = [Process(target=increment) for _ in range(10)]\nfor p in procs: p.start()\nfor p in procs: p.join()\n\nprint(counter)\n",[39,106350,106351,106361,106365,106373,106377,106385,106391,106400,106404,106433,106443,106453,106457],{"__ignoreMap":264},[268,106352,106353,106355,106357,106359],{"class":270,"line":271},[268,106354,44539],{"class":274},[268,106356,105426],{"class":282},[268,106358,662],{"class":274},[268,106360,105431],{"class":282},[268,106362,106363],{"class":270,"line":286},[268,106364,5033],{"emptyLinePlaceholder":35},[268,106366,106367,106369,106371],{"class":270,"line":296},[268,106368,105816],{"class":282},[268,106370,302],{"class":274},[268,106372,86318],{"class":305},[268,106374,106375],{"class":270,"line":311},[268,106376,5033],{"emptyLinePlaceholder":35},[268,106378,106379,106381,106383],{"class":270,"line":788},[268,106380,88976],{"class":274},[268,106382,37313],{"class":278},[268,106384,92012],{"class":282},[268,106386,106387,106389],{"class":270,"line":1951},[268,106388,105837],{"class":274},[268,106390,105840],{"class":282},[268,106392,106393,106396,106398],{"class":270,"line":8955},[268,106394,106395],{"class":282},"    counter ",[268,106397,14575],{"class":274},[268,106399,84787],{"class":305},[268,106401,106402],{"class":270,"line":8966},[268,106403,5033],{"emptyLinePlaceholder":35},[268,106405,106406,106409,106411,106413,106415,106417,106419,106421,106423,106425,106427,106429,106431],{"class":270,"line":8974},[268,106407,106408],{"class":282},"procs ",[268,106410,302],{"class":274},[268,106412,105501],{"class":282},[268,106414,65414],{"class":1222},[268,106416,302],{"class":274},[268,106418,105885],{"class":282},[268,106420,6926],{"class":274},[268,106422,83633],{"class":282},[268,106424,20749],{"class":274},[268,106426,94683],{"class":305},[268,106428,622],{"class":282},[268,106430,5825],{"class":305},[268,106432,105523],{"class":282},[268,106434,106435,106437,106439,106441],{"class":270,"line":8985},[268,106436,6926],{"class":274},[268,106438,40997],{"class":282},[268,106440,20749],{"class":274},[268,106442,105534],{"class":282},[268,106444,106445,106447,106449,106451],{"class":270,"line":8990},[268,106446,6926],{"class":274},[268,106448,40997],{"class":282},[268,106450,20749],{"class":274},[268,106452,105545],{"class":282},[268,106454,106455],{"class":270,"line":8997},[268,106456,5033],{"emptyLinePlaceholder":35},[268,106458,106459,106461],{"class":270,"line":9002},[268,106460,84797],{"class":305},[268,106462,105932],{"class":282},[23,106464,106466,106478,106500,106511],{"className":106465},[26],[28,106467,106469,106471,106472,106474,106475,106477],{"className":106468},[31],[33,106470],{"disabled":35,"type":36}," It prints ",[39,106473,5825],{}," correctly because ",[39,106476,105409],{}," synchronizes global variables automatically",[28,106479,106481,106483,106484,106486,106487,7415,106489,100662,106491,446,106494,106496,106497,106499],{"className":106480},[31],[33,106482],{"disabled":35,"type":36}," Each process gets its own copy of the module (and thus ",[39,106485,35037],{},") at fork\u002Fspawn time; changes in a child are invisible to the parent and other children, so the parent's ",[39,106488,35037],{},[39,106490,3307],{},[39,106492,106493],{},"multiprocessing.Value",[39,106495,88],{}," or a ",[39,106498,31325],{}," for real shared state",[28,106501,106503,104332,106505,106508,106509],{"className":106502},[31],[33,106504],{"disabled":35,"type":36},[39,106506,106507],{},"RuntimeError"," because global variables are forbidden with ",[39,106510,105409],{},[28,106512,106514,106516],{"className":106513},[31],[33,106515],{"disabled":35,"type":36}," It prints a random number between 0 and 10 due to race conditions, same as with threads",[66,106518,106519,106521,106536],{},[69,106520,71],{},[73,106522,106523,106525,106526,106528,106529,446,106532,446,106534,106499],{},[76,106524,78],{}," B — Each process gets its own independent copy of ",[39,106527,35037],{},"; the parent's value never changes, so the fix is ",[39,106530,106531],{},"Value",[39,106533,88],{},[39,106535,31325],{},[73,106537,106538,355,106540,106542,106543,106545,106546,106548,106549,106551,106552,106554,106555,42,106557,42493,106559,446,106562,106564],{},[76,106539,84],{},[76,106541,582],{}," Unlike threads, which share one address space, each ",[39,106544,105582],{}," has an entirely separate memory space (a copy of the parent's state at fork time, or a fresh reimport under spawn). Incrementing ",[39,106547,35037],{}," inside a child mutates that child's private copy — the parent's ",[39,106550,35037],{}," never sees it, so the parent prints ",[39,106553,3307],{},", not a race-condition-corrupted partial count (that's the threading failure mode from Q6, not this one). To actually share mutable state across processes you need explicit IPC-aware primitives: ",[39,106556,106493],{},[39,106558,88],{},[39,106560,106561],{},"Manager().dict()",[39,106563,103922],{},", all backed by shared memory or a proxy process.",[15,106566,106567,106571,106658,106703],{"language":87455},[18,106568,106570],{"id":106569},"q10-whats-wrong-with-this-locking-pattern-and-what-does-it-cause","Q10. What's wrong with this locking pattern, and what does it cause?",[257,106572,106573],{"language":87455},[260,106574,106576],{"className":87467,"code":106575,"language":87455,"meta":264,"style":264},"import threading\n\nlock = threading.Lock()\n\ndef outer():\n    with lock:\n        inner()\n\ndef inner():\n    with lock:\n        print(\"done\")\n\nouter()\n",[39,106577,106578,106584,106588,106598,106602,106610,106617,106622,106626,106634,106640,106650,106654],{"__ignoreMap":264},[268,106579,106580,106582],{"class":270,"line":271},[268,106581,662],{"class":274},[268,106583,105127],{"class":282},[268,106585,106586],{"class":270,"line":286},[268,106587,5033],{"emptyLinePlaceholder":35},[268,106589,106590,106593,106595],{"class":270,"line":296},[268,106591,106592],{"class":282},"lock ",[268,106594,302],{"class":274},[268,106596,106597],{"class":282}," threading.Lock()\n",[268,106599,106600],{"class":270,"line":311},[268,106601,5033],{"emptyLinePlaceholder":35},[268,106603,106604,106606,106608],{"class":270,"line":788},[268,106605,88976],{"class":274},[268,106607,9700],{"class":278},[268,106609,92012],{"class":282},[268,106611,106612,106614],{"class":270,"line":1951},[268,106613,106085],{"class":274},[268,106615,106616],{"class":282}," lock:\n",[268,106618,106619],{"class":270,"line":8955},[268,106620,106621],{"class":282},"        inner()\n",[268,106623,106624],{"class":270,"line":8966},[268,106625,5033],{"emptyLinePlaceholder":35},[268,106627,106628,106630,106632],{"class":270,"line":8974},[268,106629,88976],{"class":274},[268,106631,15153],{"class":278},[268,106633,92012],{"class":282},[268,106635,106636,106638],{"class":270,"line":8985},[268,106637,106085],{"class":274},[268,106639,106616],{"class":282},[268,106641,106642,106644,106646,106648],{"class":270,"line":8990},[268,106643,95279],{"class":305},[268,106645,622],{"class":282},[268,106647,55064],{"class":289},[268,106649,20702],{"class":282},[268,106651,106652],{"class":270,"line":8997},[268,106653,5033],{"emptyLinePlaceholder":35},[268,106655,106656],{"class":270,"line":9002},[268,106657,94938],{"class":282},[23,106659,106661,106669,106685,106694],{"className":106660},[26],[28,106662,106664,52864,106666,106668],{"className":106663},[31],[33,106665],{"disabled":35,"type":36},[39,106667,106009],{}," allows the same thread to reacquire it any number of times",[28,106670,106672,106674,106675,106677,106678,106680,106681,106684],{"className":106671},[31],[33,106673],{"disabled":35,"type":36}," The thread deadlocks itself: ",[39,106676,106009],{}," is non-reentrant, so ",[39,106679,55205],{},"'s attempt to acquire an already-held lock blocks forever. Using ",[39,106682,106683],{},"threading.RLock"," instead would allow the same thread to reacquire it",[28,106686,106688,104332,106690,106693],{"className":106687},[31],[33,106689],{"disabled":35,"type":36},[39,106691,106692],{},"RuntimeError: lock already held"," immediately instead of blocking",[28,106695,106697,355,106699,106702],{"className":106696},[31],[33,106698],{"disabled":35,"type":36},[39,106700,106701],{},"with lock:"," silently no-ops on the second acquisition",[66,106704,106705,106707,106718],{},[69,106706,71],{},[73,106708,106709,106711,106712,106714,106715,106717],{},[76,106710,78],{}," B — The thread deadlocks itself; ",[39,106713,106009],{}," is non-reentrant, so use ",[39,106716,106683],{}," for nested acquisition by the same thread",[73,106719,106720,355,106722,106724,106725,106727,106728,106731,106732,106734,106735,106737,106738,106740],{},[76,106721,84],{},[76,106723,582],{}," A plain ",[39,106726,106009],{}," is not reentrant — once a thread holds it, that same thread blocks (rather than passing through) on a second ",[39,106729,106730],{},"acquire()",", because the lock has no concept of \"owner.\" Since ",[39,106733,55205],{}," runs in the same thread that already holds the lock via ",[39,106736,37562],{},", the program hangs forever with no exception (option C is wrong — no error is ever raised; it just blocks). ",[39,106739,106683],{}," tracks the owning thread and an acquisition count, letting the same thread re-enter safely, which is the standard fix for recursive or nested locking within one thread's call stack.",[15,106742,106743,106747,106883,106915],{"language":87455},[18,106744,106746],{"id":106745},"q11-a-cpu-bound-function-calls-into-a-c-extension-eg-numpys-matrix-multiply-that-explicitly-releases-the-gil-during-its-computation-what-does-this-enable","Q11. A CPU-bound function calls into a C extension (e.g., NumPy's matrix multiply) that explicitly releases the GIL during its computation. What does this enable?",[257,106748,106749],{"language":87455},[260,106750,106752],{"className":87467,"code":106751,"language":87455,"meta":264,"style":264},"import threading\nimport numpy as np\n\ndef matmul_heavy():\n    a = np.random.rand(2000, 2000)\n    b = np.random.rand(2000, 2000)\n    a @ b\n\nthreads = [threading.Thread(target=matmul_heavy) for _ in range(4)]\nfor t in threads: t.start()\nfor t in threads: t.join()\n",[39,106753,106754,106760,106772,106776,106785,106804,106821,106830,106834,106863,106873],{"__ignoreMap":264},[268,106755,106756,106758],{"class":270,"line":271},[268,106757,662],{"class":274},[268,106759,105127],{"class":282},[268,106761,106762,106764,106767,106769],{"class":270,"line":286},[268,106763,662],{"class":274},[268,106765,106766],{"class":282}," numpy ",[268,106768,106095],{"class":274},[268,106770,106771],{"class":282}," np\n",[268,106773,106774],{"class":270,"line":296},[268,106775,5033],{"emptyLinePlaceholder":35},[268,106777,106778,106780,106783],{"class":270,"line":311},[268,106779,88976],{"class":274},[268,106781,106782],{"class":278}," matmul_heavy",[268,106784,92012],{"class":282},[268,106786,106787,106790,106792,106795,106798,106800,106802],{"class":270,"line":788},[268,106788,106789],{"class":282},"    a ",[268,106791,302],{"class":274},[268,106793,106794],{"class":282}," np.random.rand(",[268,106796,106797],{"class":305},"2000",[268,106799,42],{"class":282},[268,106801,106797],{"class":305},[268,106803,20702],{"class":282},[268,106805,106806,106809,106811,106813,106815,106817,106819],{"class":270,"line":1951},[268,106807,106808],{"class":282},"    b ",[268,106810,302],{"class":274},[268,106812,106794],{"class":282},[268,106814,106797],{"class":305},[268,106816,42],{"class":282},[268,106818,106797],{"class":305},[268,106820,20702],{"class":282},[268,106822,106823,106825,106828],{"class":270,"line":8955},[268,106824,106789],{"class":282},[268,106826,106827],{"class":274},"@",[268,106829,95559],{"class":282},[268,106831,106832],{"class":270,"line":8966},[268,106833,5033],{"emptyLinePlaceholder":35},[268,106835,106836,106838,106840,106842,106844,106846,106849,106851,106853,106855,106857,106859,106861],{"class":270,"line":8974},[268,106837,105315],{"class":282},[268,106839,302],{"class":274},[268,106841,105320],{"class":282},[268,106843,65414],{"class":1222},[268,106845,302],{"class":274},[268,106847,106848],{"class":282},"matmul_heavy) ",[268,106850,6926],{"class":274},[268,106852,83633],{"class":282},[268,106854,20749],{"class":274},[268,106856,94683],{"class":305},[268,106858,622],{"class":282},[268,106860,15049],{"class":305},[268,106862,105523],{"class":282},[268,106864,106865,106867,106869,106871],{"class":270,"line":8985},[268,106866,6926],{"class":274},[268,106868,85455],{"class":282},[268,106870,20749],{"class":274},[268,106872,105910],{"class":282},[268,106874,106875,106877,106879,106881],{"class":270,"line":8990},[268,106876,6926],{"class":274},[268,106878,85455],{"class":282},[268,106880,20749],{"class":274},[268,106882,105921],{"class":282},[23,106884,106886,106892,106898,106904],{"className":106885},[26],[28,106887,106889,106891],{"className":106888},[31],[33,106890],{"disabled":35,"type":36}," Nothing — pure computation always requires the GIL, so this is no different from a pure-Python loop",[28,106893,106895,106897],{"className":106894},[31],[33,106896],{"disabled":35,"type":36}," These threads can achieve genuine multi-core parallelism, because NumPy's underlying C code releases the GIL for the duration of the heavy computation, unlike pure-Python bytecode loops",[28,106899,106901,106903],{"className":106900},[31],[33,106902],{"disabled":35,"type":36}," NumPy always uses multiprocessing internally regardless of the GIL",[28,106905,106907,106909,106910,106912,106913],{"className":106906},[31],[33,106908],{"disabled":35,"type":36}," This only works if ",[39,106911,105271],{}," is replaced with ",[39,106914,105409],{},[66,106916,106917,106919,106924],{},[69,106918,71],{},[73,106920,106921,106923],{},[76,106922,78],{}," B — These threads can achieve genuine multi-core parallelism because NumPy's C code releases the GIL during the heavy computation",[73,106925,106926,355,106928,106930,106931,186,106934,106937,106938,106941,106942,446,106945,106948,106949,106951],{},[76,106927,84],{},[76,106929,438],{}," The GIL restriction applies specifically to executing Python bytecode, not to C code. Well-written C extensions (NumPy, many ",[39,106932,106933],{},"hashlib",[39,106935,106936],{},"zlib"," operations, some ",[39,106939,106940],{},"re"," operations) explicitly release the GIL around long-running C-level work using ",[39,106943,106944],{},"Py_BEGIN_ALLOW_THREADS",[39,106946,106947],{},"Py_END_ALLOW_THREADS",", letting other Python threads run truly concurrently on other cores during that window. This is an important exception to the general \"threading doesn't help CPU-bound work\" rule (Q1\u002FQ2) and explains why numeric\u002Fscientific Python libraries can benefit meaningfully from ",[39,106950,105271],{},", unlike hand-written pure-Python loops.",[15,106953,106954,106962,107052,107089],{"language":87455},[18,106955,106957,106958,106961],{"id":106956},"q12-what-is-the-effect-of-daemontrue-on-a-thread-and-what-happens-without-it","Q12. What is the effect of ",[39,106959,106960],{},"daemon=True"," on a thread, and what happens without it?",[257,106963,106964],{"language":87455},[260,106965,106967],{"className":87467,"code":106966,"language":87455,"meta":264,"style":264},"import threading, time\n\ndef background_task():\n    while True:\n        time.sleep(1)\n\nt = threading.Thread(target=background_task, daemon=True)\nt.start()\nprint(\"main thread finished\")\n",[39,106968,106969,106976,106980,106989,106998,107007,107011,107036,107041],{"__ignoreMap":264},[268,106970,106971,106973],{"class":270,"line":271},[268,106972,662],{"class":274},[268,106974,106975],{"class":282}," threading, time\n",[268,106977,106978],{"class":270,"line":286},[268,106979,5033],{"emptyLinePlaceholder":35},[268,106981,106982,106984,106987],{"class":270,"line":296},[268,106983,88976],{"class":274},[268,106985,106986],{"class":278}," background_task",[268,106988,92012],{"class":282},[268,106990,106991,106994,106996],{"class":270,"line":311},[268,106992,106993],{"class":274},"    while",[268,106995,90611],{"class":305},[268,106997,8931],{"class":282},[268,106999,107000,107003,107005],{"class":270,"line":788},[268,107001,107002],{"class":282},"        time.sleep(",[268,107004,2255],{"class":305},[268,107006,20702],{"class":282},[268,107008,107009],{"class":270,"line":1951},[268,107010,5033],{"emptyLinePlaceholder":35},[268,107012,107013,107016,107018,107020,107022,107024,107027,107030,107032,107034],{"class":270,"line":8955},[268,107014,107015],{"class":282},"t ",[268,107017,302],{"class":274},[268,107019,105188],{"class":282},[268,107021,65414],{"class":1222},[268,107023,302],{"class":274},[268,107025,107026],{"class":282},"background_task, ",[268,107028,107029],{"class":1222},"daemon",[268,107031,302],{"class":274},[268,107033,89285],{"class":305},[268,107035,20702],{"class":282},[268,107037,107038],{"class":270,"line":8966},[268,107039,107040],{"class":282},"t.start()\n",[268,107042,107043,107045,107047,107050],{"class":270,"line":8974},[268,107044,84797],{"class":305},[268,107046,622],{"class":282},[268,107048,107049],{"class":289},"\"main thread finished\"",[268,107051,20702],{"class":282},[23,107053,107055,107066,107075,107083],{"className":107054},[26],[28,107056,107058,355,107060,107062,107063,107065],{"className":107057},[31],[33,107059],{"disabled":35,"type":36},[39,107061,106960],{}," has no effect; the program always exits once ",[39,107064,102577],{}," finishes regardless of running threads",[28,107067,107069,107071,107072,107074],{"className":107068},[31],[33,107070],{"disabled":35,"type":36}," A daemon thread is killed abruptly when the main program exits; without ",[39,107073,106960],{},", this infinite-loop thread would keep the whole process alive forever since Python waits for all non-daemon threads to finish",[28,107076,107078,355,107080,107082],{"className":107077},[31],[33,107079],{"disabled":35,"type":36},[39,107081,106960],{}," makes the thread run with elevated OS privileges",[28,107084,107086,107088],{"className":107085},[31],[33,107087],{"disabled":35,"type":36}," Daemon threads run on a separate GIL, so they never block other threads",[66,107090,107091,107093,107098],{},[69,107092,71],{},[73,107094,107095,107097],{},[76,107096,78],{}," B — A daemon thread is killed when the main program exits; without it, this infinite loop would keep the process alive forever",[73,107099,107100,355,107102,107104,107105,107107,107108,107110,107111,107113],{},[76,107101,84],{},[76,107103,365],{}," By default, CPython will not exit the process until every non-daemon thread finishes, since threads represent real OS-level work that might need to complete. An infinite-loop background thread without ",[39,107106,106960],{}," would hang the program indefinitely after ",[39,107109,84797],{}," runs — the process never terminates. Marking it ",[39,107112,106960],{}," tells the interpreter it's safe to abruptly kill that thread on exit, which is standard practice for background workers (polling loops, heartbeat threads) that shouldn't block shutdown.",[15,107115,107116,107128,107199,107242],{"language":87455},[18,107117,107119,107120,107123,107124,107127],{"id":107118},"q13-what-is-likely-to-go-wrong-if-this-script-using-the-default-spawn-start-method-eg-on-windows-or-macos-omits-the-if-__name__-__main__-guard","Q13. What is likely to go wrong if this script (using the default ",[39,107121,107122],{},"spawn"," start method, e.g. on Windows or macOS) omits the ",[39,107125,107126],{},"if __name__ == \"__main__\":"," guard?",[257,107129,107130],{"language":87455},[260,107131,107133],{"className":87467,"code":107132,"language":87455,"meta":264,"style":264},"from multiprocessing import Process\n\ndef worker():\n    print(\"working\")\n\np = Process(target=worker)\np.start()\np.join()\n",[39,107134,107135,107145,107149,107158,107169,107173,107189,107194],{"__ignoreMap":264},[268,107136,107137,107139,107141,107143],{"class":270,"line":271},[268,107138,44539],{"class":274},[268,107140,105426],{"class":282},[268,107142,662],{"class":274},[268,107144,105431],{"class":282},[268,107146,107147],{"class":270,"line":286},[268,107148,5033],{"emptyLinePlaceholder":35},[268,107150,107151,107153,107156],{"class":270,"line":296},[268,107152,88976],{"class":274},[268,107154,107155],{"class":278}," worker",[268,107157,92012],{"class":282},[268,107159,107160,107162,107164,107167],{"class":270,"line":311},[268,107161,92017],{"class":305},[268,107163,622],{"class":282},[268,107165,107166],{"class":289},"\"working\"",[268,107168,20702],{"class":282},[268,107170,107171],{"class":270,"line":788},[268,107172,5033],{"emptyLinePlaceholder":35},[268,107174,107175,107177,107179,107182,107184,107186],{"class":270,"line":1951},[268,107176,98183],{"class":282},[268,107178,302],{"class":274},[268,107180,107181],{"class":282}," Process(",[268,107183,65414],{"class":1222},[268,107185,302],{"class":274},[268,107187,107188],{"class":282},"worker)\n",[268,107190,107191],{"class":270,"line":8955},[268,107192,107193],{"class":282},"p.start()\n",[268,107195,107196],{"class":270,"line":8966},[268,107197,107198],{"class":282},"p.join()\n",[23,107200,107202,107208,107223,107231],{"className":107201},[26],[28,107203,107205,107207],{"className":107204},[31],[33,107206],{"disabled":35,"type":36}," Nothing — the guard is only a stylistic convention, never functionally required",[28,107209,107211,107213,107214,107216,107217,107220,107221],{"className":107210},[31],[33,107212],{"disabled":35,"type":36}," On ",[39,107215,107122],{},"-based platforms, each child process re-imports the main module to set itself up; without the guard, the child re-executes the top-level ",[39,107218,107219],{},"Process(...).start()"," call too, spawning another child recursively — leading to a runaway process bomb or ",[39,107222,106507],{},[28,107224,107226,107228,107229,1275],{"className":107225},[31],[33,107227],{"disabled":35,"type":36}," It causes a ",[39,107230,1274],{},[28,107232,107234,107236,107237,107239,107240],{"className":107233},[31],[33,107235],{"disabled":35,"type":36}," It only affects ",[39,107238,106137],{},", never plain ",[39,107241,105556],{},[66,107243,107244,107246,107256],{},[69,107245,71],{},[73,107247,107248,107250,107251,107253,107254],{},[76,107249,78],{}," B — Without the guard, ",[39,107252,107122],{},"-based child processes re-execute the top-level code, recursively spawning more children — a process bomb or ",[39,107255,106507],{},[73,107257,107258,355,107260,107262,107263,107265,107266,107268,107269,107271,107272,107274,107275,107278,107279,107281,107282,107285],{},[76,107259,84],{},[76,107261,182],{}," On platforms using the ",[39,107264,107122],{}," start method (the default on Windows and, since Python 3.8, macOS), a new child process starts a fresh Python interpreter and re-imports ",[39,107267,88056],{}," to reconstruct what it needs to run the target function — it does not fork the parent's already-running memory. If the module-level code that creates and starts the ",[39,107270,105556],{}," isn't guarded by ",[39,107273,107126],{},", each child re-runs that same top-level code on import, spawning yet another child, recursively. CPython actually detects this specific pattern and raises ",[39,107276,107277],{},"RuntimeError: An attempt has been made to start a new process before the current process has finished its bootstrapping phase..."," with guidance to add the guard. This is a genuine functional requirement on ",[39,107280,107122],{},"\u002FWindows, not just a style preference (option A) — though on Linux's default ",[39,107283,107284],{},"fork"," method the same code often \"works\" without the guard, which is precisely why the bug is a portability trap.",[15,107287,107288,107292,107319],{},[18,107289,107291],{"id":107290},"q14-is-the-gil-a-single-global-lock-shared-across-an-entire-machine-or-something-else","Q14. Is the GIL a single global lock shared across an entire machine, or something else?",[23,107293,107295,107301,107307,107313],{"className":107294},[26],[28,107296,107298,107300],{"className":107297},[31],[33,107299],{"disabled":35,"type":36}," It's one lock per machine — even unrelated Python processes contend for the same GIL",[28,107302,107304,107306],{"className":107303},[31],[33,107305],{"disabled":35,"type":36}," It's one lock per Python process (per interpreter instance); separate processes each have their own independent GIL and don't contend with each other",[28,107308,107310,107312],{"className":107309},[31],[33,107311],{"disabled":35,"type":36}," It's one lock per CPU core",[28,107314,107316,107318],{"className":107315},[31],[33,107317],{"disabled":35,"type":36}," It's one lock per thread, meaning it provides no serialization at all",[66,107320,107321,107323,107328],{},[69,107322,71],{},[73,107324,107325,107327],{},[76,107326,78],{}," B — One GIL per Python process\u002Finterpreter; separate processes have entirely independent GILs",[73,107329,107330,107332,107333,107335],{},[76,107331,84],{}," The name \"Global Interpreter Lock\" refers to global-within-one-interpreter scope, not global-across-the-machine — each Python process runs its own interpreter with its own GIL, completely independent of any other process's GIL. This is exactly why ",[39,107334,105409],{}," sidesteps the limitation: spawning multiple processes means multiple independent GILs, each free to run bytecode on a different core simultaneously, whereas multiple threads inside one process must all share that one process's single GIL.",[15,107337,107338,107342,107448,107495],{"language":87455},[18,107339,107341],{"id":107340},"q15-two-threads-need-to-hand-off-work-items-safely-without-manual-locking-whats-the-idiomatic-tool","Q15. Two threads need to hand off work items safely without manual locking. What's the idiomatic tool?",[257,107343,107344],{"language":87455},[260,107345,107347],{"className":87467,"code":107346,"language":87455,"meta":264,"style":264},"import threading, queue\n\ndef producer(q):\n    for i in range(10):\n        q.put(i)\n\ndef consumer(q):\n    while True:\n        item = q.get()\n        print(item)\n        q.task_done()\n\nq = queue.Queue()\n",[39,107348,107349,107356,107360,107370,107386,107391,107395,107404,107412,107422,107429,107434,107438],{"__ignoreMap":264},[268,107350,107351,107353],{"class":270,"line":271},[268,107352,662],{"class":274},[268,107354,107355],{"class":282}," threading, queue\n",[268,107357,107358],{"class":270,"line":286},[268,107359,5033],{"emptyLinePlaceholder":35},[268,107361,107362,107364,107367],{"class":270,"line":296},[268,107363,88976],{"class":274},[268,107365,107366],{"class":278}," producer",[268,107368,107369],{"class":282},"(q):\n",[268,107371,107372,107374,107376,107378,107380,107382,107384],{"class":270,"line":311},[268,107373,80840],{"class":274},[268,107375,9384],{"class":282},[268,107377,20749],{"class":274},[268,107379,94683],{"class":305},[268,107381,622],{"class":282},[268,107383,5825],{"class":305},[268,107385,94690],{"class":282},[268,107387,107388],{"class":270,"line":788},[268,107389,107390],{"class":282},"        q.put(i)\n",[268,107392,107393],{"class":270,"line":1951},[268,107394,5033],{"emptyLinePlaceholder":35},[268,107396,107397,107399,107402],{"class":270,"line":8955},[268,107398,88976],{"class":274},[268,107400,107401],{"class":278}," consumer",[268,107403,107369],{"class":282},[268,107405,107406,107408,107410],{"class":270,"line":8966},[268,107407,106993],{"class":274},[268,107409,90611],{"class":305},[268,107411,8931],{"class":282},[268,107413,107414,107417,107419],{"class":270,"line":8974},[268,107415,107416],{"class":282},"        item ",[268,107418,302],{"class":274},[268,107420,107421],{"class":282}," q.get()\n",[268,107423,107424,107426],{"class":270,"line":8985},[268,107425,95279],{"class":305},[268,107427,107428],{"class":282},"(item)\n",[268,107430,107431],{"class":270,"line":8990},[268,107432,107433],{"class":282},"        q.task_done()\n",[268,107435,107436],{"class":270,"line":8997},[268,107437,5033],{"emptyLinePlaceholder":35},[268,107439,107440,107443,107445],{"class":270,"line":9002},[268,107441,107442],{"class":282},"q ",[268,107444,302],{"class":274},[268,107446,107447],{"class":282}," queue.Queue()\n",[23,107449,107451,107460,107475,107486],{"className":107450},[26],[28,107452,107454,107456,107457,107459],{"className":107453},[31],[33,107455],{"disabled":35,"type":36}," Manually appending to and popping from a shared ",[39,107458,14924],{}," with no synchronization, since list operations are \"atomic enough\"",[28,107461,107463,355,107465,107468,107469,446,107472,107474],{"className":107462},[31],[33,107464],{"disabled":35,"type":36},[39,107466,107467],{},"queue.Queue",", which is internally synchronized with its own lock\u002Fcondition variables, making ",[39,107470,107471],{},"put",[39,107473,32437],{}," safe to call from multiple threads without any extra locking code",[28,107476,107478,355,107480,107483,107484],{"className":107477},[31],[33,107479],{"disabled":35,"type":36},[39,107481,107482],{},"multiprocessing.Queue",", since it's a strict superset of ",[39,107485,107467],{},[28,107487,107489,107491,107492,107494],{"className":107488},[31],[33,107490],{"disabled":35,"type":36}," A plain Python ",[39,107493,89385],{}," keyed by timestamp",[66,107496,107497,107499,107506],{},[69,107498,71],{},[73,107500,107501,1727,107503,107505],{},[76,107502,78],{},[39,107504,107467],{}," is internally synchronized, making it safe for multi-threaded producer\u002Fconsumer patterns without manual locking",[73,107507,107508,355,107510,355,107512,107514,107515,446,107517,107519,107520,107522,107523,446,107526,107528,107529,107531],{},[76,107509,84],{},[76,107511,930],{},[39,107513,107467],{}," is specifically designed for thread-safe communication — its ",[39,107516,107471],{},[39,107518,32437],{}," methods handle all locking internally, and it additionally supports blocking with optional timeouts, making it the standard building block for producer\u002Fconsumer patterns in ",[39,107521,105271],{}," code. Relying on raw ",[39,107524,107525],{},"list.append",[39,107527,74102],{}," (option A) is risky: while individual list methods are atomic due to the GIL, compound patterns (check-then-act, popping under certain conditions) are not, and it lacks the queue's blocking\u002Fwake-up semantics. ",[39,107530,107482],{}," (option C) is a different, heavier implementation meant for cross-process communication with its own pickling overhead — not a strict superset for thread use.",[15,107533,107534,107538,107568],{},[18,107535,107537],{"id":107536},"q16-a-teams-data-pipeline-spawns-500-threads-to-process-500-small-cpu-bound-number-crunching-tasks-in-pure-python-expecting-a-500x-speedup-on-a-16-core-machine-what-actually-happens-and-whats-the-better-approach","Q16. A team's data pipeline spawns 500 threads to process 500 small CPU-bound number-crunching tasks in pure Python, expecting a 500x speedup on a 16-core machine. What actually happens, and what's the better approach?",[23,107539,107541,107547,107556,107562],{"className":107540},[26],[28,107542,107544,107546],{"className":107543},[31],[33,107545],{"disabled":35,"type":36}," It gets the expected roughly-500x speedup since threads scale linearly with count",[28,107548,107550,107552,107553,107555],{"className":107549},[31],[33,107551],{"disabled":35,"type":36}," It gets little to no speedup — likely worse than sequential due to GIL contention and context-switching overhead among 500 threads; a ",[39,107554,105654],{}," sized to the CPU count (e.g., 16) would actually use the available cores",[28,107557,107559,107561],{"className":107558},[31],[33,107560],{"disabled":35,"type":36}," It crashes because Python enforces a hard limit of 100 threads",[28,107563,107565,107567],{"className":107564},[31],[33,107566],{"disabled":35,"type":36}," It gets exactly a 16x speedup automatically because the GIL load-balances across cores",[66,107569,107570,107572,107580],{},[69,107571,71],{},[73,107573,107574,107576,107577,107579],{},[76,107575,78],{}," B — Little to no speedup, likely worse than sequential due to GIL contention\u002Fcontext-switching; a right-sized ",[39,107578,105654],{}," would use the cores",[73,107581,107582,355,107584,107586,107587,107590],{},[76,107583,84],{},[76,107585,438],{}," Since only one thread executes Python bytecode at a time regardless of thread count, adding more threads for CPU-bound work doesn't add parallelism — it adds scheduling and context-switch overhead, which can make total throughput worse than a single thread doing the work sequentially. The fix is ",[39,107588,107589],{},"ProcessPoolExecutor(max_workers=16)"," (roughly matching core count) so the OS can schedule genuinely parallel processes, each with its own GIL. Over-threading for CPU work is a common performance anti-pattern from people assuming \"more threads = more parallel,\" which only holds once I\u002FO is involved.",[15,107592,107593,107600,107687,107730],{"language":87455},[18,107594,107596,107597,107599],{"id":107595},"q17-a-web-server-handler-stores-per-request-state-in-a-variable-at-module-scope-so-different-helper-functions-can-access-it-without-passing-it-explicitly-under-threading-why-is-this-dangerous-and-whats-the-fix","Q17. A web server handler stores per-request state in a variable at module scope so different helper functions can access it without passing it explicitly. Under ",[39,107598,105271],{},", why is this dangerous, and what's the fix?",[257,107601,107602],{"language":87455},[260,107603,107605],{"className":87467,"code":107604,"language":87455,"meta":264,"style":264},"current_user = None\n\ndef handle_request(user, request):\n    global current_user\n    current_user = user\n    process(request)\n\ndef process(request):\n    print(f\"Processing for {current_user}\")\n",[39,107606,107607,107616,107620,107630,107637,107647,107652,107656,107665],{"__ignoreMap":264},[268,107608,107609,107612,107614],{"class":270,"line":271},[268,107610,107611],{"class":282},"current_user ",[268,107613,302],{"class":274},[268,107615,91331],{"class":305},[268,107617,107618],{"class":270,"line":286},[268,107619,5033],{"emptyLinePlaceholder":35},[268,107621,107622,107624,107627],{"class":270,"line":296},[268,107623,88976],{"class":274},[268,107625,107626],{"class":278}," handle_request",[268,107628,107629],{"class":282},"(user, request):\n",[268,107631,107632,107634],{"class":270,"line":311},[268,107633,105837],{"class":274},[268,107635,107636],{"class":282}," current_user\n",[268,107638,107639,107642,107644],{"class":270,"line":788},[268,107640,107641],{"class":282},"    current_user ",[268,107643,302],{"class":274},[268,107645,107646],{"class":282}," user\n",[268,107648,107649],{"class":270,"line":1951},[268,107650,107651],{"class":282},"    process(request)\n",[268,107653,107654],{"class":270,"line":8955},[268,107655,5033],{"emptyLinePlaceholder":35},[268,107657,107658,107660,107662],{"class":270,"line":8966},[268,107659,88976],{"class":274},[268,107661,10851],{"class":278},[268,107663,107664],{"class":282},"(request):\n",[268,107666,107667,107669,107671,107673,107676,107678,107681,107683,107685],{"class":270,"line":8974},[268,107668,92017],{"class":305},[268,107670,622],{"class":282},[268,107672,35286],{"class":274},[268,107674,107675],{"class":289},"\"Processing for ",[268,107677,95289],{"class":305},[268,107679,107680],{"class":282},"current_user",[268,107682,95365],{"class":305},[268,107684,85220],{"class":289},[268,107686,20702],{"class":282},[23,107688,107690,107698,107711,107722],{"className":107689},[26],[28,107691,107693,107695,107696],{"className":107692},[31],[33,107694],{"disabled":35,"type":36}," It's safe — the GIL ensures each request sees only its own ",[39,107697,107680],{},[28,107699,107701,107703,107704,107706,107707,107710],{"className":107700},[31],[33,107702],{"disabled":35,"type":36}," Concurrent requests handled by different threads share the same module-level ",[39,107705,107680],{},", so one thread can overwrite it while another is mid-request, leaking one user's identity into another's processing; the fix is ",[39,107708,107709],{},"threading.local()"," to give each thread its own isolated copy",[28,107712,107714,107716,107717,107719,107720],{"className":107713},[31],[33,107715],{"disabled":35,"type":36}," It's safe as long as ",[39,107718,140],{}," is called immediately after setting ",[39,107721,107680],{},[28,107723,107725,355,107727,107729],{"className":107724},[31],[33,107726],{"disabled":35,"type":36},[39,107728,71866],{}," automatically makes the variable thread-safe by serializing access",[66,107731,107732,107734,107745],{},[69,107733,71],{},[73,107735,107736,107738,107739,107741,107742,107744],{},[76,107737,78],{}," B — Module-level ",[39,107740,107680],{}," is shared across all threads, so concurrent requests can clobber each other's value; use ",[39,107743,107709],{}," for per-thread isolation",[73,107746,107747,355,107749,107751,107752,107755,107756,107758,107759,107762,107763,107765,107766,107768],{},[76,107748,84],{},[76,107750,582],{}," A module-level variable lives in one shared namespace regardless of which thread touches it — there's no per-thread isolation just because the GIL exists. If Thread A sets ",[39,107753,107754],{},"current_user = alice"," and, before ",[39,107757,55749],{}," runs, the GIL switches to Thread B which sets ",[39,107760,107761],{},"current_user = bob",", Thread A's ",[39,107764,55749],{}," call could print \"Processing for bob,\" a serious correctness (and potentially security) bug. ",[39,107767,107709],{}," creates an object where each thread transparently sees its own independent attribute values — the standard fix for this exact per-request-state pattern, used internally by frameworks like Flask for request-context globals.",[15,107770,107771,107782],{"language":87455},[18,107772,107774,107775,107777,107778,107781],{"id":107773},"q18-when-submitting-many-quick-tasks-to-a-processpoolexecutor-why-might-poolmap-significantly-underperform-compared-to-running-them-in-a-single-process-even-though-the-tasks-are-cpu-bound","Q18. When submitting many quick tasks to a ",[39,107776,105654],{},", why might ",[39,107779,107780],{},"pool.map()"," significantly underperform compared to running them in a single process, even though the tasks are CPU-bound?",[257,107783,107784,107787,107790,107793,107801,107803,107864,107924],{"language":87455},[73,107785,107786],{},"from concurrent.futures import ProcessPoolExecutor",[73,107788,107789],{},"def square(x):\nreturn x * x",[73,107791,107792],{},"with ProcessPoolExecutor() as pool:\nresults = list(pool.map(square, range(1_000_000)))",[260,107794,107799],{"className":107795,"code":107797,"language":107798},[107796],"language-text","::\n\n- [ ] `ProcessPoolExecutor` never actually parallelizes anything; it's identical to a loop\n- [ ] For very cheap per-item work, the fixed cost of pickling each argument\u002Fresult and IPC round-trips per task can dwarf the actual computation time, making the overhead outweigh the parallelism gained; batching items (e.g., `chunksize`) or doing the work in one process is often faster\n- [ ] `pool.map()` silently caps at processing 1,000 items maximum\n- [ ] `ProcessPoolExecutor` requires manual chunking or it raises `MemoryError`\n\n\u003Cdetails>\n\u003Csummary>Show Answer\u003C\u002Fsummary>\n\n**Answer:** B — For cheap per-item work, pickling\u002FIPC overhead per task can dwarf actual computation, so overhead can outweigh parallelism gains; batching (`chunksize`) or single-process execution is often faster\n\n**Explanation:** **Performance:** Each call to `square(x)` here does trivial work, but by default `Pool.map`\u002F`ProcessPoolExecutor.map` may send items to workers with a small chunk size, meaning the per-task pickling\u002Funpickling and inter-process messaging cost can exceed the actual `x * x` computation many times over. The fix is to increase `chunksize` (grouping many items per IPC round-trip) or to recognize that sub-millisecond per-item tasks generally aren't good candidates for process-based parallelism at all — the overhead needs to be amortized over meaningfully larger units of work.\n\n\u003C\u002Fdetails>\n::\n\n::question-wrapper\n### Q19. For a long-running batch of independent CPU-bound tasks where results should be consumed as soon as each one finishes (not necessarily in submission order), which is more appropriate: `Pool.map()` or `Pool.imap_unordered()`?\n\n- [ ] `Pool.map()`, because it always finishes faster regardless of use case\n- [ ] `Pool.imap_unordered()`, because it yields each result as soon as any worker finishes it, rather than `map()`'s behavior of collecting all results and returning them (in original order) only once the entire batch completes\n- [ ] They are functionally identical; the name difference is purely cosmetic\n- [ ] `imap_unordered()` runs tasks sequentially in one process, unlike `map()`\n\n\u003Cdetails>\n\u003Csummary>Show Answer\u003C\u002Fsummary>\n\n**Answer:** B — `imap_unordered()` yields each result as soon as it's ready, rather than waiting for the whole batch like `map()`\n\n**Explanation:** **Idiom:** `Pool.map()` blocks until every task in the iterable is complete and then returns a list in the original submission order — fine when you need all results together, but wasteful if you want to start processing\u002Fstreaming results as they arrive. `imap_unordered()` returns an iterator that yields each finished result the moment its worker completes, in whatever order they finish, which better suits streaming pipelines or progress reporting, especially when task durations vary. Choosing `map()` by default even when order doesn't matter needlessly delays consuming the earliest-finished results.\n\n\u003C\u002Fdetails>\n::\n\n::question-wrapper{language=\"python\"}\n### Q20. A codebase mixes `threading.Lock` for protecting a shared cache with `multiprocessing.Process` workers that also read\u002Fwrite that same Python-level cache object. Why is this fundamentally broken, and what's the fix?\n\n::code-wrapper{language=\"python\"}\n```python\nimport threading\nfrom multiprocessing import Process\n\ncache = {}\nlock = threading.Lock()\n\ndef worker(key, value):\n    with lock:\n        cache[key] = value\n\nprocs = [Process(target=worker, args=(i, i * i)) for i in range(5)]\n","text",[39,107800,107797],{"__ignoreMap":264},[73,107802,84903],{},[23,107804,107806,107815,107842,107851],{"className":107805},[26],[28,107807,107809,107811,107812,107814],{"className":107808},[31],[33,107810],{"disabled":35,"type":36}," It works correctly — ",[39,107813,106009],{}," synchronizes across processes just like within a single process",[28,107816,107818,355,107820,107822,107823,107825,107826,186,107829,107831,107832,100662,107834,107837,107838,107841],{"className":107817},[31],[33,107819],{"disabled":35,"type":36},[39,107821,106009],{}," only synchronizes threads within the same process's memory; each ",[39,107824,105556],{}," gets its own independent copy of ",[39,107827,107828],{},"lock",[39,107830,15925],{},", so the lock provides no cross-process protection at all, and updates in workers never appear in the parent's ",[39,107833,15925],{},[39,107835,107836],{},"multiprocessing.Manager().dict()"," with a ",[39,107839,107840],{},"multiprocessing.Lock()",", or another IPC-aware shared structure",[28,107843,107845,107847,107848,107850],{"className":107844},[31],[33,107846],{"disabled":35,"type":36}," The code raises ",[39,107849,827],{}," at process-start time because locks can't be used in worker functions",[28,107852,107854,107856,107857,107859,107860,107863],{"className":107853},[31],[33,107855],{"disabled":35,"type":36}," It's correct, but only if ",[39,107858,107828],{}," is created inside ",[39,107861,107862],{},"worker()"," instead of at module scope",[66,107865,107866,107868,107886],{},[69,107867,71],{},[73,107869,107870,1727,107872,107874,107875,107877,107878,186,107880,107882,107883,107885],{},[76,107871,78],{},[39,107873,106009],{}," only works within one process's shared memory; each ",[39,107876,105556],{}," gets an independent copy of ",[39,107879,107828],{},[39,107881,15925],{},", so it gives zero cross-process protection, and the parent's ",[39,107884,15925],{}," never updates",[73,107887,107888,355,107890,355,107892,107894,107895,107897,107898,107900,107901,107903,107904,107906,107907,107909,107910,7415,107912,107914,107915,107917,107918,46957,107920,107923],{},[76,107889,84],{},[76,107891,582],{},[39,107893,106009],{}," is implemented against in-process memory primitives — when a ",[39,107896,105556],{}," is spawned\u002Fforked, it receives its own copy of the ",[39,107899,107828],{}," object (a distinct OS-level mutex, not a shared one) and its own copy of ",[39,107902,15925],{},", exactly like the ",[39,107905,35037],{}," example in Q9. Acquiring \"the same\" lock in different processes acquires two entirely different locks, providing no real mutual exclusion across processes, and any writes to ",[39,107908,15925],{}," inside a worker only affect that worker's private copy — the parent's ",[39,107911,15925],{},[39,107913,2328],{},". The correct fix uses cross-process-aware primitives: ",[39,107916,107836],{}," for a proxy-backed shared dict, combined with ",[39,107919,107840],{},[39,107921,107922],{},"threading.Lock()",") for true cross-process mutual exclusion.","\n::",[2107,107926,107927],{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}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 pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}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}",{"title":264,"searchDepth":286,"depth":286,"links":107929},[107930,107931,107933,107935,107937,107939,107941,107943,107945,107946,107947,107948,107950,107952,107953,107954,107955,107957],{"id":105112,"depth":296,"text":105113},{"id":105267,"depth":296,"text":107932},"Q2. For which of these workloads does threading typically give a real, measurable speedup in CPython?",{"id":105405,"depth":296,"text":107934},"Q3. Why does multiprocessing achieve real parallel speedup for CPU-bound work where threading does not?",{"id":105619,"depth":296,"text":107936},"Q4. Given concurrent.futures, which executor should you pick for (a) downloading 200 files over HTTP and (b) computing 200 independent CPU-heavy Fibonacci-like calculations in pure Python?",{"id":105715,"depth":296,"text":107938},"Q5. Why does a network call like socket.recv() or requests.get() allow other Python threads to make progress, even though the GIL normally lets only one thread run at a time?",{"id":105786,"depth":296,"text":107940},"Q6. Despite the GIL serializing bytecode execution, this code can still print a final counter value less than 200000. Why?",{"id":106018,"depth":296,"text":107942},"Q7. What overhead does multiprocessing introduce that threading does not, when passing data to and from worker processes?",{"id":106181,"depth":296,"text":107944},"Q8. What happens when you try to pass this to a multiprocessing.Pool?",{"id":106342,"depth":296,"text":106343},{"id":106569,"depth":296,"text":106570},{"id":106745,"depth":296,"text":106746},{"id":106956,"depth":296,"text":107949},"Q12. What is the effect of daemon=True on a thread, and what happens without it?",{"id":107118,"depth":296,"text":107951},"Q13. What is likely to go wrong if this script (using the default spawn start method, e.g. on Windows or macOS) omits the if __name__ == \"__main__\": guard?",{"id":107290,"depth":296,"text":107291},{"id":107340,"depth":296,"text":107341},{"id":107536,"depth":296,"text":107537},{"id":107595,"depth":296,"text":107956},"Q17. A web server handler stores per-request state in a variable at module scope so different helper functions can access it without passing it explicitly. Under threading, why is this dangerous, and what's the fix?",{"id":107773,"depth":296,"text":107958},"Q18. When submitting many quick tasks to a ProcessPoolExecutor, why might pool.map() significantly underperform compared to running them in a single process, even though the tasks are CPU-bound?",{},"\u002Fpython\u002F21-concurrency-threading-and-multiprocessing",{"title":105102,"description":264},"python\u002F21-concurrency-threading-and-multiprocessing","rPQDNWVoKzJNAMU3UvInJxSrR33EKbOtHDEqplJVe5o",{"id":107965,"title":107966,"body":107967,"description":107974,"extension":2144,"meta":108543,"navigation":35,"path":108544,"seo":108545,"stem":108546,"__hash__":108547},"content\u002Fpython\u002Findex.md","Python: Zero to Hero",{"type":8,"value":107968,"toc":108531},[107969,107972,107975,107977,107997,107999,108002,108004,108006,108104,108108,108197,108201,108275,108279,108381,108385,108444,108448],[11,107970,107966],{"id":107971},"python-zero-to-hero",[73,107973,107974],{},"A complete quiz-based curriculum covering Python from first principles to expert-level, production-grade knowledge. Python's simplicity hides a lot of nuance — this track is built around the surprises that trip up even experienced developers.",[83881,107976,83884],{"id":83883},[23,107978,107979,107982,107984,107989],{},[28,107980,107981],{},"Work through the parts in order; later quizzes assume comfort with core data structures and OOP from earlier parts.",[28,107983,83892],{},[28,107985,83895,107986,107988],{},[76,107987,71],{}," only after committing to a choice — the explanations cover the underlying mechanism (mutability, the GIL, MRO, descriptor protocol), not just the right letter.",[28,107990,107991,107992,7507,107994,107996],{},"Expect classic \"wat\" moments — mutable default arguments, late-binding closures, and ",[39,107993,4447],{},[39,107995,3197],{}," — turned into quiz questions.",[83881,107998,83908],{"id":83907},[73,108000,108001],{},"None for Part 1. Comfort with basic programming concepts (variables, loops) helps but isn't required.",[83881,108003,83915],{"id":83914},[18,108005,83919],{"id":83918},[83921,108007,108008,108018],{},[83924,108009,108010],{},[83927,108011,108012,108014,108016],{},[83930,108013,78878],{},[83930,108015,83934],{},[83930,108017,83937],{},[83939,108019,108020,108031,108048,108064,108079,108091],{},[83927,108021,108022,108024,108028],{},[83944,108023,83946],{},[83944,108025,108026],{},[1223,108027,83951],{"href":88939},[83944,108029,108030],{},"CPython vs. other implementations and version differences (2 vs 3) shape everything downstream.",[83927,108032,108033,108035,108039],{},[83944,108034,83959],{},[83944,108036,108037],{},[1223,108038,83964],{"href":91645},[83944,108040,108041,108042,108044,108045,108047],{},"Dynamic typing, object identity, and small-int caching produce classic ",[39,108043,4447],{},"-vs-",[39,108046,3197],{}," gotchas.",[83927,108049,108050,108052,108056],{},[83944,108051,83978],{},[83944,108053,108054],{},[1223,108055,83983],{"href":94126},[83944,108057,108058,108059,7507,108061,108063],{},"Chained comparisons, ",[39,108060,85028],{},[39,108062,446],{},", and operator overloading via dunder methods are frequent traps.",[83927,108065,108066,108068,108073],{},[83944,108067,83995],{},[83944,108069,108070],{},[1223,108071,84000],{"href":108072},"\u002Fpython\u002F04-control-flow",[83944,108074,108075,108078],{},[39,108076,108077],{},"for...else",", walrus operator, and truthy\u002Ffalsy rules for custom objects surprise newcomers.",[83927,108080,108081,108083,108088],{},[83944,108082,84013],{},[83944,108084,108085],{},[1223,108086,87038],{"href":108087},"\u002Fpython\u002F05-functions",[83944,108089,108090],{},"Mutable default arguments are Python's most famous footgun.",[83927,108092,108093,108095,108101],{},[83944,108094,84026],{},[83944,108096,108097],{},[1223,108098,108100],{"href":108099},"\u002Fpython\u002F06-strings-and-text","Strings & Text",[83944,108102,108103],{},"Immutability, encoding pitfalls, and f-string evaluation order matter in real code.",[18,108105,108107],{"id":108106},"part-2-core-data-structures","Part 2 — Core Data Structures",[83921,108109,108110,108120],{},[83924,108111,108112],{},[83927,108113,108114,108116,108118],{},[83930,108115,78878],{},[83930,108117,83934],{},[83930,108119,83937],{},[83939,108121,108122,108135,108148,108161,108185],{},[83927,108123,108124,108126,108132],{},[83944,108125,84039],{},[83944,108127,108128],{},[1223,108129,108131],{"href":108130},"\u002Fpython\u002F07-lists-and-tuples","Lists & Tuples",[83944,108133,108134],{},"Shallow copies, list aliasing, and tuple immutability-of-reference-not-contents are daily bugs.",[83927,108136,108137,108139,108145],{},[83944,108138,84052],{},[83944,108140,108141],{},[1223,108142,108144],{"href":108143},"\u002Fpython\u002F08-dictionaries-and-sets","Dictionaries & Sets",[83944,108146,108147],{},"Hashability rules and insertion-order guarantees (3.7+) affect correctness and performance.",[83927,108149,108150,108152,108158],{},[83944,108151,84065],{},[83944,108153,108154],{},[1223,108155,108157],{"href":108156},"\u002Fpython\u002F09-comprehensions-and-generators","Comprehensions & Generators",[83944,108159,108160],{},"Lazy evaluation and comprehension scoping are common sources of subtle bugs.",[83927,108162,108163,108165,108170],{},[83944,108164,5825],{},[83944,108166,108167],{},[1223,108168,84312],{"href":108169},"\u002Fpython\u002F10-functional-programming",[83944,108171,108172,446,108174,446,108176,42,108178,108180,108181,108184],{},[39,108173,23950],{},[39,108175,14962],{},[39,108177,14980],{},[39,108179,94698],{}," limitations, and ",[39,108182,108183],{},"functools"," are idiomatic in data-heavy code.",[83927,108186,108187,108189,108194],{},[83944,108188,6879],{},[83944,108190,108191],{},[1223,108192,108193],{"href":96785},"Closures & Decorators",[83944,108195,108196],{},"Late-binding closures in loops and decorator argument order are classic interview gotchas.",[18,108198,108200],{"id":108199},"part-3-oop-design","Part 3 — OOP & Design",[83921,108202,108203,108213],{},[83924,108204,108205],{},[83927,108206,108207,108209,108211],{},[83930,108208,78878],{},[83930,108210,83934],{},[83930,108212,83937],{},[83939,108214,108215,108227,108242,108259],{},[83927,108216,108217,108219,108224],{},[83944,108218,16513],{},[83944,108220,108221],{},[1223,108222,108223],{"href":99205},"Classes & Objects",[83944,108225,108226],{},"Class vs. instance attributes and mutable class-level defaults cause shared-state bugs.",[83927,108228,108229,108231,108236],{},[83944,108230,84136],{},[83944,108232,108233],{},[1223,108234,108235],{"href":101866},"Inheritance & Polymorphism",[83944,108237,108238,108239,108241],{},"Method Resolution Order (MRO) and ",[39,108240,30889],{}," in multiple inheritance are frequently misunderstood.",[83927,108243,108244,108246,108252],{},[83944,108245,6159],{},[83944,108247,108248],{},[1223,108249,108251],{"href":108250},"\u002Fpython\u002F14-magic-methods-and-protocols","Magic Methods & Protocols",[83944,108253,108254,446,108256,108258],{},[39,108255,89232],{},[39,108257,91244],{}," consistency and operator dunders define how objects behave idiomatically.",[83927,108260,108261,108263,108269],{},[83944,108262,24207],{},[83944,108264,108265],{},[1223,108266,108268],{"href":108267},"\u002Fpython\u002F15-properties-and-descriptors","Properties & Descriptors",[83944,108270,108271,108272,108274],{},"The descriptor protocol underlies ",[39,108273,98964],{},", ORMs, and much of Python's \"magic.\"",[18,108276,108278],{"id":108277},"part-4-robustness-io","Part 4 — Robustness & I\u002FO",[83921,108280,108281,108291],{},[83924,108282,108283],{},[83927,108284,108285,108287,108289],{},[83930,108286,78878],{},[83930,108288,83934],{},[83930,108290,83937],{},[83939,108292,108293,108314,108331,108347,108367],{},[83927,108294,108295,108297,108302],{},[83944,108296,84186],{},[83944,108298,108299],{},[1223,108300,84221],{"href":108301},"\u002Fpython\u002F16-error-handling",[83944,108303,108304,108305,108307,108308,108310,108311,108313],{},"Bare ",[39,108306,91317],{},", exception chaining, and ",[39,108309,51954],{},"-with-",[39,108312,9151],{}," interactions cause silent bugs.",[83927,108315,108316,108318,108324],{},[83944,108317,84204],{},[83944,108319,108320],{},[1223,108321,108323],{"href":108322},"\u002Fpython\u002F17-modules-and-packages","Modules & Packages",[83944,108325,108326,108327,108330],{},"Circular imports and ",[39,108328,108329],{},"__init__.py"," semantics are frequent real-world stumbling blocks.",[83927,108332,108333,108335,108341],{},[83944,108334,75181],{},[83944,108336,108337],{},[1223,108338,108340],{"href":108339},"\u002Fpython\u002F18-file-io-and-serialization","File I\u002FO & Serialization",[83944,108342,108343,108344,108346],{},"Context managers, encoding defaults, and ",[39,108345,106166],{}," security risks matter in production.",[83927,108348,108349,108351,108357],{},[83944,108350,84250],{},[83944,108352,108353],{},[1223,108354,108356],{"href":108355},"\u002Fpython\u002F19-iterators-and-context-managers","Iterators & Context Managers",[83944,108358,108359,108360,446,108363,108366],{},"The iterator protocol and ",[39,108361,108362],{},"__enter__",[39,108364,108365],{},"__exit__"," exception suppression are easy to misuse.",[83927,108368,108369,108371,108376],{},[83944,108370,6149],{},[83944,108372,108373],{},[1223,108374,108375],{"href":105096},"Type Hints & Typing",[83944,108377,108378,108380],{},[39,108379,102175],{},", generics, and runtime-vs-static-only enforcement are widely misunderstood.",[18,108382,108384],{"id":108383},"part-5-concurrency-meta","Part 5 — Concurrency & Meta",[83921,108386,108387,108397],{},[83924,108388,108389],{},[83927,108390,108391,108393,108395],{},[83930,108392,78878],{},[83930,108394,83934],{},[83930,108396,83937],{},[83939,108398,108399,108411,108427],{},[83927,108400,108401,108403,108408],{},[83944,108402,42534],{},[83944,108404,108405],{},[1223,108406,108407],{"href":107960},"Concurrency: Threading & Multiprocessing",[83944,108409,108410],{},"The GIL means threads don't parallelize CPU-bound work — a top source of design mistakes.",[83927,108412,108413,108415,108420],{},[83944,108414,84289],{},[83944,108416,108417],{},[1223,108418,84209],{"href":108419},"\u002Fpython\u002F22-async-await",[83944,108421,108422,108423,108426],{},"Blocking calls inside ",[39,108424,108425],{},"async def"," silently kill concurrency without raising an error.",[83927,108428,108429,108431,108437],{},[83944,108430,84307],{},[83944,108432,108433],{},[1223,108434,108436],{"href":108435},"\u002Fpython\u002F23-metaprogramming","Metaprogramming",[83944,108438,108439,108440,108443],{},"Metaclasses, ",[39,108441,108442],{},"__init_subclass__",", and dynamic attribute access power frameworks like Django.",[18,108445,108447],{"id":108446},"part-6-professional-expert","Part 6 — Professional & Expert",[83921,108449,108450,108460],{},[83924,108451,108452],{},[83927,108453,108454,108456,108458],{},[83930,108455,78878],{},[83930,108457,83934],{},[83930,108459,83937],{},[83939,108461,108462,108474,108491,108503,108519],{},[83927,108463,108464,108466,108471],{},[83944,108465,84338],{},[83944,108467,108468],{},[1223,108469,84356],{"href":108470},"\u002Fpython\u002F24-testing",[83944,108472,108473],{},"Fixture scope, mocking pitfalls, and parametrization determine test suite trustworthiness.",[83927,108475,108476,108478,108484],{},[83944,108477,31527],{},[83944,108479,108480],{},[1223,108481,108483],{"href":108482},"\u002Fpython\u002F25-packaging-and-virtual-environments","Packaging & Virtual Environments",[83944,108485,108486,108487,108490],{},"Dependency resolution and ",[39,108488,108489],{},"pyproject.toml"," conventions are essential for shipping real projects.",[83927,108492,108493,108495,108500],{},[83944,108494,84364],{},[83944,108496,108497],{},[1223,108498,84369],{"href":108499},"\u002Fpython\u002F26-performance-and-optimization",[83944,108501,108502],{},"Profiling before optimizing, and knowing where CPython is slow, prevents wasted effort.",[83927,108504,108505,108507,108512],{},[83944,108506,84377],{},[83944,108508,108509],{},[1223,108510,82350],{"href":108511},"\u002Fpython\u002F27-security",[83944,108513,108514,446,108516,108518],{},[39,108515,1341],{},[39,108517,106166],{}," risks and injection vectors are the most common Python vulnerabilities.",[83927,108520,108521,108523,108528],{},[83944,108522,84390],{},[83944,108524,108525],{},[1223,108526,84425],{"href":108527},"\u002Fpython\u002F28-exercises-and-projects",[83944,108529,108530],{},"A mixed-review capstone spanning generators, decorators, OOP, and concurrency.",{"title":264,"searchDepth":286,"depth":286,"links":108532},[108533,108534,108535],{"id":83883,"depth":286,"text":83884},{"id":83907,"depth":286,"text":83908},{"id":83914,"depth":286,"text":83915,"children":108536},[108537,108538,108539,108540,108541,108542],{"id":83918,"depth":296,"text":83919},{"id":108106,"depth":296,"text":108107},{"id":108199,"depth":296,"text":108200},{"id":108277,"depth":296,"text":108278},{"id":108383,"depth":296,"text":108384},{"id":108446,"depth":296,"text":108447},{},"\u002Fpython",{"title":107966,"description":107974},"python\u002Findex","iZwUlYxTbjKCkiu9TH3SCDGSFWWKSTHvecHFh62fIEA",{"id":108549,"title":6,"body":108550,"description":264,"extension":2144,"meta":110238,"navigation":35,"path":110239,"seo":110240,"stem":110241,"__hash__":110242},"content\u002Frust\u002F01-introduction-and-setup.md",{"type":8,"value":108551,"toc":110201},[108552,108554,108637,108744,108814,108899,108952,109039,109148,109238,109302,109383,109457,109563,109644,109751,109824,109898,109957,110026,110118],[11,108553,6],{"id":13},[15,108555,108556,108564,108594],{},[18,108557,108559,108560,108563],{"id":108558},"q1-what-is-rustup-primarily-responsible-for","Q1. What is ",[39,108561,108562],{},"rustup"," primarily responsible for?",[23,108565,108567,108573,108579,108588],{"className":108566},[26],[28,108568,108570,108572],{"className":108569},[31],[33,108571],{"disabled":35,"type":36}," Compiling Rust source files into binaries",[28,108574,108576,108578],{"className":108575},[31],[33,108577],{"disabled":35,"type":36}," Managing Rust toolchain installations (stable\u002Fbeta\u002Fnightly) and their components",[28,108580,108582,108584,108585],{"className":108581},[31],[33,108583],{"disabled":35,"type":36}," Managing project dependencies declared in ",[39,108586,108587],{},"Cargo.toml",[28,108589,108591,108593],{"className":108590},[31],[33,108592],{"disabled":35,"type":36}," Formatting Rust source code according to style guidelines",[66,108595,108596,108598,108603],{},[69,108597,71],{},[73,108599,108600,108602],{},[76,108601,78],{}," B — Managing Rust toolchain installations (stable\u002Fbeta\u002Fnightly) and their components",[73,108604,108605,355,108607,108609,108610,446,108613,108616,108617,99,108620,108623,108624,108626,108627,108629,108630,108633,108634,108636],{},[76,108606,84],{},[39,108608,108562],{}," is the toolchain multiplexer\u002Finstaller — it installs and switches between ",[39,108611,108612],{},"rustc",[39,108614,108615],{},"cargo"," versions and channels, and manages components like ",[39,108618,108619],{},"clippy",[39,108621,108622],{},"rust-src",". Compiling source is ",[39,108625,108612],{},"'s job (A), managing dependencies is ",[39,108628,108615],{},"'s job (C), and formatting is ",[39,108631,108632],{},"rustfmt","'s job (D) — ",[39,108635,108562],{}," sits a layer above all of these tools rather than performing their work itself.",[15,108638,108639,108651,108695],{},[18,108640,108642,108643,108646,108647,108650],{"id":108641},"q2-a-developer-runs-rustc-mainrs-directly-instead-of-using-cargo-build-what-is-the-main-practical-difference-for-a-project-with-dependencies","Q2. A developer runs ",[39,108644,108645],{},"rustc main.rs"," directly instead of using ",[39,108648,108649],{},"cargo build",". What is the main practical difference for a project with dependencies?",[23,108652,108654,108662,108673,108684],{"className":108653},[26],[28,108655,108657,108659,108660],{"className":108656},[31],[33,108658],{"disabled":35,"type":36}," There is no difference — both resolve crates listed in ",[39,108661,108587],{},[28,108663,108665,355,108667,108669,108670,108672],{"className":108664},[31],[33,108666],{"disabled":35,"type":36},[39,108668,108612],{}," compiles a single file\u002Fcrate root and has no knowledge of ",[39,108671,108587],{}," dependencies, so external crates won't be found",[28,108674,108676,355,108678,108680,108681,108683],{"className":108675},[31],[33,108677],{"disabled":35,"type":36},[39,108679,108612],{}," is strictly for nightly builds while ",[39,108682,108649],{}," is stable-only",[28,108685,108687,355,108689,108691,108692],{"className":108686},[31],[33,108688],{"disabled":35,"type":36},[39,108690,108645],{}," will automatically download and link any crates used with ",[39,108693,108694],{},"use",[66,108696,108697,108699,108707],{},[69,108698,71],{},[73,108700,108701,1727,108703,108669,108705,108672],{},[76,108702,78],{},[39,108704,108612],{},[39,108706,108587],{},[73,108708,108709,355,108711,108713,108714,108716,108717,96674,108719,108721,108722,446,108724,108727,108728,108730,108731,108734,108735,108737,108738,108740,108741,108743],{},[76,108710,84],{},[39,108712,108612],{}," is the raw compiler; it takes a crate root and emits an artifact, but it has no concept of ",[39,108715,108587],{},", dependency resolution, or crates.io. ",[39,108718,108615],{},[39,108720,108612],{},", resolving dependencies from ",[39,108723,108587],{},[39,108725,108726],{},"Cargo.lock"," and invoking ",[39,108729,108612],{}," with the correct ",[39,108732,108733],{},"--extern"," flags. ",[76,108736,930],{}," running bare ",[39,108739,108612],{}," is fine for a single throwaway file, but any real project needs ",[39,108742,108615],{}," to manage dependencies.",[15,108745,108746,108754,108781],{},[18,108747,108749,108750,108753],{"id":108748},"q3-as-of-rust-2024-what-edition-does-cargo-new-my_project-select-by-default-when-using-a-current-stable-toolchain","Q3. As of Rust 2024, what edition does ",[39,108751,108752],{},"cargo new my_project"," select by default when using a current stable toolchain?",[23,108755,108757,108763,108769,108775],{"className":108756},[26],[28,108758,108760,108762],{"className":108759},[31],[33,108761],{"disabled":35,"type":36}," 2015, for backward compatibility",[28,108764,108766,108768],{"className":108765},[31],[33,108767],{"disabled":35,"type":36}," 2018",[28,108770,108772,108774],{"className":108771},[31],[33,108773],{"disabled":35,"type":36}," 2021",[28,108776,108778,108780],{"className":108777},[31],[33,108779],{"disabled":35,"type":36}," 2024",[66,108782,108783,108785,108790],{},[69,108784,71],{},[73,108786,108787,108789],{},[76,108788,78],{}," D — 2024",[73,108791,108792,355,108794,108797,108798,9057,108800,108803,108804,108806,108807,108810,108811,108813],{},[76,108793,84],{},[39,108795,108796],{},"cargo new"," writes the newest stable edition supported by the installed toolchain into ",[39,108799,108587],{},[39,108801,108802],{},"edition"," field. Since the 2024 edition shipped, current ",[39,108805,108615],{}," defaults new projects to ",[39,108808,108809],{},"edition = \"2024\"",". Older answers (2015\u002F2018\u002F2021) were correct defaults at earlier points in Rust's history but are not current — the edition a project targets is fixed by what's written in ",[39,108812,108587],{},", not by which compiler happens to build it later.",[15,108815,108816,108820,108856],{},[18,108817,108819],{"id":108818},"q4-what-command-installs-a-specific-nightly-toolchain-and-sets-it-as-the-default-for-the-current-shelluser","Q4. What command installs a specific nightly toolchain and sets it as the default for the current shell\u002Fuser?",[23,108821,108823,108831,108839,108848],{"className":108822},[26],[28,108824,108826,355,108828],{"className":108825},[31],[33,108827],{"disabled":35,"type":36},[39,108829,108830],{},"cargo install nightly",[28,108832,108834,355,108836],{"className":108833},[31],[33,108835],{"disabled":35,"type":36},[39,108837,108838],{},"rustup toolchain add nightly",[28,108840,108842,355,108844,108847],{"className":108841},[31],[33,108843],{"disabled":35,"type":36},[39,108845,108846],{},"rustup default nightly"," (after nothing else)",[28,108849,108851,355,108853],{"className":108850},[31],[33,108852],{"disabled":35,"type":36},[39,108854,108855],{},"rustup install nightly && rustup default nightly",[66,108857,108858,108860,108866],{},[69,108859,71],{},[73,108861,108862,6901,108864],{},[76,108863,78],{},[39,108865,108855],{},[73,108867,108868,355,108870,108873,108874,108877,108878,108880,108881,108883,108884,108887,108888,108891,108892,108894,108895,108898],{},[76,108869,84],{},[39,108871,108872],{},"rustup install nightly"," (alias for ",[39,108875,108876],{},"rustup toolchain install nightly",") downloads the nightly toolchain, and ",[39,108879,108846],{}," makes it the active default. ",[39,108882,108838],{}," alone (C-style option) only installs it without switching the default. ",[39,108885,108886],{},"cargo install"," (A) installs Rust ",[104,108889,108890],{},"binaries\u002Fcrates",", not toolchains — a common beginner mix-up since both start with \"install\". Running ",[39,108893,108846],{}," with nothing installed first (C) will still work because ",[39,108896,108897],{},"rustup default"," implicitly installs if missing, but it's not the most explicit\u002Fidiomatic pairing shown here.",[15,108900,108901,108905,108936],{},[18,108902,108904],{"id":108903},"q5-which-statement-correctly-distinguishes-the-stable-beta-and-nightly-release-channels","Q5. Which statement correctly distinguishes the stable, beta, and nightly release channels?",[23,108906,108908,108914,108924,108930],{"className":108907},[26],[28,108909,108911,108913],{"className":108910},[31],[33,108912],{"disabled":35,"type":36}," Beta is for experimental features, nightly is the well-tested production channel",[28,108915,108917,108919,108920,108923],{"className":108916},[31],[33,108918],{"disabled":35,"type":36}," Nightly gets new unstable features first and allows ",[39,108921,108922],{},"#![feature(...)]"," flags; beta is a preview of the next stable release; stable is the production-recommended channel",[28,108925,108927,108929],{"className":108926},[31],[33,108928],{"disabled":35,"type":36}," Stable and nightly are identical except for release cadence",[28,108931,108933,108935],{"className":108932},[31],[33,108934],{"disabled":35,"type":36}," Beta only receives security patches, while stable receives new features",[66,108937,108938,108940,108947],{},[69,108939,71],{},[73,108941,108942,108944,108945,108923],{},[76,108943,78],{}," B — Nightly gets new unstable features first and allows ",[39,108946,108922],{},[73,108948,108949,108951],{},[76,108950,84],{}," Rust ships a new nightly every day (unstable, feature-gated APIs allowed), promotes a nightly to beta roughly every six weeks as a release candidate, and promotes beta to stable after another six weeks. Option A inverts the roles, and option D describes something closer to an LTS\u002Fsecurity-only model, which Rust's channels do not follow.",[15,108953,108954,108960,109000],{},[18,108955,2916,108957,65680],{"id":108956},"q6-what-does-rustup-component-add-clippy-do",[39,108958,108959],{},"rustup component add clippy",[23,108961,108963,108974,108983,108991],{"className":108962},[26],[28,108964,108966,108968,108969,108971,108972],{"className":108965},[31],[33,108967],{"disabled":35,"type":36}," Installs the ",[39,108970,108619],{}," crate as a project dependency in ",[39,108973,108587],{},[28,108975,108977,108979,108980,108982],{"className":108976},[31],[33,108978],{"disabled":35,"type":36}," Adds the ",[39,108981,108619],{}," lint tool as an available component for the currently active toolchain",[28,108984,108986,108988,108989],{"className":108985},[31],[33,108987],{"disabled":35,"type":36}," Switches the active toolchain to a Clippy-specific fork of ",[39,108990,108612],{},[28,108992,108994,108996,108997,108999],{"className":108993},[31],[33,108995],{"disabled":35,"type":36}," Enables Clippy lints globally for all future ",[39,108998,108649],{}," invocations automatically",[66,109001,109002,109004,109011],{},[69,109003,71],{},[73,109005,109006,109008,109009,108982],{},[76,109007,78],{}," B — Adds the ",[39,109010,108619],{},[73,109012,109013,109015,109016,42,109018,42,109020,42,109022,109025,109026,109029,109030,109033,109034,109036,109037,462],{},[76,109014,84],{}," Components (",[39,109017,108619],{},[39,109019,108632],{},[39,109021,108622],{},[39,109023,109024],{},"rust-analyzer",", etc.) are optional pieces bundled per toolchain; ",[39,109027,109028],{},"rustup component add"," fetches and enables one for the active toolchain, after which ",[39,109031,109032],{},"cargo clippy"," becomes available. It is not a project dependency (A) and does not run automatically during ",[39,109035,108649],{}," (D) — you must explicitly invoke ",[39,109038,109032],{},[15,109040,109041,109055,109109],{},[18,109042,109044,109045,186,109048,109051,109052,109054],{"id":109043},"q7-running-cargo-version-and-rustc-version-on-a-machine-with-rustup-installed-can-show-two-different-underlying-toolchain-versions-why-might-this-legitimately-happen","Q7. Running ",[39,109046,109047],{},"cargo --version",[39,109049,109050],{},"rustc --version"," on a machine with ",[39,109053,108562],{}," installed can show two different underlying toolchain versions. Why might this legitimately happen?",[23,109056,109058,109069,109080,109101],{"className":109057},[26],[28,109059,109061,109063,109064,186,109066,109068],{"className":109060},[31],[33,109062],{"disabled":35,"type":36}," It can't happen — ",[39,109065,108615],{},[39,109067,108612],{}," are always bundled from the exact same toolchain release",[28,109070,109072,355,109074,109076,109077,109079],{"className":109071},[31],[33,109073],{"disabled":35,"type":36},[39,109075,108615],{}," is versioned independently of ",[39,109078,108612],{}," and is always one major version behind",[28,109081,109083,109085,109086,99,109089,109092,109093,446,109095,109097,109098,109100],{"className":109082},[31],[33,109084],{"disabled":35,"type":36}," A per-directory ",[39,109087,109088],{},"rustup override",[39,109090,109091],{},"rust-toolchain.toml"," can pin a different toolchain than the global default, and ",[39,109094,108615],{},[39,109096,108612],{}," are invoked through ",[39,109099,108562],{},"'s shims which resolve the toolchain per-invocation",[28,109102,109104,355,109106,109108],{"className":109103},[31],[33,109105],{"disabled":35,"type":36},[39,109107,109050],{}," always reports the nightly version regardless of the active toolchain",[66,109110,109111,109113,109128],{},[69,109112,71],{},[73,109114,109115,109117,109118,99,109120,109092,109122,446,109124,109097,109126,109100],{},[76,109116,78],{}," C — A per-directory ",[39,109119,109088],{},[39,109121,109091],{},[39,109123,108615],{},[39,109125,108612],{},[39,109127,108562],{},[73,109129,109130,2247,109132,186,109134,109136,109137,109139,109140,109142,109143,186,109145,109147],{},[76,109131,84],{},[39,109133,108615],{},[39,109135,108612],{}," on the PATH are actually ",[39,109138,108562],{}," \"proxy\" shims that decide which real toolchain to invoke based on directory overrides, ",[39,109141,109091],{},", environment variables, then the global default — so version drift between two separate shell sessions\u002Fdirectories is expected and normal, not a bug. Within a single resolved toolchain, ",[39,109144,108615],{},[39,109146,108612],{}," do ship together as a matched pair, contradicting the premise that cargo runs \"one major version behind\" (B).",[15,109149,109150,109166,109210],{},[18,109151,109153,109154,2029,109156,109159,109160,109162,109163,109165],{"id":109152},"q8-a-ci-pipeline-pins-rust-toolchaintoml-with-channel-1720-but-a-contributor-has-only-nightly-installed-locally-via-rustup-what-happens-when-they-run-cargo-build-in-that-directory","Q8. A CI pipeline pins ",[39,109155,109091],{},[39,109157,109158],{},"channel = \"1.72.0\"",", but a contributor has only nightly installed locally via ",[39,109161,108562],{},". What happens when they run ",[39,109164,108649],{}," in that directory?",[23,109167,109169,109177,109183,109195],{"className":109168},[26],[28,109170,109172,355,109174,109176],{"className":109171},[31],[33,109173],{"disabled":35,"type":36},[39,109175,108615],{}," silently falls back to their installed nightly toolchain",[28,109178,109180,109182],{"className":109179},[31],[33,109181],{"disabled":35,"type":36}," The build fails immediately with a \"no default toolchain configured\" panic",[28,109184,109186,355,109188,109190,109191,109194],{"className":109185},[31],[33,109187],{"disabled":35,"type":36},[39,109189,108562],{}," automatically downloads and installs the pinned 1.72.0 toolchain (if ",[39,109192,109193],{},"auto-install"," is enabled, the default), then uses it for that directory",[28,109196,109198,355,109200,109202,109203,109205,109206,109209],{"className":109197},[31],[33,109199],{"disabled":35,"type":36},[39,109201,108649],{}," ignores ",[39,109204,109091],{}," unless ",[39,109207,109208],{},"--locked"," is passed",[66,109211,109212,109214,109222],{},[69,109213,71],{},[73,109215,109216,1004,109218,109190,109220,109194],{},[76,109217,78],{},[39,109219,108562],{},[39,109221,109193],{},[73,109223,109224,355,109226,109228,109229,109231,109232,109234,109235,109237],{},[76,109225,84],{},[39,109227,109091],{}," overrides toolchain selection for anyone building inside that directory tree; by default ",[39,109230,108562],{}," will fetch the missing pinned toolchain automatically rather than silently using whatever is already installed. ",[76,109233,182],{}," this is precisely why teams commit ",[39,109236,109091],{}," — it makes builds reproducible across machines regardless of what each developer happened to install, avoiding the silent-fallback trap in option A which would produce version-dependent, non-reproducible builds.",[15,109239,109240,109248,109279],{},[18,109241,109243,109244,109247],{"id":109242},"q9-a-file-uses-featurelet_chains-at-the-crate-root-and-is-compiled-with-the-default-stable-toolchain-what-happens","Q9. A file uses ",[39,109245,109246],{},"#![feature(let_chains)]"," at the crate root and is compiled with the default stable toolchain. What happens?",[23,109249,109251,109257,109267,109273],{"className":109250},[26],[28,109252,109254,109256],{"className":109253},[31],[33,109255],{"disabled":35,"type":36}," It compiles fine — feature flags are just documentation comments to the stable compiler",[28,109258,109260,109262,109263,109266],{"className":109259},[31],[33,109261],{"disabled":35,"type":36}," Compile error: ",[39,109264,109265],{},"#![feature]"," attributes are only permitted on a nightly compiler",[28,109268,109270,109272],{"className":109269},[31],[33,109271],{"disabled":35,"type":36}," It compiles but emits a deprecation warning",[28,109274,109276,109278],{"className":109275},[31],[33,109277],{"disabled":35,"type":36}," It silently disables the named feature and continues compiling the rest of the file",[66,109280,109281,109283,109290],{},[69,109282,71],{},[73,109284,109285,109287,109288,109266],{},[76,109286,78],{}," B — Compile error: ",[39,109289,109265],{},[73,109291,109292,109294,109295,109297,109298,109301],{},[76,109293,84],{}," Unstable feature gates are only recognized on the nightly channel; stable and beta compilers reject ",[39,109296,108922],{}," with a hard error (",[39,109299,109300],{},"error[E0554]: #![feature] may not be used on the stable release channel","). This is a deliberate stability guarantee — it stops unstable APIs from leaking into code that ships on stable, unlike the tempting but incorrect assumption in A that unknown attributes are just ignored.",[15,109303,109304,109316,109352],{},[18,109305,109307,109308,109311,109312,109315],{"id":109306},"q10-inside-projectsexperimental-a-developer-runs-rustup-override-set-nightly-what-is-the-scope-of-this-change","Q10. Inside ",[39,109309,109310],{},"~\u002Fprojects\u002Fexperimental\u002F",", a developer runs ",[39,109313,109314],{},"rustup override set nightly",". What is the scope of this change?",[23,109317,109319,109325,109334,109344],{"className":109318},[26],[28,109320,109322,109324],{"className":109321},[31],[33,109323],{"disabled":35,"type":36}," It permanently changes the global default toolchain for the whole system",[28,109326,109328,109330,109331,109333],{"className":109327},[31],[33,109329],{"disabled":35,"type":36}," It only affects that one ",[39,109332,108649],{}," invocation and resets afterward",[28,109335,109337,109339,109340,109343],{"className":109336},[31],[33,109338],{"disabled":35,"type":36}," It pins the ",[39,109341,109342],{},"experimental"," directory (and its subdirectories) to nightly, leaving the global default and other directories untouched",[28,109345,109347,109349,109350],{"className":109346},[31],[33,109348],{"disabled":35,"type":36}," It has no effect unless combined with ",[39,109351,108846],{},[66,109353,109354,109356,109363],{},[69,109355,71],{},[73,109357,109358,109360,109361,109343],{},[76,109359,78],{}," C — It pins the ",[39,109362,109342],{},[73,109364,109365,355,109367,109370,109371,109373,109374,109376,109377,109379,109380,109382],{},[76,109366,84],{},[39,109368,109369],{},"rustup override set"," writes a directory-scoped override (tracked internally by ",[39,109372,108562],{},", independent of ",[39,109375,109091],{},") that takes precedence over the global default only within that directory tree. It does not touch ",[39,109378,108897],{}," (A) — a beginner might assume overrides are global since ",[39,109381,108897],{}," sounds similar, but the two are deliberately separate mechanisms for different scopes.",[15,109384,109385,109395,109429],{},[18,109386,109388,109389,2018,109392,109394],{"id":109387},"q11-a-team-upgrades-a-crate-from-the-2018-edition-to-the-2021-edition-by-editing-edition-2021-in-cargotoml-with-no-other-changes-what-is-the-safest-correct-process-and-why","Q11. A team upgrades a crate from the 2018 edition to the 2021 edition by editing ",[39,109390,109391],{},"edition = \"2021\"",[39,109393,108587],{}," with no other changes. What is the safest correct process, and why?",[23,109396,109398,109404,109410,109423],{"className":109397},[26],[28,109399,109401,109403],{"className":109400},[31],[33,109402],{"disabled":35,"type":36}," Editing the field alone is always sufficient and risk-free since editions are purely cosmetic",[28,109405,109407,109409],{"className":109406},[31],[33,109408],{"disabled":35,"type":36}," Editions require a full rewrite in a new crate, since old syntax is entirely rejected",[28,109411,109413,88738,109415,109418,109419,109422],{"className":109412},[31],[33,109414],{"disabled":35,"type":36},[39,109416,109417],{},"cargo fix --edition"," first to migrate idiom-affecting changes (e.g. array ",[39,109420,109421],{},"IntoIterator"," behavior, disjoint closure captures), then set the edition and verify tests pass",[28,109424,109426,109428],{"className":109425},[31],[33,109427],{"disabled":35,"type":36}," Editions cannot be upgraded incrementally; you must vendor the entire dependency tree first",[66,109430,109431,109433,109442],{},[69,109432,71],{},[73,109434,109435,109437,109438,109418,109440,109422],{},[76,109436,78],{}," C — Run ",[39,109439,109417],{},[39,109441,109421],{},[73,109443,109444,109446,109447,109450,109451,109453,109454,109456],{},[76,109445,84],{}," Editions are Rust's mechanism for introducing small, deliberately-scoped breaking changes (e.g. ",[39,109448,109449],{},"into_iter()"," on arrays yielding values instead of references since 2021) without splitting the ecosystem; ",[39,109452,109417],{}," automates most of the mechanical migration. Editions are ",[104,109455,95],{}," purely cosmetic (A is a tempting but wrong simplification) — real behavioral differences exist, which is exactly why blind field-editing without testing can silently change runtime behavior.",[15,109458,109459,109483,109523],{},[18,109460,109462,109463,2029,109465,186,109468,109471,109472,109474,109475,109477,109478,446,109480,109482],{"id":109461},"q12-a-repositorys-root-contains-a-rust-toolchaintoml-with-channel-stable-and-components-clippy-rustfmt-a-contributor-runs-cargo-build-without-ever-running-rustup-component-add-what-happens-to-clippyrustfmt-availability","Q12. A repository's root contains a ",[39,109464,109091],{},[39,109466,109467],{},"channel = \"stable\"",[39,109469,109470],{},"components = [\"clippy\", \"rustfmt\"]",". A contributor runs ",[39,109473,108649],{}," without ever running ",[39,109476,109028],{},". What happens to ",[39,109479,108619],{},[39,109481,108632],{}," availability?",[23,109484,109486,109494,109502,109508],{"className":109485},[26],[28,109487,109489,52864,109491,109493],{"className":109488},[31],[33,109490],{"disabled":35,"type":36},[39,109492,109091],{}," only affects the channel, never components",[28,109495,109497,355,109499,109501],{"className":109496},[31],[33,109498],{"disabled":35,"type":36},[39,109500,108562],{}," installs the listed components automatically as part of resolving the pinned toolchain for that directory",[28,109503,109505,109507],{"className":109504},[31],[33,109506],{"disabled":35,"type":36}," The build fails because required components are missing",[28,109509,109511,109513,109514,109516,109517,109519,109520],{"className":109510},[31],[33,109512],{"disabled":35,"type":36}," Components listed in ",[39,109515,109091],{}," are ignored unless ",[39,109518,108615],{}," is run with ",[39,109521,109522],{},"--all-features",[66,109524,109525,109527,109533],{},[69,109526,71],{},[73,109528,109529,1727,109531,109501],{},[76,109530,78],{},[39,109532,108562],{},[73,109534,109535,4396,109537,109540,109541,109543,109544,42,109547,42,109550,137,109553,2272,109555,109557,109558,446,109560,109562],{},[76,109536,84],{},[39,109538,109539],{},"[toolchain]"," table in ",[39,109542,109091],{}," can declare ",[39,109545,109546],{},"channel",[39,109548,109549],{},"components",[39,109551,109552],{},"targets",[39,109554,54011],{},[39,109556,108562],{}," provisions all of them automatically the first time the toolchain is resolved in that directory, so a fresh clone gets a fully working ",[39,109559,108619],{},[39,109561,108632],{}," setup with zero manual steps. This is a widely underused feature — many assume (incorrectly, option A) that the file only pins the compiler version.",[15,109564,109565,109579,109619],{},[18,109566,109568,109569,109572,109573,109575,109576,109578],{"id":109567},"q13-a-crate-declares-rust-version-170-msrv-in-cargotoml-a-contributor-on-rust-165-stable-runs-cargo-build-what-happens","Q13. A crate declares ",[39,109570,109571],{},"rust-version = \"1.70\""," (MSRV) in ",[39,109574,108587],{},". A contributor on Rust 1.65 stable runs ",[39,109577,108649],{},". What happens?",[23,109580,109582,109593,109602,109613],{"className":109581},[26],[28,109583,109585,355,109587,100298,109589,109592],{"className":109584},[31],[33,109586],{"disabled":35,"type":36},[39,109588,108615],{},[39,109590,109591],{},"rust-version"," — it's purely informational metadata shown on crates.io, so the build proceeds normally on 1.65",[28,109594,109596,109598,109599,109601],{"className":109595},[31],[33,109597],{"disabled":35,"type":36}," Since Rust 1.65 supports MSRV-aware resolution for the ",[39,109600,109591],{}," field itself in newer cargo versions, and if the code actually uses syntax\u002FAPIs from 1.70, compilation fails with errors about unrecognized syntax or missing items — cargo does not downgrade language features for you",[28,109603,109605,355,109607,109609,109610,109612],{"className":109604},[31],[33,109606],{"disabled":35,"type":36},[39,109608,108615],{}," automatically installs Rust 1.70 via ",[39,109611,108562],{}," to satisfy the requirement",[28,109614,109616,109618],{"className":109615},[31],[33,109617],{"disabled":35,"type":36}," The build always fails immediately with an MSRV violation error before any compilation is attempted, regardless of what language features are actually used",[66,109620,109621,109623,109628],{},[69,109622,71],{},[73,109624,109625,109627],{},[76,109626,78],{}," B — If the code actually uses syntax\u002FAPIs from 1.70, compilation fails with errors about unrecognized syntax or missing items; cargo does not downgrade language features for you",[73,109629,109630,355,109632,109634,109635,109637,109638,109640,109641,109643],{},[76,109631,84],{},[39,109633,109591],{}," is primarily advisory metadata (and, in newer cargo, can influence dependency version resolution to prefer MSRV-compatible versions), but it does not make cargo auto-install a compiler (C) or hard-fail purely on the declared number (D) — the ",[104,109636,97216],{}," failure, if any, comes from the older ",[39,109639,108612],{}," genuinely not understanding newer syntax or standard library items used in the code. ",[76,109642,182],{}," MSRV mismatches are a common real-world CI trap — the fix is either raising the contributor's toolchain or avoiding the newer language feature in the crate.",[15,109645,109646,109666,109713],{},[18,109647,109649,109650,5125,109652,109655,109656,109658,109659,109662,109663,109665],{"id":109648},"q14-what-happens-if-you-run-rustc-on-a-rs-file-that-has-zero-use-statements-and-a-fn-main-body-with-no-cargotoml-anywhere-nearby","Q14. What happens if you run ",[39,109651,108612],{},[39,109653,109654],{},".rs"," file that has zero ",[39,109657,108694],{}," statements and a ",[39,109660,109661],{},"fn main() {}"," body, with no ",[39,109664,108587],{}," anywhere nearby?",[23,109667,109669,109681,109690,109703],{"className":109668},[26],[28,109670,109672,109674,109675,109677,109678,109680],{"className":109671},[31],[33,109673],{"disabled":35,"type":36}," It fails because ",[39,109676,108612],{}," always requires a ",[39,109679,108587],{}," to know the crate name",[28,109682,109684,109686,109687,109689],{"className":109683},[31],[33,109685],{"disabled":35,"type":36}," It compiles successfully — ",[39,109688,108612],{}," can compile a standalone file into a binary using only the standard library, entirely independent of Cargo",[28,109691,109693,109674,109695,109698,109699,109702],{"className":109692},[31],[33,109694],{"disabled":35,"type":36},[39,109696,109697],{},"main.rs"," must live inside a ",[39,109700,109701],{},"src\u002F"," directory",[28,109704,109706,109708,109709,109712],{"className":109705},[31],[33,109707],{"disabled":35,"type":36}," It compiles but produces a ",[39,109710,109711],{},".rlib"," instead of an executable by default",[66,109714,109715,109717,109724],{},[69,109716,71],{},[73,109718,109719,109721,109722,109689],{},[76,109720,78],{}," B — It compiles successfully; ",[39,109723,108612],{},[73,109725,109726,355,109728,109730,109731,109734,109735,109738,109739,109741,109742,109744,109745,109747,109748,4755],{},[76,109727,84],{},[39,109729,108612],{}," predates and does not require Cargo at all — Cargo is a build-system\u002Fpackage-manager layered on top. A bare ",[39,109732,109733],{},"rustc file.rs"," with only ",[39,109736,109737],{},"std"," usage compiles to an executable by default (binary crate type), with no ",[39,109740,109701],{}," directory or ",[39,109743,108587],{}," requirement. Option D confuses the default crate-type: ",[39,109746,109711],{}," output only happens if you pass ",[39,109749,109750],{},"--crate-type=lib",[15,109752,109753,109757,109801],{},[18,109754,109756],{"id":109755},"q15-which-is-the-recommended-way-to-install-rust-on-a-development-machine-and-why","Q15. Which is the recommended way to install Rust on a development machine, and why?",[23,109758,109760,109775,109783,109792],{"className":109759},[26],[28,109761,109763,109765,109766,186,109768,109770,109771,109774],{"className":109762},[31],[33,109764],{"disabled":35,"type":36}," Install ",[39,109767,108612],{},[39,109769,108615],{}," separately via the OS package manager (e.g. ",[39,109772,109773],{},"apt install rustc cargo","), since it's pre-integrated with system libraries",[28,109776,109778,4353,109780,109782],{"className":109777},[31],[33,109779],{"disabled":35,"type":36},[39,109781,108562],{},", since it manages multiple toolchains\u002Fchannels, supports per-project overrides, and keeps the toolchain easily updatable independent of the OS release cycle",[28,109784,109786,109788,109789,109791],{"className":109785},[31],[33,109787],{"disabled":35,"type":36}," Manually download prebuilt ",[39,109790,108612],{}," binaries from GitHub Releases and add them to PATH",[28,109793,109795,109797,109798,109800],{"className":109794},[31],[33,109796],{"disabled":35,"type":36}," Compile ",[39,109799,108612],{}," from source on first install for maximum compatibility",[66,109802,109803,109805,109811],{},[69,109804,71],{},[73,109806,109807,4409,109809,109782],{},[76,109808,78],{},[39,109810,108562],{},[73,109812,109813,355,109815,109817,109818,109820,109821,109823],{},[76,109814,84],{},[39,109816,108562],{}," is the officially recommended installer specifically because OS package managers (A) often ship an outdated, single, system-wide Rust version tied to the distro's release cadence, making per-project toolchain pinning and quick updates painful. ",[76,109819,930],{}," professional Rust workflows almost universally standardize on ",[39,109822,108562],{}," for exactly this flexibility, reserving OS packages mainly for minimal container images where a single fixed version is acceptable.",[15,109825,109826,109830,109871],{},[18,109827,109829],{"id":109828},"q16-for-a-team-that-wants-every-contributor-and-ci-runner-to-build-with-the-exact-same-compiler-version-automatically-what-is-the-best-practice-setup","Q16. For a team that wants every contributor and CI runner to build with the exact same compiler version automatically, what is the best-practice setup?",[23,109831,109833,109839,109851,109861],{"className":109832},[26],[28,109834,109836,109838],{"className":109835},[31],[33,109837],{"disabled":35,"type":36}," Document the required version in the README and trust contributors to install it manually",[28,109840,109842,109844,109845,109847,109848,109850],{"className":109841},[31],[33,109843],{"disabled":35,"type":36}," Commit a ",[39,109846,109091],{}," file with a pinned ",[39,109849,109546],{}," value at the repository root",[28,109852,109854,54143,109856,109858,109859,1619],{"className":109853},[31],[33,109855],{"disabled":35,"type":36},[39,109857,109591],{}," field to ",[39,109860,108587],{},[28,109862,109864,109866,109867,109870],{"className":109863},[31],[33,109865],{"disabled":35,"type":36}," Require everyone to run ",[39,109868,109869],{},"rustup update"," before every build",[66,109872,109873,109875,109884],{},[69,109874,71],{},[73,109876,109877,109879,109880,109847,109882,109850],{},[76,109878,78],{}," B — Commit a ",[39,109881,109091],{},[39,109883,109546],{},[73,109885,109886,109888,109889,109891,109892,109894,109895,109897],{},[76,109887,84],{}," Committing ",[39,109890,109091],{}," makes toolchain pinning automatic and enforced by tooling rather than relying on documentation discipline (A, easy to go stale) or ",[39,109893,109591],{}," (C, which is advisory\u002FMSRV-oriented, not a hard pin — it doesn't force a specific compiler, just declares a floor). ",[39,109896,109869],{}," (D) does the opposite of pinning — it moves everyone to the latest, which can introduce drift between machines.",[15,109899,109900,109907,109937],{},[18,109901,109903,109904,109906],{"id":109902},"q17-a-library-needs-an-unstable-standard-library-api-only-available-via-feature-on-nightly-what-is-the-idiomatic-recommendation-for-a-crate-intended-for-wide-production-use","Q17. A library needs an unstable standard library API only available via ",[39,109905,108922],{}," on nightly. What is the idiomatic recommendation for a crate intended for wide production use?",[23,109908,109910,109916,109922,109928],{"className":109909},[26],[28,109911,109913,109915],{"className":109912},[31],[33,109914],{"disabled":35,"type":36}," Ship it requiring nightly permanently, since nightly is functionally a superset of stable and equally safe for production",[28,109917,109919,109921],{"className":109918},[31],[33,109920],{"disabled":35,"type":36}," Avoid the unstable feature and find a stable-compatible alternative (or gate the nightly-only code path behind an optional feature flag), since requiring nightly forces every downstream consumer onto an unstable, less API-stable compiler",[28,109923,109925,109927],{"className":109924},[31],[33,109926],{"disabled":35,"type":36}," Vendor a copy of the nightly compiler inside the crate's repository",[28,109929,109931,109933,109934,109936],{"className":109930},[31],[33,109932],{"disabled":35,"type":36}," Silently use the feature without any ",[39,109935,108922],{}," gate since stable compilers permit unstable APIs on crates.io",[66,109938,109939,109941,109946],{},[69,109940,71],{},[73,109942,109943,109945],{},[76,109944,78],{}," B — Avoid the unstable feature and find a stable-compatible alternative (or gate the nightly-only code path behind an optional feature flag), since requiring nightly forces every downstream consumer onto an unstable, less API-stable compiler",[73,109947,109948,109950,109951,109953,109954,109956],{},[76,109949,84],{}," Widely-used production crates generally avoid hard nightly requirements because nightly's unstable APIs can change or disappear between releases with no deprecation guarantee, unlike stable's strict backward-compatibility promise. Option A is the tempting trap: nightly ",[104,109952,10043],{}," include everything stable has, but \"superset\" doesn't mean \"equally safe\" — the unstable portion is explicitly unguaranteed. Option D is simply false: ",[39,109955,109265],{}," gates are mandatory and stable rejects them outright (see Q9).",[15,109958,109959,109963,110002],{},[18,109960,109962],{"id":109961},"q18-when-rust-ships-a-new-edition-eg-2024-what-is-the-recommended-migration-workflow-for-an-existing-crate","Q18. When Rust ships a new edition (e.g. 2024), what is the recommended migration workflow for an existing crate?",[23,109964,109966,109977,109983,109996],{"className":109965},[26],[28,109967,109969,109971,109972,2018,109974,109976],{"className":109968},[31],[33,109970],{"disabled":35,"type":36}," Immediately bump ",[39,109973,108802],{},[39,109975,108587],{}," with no other action, then fix whatever compile errors appear",[28,109978,109980,109982],{"className":109979},[31],[33,109981],{"disabled":35,"type":36}," Never adopt new editions — staying on the original edition forever is the safest long-term choice",[28,109984,109986,88738,109988,109990,109991,2018,109993,109995],{"className":109985},[31],[33,109987],{"disabled":35,"type":36},[39,109989,109417],{}," on the current edition first to apply automated migrations, review the diff, then update ",[39,109992,108802],{},[39,109994,108587],{},", and finally run the full test suite",[28,109997,109999,110001],{"className":109998},[31],[33,110000],{"disabled":35,"type":36}," Rewrite the crate from scratch targeting the new edition",[66,110003,110004,110006,110016],{},[69,110005,71],{},[73,110007,110008,109437,110010,109990,110012,2018,110014,109995],{},[76,110009,78],{},[39,110011,109417],{},[39,110013,108802],{},[39,110015,108587],{},[73,110017,110018,355,110020,110022,110023,110025],{},[76,110019,84],{},[39,110021,109417],{}," is purpose-built to mechanically apply the safe, known migrations for the ",[104,110024,16949],{}," edition before you actually switch, minimizing manual breakage — jumping straight to editing the field (A) skips this safety net and can leave silent behavioral differences uncaught by the compiler (e.g., changes to closure capture or iterator semantics that compile fine both ways but behave differently). Staying on an old edition forever (B) is a legitimate but conservative choice, not the generally recommended one, since crates interop across editions within a dependency graph anyway.",[15,110027,110028,110035,110080],{},[18,110029,110031,110032,110034],{"id":110030},"q19-what-is-the-idiomatic-way-to-check-code-style-and-common-mistakes-beyond-what-rustc-itself-reports-before-opening-a-pull-request","Q19. What is the idiomatic way to check code style and common mistakes beyond what ",[39,110033,108612],{}," itself reports, before opening a pull request?",[23,110036,110038,110050,110065,110071],{"className":110037},[26],[28,110039,110041,110043,110044,110046,110047,110049],{"className":110040},[31],[33,110042],{"disabled":35,"type":36}," Rely solely on ",[39,110045,108649],{}," warnings, since ",[39,110048,108612],{}," already reports every stylistic and logic issue",[28,110051,110053,88738,110055,110058,110059,110061,110062],{"className":110052},[31],[33,110054],{"disabled":35,"type":36},[39,110056,110057],{},"cargo fmt"," to format and ",[39,110060,109032],{}," to lint, both installed via ",[39,110063,110064],{},"rustup component add rustfmt clippy",[28,110066,110068,110070],{"className":110067},[31],[33,110069],{"disabled":35,"type":36}," Manually re-read the diff for style issues; automated linting is unnecessary in Rust",[28,110072,110074,4353,110076,110079],{"className":110073},[31],[33,110075],{"disabled":35,"type":36},[39,110077,110078],{},"rustc --lint-all"," as a single command that replaces both formatting and linting",[66,110081,110082,110084,110095],{},[69,110083,71],{},[73,110085,110086,110088,110089,110058,110091,110061,110093],{},[76,110087,78],{}," B — Run ",[39,110090,110057],{},[39,110092,109032],{},[39,110094,110064],{},[73,110096,110097,355,110099,110101,110102,110104,110105,6033,110108,110111,110112,110114,110115,110117],{},[76,110098,84],{},[39,110100,108612],{},"'s built-in warnings focus on correctness\u002Fsoundness, not style or idiom; ",[39,110103,108619],{}," catches a much broader class of stylistic, performance, and common-mistake lints (e.g. needless clones, ",[39,110106,110107],{},".unwrap()",[39,110109,110110],{},"Result"," in non-test code), while ",[39,110113,108632],{}," enforces consistent formatting. ",[39,110116,110078],{}," (D) is not a real flag — a plausible-sounding distractor for anyone assuming the compiler alone covers everything.",[15,110119,110120,110131,110164],{},[18,110121,110123,110124,110126,110127,110130],{"id":110122},"q20-a-developer-notices-cargo-build-debug-profile-produces-a-binary-that-runs-noticeably-slower-than-cargo-build-release-what-best-practice-conclusion-should-they-draw","Q20. A developer notices ",[39,110125,108649],{}," (debug profile) produces a binary that runs noticeably slower than ",[39,110128,110129],{},"cargo build --release",". What best-practice conclusion should they draw?",[23,110132,110134,110140,110150,110158],{"className":110133},[26],[28,110135,110137,110139],{"className":110136},[31],[33,110138],{"disabled":35,"type":36}," This indicates a compiler bug and should be reported immediately",[28,110141,110143,110145,110146,110149],{"className":110142},[31],[33,110144],{"disabled":35,"type":36}," Debug builds intentionally skip most optimizations and include extra runtime checks (like overflow checks) to prioritize fast compile times and better debugging; use ",[39,110147,110148],{},"--release"," for performance testing and production artifacts, and the default debug profile for day-to-day development iteration",[28,110151,110153,355,110155,110157],{"className":110152},[31],[33,110154],{"disabled":35,"type":36},[39,110156,110148],{}," only changes the output file name, not actual compiled behavior",[28,110159,110161,110163],{"className":110160},[31],[33,110162],{"disabled":35,"type":36}," Debug and release builds are functionally identical except for binary size",[66,110165,110166,110168,110175],{},[69,110167,71],{},[73,110169,110170,110172,110173,110149],{},[76,110171,78],{}," B — Debug builds intentionally skip most optimizations and include extra runtime checks (like overflow checks) to prioritize fast compile times and better debugging; use ",[39,110174,110148],{},[73,110176,110177,4396,110179,110182,110183,110186,110187,110190,110191,110194,110195,110197,110198,110200],{},[76,110178,84],{},[39,110180,110181],{},"dev"," (default) profile favors compile speed and debuggability (",[39,110184,110185],{},"opt-level = 0",", overflow checks on, debug symbols included), while ",[39,110188,110189],{},"release"," enables optimizations (",[39,110192,110193],{},"opt-level = 3"," by default) and disables overflow checks, trading compile time for runtime speed. ",[76,110196,438],{}," always benchmark and ship with ",[39,110199,110148],{}," — never draw performance conclusions, and never ship to production, using unoptimized debug builds, since the \"slowness\" observed here is expected behavior, not a defect (ruling out option A).",{"title":264,"searchDepth":286,"depth":286,"links":110202},[110203,110205,110207,110209,110210,110211,110213,110215,110217,110219,110221,110223,110225,110227,110229,110230,110231,110233,110234,110236],{"id":108558,"depth":296,"text":110204},"Q1. What is rustup primarily responsible for?",{"id":108641,"depth":296,"text":110206},"Q2. A developer runs rustc main.rs directly instead of using cargo build. What is the main practical difference for a project with dependencies?",{"id":108748,"depth":296,"text":110208},"Q3. As of Rust 2024, what edition does cargo new my_project select by default when using a current stable toolchain?",{"id":108818,"depth":296,"text":108819},{"id":108903,"depth":296,"text":108904},{"id":108956,"depth":296,"text":110212},"Q6. What does rustup component add clippy do?",{"id":109043,"depth":296,"text":110214},"Q7. Running cargo --version and rustc --version on a machine with rustup installed can show two different underlying toolchain versions. Why might this legitimately happen?",{"id":109152,"depth":296,"text":110216},"Q8. A CI pipeline pins rust-toolchain.toml with channel = \"1.72.0\", but a contributor has only nightly installed locally via rustup. What happens when they run cargo build in that directory?",{"id":109242,"depth":296,"text":110218},"Q9. A file uses #![feature(let_chains)] at the crate root and is compiled with the default stable toolchain. What happens?",{"id":109306,"depth":296,"text":110220},"Q10. Inside ~\u002Fprojects\u002Fexperimental\u002F, a developer runs rustup override set nightly. What is the scope of this change?",{"id":109387,"depth":296,"text":110222},"Q11. A team upgrades a crate from the 2018 edition to the 2021 edition by editing edition = \"2021\" in Cargo.toml with no other changes. What is the safest correct process, and why?",{"id":109461,"depth":296,"text":110224},"Q12. A repository's root contains a rust-toolchain.toml with channel = \"stable\" and components = [\"clippy\", \"rustfmt\"]. A contributor runs cargo build without ever running rustup component add. What happens to clippy\u002Frustfmt availability?",{"id":109567,"depth":296,"text":110226},"Q13. A crate declares rust-version = \"1.70\" (MSRV) in Cargo.toml. A contributor on Rust 1.65 stable runs cargo build. What happens?",{"id":109648,"depth":296,"text":110228},"Q14. What happens if you run rustc on a .rs file that has zero use statements and a fn main() {} body, with no Cargo.toml anywhere nearby?",{"id":109755,"depth":296,"text":109756},{"id":109828,"depth":296,"text":109829},{"id":109902,"depth":296,"text":110232},"Q17. A library needs an unstable standard library API only available via #![feature(...)] on nightly. What is the idiomatic recommendation for a crate intended for wide production use?",{"id":109961,"depth":296,"text":109962},{"id":110030,"depth":296,"text":110235},"Q19. What is the idiomatic way to check code style and common mistakes beyond what rustc itself reports, before opening a pull request?",{"id":110122,"depth":296,"text":110237},"Q20. A developer notices cargo build (debug profile) produces a binary that runs noticeably slower than cargo build --release. What best-practice conclusion should they draw?",{},"\u002Frust\u002F01-introduction-and-setup",{"title":6,"description":264},"rust\u002F01-introduction-and-setup","kxgLBL5APfr6-eUNMjut2naImjz63-a09htBPHAixpA",{"id":110244,"title":110245,"body":110246,"description":264,"extension":2144,"meta":111894,"navigation":35,"path":111895,"seo":111896,"stem":111897,"__hash__":111898},"content\u002Frust\u002F02-hello-world-and-cargo.md","02 — Hello World & Cargo",{"type":8,"value":110247,"toc":111856},[110248,110251,110350,110434,110518,110587,110679,110757,110841,110940,111035,111097,111169,111248,111344,111417,111481,111548,111636,111723,111795],[11,110249,110245],{"id":110250},"_02-hello-world-cargo",[15,110252,110253,110260,110304],{},[18,110254,19520,110256,110259],{"id":110255},"q1-what-does-cargo-new-my_app-create-by-default",[39,110257,110258],{},"cargo new my_app"," create by default?",[23,110261,110263,110272,110284,110295],{"className":110262},[26],[28,110264,110266,110268,110269,110271],{"className":110265},[31],[33,110267],{"disabled":35,"type":36}," Only a ",[39,110270,108587],{}," file with no source directory",[28,110273,110275,812,110277,110280,110281,110283],{"className":110274},[31],[33,110276],{"disabled":35,"type":36},[39,110278,110279],{},"src\u002Fmain.rs"," binary crate, a ",[39,110282,108587],{},", and a git repository (if not already inside one)",[28,110285,110287,812,110289,110292,110293,1619],{"className":110286},[31],[33,110288],{"disabled":35,"type":36},[39,110290,110291],{},"src\u002Flib.rs"," library crate and a ",[39,110294,108726],{},[28,110296,110298,110300,110301],{"className":110297},[31],[33,110299],{"disabled":35,"type":36}," An empty directory that must be populated manually with ",[39,110302,110303],{},"cargo init --full",[66,110305,110306,110308,110316],{},[69,110307,71],{},[73,110309,110310,853,110312,110280,110314,110283],{},[76,110311,78],{},[39,110313,110279],{},[39,110315,108587],{},[73,110317,110318,355,110320,110322,110323,107837,110325,110328,110329,110331,110332,110335,110336,110338,110339,110342,110343,110346,110347,110349],{},[76,110319,84],{},[39,110321,108796],{}," scaffolds a binary crate by default (",[39,110324,110279],{},[39,110326,110327],{},"Hello, world!"," program), generates ",[39,110330,108587],{},", and also runs ",[39,110333,110334],{},"git init"," plus a ",[39,110337,83515],{}," unless one already exists in a parent directory or ",[39,110340,110341],{},"--vcs none"," is passed. Use ",[39,110344,110345],{},"cargo new --lib"," to get a ",[39,110348,110291],{}," library crate instead (C describes the wrong default).",[15,110351,110352,110361,110405],{},[18,110353,110355,110356,186,110358,1685],{"id":110354},"q2-what-is-the-key-functional-difference-between-cargo-build-and-cargo-check","Q2. What is the key functional difference between ",[39,110357,108649],{},[39,110359,110360],{},"cargo check",[23,110362,110364,110375,110386,110397],{"className":110363},[26],[28,110365,110367,355,110369,110371,110372,110374],{"className":110366},[31],[33,110368],{"disabled":35,"type":36},[39,110370,110360],{}," only validates ",[39,110373,108587],{}," syntax; it does not touch source files",[28,110376,110378,355,110380,110382,110383,110385],{"className":110377},[31],[33,110379],{"disabled":35,"type":36},[39,110381,110360],{}," runs the full borrow checker and type checker like ",[39,110384,108649],{},", but skips code generation\u002Flinking, making it much faster for catching compile errors",[28,110387,110389,355,110391,110393,110394,110396],{"className":110388},[31],[33,110390],{"disabled":35,"type":36},[39,110392,108649],{}," is faster because it skips borrow checking, which only ",[39,110395,110360],{}," performs",[28,110398,110400,5275,110402,110404],{"className":110399},[31],[33,110401],{"disabled":35,"type":36},[39,110403,110360],{}," is simply a deprecated alias",[66,110406,110407,110409,110417],{},[69,110408,71],{},[73,110410,110411,1727,110413,110382,110415,110385],{},[76,110412,78],{},[39,110414,110360],{},[39,110416,108649],{},[73,110418,110419,110421,110422,110424,110425,110427,110428,110430,110431,110433],{},[76,110420,84],{}," Both commands run the same front-end analysis (type checking, borrow checking, trait resolution), so ",[39,110423,110360],{}," catches the same compile errors as ",[39,110426,108649],{},". The difference is that ",[39,110429,10507],{}," stops before LLVM codegen and linking, which are the most time-consuming stages, so it's dramatically faster for a tight edit-check loop. Option C inverts this — borrow checking is not something ",[39,110432,14155],{}," skips.",[15,110435,110436,110444,110483],{},[18,110437,110439,110440,186,110442,1685],{"id":110438},"q3-what-is-the-correct-relationship-between-cargotoml-and-cargolock","Q3. What is the correct relationship between ",[39,110441,108587],{},[39,110443,108726],{},[23,110445,110447,110458,110469,110475],{"className":110446},[26],[28,110448,110450,355,110452,110454,110455,110457],{"className":110449},[31],[33,110451],{"disabled":35,"type":36},[39,110453,108587],{}," is auto-generated from ",[39,110456,108726],{}," on every build",[28,110459,110461,355,110463,110465,110466,110468],{"className":110460},[31],[33,110462],{"disabled":35,"type":36},[39,110464,108587],{}," declares dependency requirements (often with version ranges); ",[39,110467,108726],{}," records the exact resolved versions actually used, ensuring reproducible builds",[28,110470,110472,110474],{"className":110471},[31],[33,110473],{"disabled":35,"type":36}," They serve the same purpose and either one alone is sufficient",[28,110476,110478,355,110480,110482],{"className":110477},[31],[33,110479],{"disabled":35,"type":36},[39,110481,108726],{}," is only created for library crates, never for binaries",[66,110484,110485,110487,110495],{},[69,110486,71],{},[73,110488,110489,1727,110491,110465,110493,110468],{},[76,110490,78],{},[39,110492,108587],{},[39,110494,108726],{},[73,110496,110497,355,110499,110501,110502,5789,110505,110507,110508,110510,110511,110513,110514,110517],{},[76,110498,84],{},[39,110500,108587],{}," is the human-edited manifest expressing acceptable version ranges (e.g. ",[39,110503,110504],{},"serde = \"1.0\"",[39,110506,108726],{}," is generated\u002Fupdated by Cargo and pins the exact versions (and their transitive dependency graph) that were actually resolved, so a second ",[39,110509,108649],{}," on another machine reproduces the identical dependency tree rather than re-resolving to potentially newer semver-compatible versions. Both binaries and libraries get a ",[39,110512,108726],{}," when built, though it's typically only ",[104,110515,110516],{},"committed to version control"," for binaries (option D is wrong on both the \"only libraries\" claim and the general practice).",[15,110519,110520,110524,110560],{},[18,110521,110523],{"id":110522},"q4-what-command-compiles-and-immediately-runs-a-binary-crate-in-one-step-during-development","Q4. What command compiles and immediately runs a binary crate in one step during development?",[23,110525,110527,110536,110544,110552],{"className":110526},[26],[28,110528,110530,355,110532,110535],{"className":110529},[31],[33,110531],{"disabled":35,"type":36},[39,110533,110534],{},"cargo build && .\u002Ftarget\u002Fdebug\u002Fapp"," is the only way; there is no shortcut",[28,110537,110539,355,110541],{"className":110538},[31],[33,110540],{"disabled":35,"type":36},[39,110542,110543],{},"cargo run",[28,110545,110547,355,110549],{"className":110546},[31],[33,110548],{"disabled":35,"type":36},[39,110550,110551],{},"cargo exec",[28,110553,110555,355,110557],{"className":110554},[31],[33,110556],{"disabled":35,"type":36},[39,110558,110559],{},"cargo start",[66,110561,110562,110564,110570],{},[69,110563,71],{},[73,110565,110566,1727,110568],{},[76,110567,78],{},[39,110569,110543],{},[73,110571,110572,355,110574,110576,110577,3277,110579,186,110581,110583,110584,6232],{},[76,110573,84],{},[39,110575,110543],{}," builds the binary (if needed — it skips rebuilding when nothing changed) and then executes it, forwarding any arguments after ",[39,110578,72712],{},[39,110580,110551],{},[39,110582,110559],{}," (C, D) are not real Cargo subcommands — plausible-sounding distractors modeled after other ecosystems' tooling (e.g. ",[39,110585,110586],{},"npm start",[15,110588,110589,110604,110656],{},[18,110590,110592,110593,110595,110596,110599,110600,110603],{"id":110591},"q5-a-repository-has-a-root-cargotoml-containing-a-workspace-table-with-members-core-cli-what-does-this-achieve","Q5. A repository has a root ",[39,110594,108587],{}," containing a ",[39,110597,110598],{},"[workspace]"," table with ",[39,110601,110602],{},"members = [\"core\", \"cli\"]",". What does this achieve?",[23,110605,110607,110620,110635,110645],{"className":110606},[26],[28,110608,110610,110612,110613,186,110616,110619],{"className":110609},[31],[33,110611],{"disabled":35,"type":36}," It merges ",[39,110614,110615],{},"core",[39,110617,110618],{},"cli"," into a single crate at build time",[28,110621,110623,110625,110626,186,110628,110631,110632,110634],{"className":110622},[31],[33,110624],{"disabled":35,"type":36}," It groups multiple crates so they share a single ",[39,110627,108726],{},[39,110629,110630],{},"target\u002F"," directory, and can be built\u002Ftested together with one ",[39,110633,108649],{}," from the workspace root",[28,110636,110638,110640,110641,110644],{"className":110637},[31],[33,110639],{"disabled":35,"type":36}," It has no build effect; ",[39,110642,110643],{},"members"," is purely documentation",[28,110646,110648,110650,110651,186,110653,110655],{"className":110647},[31],[33,110649],{"disabled":35,"type":36}," It forces ",[39,110652,110615],{},[39,110654,110618],{}," to be published together as one package to crates.io",[66,110657,110658,110660,110671],{},[69,110659,71],{},[73,110661,110662,110664,110665,186,110667,110631,110669,110634],{},[76,110663,78],{}," B — It groups multiple crates so they share a single ",[39,110666,108726],{},[39,110668,110630],{},[39,110670,108649],{},[73,110672,110673,110675,110676,110678],{},[76,110674,84],{}," A Cargo workspace lets related crates share dependency resolution (one ",[39,110677,108726],{},") and a build output directory, avoiding duplicate compilation of shared dependencies across crates. Each member remains its own independently publishable crate (contradicting D) — the workspace is an organizational\u002Fbuild-sharing construct, not a merge (contradicting A).",[15,110680,110681,110688,110723],{},[18,110682,110684,110685,110687],{"id":110683},"q6-where-does-cargo-build-default-profile-place-the-compiled-binary","Q6. Where does ",[39,110686,108649],{}," (default profile) place the compiled binary?",[23,110689,110691,110699,110707,110715],{"className":110690},[26],[28,110692,110694,355,110696],{"className":110693},[31],[33,110695],{"disabled":35,"type":36},[39,110697,110698],{},".\u002Fbin\u002F",[28,110700,110702,355,110704],{"className":110701},[31],[33,110703],{"disabled":35,"type":36},[39,110705,110706],{},".\u002Ftarget\u002Fdebug\u002F",[28,110708,110710,355,110712],{"className":110709},[31],[33,110711],{"disabled":35,"type":36},[39,110713,110714],{},".\u002Ftarget\u002Frelease\u002F",[28,110716,110718,110720,110721],{"className":110717},[31],[33,110719],{"disabled":35,"type":36}," Directly in the project root alongside ",[39,110722,108587],{},[66,110724,110725,110727,110733],{},[69,110726,71],{},[73,110728,110729,1727,110731],{},[76,110730,78],{},[39,110732,110706],{},[73,110734,110735,19159,110737,110739,110740,110742,110743,110746,110747,110749,110750,110753,110754,110756],{},[76,110736,84],{},[39,110738,108649],{}," uses the ",[39,110741,110181],{}," profile, which outputs to ",[39,110744,110745],{},"target\u002Fdebug\u002F",". Only ",[39,110748,110129],{}," outputs to ",[39,110751,110752],{},"target\u002Frelease\u002F"," (C is the release path, a common mix-up). Cargo never places build artifacts in the project root (D) — ",[39,110755,110630],{}," is the dedicated, gitignored build directory.",[15,110758,110759,110769,110800],{},[18,110760,110762,110763,110766,110767,1685],{"id":110761},"q7-what-is-the-purpose-of-the-dependencies-section-in-cargotoml","Q7. What is the purpose of the ",[39,110764,110765],{},"[dependencies]"," section in ",[39,110768,108587],{},[23,110770,110772,110782,110788,110794],{"className":110771},[26],[28,110773,110775,110777,110778,186,110780],{"className":110774},[31],[33,110776],{"disabled":35,"type":36}," It lists development-only tools like ",[39,110779,108632],{},[39,110781,108619],{},[28,110783,110785,110787],{"className":110784},[31],[33,110786],{"disabled":35,"type":36}," It declares external crates the package needs at compile\u002Fruntime, with version requirements",[28,110789,110791,110793],{"className":110790},[31],[33,110792],{"disabled":35,"type":36}," It lists the Rust toolchain version required to build the project",[28,110795,110797,110799],{"className":110796},[31],[33,110798],{"disabled":35,"type":36}," It configures which target platforms the binary can run on",[66,110801,110802,110804,110809],{},[69,110803,71],{},[73,110805,110806,110808],{},[76,110807,78],{}," B — It declares external crates the package needs at compile\u002Fruntime, with version requirements",[73,110810,110811,355,110813,110815,110816,99,110819,110822,110823,110826,110827,110829,110830,110833,110834,110837,110838,110840],{},[76,110812,84],{},[39,110814,110765],{}," is where crates like ",[39,110817,110818],{},"serde",[39,110820,110821],{},"tokio"," are declared with semver-style version requirements that Cargo resolves against crates.io (or another registry\u002Fpath\u002Fgit source). Dev-only tooling dependencies belong in ",[39,110824,110825],{},"[dev-dependencies]"," (A describes a different section), toolchain version pinning belongs in ",[39,110828,109091],{}," (C), and target platforms are handled via ",[39,110831,110832],{},"--target"," flags or ",[39,110835,110836],{},"[target.'cfg(...)']"," sections, not ",[39,110839,110765],{}," (D).",[15,110842,110843,110856,110909],{},[18,110844,110846,110847,110849,110850,110852,110853,109578],{"id":110845},"q8-a-developer-deletes-cargolock-from-a-binary-project-and-runs-cargo-build-the-project-depends-on-rand-08-what-happens","Q8. A developer deletes ",[39,110848,108726],{}," from a binary project and runs ",[39,110851,108649],{},". The project depends on ",[39,110854,110855],{},"rand = \"0.8\"",[23,110857,110859,110870,110880,110899],{"className":110858},[26],[28,110860,110862,355,110864,110866,110867,110869],{"className":110861},[31],[33,110863],{"disabled":35,"type":36},[39,110865,108649],{}," fails immediately because ",[39,110868,108726],{}," is required to exist",[28,110871,110873,110875,110876,110879],{"className":110872},[31],[33,110874],{"disabled":35,"type":36}," Cargo silently reuses cached resolution from ",[39,110877,110878],{},"~\u002F.cargo"," with no re-resolution",[28,110881,110883,110885,110886,110888,110889,110891,110892,110895,110896,2690],{"className":110882},[31],[33,110884],{"disabled":35,"type":36}," Cargo re-resolves dependency versions from scratch (honoring the semver ranges in ",[39,110887,108587],{},") and regenerates a new ",[39,110890,108726],{},", which may pick up newer compatible versions than before (e.g. ",[39,110893,110894],{},"0.8.5"," instead of a previously pinned ",[39,110897,110898],{},"0.8.3",[28,110900,110902,110904,110905,110908],{"className":110901},[31],[33,110903],{"disabled":35,"type":36}," The build always fails because ",[39,110906,110907],{},"rand","'s exact version can no longer be determined",[66,110910,110911,110913,110923],{},[69,110912,71],{},[73,110914,110915,110917,110918,110888,110920,110922],{},[76,110916,78],{}," C — Cargo re-resolves dependency versions from scratch (honoring the semver ranges in ",[39,110919,108587],{},[39,110921,108726],{},", which may pick up newer compatible versions than before",[73,110924,110925,355,110927,110929,110930,110932,110933,110935,110936,110939],{},[76,110926,84],{},[39,110928,108726],{}," is not required for the build to succeed — Cargo can always regenerate it by resolving ",[39,110931,108587],{},"'s version requirements against the registry. ",[76,110934,365],{}," this is exactly why deleting a committed lock file for a ",[104,110937,110938],{},"binary"," project is risky in production contexts — a newer semver-compatible dependency version could introduce a regression or subtle behavior change that wasn't present when the lock was last committed, even though no application code changed.",[15,110941,110942,110953,111000],{},[18,110943,110945,110946,110948,110949,110952],{"id":110944},"q9-in-a-fresh-clone-of-a-workspace-with-members-core-cli-running-cargo-build-p-cli-from-the-workspace-root-does-what","Q9. In a fresh clone of a workspace with ",[39,110947,110602],{},", running ",[39,110950,110951],{},"cargo build -p cli"," from the workspace root does what?",[23,110954,110956,110965,110974,110989],{"className":110955},[26],[28,110957,110959,110961,110962,18352],{"className":110958},[31],[33,110960],{"disabled":35,"type":36}," Builds every member of the workspace regardless of the ",[39,110963,110964],{},"-p",[28,110966,110968,110970,110971,110973],{"className":110967},[31],[33,110969],{"disabled":35,"type":36}," Fails, because ",[39,110972,110964],{}," is not a valid flag for workspaces",[28,110975,110977,110979,110980,110982,110983,110985,110986,110988],{"className":110976},[31],[33,110978],{"disabled":35,"type":36}," Builds only the ",[39,110981,110618],{}," package (and its path\u002Fworkspace dependencies like ",[39,110984,110615],{},", if ",[39,110987,110618],{}," depends on it), skipping unrelated workspace members",[28,110990,110992,110994,110995,4387,110997,110999],{"className":110991},[31],[33,110993],{"disabled":35,"type":36}," Builds only ",[39,110996,110615],{},[39,110998,110964],{}," selects dependencies rather than the named package",[66,111001,111002,111004,111015],{},[69,111003,71],{},[73,111005,111006,111008,111009,110982,111011,110985,111013,110988],{},[76,111007,78],{}," C — Builds only the ",[39,111010,110618],{},[39,111012,110615],{},[39,111014,110618],{},[73,111016,111017,355,111019,446,111021,111024,111025,42,111027,111029,111030,830,111032,462],{},[76,111018,84],{},[39,111020,110964],{},[39,111022,111023],{},"--package"," scopes a workspace command to one member (plus whatever that member transitively needs), which is useful in large workspaces to avoid rebuilding unrelated crates. Without ",[39,111026,110964],{},[39,111028,108649],{}," at the workspace root builds all members by default — that's the \"build everything\" behavior in option A, but it only applies when ",[39,111031,110964],{},[104,111033,111034],{},"omitted",[15,111036,111037,111053,111083],{},[18,111038,111040,111041,111043,111044,111046,111047,111049,111050,111052],{"id":111039},"q10-a-projects-cargotoml-has-edition-2021-but-the-committed-cargolock-was-generated-by-an-older-cargo-that-used-lockfile-format-version-3-a-contributor-with-a-very-new-cargo-runs-cargo-build-what-typically-happens","Q10. A project's ",[39,111042,108587],{}," has ",[39,111045,109391],{}," but the committed ",[39,111048,108726],{}," was generated by an older Cargo that used lockfile format version 3. A contributor with a very new Cargo runs ",[39,111051,108649],{},". What typically happens?",[23,111054,111056,111062,111068,111074],{"className":111055},[26],[28,111057,111059,111061],{"className":111058},[31],[33,111060],{"disabled":35,"type":36}," The build always fails outright with an incompatible lockfile error",[28,111063,111065,111067],{"className":111064},[31],[33,111066],{"disabled":35,"type":36}," Cargo silently deletes and ignores the old lock file every time",[28,111069,111071,111073],{"className":111070},[31],[33,111072],{"disabled":35,"type":36}," Newer Cargo versions can read and work with older lockfile format versions (and may upgrade the format in place on next resolution), so the build generally proceeds without manual intervention",[28,111075,111077,111079,111080,111082],{"className":111076},[31],[33,111078],{"disabled":35,"type":36}," The project must be re-initialized with ",[39,111081,108796],{}," to fix the format mismatch",[66,111084,111085,111087,111092],{},[69,111086,71],{},[73,111088,111089,111091],{},[76,111090,78],{}," C — Newer Cargo versions can read and work with older lockfile format versions (and may upgrade the format in place on next resolution), so the build generally proceeds without manual intervention",[73,111093,111094,111096],{},[76,111095,84],{}," Cargo maintains backward compatibility for reading older lock file formats; it's forward compatibility (an old Cargo reading a lock file produced by a much newer Cargo using a newer format) that can actually cause problems. Options A and D describe unnecessarily destructive\u002Fdrastic reactions to what is normally a non-issue.",[15,111098,111099,111106,111141],{},[18,111100,111102,111103,111105],{"id":111101},"q11-what-happens-when-cargo-run-is-invoked-in-a-crate-whose-source-has-zero-changes-since-the-last-successful-build","Q11. What happens when ",[39,111104,110543],{}," is invoked in a crate whose source has zero changes since the last successful build?",[23,111107,111109,111115,111124,111132],{"className":111108},[26],[28,111110,111112,111114],{"className":111111},[31],[33,111113],{"disabled":35,"type":36}," It always recompiles from scratch as a safety measure",[28,111116,111118,111120,111121,111123],{"className":111117},[31],[33,111119],{"disabled":35,"type":36}," It skips recompilation (relying on cached fingerprint\u002Ftimestamp checks in ",[39,111122,110630],{},") and directly executes the existing binary",[28,111125,111127,111129,111130,47835],{"className":111126},[31],[33,111128],{"disabled":35,"type":36}," It fails, requiring an explicit ",[39,111131,108649],{},[28,111133,111135,111137,111138,111140],{"className":111134},[31],[33,111136],{"disabled":35,"type":36}," It recompiles only ",[39,111139,108587],{}," changes, ignoring source files entirely",[66,111142,111143,111145,111152],{},[69,111144,71],{},[73,111146,111147,111149,111150,111123],{},[76,111148,78],{}," B — It skips recompilation (relying on cached fingerprint\u002Ftimestamp checks in ",[39,111151,110630],{},[73,111153,111154,111156,111157,111159,111160,111162,111163,111165,111166,111168],{},[76,111155,84],{}," Cargo tracks fingerprints (mtimes, flags, dependency versions) in ",[39,111158,110630],{}," to detect whether a rebuild is actually necessary; if nothing relevant changed, ",[39,111161,110543],{}," just executes the already-built artifact, making repeated ",[39,111164,110543],{}," calls during development fast. This incremental behavior is why ",[39,111167,110543],{}," is safe to invoke frequently rather than something to avoid for fear of unnecessary rebuilds (contradicting A).",[15,111170,111171,111180,111217],{},[18,111172,111174,111175,111177,111178,1685],{"id":111173},"q12-an-empty-srcmainrs-file-0-bytes-exists-in-an-otherwise-valid-cargo-project-what-happens-on-cargo-build","Q12. An empty ",[39,111176,110279],{}," file (0 bytes) exists in an otherwise valid Cargo project. What happens on ",[39,111179,108649],{},[23,111181,111183,111189,111199,111208],{"className":111182},[26],[28,111184,111186,111188],{"className":111185},[31],[33,111187],{"disabled":35,"type":36}," It compiles successfully, producing a binary that does nothing when run",[28,111190,111192,111194,111195,111198],{"className":111191},[31],[33,111193],{"disabled":35,"type":36}," Compile error: a binary crate root must contain a ",[39,111196,111197],{},"fn main()"," entry point",[28,111200,111202,111204,111205,12080],{"className":111201},[31],[33,111203],{"disabled":35,"type":36}," It's treated as a library crate automatically since there's no ",[39,111206,111207],{},"main",[28,111209,111211,111213,111214,111216],{"className":111210},[31],[33,111212],{"disabled":35,"type":36}," Cargo auto-generates a default ",[39,111215,109661],{}," to fill the gap",[66,111218,111219,111221,111228],{},[69,111220,71],{},[73,111222,111223,111225,111226,111198],{},[76,111224,78],{}," B — Compile error: a binary crate root must contain a ",[39,111227,111197],{},[73,111229,111230,111232,111233,111235,111236,111239,111240,111242,111243,7507,111245,111247],{},[76,111231,84],{}," For a binary target, Rust requires a ",[39,111234,111207],{}," function as the entry point (",[39,111237,111238],{},"error[E0601]: main function not found","); an empty file has no such function, so it fails to compile rather than silently producing a no-op executable (A) or being reinterpreted as a library (C — target type is determined by ",[39,111241,108587],{},"\u002Fdirectory layout, e.g. ",[39,111244,110279],{},[39,111246,110291],{},", not by file contents).",[15,111249,111250,111268,111306],{},[18,111251,111253,111254,111257,111258,186,111261,111257,111264,111267],{"id":111252},"q13-in-a-workspace-corecargotoml-depends-on-serde-10150-and-clicargotoml-depends-on-serde-10190-what-does-cargo-do-when-resolving-the-workspace","Q13. In a workspace, ",[39,111255,111256],{},"core\u002FCargo.toml"," depends on ",[39,111259,111260],{},"serde = \"1.0.150\"",[39,111262,111263],{},"cli\u002FCargo.toml",[39,111265,111266],{},"serde = \"1.0.190\"",". What does Cargo do when resolving the workspace?",[23,111269,111271,111277,111283,111300],{"className":111270},[26],[28,111272,111274,111276],{"className":111273},[31],[33,111275],{"disabled":35,"type":36}," The build fails because two members request different versions",[28,111278,111280,111282],{"className":111279},[31],[33,111281],{"disabled":35,"type":36}," Both versions are compiled and linked into the final binary as separate copies unconditionally",[28,111284,111286,111288,111289,111291,111292,111295,111296,111299],{"className":111285},[31],[33,111287],{"disabled":35,"type":36}," Cargo's resolver picks a single version of ",[39,111290,110818],{}," satisfying both semver ranges (here, ",[39,111293,111294],{},"1.0.190"," or newer within ",[39,111297,111298],{},"1.x",") to share across the workspace where possible, avoiding duplicate compilation",[28,111301,111303,111305],{"className":111302},[31],[33,111304],{"disabled":35,"type":36}," Only the workspace root's own direct dependency version is used, and member-level requirements are ignored",[66,111307,111308,111310,111318],{},[69,111309,71],{},[73,111311,111312,111314,111315,111317],{},[76,111313,78],{}," C — Cargo's resolver picks a single version of ",[39,111316,110818],{}," satisfying both semver ranges to share across the workspace where possible, avoiding duplicate compilation",[73,111319,111320,111322,111323,186,111326,111328,111329,111331,111332,111334,111335,111338,111339,7507,111341,111343],{},[76,111321,84],{}," Because both ",[39,111324,111325],{},"1.0.150",[39,111327,111294],{}," are compatible under Cargo's caret (",[39,111330,82707],{},") semver default, the resolver unifies them to one shared version (the highest that satisfies all constraints) recorded once in ",[39,111333,108726],{},", rather than building duplicate copies (which only happens when version ",[104,111336,111337],{},"ranges"," are genuinely incompatible, e.g. ",[39,111340,111298],{},[39,111342,82796],{},", producing two separate dependency instances rather than a hard failure).",[15,111345,111346,111363,111395],{},[18,111347,111349,111350,111352,111353,111355,111356,111359,111360,111362],{"id":111348},"q14-a-gitignore-generated-by-cargo-new-includes-target-a-teammate-accidentally-force-adds-and-commits-the-target-directory-anyway-what-is-the-main-practical-problem","Q14. A ",[39,111351,83515],{}," generated by ",[39,111354,108796],{}," includes ",[39,111357,111358],{},"\u002Ftarget",". A teammate accidentally force-adds and commits the ",[39,111361,110630],{}," directory anyway. What is the main practical problem?",[23,111364,111366,111372,111378,111387],{"className":111365},[26],[28,111367,111369,111371],{"className":111368},[31],[33,111370],{"disabled":35,"type":36}," None — committing build artifacts has no downsides since they're just cached output",[28,111373,111375,111377],{"className":111374},[31],[33,111376],{"disabled":35,"type":36}," It bloats the repository with large, machine\u002Fplatform-specific compiled artifacts that don't belong in version control and can go stale relative to source",[28,111379,111381,111383,111384,111386],{"className":111380},[31],[33,111382],{"disabled":35,"type":36}," It will cause ",[39,111385,108649],{}," to fail on other machines due to a directory name conflict",[28,111388,111390,111392,111393],{"className":111389},[31],[33,111391],{"disabled":35,"type":36}," It automatically overrides everyone's local ",[39,111394,108726],{},[66,111396,111397,111399,111404],{},[69,111398,71],{},[73,111400,111401,111403],{},[76,111402,78],{}," B — It bloats the repository with large, machine\u002Fplatform-specific compiled artifacts that don't belong in version control and can go stale relative to source",[73,111405,111406,355,111408,111410,111411,111413,111414,111416],{},[76,111407,84],{},[39,111409,110630],{}," contains derived build output (often gigabytes for large projects) that is regenerable, platform-specific, and irrelevant to other contributors — committing it bloats repo size\u002Fclone time and can cause confusing stale-artifact issues, which is exactly why ",[39,111412,108796],{}," gitignores it by default. It doesn't break other machines' builds outright (C) since ",[39,111415,108649],{}," will simply overwrite\u002Fregenerate what it needs, but it is still bad practice.",[15,111418,111419,111429,111461],{},[18,111420,111422,111423,111425,111426,111428],{"id":111421},"q15-what-is-the-idiomatic-reason-to-commit-cargolock-for-a-binary-application-but-often-not-commit-it-for-a-pure-library-crate-published-to-cratesio","Q15. What is the idiomatic reason to commit ",[39,111424,108726],{}," for a binary application but often ",[104,111427,95],{}," commit it for a pure library crate published to crates.io?",[23,111430,111432,111440,111446,111452],{"className":111431},[26],[28,111433,111435,355,111437,111439],{"className":111434},[31],[33,111436],{"disabled":35,"type":36},[39,111438,108726],{}," is required for compilation for binaries but forbidden by crates.io for libraries",[28,111441,111443,111445],{"className":111442},[31],[33,111444],{"disabled":35,"type":36}," Applications benefit from pinned, reproducible dependency versions across environments (dev\u002FCI\u002Fprod), while libraries should generally let downstream consumers resolve dependency versions themselves against their own constraints, so committing a library's lock file provides little benefit and can be misleading",[28,111447,111449,111451],{"className":111448},[31],[33,111450],{"disabled":35,"type":36}," There is no difference; the convention is arbitrary tooling trivia with no technical rationale",[28,111453,111455,111457,111458,111460],{"className":111454},[31],[33,111456],{"disabled":35,"type":36}," Libraries never have a ",[39,111459,108726],{}," generated in the first place",[66,111462,111463,111465,111470],{},[69,111464,71],{},[73,111466,111467,111469],{},[76,111468,78],{}," B — Applications benefit from pinned, reproducible dependency versions across environments, while libraries should let downstream consumers resolve dependency versions themselves",[73,111471,111472,111474,111475,111477,111478,111480],{},[76,111473,84],{}," A binary's ",[39,111476,108726],{}," is the actual deployed artifact's dependency snapshot, so pinning it avoids \"works on my machine\" drift. A library's ",[39,111479,108726],{}," is not used when the library is pulled in as a dependency elsewhere (the consuming binary's own lock file governs resolution), so committing it mainly matters for the library's own CI\u002Ftests, not for downstream consumers — Cargo does still generate one locally either way (ruling out D).",[15,111482,111483,111487,111522],{},[18,111484,111486],{"id":111485},"q16-during-active-development-a-programmer-wants-the-fastest-feedback-loop-for-catching-type-errors-without-waiting-for-full-binary-generation-on-every-edit-what-is-the-best-practice-command-to-run-repeatedly","Q16. During active development, a programmer wants the fastest feedback loop for catching type errors without waiting for full binary generation on every edit. What is the best-practice command to run repeatedly?",[23,111488,111490,111498,111505,111513],{"className":111489},[26],[28,111491,111493,355,111495,111497],{"className":111492},[31],[33,111494],{"disabled":35,"type":36},[39,111496,110129],{},", since release mode catches more errors",[28,111499,111501,355,111503],{"className":111500},[31],[33,111502],{"disabled":35,"type":36},[39,111504,110360],{},[28,111506,111508,355,111510,111512],{"className":111507},[31],[33,111509],{"disabled":35,"type":36},[39,111511,110543],{},", since it always recompiles fully every time",[28,111514,111516,355,111518,111521],{"className":111515},[31],[33,111517],{"disabled":35,"type":36},[39,111519,111520],{},"rustc src\u002Fmain.rs"," directly, bypassing Cargo for speed",[66,111523,111524,111526,111532],{},[69,111525,71],{},[73,111527,111528,1727,111530],{},[76,111529,78],{},[39,111531,110360],{},[73,111533,111534,111536,111537,111539,111540,111542,111543,10819,111545,111547],{},[76,111535,84],{}," As established in Q2, ",[39,111538,110360],{}," performs the same error-catching analysis as ",[39,111541,108649],{}," while skipping the slow codegen\u002Flink stages, making it the standard fast-loop command (many editors\u002FIDEs run it automatically on save via ",[39,111544,109024],{},[39,111546,110148],{}," (A) is slower, not faster, due to heavier optimization passes — the opposite of what's wanted here, and it doesn't catch a superset of errors that debug builds miss.",[15,111549,111550,111556,111607],{},[18,111551,111553,111554,1685],{"id":111552},"q17-what-is-the-recommended-way-to-add-a-new-dependency-to-a-project-versus-manually-typing-a-version-guess-into-cargotoml","Q17. What is the recommended way to add a new dependency to a project, versus manually typing a version guess into ",[39,111555,108587],{},[23,111557,111559,111572,111586,111598],{"className":111558},[26],[28,111560,111562,111564,111565,111567,111568,111571],{"className":111561},[31],[33,111563],{"disabled":35,"type":36}," Manually edit ",[39,111566,108587],{}," with a version pulled from memory, since ",[39,111569,111570],{},"cargo add"," doesn't verify anything",[28,111573,111575,4353,111577,111580,111581,111583,111584],{"className":111574},[31],[33,111576],{"disabled":35,"type":36},[39,111578,111579],{},"cargo add \u003Ccrate>",", which fetches the current appropriate version from the registry and writes a correct ",[39,111582,108587],{}," entry automatically, then run a build to update ",[39,111585,108726],{},[28,111587,111589,111591,111592,111594,111595,111597],{"className":111588},[31],[33,111590],{"disabled":35,"type":36}," Directly edit ",[39,111593,108726],{}," by hand since ",[39,111596,108587],{}," is regenerated from it",[28,111599,111601,111603,111604,111606],{"className":111600},[31],[33,111602],{"disabled":35,"type":36}," Copy an entry from an unrelated project's ",[39,111605,108587],{}," verbatim, regardless of version compatibility",[66,111608,111609,111611,111621],{},[69,111610,71],{},[73,111612,111613,4409,111615,111580,111617,111583,111619],{},[76,111614,78],{},[39,111616,111579],{},[39,111618,108587],{},[39,111620,108726],{},[73,111622,111623,355,111625,111627,111628,111630,111631,355,111633,111635],{},[76,111624,84],{},[39,111626,111570],{}," (built into modern Cargo) queries the registry for the latest suitable version and writes a properly formatted dependency entry, reducing typos and stale-version guesses versus hand-editing (A). ",[39,111629,108726],{}," is derived ",[104,111632,44539],{},[39,111634,108587],{},", never the reverse (C inverts the real relationship established in Q3).",[15,111637,111638,111648,111690],{},[18,111639,111641,111642,111644,111645,111647],{"id":111640},"q18-a-team-wants-ci-to-fail-if-cargolock-would-change-ie-to-catch-cases-where-cargotoml-allows-a-new-version-that-hasnt-been-vettedcommitted-what-is-the-idiomatic-flag-to-use","Q18. A team wants CI to fail if ",[39,111643,108726],{}," would change (i.e., to catch cases where ",[39,111646,108587],{}," allows a new version that hasn't been vetted\u002Fcommitted). What is the idiomatic flag to use?",[23,111649,111651,111663,111672,111681],{"className":111650},[26],[28,111652,111654,355,111656,99,111659,111662],{"className":111653},[31],[33,111655],{"disabled":35,"type":36},[39,111657,111658],{},"cargo build --frozen",[39,111660,111661],{},"cargo build --locked",", which error out instead of silently updating the lock file if it's out of date",[28,111664,111666,355,111668,111671],{"className":111665},[31],[33,111667],{"disabled":35,"type":36},[39,111669,111670],{},"cargo build --no-lock",", which disables lock file usage entirely",[28,111673,111675,111677,111678,111680],{"className":111674},[31],[33,111676],{"disabled":35,"type":36}," There is no such mechanism; this must be checked manually by diffing ",[39,111679,108726],{}," after every CI run",[28,111682,111684,355,111686,111689],{"className":111683},[31],[33,111685],{"disabled":35,"type":36},[39,111687,111688],{},"cargo build --offline",", which is unrelated to lock file freshness but is commonly confused with it",[66,111691,111692,111694,111702],{},[69,111693,71],{},[73,111695,111696,3459,111698,99,111700,111662],{},[76,111697,78],{},[39,111699,111658],{},[39,111701,111661],{},[73,111703,111704,355,111706,71990,111708,111710,111711,111714,111715,186,111717,3277,111720,111722],{},[76,111705,84],{},[39,111707,109208],{},[39,111709,108726],{}," to be up to date and errors otherwise; ",[39,111712,111713],{},"--frozen"," additionally forbids any network access, combining ",[39,111716,109208],{},[39,111718,111719],{},"--offline",[39,111721,111719],{}," alone (D) only controls network access and does not by itself enforce lock file freshness — a common point of confusion since the two flags are often used together but solve different problems.",[15,111724,111725,111729,111770],{},[18,111726,111728],{"id":111727},"q19-what-is-the-idiomatic-way-to-organize-a-project-that-has-both-a-reusable-library-and-a-thin-cli-binary-that-uses-it","Q19. What is the idiomatic way to organize a project that has both a reusable library and a thin CLI binary that uses it?",[23,111730,111732,111741,111755,111764],{"className":111731},[26],[28,111733,111735,111737,111738,111740],{"className":111734},[31],[33,111736],{"disabled":35,"type":36}," Put all logic in ",[39,111739,110279],{}," as one large file; splitting is unnecessary in Rust",[28,111742,111744,4353,111746,111748,111749,7255,111751,111754],{"className":111743},[31],[33,111745],{"disabled":35,"type":36},[39,111747,110291],{}," for the core reusable logic and a thin ",[39,111750,110279],{},[39,111752,111753],{},"src\u002Fbin\u002F*.rs",") that depends on the library crate, enabling the logic to be unit-tested and reused independent of the CLI entry point",[28,111756,111758,111760,111761,111763],{"className":111757},[31],[33,111759],{"disabled":35,"type":36}," Duplicate the logic in both ",[39,111762,109697],{}," and a separate crate to avoid coupling",[28,111765,111767,111769],{"className":111766},[31],[33,111768],{"disabled":35,"type":36}," Always split into a full Cargo workspace, even for small single-purpose projects, since workspaces are required for any crate with more than one file",[66,111771,111772,111774,111783],{},[69,111773,71],{},[73,111775,111776,4409,111778,111748,111780,111782],{},[76,111777,78],{},[39,111779,110291],{},[39,111781,110279],{}," that depends on the library crate, enabling the logic to be unit-tested and reused independent of the CLI entry point",[73,111784,111785,111787,111788,111790,111791,111794],{},[76,111786,84],{}," The \"thin binary, fat library\" pattern is a widely recommended Rust idiom: a single package can contain both a library target (",[39,111789,110291],{},") and one or more binary targets that consume it, giving you testable, reusable logic without needing a full multi-crate workspace (D overstates when workspaces are actually necessary — they matter for multiple ",[104,111792,111793],{},"separately versioned\u002Fpublished"," crates, not merely for having more than one file).",[15,111796,111797,111801,111834],{},[18,111798,111800],{"id":111799},"q20-before-committing-a-developer-wants-to-be-sure-their-code-both-compiles-cleanly-and-follows-the-projects-formattinglint-conventions-with-minimal-manual-effort-what-sequence-of-commands-best-reflects-idiomatic-practice","Q20. Before committing, a developer wants to be sure their code both compiles cleanly and follows the project's formatting\u002Flint conventions with minimal manual effort. What sequence of commands best reflects idiomatic practice?",[23,111802,111804,111812,111820,111826],{"className":111803},[26],[28,111805,111807,355,111809,111811],{"className":111806},[31],[33,111808],{"disabled":35,"type":36},[39,111810,110543],{}," only — if it runs without crashing, the code is ready to commit",[28,111813,111815,355,111817],{"className":111814},[31],[33,111816],{"disabled":35,"type":36},[39,111818,111819],{},"cargo fmt && cargo clippy -- -D warnings && cargo test",[28,111821,111823,111825],{"className":111822},[31],[33,111824],{"disabled":35,"type":36}," Skip all tooling and rely on code review to catch formatting and lint issues",[28,111827,111829,355,111831,111833],{"className":111828},[31],[33,111830],{"disabled":35,"type":36},[39,111832,110129],{}," alone, since release mode implies all checks passed",[66,111835,111836,111838,111844],{},[69,111837,71],{},[73,111839,111840,1727,111842],{},[76,111841,78],{},[39,111843,111819],{},[73,111845,111846,111848,111849,111852,111853,111855],{},[76,111847,84],{}," This sequence formats code consistently, runs Clippy with warnings promoted to errors (",[39,111850,111851],{},"-D warnings",") to enforce a clean lint baseline, and runs the test suite — a standard pre-commit\u002FCI gate in professional Rust projects. Running successfully (A) says nothing about style, lint hygiene, or correctness beyond the one code path exercised; ",[39,111854,110148],{}," (D) says nothing about lints or tests at all, and optimized builds can even mask certain debug-only assertions (like overflow checks), making it a poor substitute for an actual verification pipeline.",{"title":264,"searchDepth":286,"depth":286,"links":111857},[111858,111860,111862,111864,111865,111867,111869,111871,111873,111875,111877,111879,111881,111883,111885,111887,111888,111890,111892,111893],{"id":110255,"depth":296,"text":111859},"Q1. What does cargo new my_app create by default?",{"id":110354,"depth":296,"text":111861},"Q2. What is the key functional difference between cargo build and cargo check?",{"id":110438,"depth":296,"text":111863},"Q3. What is the correct relationship between Cargo.toml and Cargo.lock?",{"id":110522,"depth":296,"text":110523},{"id":110591,"depth":296,"text":111866},"Q5. A repository has a root Cargo.toml containing a [workspace] table with members = [\"core\", \"cli\"]. What does this achieve?",{"id":110683,"depth":296,"text":111868},"Q6. Where does cargo build (default profile) place the compiled binary?",{"id":110761,"depth":296,"text":111870},"Q7. What is the purpose of the [dependencies] section in Cargo.toml?",{"id":110845,"depth":296,"text":111872},"Q8. A developer deletes Cargo.lock from a binary project and runs cargo build. The project depends on rand = \"0.8\". What happens?",{"id":110944,"depth":296,"text":111874},"Q9. In a fresh clone of a workspace with members = [\"core\", \"cli\"], running cargo build -p cli from the workspace root does what?",{"id":111039,"depth":296,"text":111876},"Q10. A project's Cargo.toml has edition = \"2021\" but the committed Cargo.lock was generated by an older Cargo that used lockfile format version 3. A contributor with a very new Cargo runs cargo build. What typically happens?",{"id":111101,"depth":296,"text":111878},"Q11. What happens when cargo run is invoked in a crate whose source has zero changes since the last successful build?",{"id":111173,"depth":296,"text":111880},"Q12. An empty src\u002Fmain.rs file (0 bytes) exists in an otherwise valid Cargo project. What happens on cargo build?",{"id":111252,"depth":296,"text":111882},"Q13. In a workspace, core\u002FCargo.toml depends on serde = \"1.0.150\" and cli\u002FCargo.toml depends on serde = \"1.0.190\". What does Cargo do when resolving the workspace?",{"id":111348,"depth":296,"text":111884},"Q14. A .gitignore generated by cargo new includes \u002Ftarget. A teammate accidentally force-adds and commits the target\u002F directory anyway. What is the main practical problem?",{"id":111421,"depth":296,"text":111886},"Q15. What is the idiomatic reason to commit Cargo.lock for a binary application but often not commit it for a pure library crate published to crates.io?",{"id":111485,"depth":296,"text":111486},{"id":111552,"depth":296,"text":111889},"Q17. What is the recommended way to add a new dependency to a project, versus manually typing a version guess into Cargo.toml?",{"id":111640,"depth":296,"text":111891},"Q18. A team wants CI to fail if Cargo.lock would change (i.e., to catch cases where Cargo.toml allows a new version that hasn't been vetted\u002Fcommitted). What is the idiomatic flag to use?",{"id":111727,"depth":296,"text":111728},{"id":111799,"depth":296,"text":111800},{},"\u002Frust\u002F02-hello-world-and-cargo",{"title":110245,"description":264},"rust\u002F02-hello-world-and-cargo","L6cAeoEeljHZh8ncQfOCB0ivNuLACiwNQmwFi4-ytbw",{"id":111900,"title":111901,"body":111902,"description":264,"extension":2144,"meta":114562,"navigation":35,"path":114563,"seo":114564,"stem":114565,"__hash__":114566},"content\u002Frust\u002F03-variables-and-mutability.md","03 — Variables & Mutability",{"type":8,"value":111903,"toc":114528},[111904,111907,112031,112104,112271,112351,112459,112561,112693,112869,113044,113262,113425,113573,113748,113934,114006,114074,114156,114299,114375,114526],[11,111905,111901],{"id":111906},"_03-variables-mutability",[15,111908,111910,111914,111970,112003],{"language":111909},"rust",[18,111911,111913],{"id":111912},"q1-what-happens-when-this-code-is-compiled","Q1. What happens when this code is compiled?",[257,111915,111916],{"language":111909},[260,111917,111920],{"className":111918,"code":111919,"language":111909,"meta":264,"style":264},"language-rust shiki shiki-themes github-light github-dark","fn main() {\n    let x = 5;\n    x = 6;\n    println!(\"{x}\");\n}\n",[39,111921,111922,111931,111943,111954,111966],{"__ignoreMap":264},[268,111923,111924,111926,111929],{"class":270,"line":271},[268,111925,37837],{"class":274},[268,111927,111928],{"class":278}," main",[268,111930,283],{"class":282},[268,111932,111933,111935,111937,111939,111941],{"class":270,"line":286},[268,111934,80826],{"class":274},[268,111936,2382],{"class":282},[268,111938,302],{"class":274},[268,111940,2387],{"class":305},[268,111942,293],{"class":282},[268,111944,111945,111948,111950,111952],{"class":270,"line":296},[268,111946,111947],{"class":282},"    x ",[268,111949,302],{"class":274},[268,111951,6841],{"class":305},[268,111953,293],{"class":282},[268,111955,111956,111959,111961,111964],{"class":270,"line":311},[268,111957,111958],{"class":278},"    println!",[268,111960,622],{"class":282},[268,111962,111963],{"class":289},"\"{x}\"",[268,111965,628],{"class":282},[268,111967,111968],{"class":270,"line":788},[268,111969,314],{"class":282},[23,111971,111973,111981,111989,111997],{"className":111972},[26],[28,111974,111976,111978,111979],{"className":111975},[31],[33,111977],{"disabled":35,"type":36}," It compiles and prints ",[39,111980,13663],{},[28,111982,111984,111986,111987],{"className":111983},[31],[33,111985],{"disabled":35,"type":36}," Compile error: cannot assign twice to immutable variable ",[39,111988,2403],{},[28,111990,111992,111978,111994,111996],{"className":111991},[31],[33,111993],{"disabled":35,"type":36},[39,111995,2429],{},", since the second assignment is silently ignored",[28,111998,112000,112002],{"className":111999},[31],[33,112001],{"disabled":35,"type":36}," Runtime panic: attempted reassignment of immutable variable",[66,112004,112005,112007,112014],{},[69,112006,71],{},[73,112008,112009,112011,112012],{},[76,112010,78],{}," B — Compile error: cannot assign twice to immutable variable ",[39,112013,2403],{},[73,112015,112016,112018,112019,112022,112023,112026,112027,112030],{},[76,112017,84],{}," Variables in Rust are immutable by default; ",[39,112020,112021],{},"let x = 5;"," without ",[39,112024,112025],{},"mut"," forbids any further assignment, and the compiler catches this at compile time with ",[39,112028,112029],{},"error[E0384]",", not at runtime (ruling out D, since immutability is a compile-time property, not a runtime check). Nothing is silently ignored (C) — the code simply fails to compile.",[15,112032,112033,112037,112072],{},[18,112034,112036],{"id":112035},"q2-what-is-required-to-make-the-reassignment-in-q1-valid","Q2. What is required to make the reassignment in Q1 valid?",[23,112038,112040,112049,112058,112066],{"className":112039},[26],[28,112041,112043,112045,112046],{"className":112042},[31],[33,112044],{"disabled":35,"type":36}," Wrapping the value in ",[39,112047,112048],{},"Cell::new(5)",[28,112050,112052,112054,112055],{"className":112051},[31],[33,112053],{"disabled":35,"type":36}," Declaring the variable with ",[39,112056,112057],{},"let mut x = 5;",[28,112059,112061,112054,112063],{"className":112060},[31],[33,112062],{"disabled":35,"type":36},[39,112064,112065],{},"const mut x: i32 = 5;",[28,112067,112069,112071],{"className":112068},[31],[33,112070],{"disabled":35,"type":36}," Nothing — the original code already compiles",[66,112073,112074,112076,112083],{},[69,112075,71],{},[73,112077,112078,112080,112081],{},[76,112079,78],{}," B — Declaring the variable with ",[39,112082,112057],{},[73,112084,112085,4396,112087,112089,112090,112093,112094,112096,112097,112099,112100,112103],{},[76,112086,84],{},[39,112088,112025],{}," keyword explicitly opts a binding into mutability, after which ",[39,112091,112092],{},"x = 6;"," is a legal reassignment. ",[39,112095,243],{}," (C) can never be combined with ",[39,112098,112025],{}," — constants are always immutable and this is a syntax error, not a valid alternative. ",[39,112101,112102],{},"Cell::new"," (A) provides interior mutability for shared references, which is a different, more advanced mechanism not needed for a simple owned local variable.",[15,112105,112106,112110,112183,112233],{"language":111909},[18,112107,112109],{"id":112108},"q3-what-is-the-difference-between-shadowing-and-mutation-in-this-snippet","Q3. What is the difference between shadowing and mutation in this snippet?",[257,112111,112112],{"language":111909},[260,112113,112115],{"className":111918,"code":112114,"language":111909,"meta":264,"style":264},"fn main() {\n    let x = 5;\n    let x = x + 1;\n    let x = x * 2;\n    println!(\"{x}\");\n}\n",[39,112116,112117,112125,112137,112153,112169,112179],{"__ignoreMap":264},[268,112118,112119,112121,112123],{"class":270,"line":271},[268,112120,37837],{"class":274},[268,112122,111928],{"class":278},[268,112124,283],{"class":282},[268,112126,112127,112129,112131,112133,112135],{"class":270,"line":286},[268,112128,80826],{"class":274},[268,112130,2382],{"class":282},[268,112132,302],{"class":274},[268,112134,2387],{"class":305},[268,112136,293],{"class":282},[268,112138,112139,112141,112143,112145,112147,112149,112151],{"class":270,"line":296},[268,112140,80826],{"class":274},[268,112142,2382],{"class":282},[268,112144,302],{"class":274},[268,112146,2382],{"class":282},[268,112148,1246],{"class":274},[268,112150,2199],{"class":305},[268,112152,293],{"class":282},[268,112154,112155,112157,112159,112161,112163,112165,112167],{"class":270,"line":311},[268,112156,80826],{"class":274},[268,112158,2382],{"class":282},[268,112160,302],{"class":274},[268,112162,2382],{"class":282},[268,112164,6134],{"class":274},[268,112166,2214],{"class":305},[268,112168,293],{"class":282},[268,112170,112171,112173,112175,112177],{"class":270,"line":788},[268,112172,111958],{"class":278},[268,112174,622],{"class":282},[268,112176,111963],{"class":289},[268,112178,628],{"class":282},[268,112180,112181],{"class":270,"line":1951},[268,112182,314],{"class":282},[23,112184,112186,112197,112209,112223],{"className":112185},[26],[28,112187,112189,112191,112192,112194,112195],{"className":112188},[31],[33,112190],{"disabled":35,"type":36}," This is a compile error because ",[39,112193,2403],{}," is redeclared without ",[39,112196,112025],{},[28,112198,112200,112202,112203,112206,112207],{"className":112199},[31],[33,112201],{"disabled":35,"type":36}," This is valid shadowing: each ",[39,112204,112205],{},"let x = ..."," creates a brand-new binding that temporarily hides the previous one; it prints ",[39,112208,16513],{},[28,112210,112212,112214,112215,112217,112218,112220,112221],{"className":112211},[31],[33,112213],{"disabled":35,"type":36}," This mutates the original ",[39,112216,2403],{}," in place, requiring ",[39,112219,112025],{},", and prints ",[39,112222,16513],{},[28,112224,112226,112228,112229,112232],{"className":112225},[31],[33,112227],{"disabled":35,"type":36}," Only the first two ",[39,112230,112231],{},"let x"," lines are valid; the third causes a compile error for redefining twice",[66,112234,112235,112237,112246],{},[69,112236,71],{},[73,112238,112239,112241,112242,112206,112244],{},[76,112240,78],{}," B — This is valid shadowing: each ",[39,112243,112205],{},[39,112245,16513],{},[73,112247,112248,112250,112251,112253,112254,112256,112257,112259,112260,112263,112264,112267,112268,112270],{},[76,112249,84],{}," Shadowing with repeated ",[39,112252,240],{}," is explicitly allowed any number of times and does not require ",[39,112255,112025],{},", because each ",[39,112258,240],{}," introduces a distinct variable (",[39,112261,112262],{},"(5+1)*2 = 12",") rather than mutating existing storage — unlike mutation, which changes a value in place through the same binding. This is a common point of confusion: shadowing ",[104,112265,112266],{},"looks"," like reassignment but is a completely different mechanism (C incorrectly claims ",[39,112269,112025],{}," is required).",[15,112272,112273,112282,112318],{},[18,112274,112276,112277,112279,112280,8691],{"id":112275},"q4-which-of-the-following-is-only-possible-with-shadowing-let-not-with-plain-mutation-mut","Q4. Which of the following is only possible with shadowing (",[39,112278,240],{},"), not with plain mutation (",[39,112281,112025],{},[23,112283,112285,112291,112306,112312],{"className":112284},[26],[28,112286,112288,112290],{"className":112287},[31],[33,112289],{"disabled":35,"type":36}," Increasing a numeric value",[28,112292,112294,112296,112297,112299,112300,5425,112303],{"className":112293},[31],[33,112295],{"disabled":35,"type":36}," Changing the ",[104,112298,8623],{}," of the variable binding, e.g. from ",[39,112301,112302],{},"&str",[39,112304,112305],{},"usize",[28,112307,112309,112311],{"className":112308},[31],[33,112310],{"disabled":35,"type":36}," Using the variable inside a loop",[28,112313,112315,112317],{"className":112314},[31],[33,112316],{"disabled":35,"type":36}," Passing the variable to a function",[66,112319,112320,112322,112333],{},[69,112321,71],{},[73,112323,112324,112326,112327,112299,112329,5425,112331],{},[76,112325,78],{}," B — Changing the ",[104,112328,8623],{},[39,112330,112302],{},[39,112332,112305],{},[73,112334,112335,812,112337,112339,112340,112343,112344,112346,112347,112350],{},[76,112336,84],{},[39,112338,112025],{}," binding keeps a fixed type for its entire lifetime — ",[39,112341,112342],{},"let mut x = \"5\"; x = 5;"," is a compile error (type mismatch: expected ",[39,112345,112302],{},", found integer). Shadowing, however, creates an entirely new variable each time, so its type can freely differ: ",[39,112348,112349],{},"let x = \"5\"; let x: usize = x.parse().unwrap();"," is valid and idiomatic, commonly used to convert a value while reusing a meaningful name.",[15,112352,112353,112359,112384,112424],{"language":111909},[18,112354,112356,112357,1685],{"id":112355},"q5-what-is-the-correct-syntax-and-semantics-of-a-const","Q5. What is the correct syntax and semantics of a ",[39,112358,243],{},[257,112360,112361],{"language":111909},[260,112362,112364],{"className":111918,"code":112363,"language":111909,"meta":264,"style":264},"const MAX_RETRIES: u32 = 3;\n",[39,112365,112366],{"__ignoreMap":264},[268,112367,112368,112370,112373,112375,112378,112380,112382],{"class":270,"line":271},[268,112369,243],{"class":274},[268,112371,112372],{"class":305}," MAX_RETRIES",[268,112374,10728],{"class":274},[268,112376,112377],{"class":278}," u32",[268,112379,616],{"class":274},[268,112381,3396],{"class":305},[268,112383,293],{"class":282},[23,112385,112387,112395,112406,112416],{"className":112386},[26],[28,112388,112390,355,112392,112394],{"className":112389},[31],[33,112391],{"disabled":35,"type":36},[39,112393,243],{}," values must have an explicit type annotation, are evaluated at compile time, and can never be mutated",[28,112396,112398,355,112400,112402,112403,112405],{"className":112397},[31],[33,112399],{"disabled":35,"type":36},[39,112401,243],{}," values are inferred automatically like ",[39,112404,240],{},", and type annotations are optional",[28,112407,112409,355,112411,34695,112413,112415],{"className":112408},[31],[33,112410],{"disabled":35,"type":36},[39,112412,243],{},[39,112414,240],{}," but with a different keyword for style purposes",[28,112417,112419,355,112421,112423],{"className":112418},[31],[33,112420],{"disabled":35,"type":36},[39,112422,243],{}," values are computed once at program startup (runtime), similar to a lazily initialized static",[66,112425,112426,112428,112434],{},[69,112427,71],{},[73,112429,112430,3459,112432,112394],{},[76,112431,78],{},[39,112433,243],{},[73,112435,112436,4030,112438,42,112440,112442,112443,112445,112446,112448,112449,112451,112452,446,112455,112458],{},[76,112437,84],{},[39,112439,240],{},[39,112441,243],{}," requires an explicit type annotation and its initializer must be a compile-time constant expression — the compiler effectively inlines its value wherever it's used, and ",[39,112444,112025],{}," is never permitted on a ",[39,112447,243],{},". Option D describes lazy runtime initialization, which is not how plain ",[39,112450,243],{}," works (that pattern would need something like ",[39,112453,112454],{},"std::sync::LazyLock",[39,112456,112457],{},"once_cell"," for genuinely runtime-computed constants).",[15,112460,112461,112470,112528],{},[18,112462,112464,112465,112467,112468,1685],{"id":112463},"q6-how-does-static-differ-from-const","Q6. How does ",[39,112466,31581],{}," differ from ",[39,112469,243],{},[23,112471,112473,112482,112503,112517],{"className":112472},[26],[28,112474,112476,112478,112479,112481],{"className":112475},[31],[33,112477],{"disabled":35,"type":36}," They are identical in every respect; ",[39,112480,31581],{}," is just older syntax",[28,112483,112485,812,112487,112489,112490,112493,112494,112496,112497,91245,112500,112502],{"className":112484},[31],[33,112486],{"disabled":35,"type":36},[39,112488,31581],{}," has a fixed memory address and lives for the entire program (",[39,112491,112492],{},"'static"," lifetime), and can be declared ",[39,112495,112025],{}," (though accessing a mutable static requires ",[39,112498,112499],{},"unsafe",[39,112501,243],{}," is inlined at each use site and has no fixed address",[28,112504,112506,355,112508,112510,112511,112513,112514,112516],{"className":112505},[31],[33,112507],{"disabled":35,"type":36},[39,112509,243],{}," can be mutable with the ",[39,112512,112025],{}," keyword, but ",[39,112515,31581],{}," cannot",[28,112518,112520,355,112522,112524,112525,112527],{"className":112519},[31],[33,112521],{"disabled":35,"type":36},[39,112523,31581],{}," values must be recomputed every time they're accessed, while ",[39,112526,243],{}," is cached",[66,112529,112530,112532,112547],{},[69,112531,71],{},[73,112533,112534,853,112536,112538,112539,112541,112542,112544,112545,112502],{},[76,112535,78],{},[39,112537,31581],{}," has a fixed memory address and lives for the entire program, and can be declared ",[39,112540,112025],{}," (requiring ",[39,112543,112499],{}," to access); a ",[39,112546,243],{},[73,112548,112549,355,112551,112553,112554,112556,112557,112560],{},[76,112550,84],{},[39,112552,243],{}," is conceptually a compile-time substitution with no guaranteed single memory location (the compiler may duplicate its value at each usage), whereas ",[39,112555,31581],{}," reserves one fixed, program-lifetime memory location — this matters when you need a stable address (e.g., for FFI) or genuine shared mutable global state, which is only possible (and only unsafely) via ",[39,112558,112559],{},"static mut"," (option C has the mutability rule backwards).",[15,112562,112563,112567,112629,112668],{"language":111909},[18,112564,112566],{"id":112565},"q7-what-does-this-program-print","Q7. What does this program print?",[257,112568,112569],{"language":111909},[260,112570,112572],{"className":111918,"code":112571,"language":111909,"meta":264,"style":264},"fn main() {\n    let spaces = \"   \";\n    let spaces = spaces.len();\n    println!(\"{spaces}\");\n}\n",[39,112573,112574,112582,112596,112614,112625],{"__ignoreMap":264},[268,112575,112576,112578,112580],{"class":270,"line":271},[268,112577,37837],{"class":274},[268,112579,111928],{"class":278},[268,112581,283],{"class":282},[268,112583,112584,112586,112589,112591,112594],{"class":270,"line":286},[268,112585,80826],{"class":274},[268,112587,112588],{"class":282}," spaces ",[268,112590,302],{"class":274},[268,112592,112593],{"class":289}," \"   \"",[268,112595,293],{"class":282},[268,112597,112598,112600,112602,112604,112607,112609,112612],{"class":270,"line":296},[268,112599,80826],{"class":274},[268,112601,112588],{"class":282},[268,112603,302],{"class":274},[268,112605,112606],{"class":282}," spaces",[268,112608,462],{"class":274},[268,112610,112611],{"class":278},"len",[268,112613,794],{"class":282},[268,112615,112616,112618,112620,112623],{"class":270,"line":311},[268,112617,111958],{"class":278},[268,112619,622],{"class":282},[268,112621,112622],{"class":289},"\"{spaces}\"",[268,112624,628],{"class":282},[268,112626,112627],{"class":270,"line":788},[268,112628,314],{"class":282},[23,112630,112632,112642,112649,112659],{"className":112631},[26],[28,112633,112635,112637,112638,186,112640],{"className":112634},[31],[33,112636],{"disabled":35,"type":36}," Compile error: mismatched types between ",[39,112639,112302],{},[39,112641,112305],{},[28,112643,112645,355,112647],{"className":112644},[31],[33,112646],{"disabled":35,"type":36},[39,112648,3423],{},[28,112650,112652,112654,112655,112658],{"className":112651},[31],[33,112653],{"disabled":35,"type":36}," It prints the string ",[39,112656,112657],{},"\"   \""," itself",[28,112660,112662,109262,112664,112667],{"className":112661},[31],[33,112663],{"disabled":35,"type":36},[39,112665,112666],{},"spaces"," was already defined",[66,112669,112670,112672,112678],{},[69,112671,71],{},[73,112673,112674,1727,112676],{},[76,112675,78],{},[39,112677,3423],{},[73,112679,112680,112682,112683,112686,112687,112689,112690,112692],{},[76,112681,84],{}," This is the canonical shadowing example: the second ",[39,112684,112685],{},"let spaces"," shadows the first with a new binding of a completely different type (",[39,112688,112305],{},", holding the length of the original three-space string), which compiles fine specifically because shadowing (unlike mutation) permits type changes. Option A is the tempting mistake of assuming this is a ",[39,112691,112025],{}," reassignment, where a type mismatch really would occur.",[15,112694,112695,112699,112779,112829],{"language":111909},[18,112696,112698],{"id":112697},"q8-what-happens-with-this-nested-scope-shadowing","Q8. What happens with this nested-scope shadowing?",[257,112700,112701],{"language":111909},[260,112702,112704],{"className":111918,"code":112703,"language":111909,"meta":264,"style":264},"fn main() {\n    let x = 1;\n    {\n        let x = x * 100;\n        println!(\"inner: {x}\");\n    }\n    println!(\"outer: {x}\");\n}\n",[39,112705,112706,112714,112726,112731,112748,112760,112764,112775],{"__ignoreMap":264},[268,112707,112708,112710,112712],{"class":270,"line":271},[268,112709,37837],{"class":274},[268,112711,111928],{"class":278},[268,112713,283],{"class":282},[268,112715,112716,112718,112720,112722,112724],{"class":270,"line":286},[268,112717,80826],{"class":274},[268,112719,2382],{"class":282},[268,112721,302],{"class":274},[268,112723,2199],{"class":305},[268,112725,293],{"class":282},[268,112727,112728],{"class":270,"line":296},[268,112729,112730],{"class":282},"    {\n",[268,112732,112733,112736,112738,112740,112742,112744,112746],{"class":270,"line":311},[268,112734,112735],{"class":274},"        let",[268,112737,2382],{"class":282},[268,112739,302],{"class":274},[268,112741,2382],{"class":282},[268,112743,6134],{"class":274},[268,112745,13821],{"class":305},[268,112747,293],{"class":282},[268,112749,112750,112753,112755,112758],{"class":270,"line":788},[268,112751,112752],{"class":278},"        println!",[268,112754,622],{"class":282},[268,112756,112757],{"class":289},"\"inner: {x}\"",[268,112759,628],{"class":282},[268,112761,112762],{"class":270,"line":1951},[268,112763,11972],{"class":282},[268,112765,112766,112768,112770,112773],{"class":270,"line":8955},[268,112767,111958],{"class":278},[268,112769,622],{"class":282},[268,112771,112772],{"class":289},"\"outer: {x}\"",[268,112774,628],{"class":282},[268,112776,112777],{"class":270,"line":8966},[268,112778,314],{"class":282},[23,112780,112782,112796,112810,112818],{"className":112781},[26],[28,112783,112785,85345,112787,1133,112790,112793,112794],{"className":112784},[31],[33,112786],{"disabled":35,"type":36},[39,112788,112789],{},"inner: 100",[39,112791,112792],{},"outer: 100"," — the inner shadow permanently changes ",[39,112795,2403],{},[28,112797,112799,85345,112801,1133,112803,112806,112807,112809],{"className":112798},[31],[33,112800],{"disabled":35,"type":36},[39,112802,112789],{},[39,112804,112805],{},"outer: 1"," — the inner shadow only applies within its block scope; once the block ends, the outer ",[39,112808,2403],{}," is unaffected",[28,112811,112813,109262,112815,112817],{"className":112812},[31],[33,112814],{"disabled":35,"type":36},[39,112816,2403],{}," used before being fully shadowed",[28,112819,112821,85345,112823,1133,112826,112828],{"className":112820},[31],[33,112822],{"disabled":35,"type":36},[39,112824,112825],{},"inner: 1",[39,112827,112792],{},", since block scoping is evaluated bottom-up",[66,112830,112831,112833,112843],{},[69,112832,71],{},[73,112834,112835,112837,112838,1133,112840,112842],{},[76,112836,78],{}," B — Prints ",[39,112839,112789],{},[39,112841,112805],{}," — the inner shadow only applies within its block scope",[73,112844,112845,112847,112848,112850,112851,112854,112855,112857,112858,20314,112860,112862,112863,112865,112866,112868],{},[76,112846,84],{}," Shadowing is scoped like any other ",[39,112849,240],{}," binding: the inner ",[39,112852,112853],{},"let x = x * 100;"," creates a new variable visible only inside the ",[39,112856,11010],{}," block; once that block ends, that shadow goes out of scope and the original outer ",[39,112859,2403],{},[39,112861,2255],{},") becomes visible again. This is a key edge case distinguishing shadowing from mutation — a ",[39,112864,112025],{}," variable's value change would persist outside a nested block that merely reassigns it (assuming no re-",[39,112867,240],{},"), whereas a shadow's effect is strictly scoped.",[15,112870,112871,112879,112950,112993],{"language":111909},[18,112872,112874,112875,112878],{"id":112873},"q9-what-happens-when-an-immutable-variable-holding-a-vec-is-used-like-this","Q9. What happens when an immutable variable holding a ",[39,112876,112877],{},"Vec"," is used like this?",[257,112880,112881],{"language":111909},[260,112882,112884],{"className":111918,"code":112883,"language":111909,"meta":264,"style":264},"fn main() {\n    let v = vec![1, 2, 3];\n    v.push(4);\n    println!(\"{v:?}\");\n}\n",[39,112885,112886,112894,112920,112935,112946],{"__ignoreMap":264},[268,112887,112888,112890,112892],{"class":270,"line":271},[268,112889,37837],{"class":274},[268,112891,111928],{"class":278},[268,112893,283],{"class":282},[268,112895,112896,112898,112901,112903,112906,112908,112910,112912,112914,112916,112918],{"class":270,"line":286},[268,112897,80826],{"class":274},[268,112899,112900],{"class":282}," v ",[268,112902,302],{"class":274},[268,112904,112905],{"class":278}," vec!",[268,112907,15175],{"class":282},[268,112909,2255],{"class":305},[268,112911,42],{"class":282},[268,112913,2258],{"class":305},[268,112915,42],{"class":282},[268,112917,3423],{"class":305},[268,112919,8737],{"class":282},[268,112921,112922,112925,112927,112929,112931,112933],{"class":270,"line":296},[268,112923,112924],{"class":282},"    v",[268,112926,462],{"class":274},[268,112928,12499],{"class":278},[268,112930,622],{"class":282},[268,112932,15049],{"class":305},[268,112934,628],{"class":282},[268,112936,112937,112939,112941,112944],{"class":270,"line":311},[268,112938,111958],{"class":278},[268,112940,622],{"class":282},[268,112942,112943],{"class":289},"\"{v:?}\"",[268,112945,628],{"class":282},[268,112947,112948],{"class":270,"line":788},[268,112949,314],{"class":282},[23,112951,112953,112966,112975,112984],{"className":112952},[26],[28,112954,112956,112958,112959,112961,112962,112965],{"className":112955},[31],[33,112957],{"disabled":35,"type":36}," Compiles fine — ",[39,112960,12499],{}," only needs ",[39,112963,112964],{},"&self",", so mutability of the binding doesn't matter",[28,112967,112969,112971,112972,112974],{"className":112968},[31],[33,112970],{"disabled":35,"type":36}," Compile error: cannot borrow ",[39,112973,52799],{}," as mutable, as it is not declared as mutable",[28,112976,112978,112980,112981,112983],{"className":112977},[31],[33,112979],{"disabled":35,"type":36}," Compiles but panics at runtime because ",[39,112982,52799],{}," is immutable",[28,112985,112987,112989,112990,112992],{"className":112986},[31],[33,112988],{"disabled":35,"type":36}," Compiles fine because ",[39,112991,112877],{}," has interior mutability by default",[66,112994,112995,112997,113004],{},[69,112996,71],{},[73,112998,112999,113001,113002,112974],{},[76,113000,78],{}," B — Compile error: cannot borrow ",[39,113003,52799],{},[73,113005,113006,355,113008,26924,113011,113014,113015,71990,113017,113019,113020,113022,113023,113026,113027,3277,113029,113031,113032,446,113035,2758,113038,113040,113041,462],{},[76,113007,84],{},[39,113009,113010],{},"Vec::push",[39,113012,113013],{},"&mut self",", and obtaining a mutable borrow of ",[39,113016,52799],{},[39,113018,52799],{}," itself to be declared ",[39,113021,112025],{}," — immutability is not just about direct reassignment (",[39,113024,113025],{},"v = ...",") but about disallowing any mutable access to the value's contents, including through method calls that need ",[39,113028,113013],{},[39,113030,112877],{}," does not have interior mutability (D describes types like ",[39,113033,113034],{},"RefCell",[39,113036,113037],{},"Cell",[39,113039,112877],{},"), so the fix is simply ",[39,113042,113043],{},"let mut v = vec![1, 2, 3];",[15,113045,113046,113050,113141,113205],{"language":111909},[18,113047,113049],{"id":113048},"q10-what-is-the-effect-of-shadowing-inside-a-loop-as-shown-here","Q10. What is the effect of shadowing inside a loop, as shown here?",[257,113051,113052],{"language":111909},[260,113053,113055],{"className":111918,"code":113054,"language":111909,"meta":264,"style":264},"fn main() {\n    let mut count = 0;\n    for i in 0..3 {\n        let count = count + i;\n        println!(\"{count}\");\n    }\n    println!(\"final: {count}\");\n}\n",[39,113056,113057,113065,113080,113096,113111,113122,113126,113137],{"__ignoreMap":264},[268,113058,113059,113061,113063],{"class":270,"line":271},[268,113060,37837],{"class":274},[268,113062,111928],{"class":278},[268,113064,283],{"class":282},[268,113066,113067,113069,113072,113074,113076,113078],{"class":270,"line":286},[268,113068,80826],{"class":274},[268,113070,113071],{"class":274}," mut",[268,113073,10091],{"class":282},[268,113075,302],{"class":274},[268,113077,5728],{"class":305},[268,113079,293],{"class":282},[268,113081,113082,113084,113086,113088,113090,113092,113094],{"class":270,"line":296},[268,113083,80840],{"class":274},[268,113085,9384],{"class":282},[268,113087,20749],{"class":274},[268,113089,5728],{"class":305},[268,113091,86888],{"class":274},[268,113093,3423],{"class":305},[268,113095,9914],{"class":282},[268,113097,113098,113100,113102,113104,113106,113108],{"class":270,"line":311},[268,113099,112735],{"class":274},[268,113101,10091],{"class":282},[268,113103,302],{"class":274},[268,113105,10091],{"class":282},[268,113107,1246],{"class":274},[268,113109,113110],{"class":282}," i;\n",[268,113112,113113,113115,113117,113120],{"class":270,"line":788},[268,113114,112752],{"class":278},[268,113116,622],{"class":282},[268,113118,113119],{"class":289},"\"{count}\"",[268,113121,628],{"class":282},[268,113123,113124],{"class":270,"line":1951},[268,113125,11972],{"class":282},[268,113127,113128,113130,113132,113135],{"class":270,"line":8955},[268,113129,111958],{"class":278},[268,113131,622],{"class":282},[268,113133,113134],{"class":289},"\"final: {count}\"",[268,113136,628],{"class":282},[268,113138,113139],{"class":270,"line":8966},[268,113140,314],{"class":282},[23,113142,113144,113166,113181,113192],{"className":113143},[26],[28,113145,113147,85345,113149,42,113151,42,113153,186,113155,113158,113159,113161,113162,113165],{"className":113146},[31],[33,113148],{"disabled":35,"type":36},[39,113150,3307],{},[39,113152,2255],{},[39,113154,2258],{},[39,113156,113157],{},"final: 0"," — the shadowed ",[39,113160,10191],{}," inside the loop body never affects the outer ",[39,113163,113164],{},"mut count",", which is never actually mutated anywhere in this program",[28,113167,113169,85345,113171,42,113173,42,113175,186,113177,113180],{"className":113168},[31],[33,113170],{"disabled":35,"type":36},[39,113172,3307],{},[39,113174,2255],{},[39,113176,3423],{},[39,113178,113179],{},"final: 3",", since the shadow accumulates across iterations",[28,113182,113184,109262,113186,113188,113189,113191],{"className":113183},[31],[33,113185],{"disabled":35,"type":36},[39,113187,10191],{}," conflicts between ",[39,113190,112025],{}," and shadowed declarations",[28,113193,113195,85345,113197,42,113199,42,113201,186,113203],{"className":113194},[31],[33,113196],{"disabled":35,"type":36},[39,113198,3307],{},[39,113200,2255],{},[39,113202,2258],{},[39,113204,113179],{},[66,113206,113207,113209,113226],{},[69,113208,71],{},[73,113210,113211,113213,113214,42,113216,42,113218,186,113220,113158,113222,113161,113224,113165],{},[76,113212,78],{}," A — Prints ",[39,113215,3307],{},[39,113217,2255],{},[39,113219,2258],{},[39,113221,113157],{},[39,113223,10191],{},[39,113225,113164],{},[73,113227,113228,113230,113231,113234,113235,355,113237,113239,113240,113242,113243,113246,113247,113249,113250,113252,113253,113255,113256,113258,113259,113261],{},[76,113229,84],{}," Each loop iteration re-declares a fresh shadow ",[39,113232,113233],{},"let count = count + i",", reading the ",[104,113236,9628],{},[39,113238,10191],{}," (always ",[39,113241,3307],{},", since it's never reassigned with ",[39,113244,113245],{},"count = ..."," anywhere) plus the current ",[39,113248,9509],{},", then discarding that shadow at the end of the iteration's block scope. Despite being marked ",[39,113251,112025],{},", the outer ",[39,113254,10191],{}," is never actually mutated — only shadowed — which is a common gotcha: declaring ",[39,113257,112025],{}," doesn't mean a variable ",[104,113260,4447],{}," being mutated, and shadowing inside a loop body does not accumulate like a running total would (contradicting the tempting B).",[15,113263,113264,113268,113349,113396],{"language":111909},[18,113265,113267],{"id":113266},"q11-what-is-wrong-if-anything-with-this-code","Q11. What is wrong, if anything, with this code?",[257,113269,113270],{"language":111909},[260,113271,113273],{"className":111918,"code":113272,"language":111909,"meta":264,"style":264},"const BUFFER_SIZE: usize = compute_size();\n\nfn compute_size() -> usize {\n    42\n}\n\nfn main() {\n    println!(\"{BUFFER_SIZE}\");\n}\n",[39,113274,113275,113294,113298,113313,113318,113322,113326,113334,113345],{"__ignoreMap":264},[268,113276,113277,113279,113282,113284,113287,113289,113292],{"class":270,"line":271},[268,113278,243],{"class":274},[268,113280,113281],{"class":305}," BUFFER_SIZE",[268,113283,10728],{"class":274},[268,113285,113286],{"class":278}," usize",[268,113288,616],{"class":274},[268,113290,113291],{"class":278}," compute_size",[268,113293,794],{"class":282},[268,113295,113296],{"class":270,"line":286},[268,113297,5033],{"emptyLinePlaceholder":35},[268,113299,113300,113302,113304,113306,113309,113311],{"class":270,"line":296},[268,113301,37837],{"class":274},[268,113303,113291],{"class":278},[268,113305,16182],{"class":282},[268,113307,113308],{"class":274},"->",[268,113310,113286],{"class":278},[268,113312,9914],{"class":282},[268,113314,113315],{"class":270,"line":311},[268,113316,113317],{"class":305},"    42\n",[268,113319,113320],{"class":270,"line":788},[268,113321,314],{"class":282},[268,113323,113324],{"class":270,"line":1951},[268,113325,5033],{"emptyLinePlaceholder":35},[268,113327,113328,113330,113332],{"class":270,"line":8955},[268,113329,37837],{"class":274},[268,113331,111928],{"class":278},[268,113333,283],{"class":282},[268,113335,113336,113338,113340,113343],{"class":270,"line":8966},[268,113337,111958],{"class":278},[268,113339,622],{"class":282},[268,113341,113342],{"class":289},"\"{BUFFER_SIZE}\"",[268,113344,628],{"class":282},[268,113346,113347],{"class":270,"line":8974},[268,113348,314],{"class":282},[23,113350,113352,113364,113376,113385],{"className":113351},[26],[28,113353,113355,113357,113358,4387,113360,113363],{"className":113354},[31],[33,113356],{"disabled":35,"type":36}," Nothing — this compiles and prints ",[39,113359,4659],{},[39,113361,113362],{},"compute_size"," is a simple const-evaluable function",[28,113365,113367,109262,113369,113371,113372,113375],{"className":113366},[31],[33,113368],{"disabled":35,"type":36},[39,113370,113362],{}," is not marked ",[39,113373,113374],{},"const fn",", so it cannot be called in a const-evaluation context",[28,113377,113379,113381,113382,113384],{"className":113378},[31],[33,113380],{"disabled":35,"type":36}," Runtime panic because ",[39,113383,243],{}," initializers cannot call functions",[28,113386,113388,109262,113390,113392,113393],{"className":113387},[31],[33,113389],{"disabled":35,"type":36},[39,113391,243],{}," items cannot appear before ",[39,113394,113395],{},"fn main",[66,113397,113398,113400,113408],{},[69,113399,71],{},[73,113401,113402,109287,113404,113371,113406,113375],{},[76,113403,78],{},[39,113405,113362],{},[39,113407,113374],{},[73,113409,113410,812,113412,113414,113415,113417,113418,113421,113422,113424],{},[76,113411,84],{},[39,113413,243],{}," initializer must be evaluable entirely at compile time; calling an ordinary ",[39,113416,37837],{}," is not permitted because the compiler cannot generally guarantee it has no runtime-only behavior. The fix is ",[39,113419,113420],{},"const fn compute_size() -> usize { 42 }",", which explicitly opts the function into compile-time (and still-usable-at-runtime) evaluation. Declaration order (D) is a red herring — Rust items are not order-dependent within a module, unlike ",[39,113423,240],{}," statements.",[15,113426,113427,113434,113502,113540],{"language":111909},[18,113428,113430,113431,113433],{"id":113429},"q12-given-this-snippet-what-does-total-end-up-being-and-why","Q12. Given this snippet, what does ",[39,113432,805],{}," end up being, and why?",[257,113435,113436],{"language":111909},[260,113437,113439],{"className":111918,"code":113438,"language":111909,"meta":264,"style":264},"fn main() {\n    let total = 10;\n    let total = total;\n    let total = total + 5;\n    println!(\"{total}\");\n}\n",[39,113440,113441,113449,113461,113471,113487,113498],{"__ignoreMap":264},[268,113442,113443,113445,113447],{"class":270,"line":271},[268,113444,37837],{"class":274},[268,113446,111928],{"class":278},[268,113448,283],{"class":282},[268,113450,113451,113453,113455,113457,113459],{"class":270,"line":286},[268,113452,80826],{"class":274},[268,113454,21479],{"class":282},[268,113456,302],{"class":274},[268,113458,306],{"class":305},[268,113460,293],{"class":282},[268,113462,113463,113465,113467,113469],{"class":270,"line":296},[268,113464,80826],{"class":274},[268,113466,21479],{"class":282},[268,113468,302],{"class":274},[268,113470,21493],{"class":282},[268,113472,113473,113475,113477,113479,113481,113483,113485],{"class":270,"line":311},[268,113474,80826],{"class":274},[268,113476,21479],{"class":282},[268,113478,302],{"class":274},[268,113480,21479],{"class":282},[268,113482,1246],{"class":274},[268,113484,2387],{"class":305},[268,113486,293],{"class":282},[268,113488,113489,113491,113493,113496],{"class":270,"line":788},[268,113490,111958],{"class":278},[268,113492,622],{"class":282},[268,113494,113495],{"class":289},"\"{total}\"",[268,113497,628],{"class":282},[268,113499,113500],{"class":270,"line":1951},[268,113501,314],{"class":282},[23,113503,113505,113514,113524,113532],{"className":113504},[26],[28,113506,113508,113510,113511,2690],{"className":113507},[31],[33,113509],{"disabled":35,"type":36}," Compile error: cannot shadow a variable with itself (",[39,113512,113513],{},"let total = total;",[28,113515,113517,355,113519,21554,113521,113523],{"className":113516},[31],[33,113518],{"disabled":35,"type":36},[39,113520,24207],{},[39,113522,113513],{}," is a valid (if redundant) shadow that simply moves\u002Fcopies the value into a new binding, and shadowing continues to work normally afterward",[28,113525,113527,355,113529,113531],{"className":113526},[31],[33,113528],{"disabled":35,"type":36},[39,113530,5825],{},", because the final shadow is ignored",[28,113533,113535,109262,113537,113539],{"className":113534},[31],[33,113536],{"disabled":35,"type":36},[39,113538,805],{}," used in its own initializer is a circular definition",[66,113541,113542,113544,113553],{},[69,113543,71],{},[73,113545,113546,1727,113548,21554,113550,113552],{},[76,113547,78],{},[39,113549,24207],{},[39,113551,113513],{}," is a valid (if redundant) shadow that simply moves\u002Fcopies the value into a new binding",[73,113554,113555,17028,113557,113560,113561,113563,113564,113566,113567,113569,113570,462],{},[76,113556,84],{},[39,113558,113559],{},"let total = \u003Cexpr>"," evaluates its right-hand side using whatever ",[39,113562,805],{}," was previously in scope ",[104,113565,11314],{}," introducing the new binding — this is not circular (ruling out D) because the old and new ",[39,113568,805],{}," are different variables, not the same one referring to itself. This pattern (shadowing a variable with an expression referencing itself) is completely ordinary and compiles without any special-casing, ultimately yielding ",[39,113571,113572],{},"10 + 5 = 15",[15,113574,113575,113582,113656,113704],{"language":111909},[18,113576,113578,113579,113581],{"id":113577},"q13-what-happens-with-this-pattern-matched-let-binding","Q13. What happens with this pattern-matched ",[39,113580,240],{}," binding?",[257,113583,113584],{"language":111909},[260,113585,113587],{"className":111918,"code":113586,"language":111909,"meta":264,"style":264},"fn main() {\n    let (a, mut b) = (1, 2);\n    a = 10;\n    b = 20;\n    println!(\"{a} {b}\");\n}\n",[39,113588,113589,113597,113621,113631,113641,113652],{"__ignoreMap":264},[268,113590,113591,113593,113595],{"class":270,"line":271},[268,113592,37837],{"class":274},[268,113594,111928],{"class":278},[268,113596,283],{"class":282},[268,113598,113599,113601,113604,113606,113609,113611,113613,113615,113617,113619],{"class":270,"line":286},[268,113600,80826],{"class":274},[268,113602,113603],{"class":282}," (a, ",[268,113605,112025],{"class":274},[268,113607,113608],{"class":282}," b) ",[268,113610,302],{"class":274},[268,113612,2182],{"class":282},[268,113614,2255],{"class":305},[268,113616,42],{"class":282},[268,113618,2258],{"class":305},[268,113620,628],{"class":282},[268,113622,113623,113625,113627,113629],{"class":270,"line":296},[268,113624,106789],{"class":282},[268,113626,302],{"class":274},[268,113628,306],{"class":305},[268,113630,293],{"class":282},[268,113632,113633,113635,113637,113639],{"class":270,"line":311},[268,113634,106808],{"class":282},[268,113636,302],{"class":274},[268,113638,8941],{"class":305},[268,113640,293],{"class":282},[268,113642,113643,113645,113647,113650],{"class":270,"line":788},[268,113644,111958],{"class":278},[268,113646,622],{"class":282},[268,113648,113649],{"class":289},"\"{a} {b}\"",[268,113651,628],{"class":282},[268,113653,113654],{"class":270,"line":1951},[268,113655,314],{"class":282},[23,113657,113659,113668,113687,113698],{"className":113658},[26],[28,113660,113662,113664,113665,113667],{"className":113661},[31],[33,113663],{"disabled":35,"type":36}," Both reassignments compile fine, since ",[39,113666,112025],{}," applies to the whole tuple pattern",[28,113669,113671,113673,113674,113677,113678,113680,113681,113683,113684,113686],{"className":113670},[31],[33,113672],{"disabled":35,"type":36}," Compile error on ",[39,113675,113676],{},"a = 10;"," — mutability in a destructuring pattern is per-binding; ",[39,113679,1223],{}," was not marked ",[39,113682,112025],{},", so only ",[39,113685,1232],{}," is reassignable",[28,113688,113690,113673,113692,3990,113695,113697],{"className":113689},[31],[33,113691],{"disabled":35,"type":36},[39,113693,113694],{},"b = 20;",[39,113696,112025],{}," inside a tuple pattern is not valid syntax",[28,113699,113701,113703],{"className":113700},[31],[33,113702],{"disabled":35,"type":36}," Compile error on both lines, since tuple destructuring never allows subsequent reassignment",[66,113705,113706,113708,113721],{},[69,113707,71],{},[73,113709,113710,113712,113713,113677,113715,113680,113717,113683,113719,113686],{},[76,113711,78],{}," B — Compile error on ",[39,113714,113676],{},[39,113716,1223],{},[39,113718,112025],{},[39,113720,1232],{},[73,113722,113723,113725,113726,42,113729,113731,113732,113734,113735,113737,113738,42,113740,113742,113743,5804,113745,113747],{},[76,113724,84],{}," In pattern destructuring like ",[39,113727,113728],{},"let (a, mut b) = ...",[39,113730,112025],{}," attaches to the individual identifier it precedes, not to the tuple as a whole — a common gotcha for developers assuming ",[39,113733,112025],{}," on one part of a pattern applies globally. Since ",[39,113736,1223],{}," lacks ",[39,113739,112025],{},[39,113741,113676],{}," triggers ",[39,113744,112029],{},[39,113746,113694],{}," is perfectly valid.",[15,113749,113750,113754,113844,113890],{"language":111909},[18,113751,113753],{"id":113752},"q14-what-is-the-behavior-of-this-code-involving-a-shadowed-reference","Q14. What is the behavior of this code involving a shadowed reference?",[257,113755,113756],{"language":111909},[260,113757,113759],{"className":111918,"code":113758,"language":111909,"meta":264,"style":264},"fn main() {\n    let guess = \"42\";\n    let guess: i32 = guess.trim().parse().expect(\"not a number\");\n    println!(\"{}\", guess + 1);\n}\n",[39,113760,113761,113769,113783,113822,113840],{"__ignoreMap":264},[268,113762,113763,113765,113767],{"class":270,"line":271},[268,113764,37837],{"class":274},[268,113766,111928],{"class":278},[268,113768,283],{"class":282},[268,113770,113771,113773,113776,113778,113781],{"class":270,"line":286},[268,113772,80826],{"class":274},[268,113774,113775],{"class":282}," guess ",[268,113777,302],{"class":274},[268,113779,113780],{"class":289}," \"42\"",[268,113782,293],{"class":282},[268,113784,113785,113787,113790,113792,113795,113797,113799,113801,113803,113805,113807,113809,113811,113813,113815,113817,113820],{"class":270,"line":296},[268,113786,80826],{"class":274},[268,113788,113789],{"class":282}," guess",[268,113791,10728],{"class":274},[268,113793,113794],{"class":278}," i32",[268,113796,616],{"class":274},[268,113798,113789],{"class":282},[268,113800,462],{"class":274},[268,113802,18832],{"class":278},[268,113804,16952],{"class":282},[268,113806,462],{"class":274},[268,113808,22274],{"class":278},[268,113810,16952],{"class":282},[268,113812,462],{"class":274},[268,113814,75834],{"class":278},[268,113816,622],{"class":282},[268,113818,113819],{"class":289},"\"not a number\"",[268,113821,628],{"class":282},[268,113823,113824,113826,113828,113831,113834,113836,113838],{"class":270,"line":311},[268,113825,111958],{"class":278},[268,113827,622],{"class":282},[268,113829,113830],{"class":289},"\"{}\"",[268,113832,113833],{"class":282},", guess ",[268,113835,1246],{"class":274},[268,113837,2199],{"class":305},[268,113839,628],{"class":282},[268,113841,113842],{"class":270,"line":788},[268,113843,314],{"class":282},[23,113845,113847,113861,113871,113879],{"className":113846},[26],[28,113848,113850,109262,113852,113855,113856,58522,113858],{"className":113849},[31],[33,113851],{"disabled":35,"type":36},[39,113853,113854],{},"guess"," cannot be both a ",[39,113857,112302],{},[39,113859,113860],{},"i32",[28,113862,113864,113866,113867,113870],{"className":113863},[31],[33,113865],{"disabled":35,"type":36}," Compiles and prints ",[39,113868,113869],{},"43"," — shadowing lets the string be parsed into a numeric type under the same name, a common idiom for input validation\u002Fconversion",[28,113872,113874,112980,113876,113878],{"className":113873},[31],[33,113875],{"disabled":35,"type":36},[39,113877,6960],{}," is not trimmed first",[28,113880,113882,109262,113884,76561,113887,113889],{"className":113881},[31],[33,113883],{"disabled":35,"type":36},[39,113885,113886],{},".expect()",[39,113888,240],{}," initializer",[66,113891,113892,113894,113901],{},[69,113893,71],{},[73,113895,113896,113898,113899,113870],{},[76,113897,78],{}," B — Compiles and prints ",[39,113900,113869],{},[73,113902,113903,113905,113906,113908,113909,446,113912,113915,113916,113918,113919,113922,113923,113925,113926,113928,113929,113931,113932,462],{},[76,113904,84],{}," This is the textbook idiomatic use of shadowing shown in the official Rust book: reusing the name ",[39,113907,113854],{}," avoids inventing a separate name like ",[39,113910,113911],{},"guess_str",[39,113913,113914],{},"guess_num"," for what is conceptually \"the same value, converted.\" ",[39,113917,18953],{}," removes whitespace before ",[39,113920,113921],{},".parse::\u003Ci32>()",", which succeeds here since ",[39,113924,6960],{}," parses cleanly, so ",[39,113927,113886],{}," never triggers its panic path, and the value is a genuine ",[39,113930,113860],{}," addition yielding ",[39,113933,113869],{},[15,113935,113936,113943,113981],{},[18,113937,113939,113940,113942],{"id":113938},"q15-when-choosing-between-mut-and-shadowing-to-transform-a-value-while-keeping-semantic-continuity-eg-trimming-and-parsing-user-input-what-is-the-idiomatic-best-practice","Q15. When choosing between ",[39,113941,112025],{}," and shadowing to transform a value while keeping semantic continuity (e.g., trimming and parsing user input), what is the idiomatic best practice?",[23,113944,113946,113955,113966,113972],{"className":113945},[26],[28,113947,113949,113951,113952,113954],{"className":113948},[31],[33,113950],{"disabled":35,"type":36}," Always prefer ",[39,113953,112025],{}," in every case, since shadowing is considered a deprecated pattern",[28,113956,113958,113960,113961,113963,113964,2690],{"className":113957},[31],[33,113959],{"disabled":35,"type":36}," Prefer shadowing when the transformation also changes the type or represents a distinct logical value (e.g., raw string to parsed number), and reserve ",[39,113962,112025],{}," for genuine in-place accumulation\u002Fmutation of the same logical value (e.g., a running counter or a growing ",[39,113965,112877],{},[28,113967,113969,113971],{"className":113968},[31],[33,113970],{"disabled":35,"type":36}," It never matters; both are functionally and stylistically interchangeable in all cases",[28,113973,113975,113977,113978,113980],{"className":113974},[31],[33,113976],{"disabled":35,"type":36}," Always prefer shadowing over ",[39,113979,112025],{},", even for loop counters and accumulators",[66,113982,113983,113985,113993],{},[69,113984,71],{},[73,113986,113987,113989,113990,113992],{},[76,113988,78],{}," B — Prefer shadowing when the transformation also changes the type or represents a distinct logical value, and reserve ",[39,113991,112025],{}," for genuine in-place accumulation\u002Fmutation",[73,113994,113995,355,113997,113999,114000,114002,114003,114005],{},[76,113996,84],{},[76,113998,930],{}," shadowing communicates \"this is conceptually a new, immutable value derived from the old one\" (great for type conversions or applying a series of independent transformations), while ",[39,114001,112025],{}," communicates \"this variable's value genuinely changes over time\" (ideal for counters, accumulators, or mutable collections). Defaulting to ",[39,114004,112025],{}," everywhere (A) loses the compiler's help in catching accidental unintended mutation, since immutable-by-default is one of Rust's core safety features, not a style preference to override universally.",[15,114007,114008,114018,114049],{},[18,114009,114011,114012,114014,114015,1685],{"id":114010},"q16-what-is-the-idiomatic-best-practice-reason-to-prefer-const-over-a-magic-number-literal-scattered-throughout-code-such-as-const-max_connections-u32-100","Q16. What is the idiomatic best-practice reason to prefer ",[39,114013,243],{}," over a \"magic number\" literal scattered throughout code, such as ",[39,114016,114017],{},"const MAX_CONNECTIONS: u32 = 100;",[23,114019,114021,114029,114035,114043],{"className":114020},[26],[28,114022,114024,355,114026,114028],{"className":114023},[31],[33,114025],{"disabled":35,"type":36},[39,114027,243],{}," values are faster at runtime than literals because they're cached in a register",[28,114030,114032,114034],{"className":114031},[31],[33,114033],{"disabled":35,"type":36}," It gives the value a descriptive name (improving readability\u002Fintent), centralizes the value for easy updates, and lets the compiler enforce its type — literal magic numbers offer none of these and are error-prone to keep in sync across a codebase",[28,114036,114038,355,114040,114042],{"className":114037},[31],[33,114039],{"disabled":35,"type":36},[39,114041,243],{}," is required by the compiler for any numeric literal used more than once",[28,114044,114046,114048],{"className":114045},[31],[33,114047],{"disabled":35,"type":36}," There is no practical benefit; it's purely a stylistic preference with zero technical merit",[66,114050,114051,114053,114058],{},[69,114052,71],{},[73,114054,114055,114057],{},[76,114056,78],{}," B — It gives the value a descriptive name, centralizes the value for easy updates, and lets the compiler enforce its type — literal magic numbers offer none of these and are error-prone to keep in sync",[73,114059,114060,355,114062,5887,114064,114066,114067,114070,114071,114073],{},[76,114061,84],{},[76,114063,930],{},[39,114065,243],{}," values are inlined by the compiler, there's no meaningful runtime performance difference versus a literal (A is a myth) — the real benefit is entirely about maintainability and self-documenting code, e.g. changing ",[39,114068,114069],{},"MAX_CONNECTIONS"," in one place instead of hunting down every ",[39,114072,13912],{}," in the codebase, some of which might mean something else entirely.",[15,114075,114076,114085,114112],{},[18,114077,114079,114080,186,114082,114084],{"id":114078},"q17-which-naming-convention-does-idiomatic-rust-use-for-const-and-static-items-as-enforced-by-default-clippyrustc-style-lints","Q17. Which naming convention does idiomatic Rust use for ",[39,114081,243],{},[39,114083,31581],{}," items, as enforced by default Clippy\u002Frustc style lints?",[23,114086,114088,114094,114100,114106],{"className":114087},[26],[28,114089,114091,114093],{"className":114090},[31],[33,114092],{"disabled":35,"type":36}," camelCase, matching function and variable names",[28,114095,114097,114099],{"className":114096},[31],[33,114098],{"disabled":35,"type":36}," SCREAMING_SNAKE_CASE",[28,114101,114103,114105],{"className":114102},[31],[33,114104],{"disabled":35,"type":36}," PascalCase, matching type names",[28,114107,114109,114111],{"className":114108},[31],[33,114110],{"disabled":35,"type":36}," snake_case, identical to regular variables",[66,114113,114114,114116,114121],{},[69,114115,71],{},[73,114117,114118,114120],{},[76,114119,78],{}," B — SCREAMING_SNAKE_CASE",[73,114122,114123,355,114125,114127,114128,114131,114132,446,114134,114136,114137,98691,114140,114142,114143,114146,114147,114150,114151,89580,114153,114155],{},[76,114124,84],{},[76,114126,930],{}," Rust's naming conventions (enforced by the ",[39,114129,114130],{},"non_upper_case_globals"," lint) require ",[39,114133,243],{},[39,114135,31581],{}," identifiers in ",[39,114138,114139],{},"SCREAMING_SNAKE_CASE",[39,114141,88532],{},", visually distinguishing compile-time constants from ordinary ",[39,114144,114145],{},"snake_case"," variables and ",[39,114148,114149],{},"PascalCase"," types — using ",[39,114152,114145],{},[39,114154,243],{}," (D) will trigger a compiler warning by default, not silently pass unnoticed.",[15,114157,114158,114166,114218,114259],{"language":111909},[18,114159,114161,114162,114165],{"id":114160},"q18-a-function-parameter-needs-to-be-modified-locally-within-the-function-body-without-affecting-the-callers-original-value-for-copy-types-what-is-the-idiomatic-approach","Q18. A function parameter needs to be modified locally within the function body without affecting the caller's original value (for ",[39,114163,114164],{},"Copy"," types). What is the idiomatic approach?",[257,114167,114168],{"language":111909},[260,114169,114171],{"className":111918,"code":114170,"language":111909,"meta":264,"style":264},"fn double(mut n: i32) -> i32 {\n    n *= 2;\n    n\n}\n",[39,114172,114173,114197,114209,114214],{"__ignoreMap":264},[268,114174,114175,114177,114179,114181,114183,114185,114187,114189,114191,114193,114195],{"class":270,"line":271},[268,114176,37837],{"class":274},[268,114178,41156],{"class":278},[268,114180,622],{"class":282},[268,114182,112025],{"class":274},[268,114184,26428],{"class":282},[268,114186,10728],{"class":274},[268,114188,113794],{"class":278},[268,114190,6131],{"class":282},[268,114192,113308],{"class":274},[268,114194,113794],{"class":278},[268,114196,9914],{"class":282},[268,114198,114199,114202,114205,114207],{"class":270,"line":286},[268,114200,114201],{"class":282},"    n ",[268,114203,114204],{"class":274},"*=",[268,114206,2214],{"class":305},[268,114208,293],{"class":282},[268,114210,114211],{"class":270,"line":296},[268,114212,114213],{"class":282},"    n\n",[268,114215,114216],{"class":270,"line":311},[268,114217,314],{"class":282},[23,114219,114221,114230,114245,114251],{"className":114220},[26],[28,114222,114224,114226,114227,114229],{"className":114223},[31],[33,114225],{"disabled":35,"type":36}," This is invalid; parameters can never be declared ",[39,114228,112025],{}," in a function signature",[28,114231,114233,114235,114236,114239,114240,830,114242,114244],{"className":114232},[31],[33,114234],{"disabled":35,"type":36}," This is valid and idiomatic — ",[39,114237,114238],{},"mut n"," makes the local parameter binding mutable within the function body, and since ",[39,114241,113860],{},[39,114243,114164],{},", the caller's original value is entirely unaffected",[28,114246,114248,114250],{"className":114247},[31],[33,114249],{"disabled":35,"type":36}," This mutates the caller's original variable as a side effect, since all integers are passed by reference",[28,114252,114254,355,114256,114258],{"className":114253},[31],[33,114255],{"disabled":35,"type":36},[39,114257,112025],{}," here is redundant and should be removed, since function parameters are always mutable by default",[66,114260,114261,114263,114274],{},[69,114262,71],{},[73,114264,114265,114267,114268,114239,114270,830,114272,114244],{},[76,114266,78],{}," B — This is valid and idiomatic — ",[39,114269,114238],{},[39,114271,113860],{},[39,114273,114164],{},[73,114275,114276,114278,114279,114281,114282,114284,114285,42,114287,114289,114290,114292,114293,114295,114296,114298],{},[76,114277,84],{}," Marking a by-value parameter ",[39,114280,112025],{}," is a common, idiomatic pattern when a function wants to use the parameter as a local scratch variable; because ",[39,114283,113860],{}," implements ",[39,114286,114164],{},[39,114288,4599],{}," is a completely independent copy of whatever the caller passed, so mutating it inside ",[39,114291,41177],{}," has zero effect on the caller's variable (ruling out C, a mistaken assumption from languages that pass primitives by reference). Function parameters are immutable by default just like ",[39,114294,240],{}," bindings (contradicting D) — ",[39,114297,112025],{}," must be explicitly opted into here too.",[15,114300,114301,114308,114345],{},[18,114302,114304,114305,114307],{"id":114303},"q19-best-practice-a-function-receives-configuration-flags-that-should-never-change-after-being-read-at-startup-and-are-used-throughout-the-entire-programs-lifetime-across-multiple-modules-what-is-more-idiomatic-a-static-or-passing-values-explicitly-through-function-parametersstructs","Q19. Best practice: a function receives configuration flags that should never change after being read at startup and are used throughout the entire program's lifetime across multiple modules. What is more idiomatic — a ",[39,114306,31581],{}," or passing values explicitly through function parameters\u002Fstructs?",[23,114309,114311,114319,114331,114339],{"className":114310},[26],[28,114312,114314,4207,114316,114318],{"className":114313},[31],[33,114315],{"disabled":35,"type":36},[39,114317,112559],{}," globals for any cross-module shared configuration, since it's the simplest to set up",[28,114320,114322,114324,114325,114327,114328,114330],{"className":114321},[31],[33,114323],{"disabled":35,"type":36}," Prefer passing configuration explicitly (e.g., via a struct passed by reference or dependency injection) over global ",[39,114326,31581],{}," state; reserve ",[39,114329,31581],{},"\u002Fglobal state for cases with no reasonable alternative, since globals make code harder to test and reason about",[28,114332,114334,4353,114336,114338],{"className":114333},[31],[33,114335],{"disabled":35,"type":36},[39,114337,243],{}," for configuration that is only known at runtime (e.g., read from a file or environment variable)",[28,114340,114342,114344],{"className":114341},[31],[33,114343],{"disabled":35,"type":36}," There is no idiomatic distinction; global mutable state is equally recommended in Rust as in any other language",[66,114346,114347,114349,114359],{},[69,114348,71],{},[73,114350,114351,114353,114354,114327,114356,114358],{},[76,114352,78],{}," B — Prefer passing configuration explicitly over global ",[39,114355,31581],{},[39,114357,31581],{},"\u002Fglobal state for cases with no reasonable alternative",[73,114360,114361,355,114363,114365,114366,114368,114369,114371,114372,114374],{},[76,114362,84],{},[76,114364,930],{}," explicit parameter\u002Fstruct passing keeps dependencies visible and testable (you can construct different configs in different tests without global interference), whereas global mutable state (especially ",[39,114367,112559],{},", which requires ",[39,114370,112499],{}," and is a well-known source of data races and hard-to-trace bugs) is generally discouraged. ",[39,114373,243],{}," (C) cannot hold runtime-only values like file\u002Fenv contents at all — its initializer must be evaluable at compile time, ruling that option out entirely, not just as bad practice.",[15,114376,114377,114384,114432,114487],{"language":111909},[18,114378,114380,114381,114383],{"id":114379},"q20-a-code-reviewer-flags-this-function-for-using-mut-where-it-isnt-needed","Q20. A code reviewer flags this function for using ",[39,114382,112025],{}," where it isn't needed:",[257,114385,114386],{"language":111909},[260,114387,114389],{"className":111918,"code":114388,"language":111909,"meta":264,"style":264},"fn describe(mut name: String) -> String {\n    format!(\"Hello, {name}\")\n}\n",[39,114390,114391,114416,114428],{"__ignoreMap":264},[268,114392,114393,114395,114397,114399,114401,114403,114405,114408,114410,114412,114414],{"class":270,"line":271},[268,114394,37837],{"class":274},[268,114396,9852],{"class":278},[268,114398,622],{"class":282},[268,114400,112025],{"class":274},[268,114402,16204],{"class":282},[268,114404,10728],{"class":274},[268,114406,114407],{"class":278}," String",[268,114409,6131],{"class":282},[268,114411,113308],{"class":274},[268,114413,114407],{"class":278},[268,114415,9914],{"class":282},[268,114417,114418,114421,114423,114426],{"class":270,"line":286},[268,114419,114420],{"class":278},"    format!",[268,114422,622],{"class":282},[268,114424,114425],{"class":289},"\"Hello, {name}\"",[268,114427,20702],{"class":282},[268,114429,114430],{"class":270,"line":296},[268,114431,314],{"class":282},[23,114433,114435,114454,114466,114479],{"className":114434},[26],[28,114436,114438,114440,114441,114443,114444,114446,114447,114450,114451,114453],{"className":114437},[31],[33,114439],{"disabled":35,"type":36}," The reviewer is right to flag it — ",[39,114442,112025],{}," is unused here since ",[39,114445,14605],{}," is never reassigned or mutated in the body, and the compiler would emit an ",[39,114448,114449],{},"unused_mut"," warning; removing ",[39,114452,112025],{}," is the idiomatic fix",[28,114455,114457,114459,114460,114462,114463,114465],{"className":114456},[31],[33,114458],{"disabled":35,"type":36}," The reviewer is wrong — ",[39,114461,112025],{}," is required whenever a ",[39,114464,16721],{}," is taken by value",[28,114467,114469,114471,114472,114474,114475,114478],{"className":114468},[31],[33,114470],{"disabled":35,"type":36}," The reviewer is wrong — removing ",[39,114473,112025],{}," would cause a compile error since ",[39,114476,114477],{},"format!"," internally mutates its arguments",[28,114480,114482,355,114484,114486],{"className":114481},[31],[33,114483],{"disabled":35,"type":36},[39,114485,112025],{}," has no effect either way here and the compiler never warns about it",[66,114488,114489,114491,114499],{},[69,114490,71],{},[73,114492,114493,114495,114496,114498],{},[76,114494,78],{}," A — The reviewer is right to flag it; ",[39,114497,112025],{}," is unused, and removing it is the idiomatic fix",[73,114500,114501,355,114503,355,114505,114507,114508,114511,114512,114514,114515,1179,114517,114519,114520,114522,114523,114525],{},[76,114502,84],{},[76,114504,930],{},[39,114506,112025],{}," should only be applied when a binding is actually reassigned or mutated through a ",[39,114509,114510],{},"&mut"," borrow; here ",[39,114513,14605],{}," is only read via ",[39,114516,114477],{},[39,114518,112025],{}," is dead weight that the compiler flags with an ",[39,114521,114449],{}," warning by default (contradicting D). Leaving unnecessary ",[39,114524,112025],{}," around is a minor but real code-smell — it misleads readers into thinking the parameter is modified, and idiomatic Rust code keeps mutability annotations minimal and accurate to signal actual intent.",[2107,114527,99167],{},{"title":264,"searchDepth":286,"depth":286,"links":114529},[114530,114531,114532,114533,114535,114537,114539,114540,114541,114543,114544,114545,114547,114549,114550,114552,114554,114556,114558,114560],{"id":111912,"depth":296,"text":111913},{"id":112035,"depth":296,"text":112036},{"id":112108,"depth":296,"text":112109},{"id":112275,"depth":296,"text":114534},"Q4. Which of the following is only possible with shadowing (let), not with plain mutation (mut)?",{"id":112355,"depth":296,"text":114536},"Q5. What is the correct syntax and semantics of a const?",{"id":112463,"depth":296,"text":114538},"Q6. How does static differ from const?",{"id":112565,"depth":296,"text":112566},{"id":112697,"depth":296,"text":112698},{"id":112873,"depth":296,"text":114542},"Q9. What happens when an immutable variable holding a Vec is used like this?",{"id":113048,"depth":296,"text":113049},{"id":113266,"depth":296,"text":113267},{"id":113429,"depth":296,"text":114546},"Q12. Given this snippet, what does total end up being, and why?",{"id":113577,"depth":296,"text":114548},"Q13. What happens with this pattern-matched let binding?",{"id":113752,"depth":296,"text":113753},{"id":113938,"depth":296,"text":114551},"Q15. When choosing between mut and shadowing to transform a value while keeping semantic continuity (e.g., trimming and parsing user input), what is the idiomatic best practice?",{"id":114010,"depth":296,"text":114553},"Q16. What is the idiomatic best-practice reason to prefer const over a \"magic number\" literal scattered throughout code, such as const MAX_CONNECTIONS: u32 = 100;?",{"id":114078,"depth":296,"text":114555},"Q17. Which naming convention does idiomatic Rust use for const and static items, as enforced by default Clippy\u002Frustc style lints?",{"id":114160,"depth":296,"text":114557},"Q18. A function parameter needs to be modified locally within the function body without affecting the caller's original value (for Copy types). What is the idiomatic approach?",{"id":114303,"depth":296,"text":114559},"Q19. Best practice: a function receives configuration flags that should never change after being read at startup and are used throughout the entire program's lifetime across multiple modules. What is more idiomatic — a static or passing values explicitly through function parameters\u002Fstructs?",{"id":114379,"depth":296,"text":114561},"Q20. A code reviewer flags this function for using mut where it isn't needed:",{},"\u002Frust\u002F03-variables-and-mutability",{"title":111901,"description":264},"rust\u002F03-variables-and-mutability","mNX6jqUlMntoHcCUJXv5LhB1Lhv_BzoZ63VXdn5YoHg",{"id":114568,"title":114569,"body":114570,"description":264,"extension":2144,"meta":117008,"navigation":35,"path":117009,"seo":117010,"stem":117011,"__hash__":117012},"content\u002Frust\u002F04-data-types.md","04 — Data Types",{"type":8,"value":114571,"toc":116974},[114572,114575,114655,114724,114853,114933,115087,115167,115331,115479,115603,115767,115922,116112,116208,116388,116470,116567,116679,116778,116880,116971],[11,114573,114569],{"id":114574},"_04-data-types",[15,114576,114577,114581,114600,114634],{"language":111909},[18,114578,114580],{"id":114579},"q1-what-is-the-default-integer-type-rust-infers-when-no-suffix-or-context-specifies-otherwise","Q1. What is the default integer type Rust infers when no suffix or context specifies otherwise?",[257,114582,114583],{"language":111909},[260,114584,114586],{"className":111918,"code":114585,"language":111909,"meta":264,"style":264},"let x = 42;\n",[39,114587,114588],{"__ignoreMap":264},[268,114589,114590,114592,114594,114596,114598],{"class":270,"line":271},[268,114591,240],{"class":274},[268,114593,2382],{"class":282},[268,114595,302],{"class":274},[268,114597,779],{"class":305},[268,114599,293],{"class":282},[23,114601,114603,114611,114618,114626],{"className":114602},[26],[28,114604,114606,355,114608],{"className":114605},[31],[33,114607],{"disabled":35,"type":36},[39,114609,114610],{},"i64",[28,114612,114614,355,114616],{"className":114613},[31],[33,114615],{"disabled":35,"type":36},[39,114617,113860],{},[28,114619,114621,355,114623],{"className":114620},[31],[33,114622],{"disabled":35,"type":36},[39,114624,114625],{},"u32",[28,114627,114629,355,114631],{"className":114628},[31],[33,114630],{"disabled":35,"type":36},[39,114632,114633],{},"isize",[66,114635,114636,114638,114644],{},[69,114637,71],{},[73,114639,114640,1727,114642],{},[76,114641,78],{},[39,114643,113860],{},[73,114645,114646,114648,114649,114651,114652,114654],{},[76,114647,84],{}," When an integer literal's type can't be inferred from context (e.g. no explicit annotation, no usage that constrains it), Rust defaults to ",[39,114650,113860],{},", generally the fastest integer type on modern platforms even on 64-bit systems. ",[39,114653,114633],{}," (D) is instead the pointer-sized type used for indexing, not the default for bare literals.",[15,114656,114657,114666,114693],{},[18,114658,114660,114661,186,114663,114665],{"id":114659},"q2-what-are-isize-and-usize-primarily-used-for","Q2. What are ",[39,114662,114633],{},[39,114664,112305],{}," primarily used for?",[23,114667,114669,114675,114681,114687],{"className":114668},[26],[28,114670,114672,114674],{"className":114671},[31],[33,114673],{"disabled":35,"type":36}," They are arbitrary-precision integer types with no fixed size",[28,114676,114678,114680],{"className":114677},[31],[33,114679],{"disabled":35,"type":36}," Their size is platform-dependent (matching pointer width — e.g. 8 bytes on 64-bit systems), and they're primarily used for indexing collections and representing memory sizes\u002Foffsets",[28,114682,114684,114686],{"className":114683},[31],[33,114685],{"disabled":35,"type":36}," They are always exactly 32 bits regardless of platform, used for network protocol fields",[28,114688,114690,114692],{"className":114689},[31],[33,114691],{"disabled":35,"type":36}," They are floating-point types optimized for scientific computation",[66,114694,114695,114697,114702],{},[69,114696,71],{},[73,114698,114699,114701],{},[76,114700,78],{}," B — Their size is platform-dependent, matching pointer width, and they're primarily used for indexing collections and memory sizes",[73,114703,114704,355,114706,446,114708,114710,114711,114714,114715,114717,114718,114720,114721,114723],{},[76,114705,84],{},[39,114707,112305],{},[39,114709,114633],{}," are defined to be exactly as wide as a pointer on the target platform (4 bytes on 32-bit, 8 bytes on 64-bit), which is why ",[39,114712,114713],{},"Vec::len()"," and slice indexing return\u002Faccept ",[39,114716,112305],{}," — indices can never exceed addressable memory. ",[76,114719,182],{}," code that hardcodes assumptions like \"",[39,114722,112305],{}," is always 8 bytes\" (as option D of a fixed 32-bit width would imply) can break when cross-compiling to 32-bit or embedded targets.",[15,114725,114726,114733,114796,114831],{"language":111909},[18,114727,114729,114730,114732],{"id":114728},"q3-what-does-this-program-print-when-run-with-cargo-run-debug-profile-the-default","Q3. What does this program print when run with ",[39,114731,110543],{}," (debug profile, the default)?",[257,114734,114735],{"language":111909},[260,114736,114738],{"className":111918,"code":114737,"language":111909,"meta":264,"style":264},"fn main() {\n    let x: u8 = 255;\n    let y = x + 1;\n    println!(\"{y}\");\n}\n",[39,114739,114740,114748,114765,114781,114792],{"__ignoreMap":264},[268,114741,114742,114744,114746],{"class":270,"line":271},[268,114743,37837],{"class":274},[268,114745,111928],{"class":278},[268,114747,283],{"class":282},[268,114749,114750,114752,114754,114756,114759,114761,114763],{"class":270,"line":286},[268,114751,80826],{"class":274},[268,114753,9206],{"class":282},[268,114755,10728],{"class":274},[268,114757,114758],{"class":278}," u8",[268,114760,616],{"class":274},[268,114762,27574],{"class":305},[268,114764,293],{"class":282},[268,114766,114767,114769,114771,114773,114775,114777,114779],{"class":270,"line":296},[268,114768,80826],{"class":274},[268,114770,2509],{"class":282},[268,114772,302],{"class":274},[268,114774,2382],{"class":282},[268,114776,1246],{"class":274},[268,114778,2199],{"class":305},[268,114780,293],{"class":282},[268,114782,114783,114785,114787,114790],{"class":270,"line":311},[268,114784,111958],{"class":278},[268,114786,622],{"class":282},[268,114788,114789],{"class":289},"\"{y}\"",[268,114791,628],{"class":282},[268,114793,114794],{"class":270,"line":788},[268,114795,314],{"class":282},[23,114797,114799,114810,114819,114825],{"className":114798},[26],[28,114800,114802,355,114804,2833,114806,114809],{"className":114801},[31],[33,114803],{"disabled":35,"type":36},[39,114805,3307],{},[39,114807,114808],{},"u8"," silently wraps around on overflow",[28,114811,114813,355,114815,114818],{"className":114812},[31],[33,114814],{"disabled":35,"type":36},[39,114816,114817],{},"256",", because Rust automatically promotes to a wider type on overflow",[28,114820,114822,114824],{"className":114821},[31],[33,114823],{"disabled":35,"type":36}," It panics at runtime with an \"attempt to add with overflow\" message, because debug builds include overflow checks",[28,114826,114828,114830],{"className":114827},[31],[33,114829],{"disabled":35,"type":36}," Compile error, because the compiler statically proves this will overflow",[66,114832,114833,114835,114840],{},[69,114834,71],{},[73,114836,114837,114839],{},[76,114838,78],{}," C — It panics at runtime with an \"attempt to add with overflow\" message, because debug builds include overflow checks",[73,114841,114842,355,114844,114846,114847,114849,114850,462],{},[76,114843,84],{},[76,114845,365],{}," in debug\u002Fdev builds, arithmetic overflow triggers a runtime panic by default (a deliberate safety net during development); this is ",[104,114848,95],{}," a compile-time error (ruling out D — the compiler doesn't generally prove overflow for non-constant expressions) and there is no automatic widening (ruling out B — Rust never implicitly changes an integer's type). To get the wraparound behavior some beginners expect, you'd need an explicit method like ",[39,114851,114852],{},"x.wrapping_add(1)",[15,114854,114855,114862,114902],{},[18,114856,114858,114859,114861],{"id":114857},"q4-what-is-the-correct-way-to-describe-integer-overflow-behavior-in-release-builds-by-default","Q4. What is the correct way to describe integer overflow behavior in ",[39,114860,110148],{}," builds by default?",[23,114863,114865,114871,114883,114896],{"className":114864},[26],[28,114866,114868,114870],{"className":114867},[31],[33,114869],{"disabled":35,"type":36}," Release builds panic on overflow just like debug builds, for consistency",[28,114872,114874,114876,114877,7083,114880,114882],{"className":114873},[31],[33,114875],{"disabled":35,"type":36}," Release builds disable overflow checks by default and perform two's-complement wraparound silently (e.g., ",[39,114878,114879],{},"255u8 + 1",[39,114881,3307],{},") — a deliberate trade-off for performance",[28,114884,114886,114888,114889,20968,114891,114893,114894],{"className":114885},[31],[33,114887],{"disabled":35,"type":36}," Release builds return ",[39,114890,90944],{},[39,114892,1246],{}," automatically, requiring ",[39,114895,110107],{},[28,114897,114899,114901],{"className":114898},[31],[33,114900],{"disabled":35,"type":36}," Overflow is undefined behavior in release builds, same as in C",[66,114903,114904,114906,114911],{},[69,114905,71],{},[73,114907,114908,114910],{},[76,114909,78],{}," B — Release builds disable overflow checks by default and perform two's-complement wraparound silently — a deliberate trade-off for performance",[73,114912,114913,355,114915,21599,114917,114920,114921,2018,114923,186,114925,2018,114927,114929,114930,114932],{},[76,114914,84],{},[76,114916,438],{},[39,114918,114919],{},"overflow-checks"," profile setting defaults to ",[39,114922,2185],{},[39,114924,110181],{},[39,114926,2986],{},[39,114928,110189],{},", so the exact same overflowing code that panics in debug (Q3) silently wraps to ",[39,114931,3307],{}," in release — a classic and dangerous debug\u002Frelease behavior divergence. Unlike C's undefined behavior for signed overflow (D is false for Rust — Rust always defines wraparound as two's-complement, never UB, unlike C\u002FC++), so this is technically safe but can still produce silently wrong application results if unnoticed.",[15,114934,114935,114942,115003,115043],{"language":111909},[18,114936,114938,114939,114941],{"id":114937},"q5-what-does-casting-with-as-do-in-this-example","Q5. What does casting with ",[39,114940,106095],{}," do in this example?",[257,114943,114944],{"language":111909},[260,114945,114947],{"className":111918,"code":114946,"language":111909,"meta":264,"style":264},"fn main() {\n    let x: i32 = 300;\n    let y = x as u8;\n    println!(\"{y}\");\n}\n",[39,114948,114949,114957,114973,114989,114999],{"__ignoreMap":264},[268,114950,114951,114953,114955],{"class":270,"line":271},[268,114952,37837],{"class":274},[268,114954,111928],{"class":278},[268,114956,283],{"class":282},[268,114958,114959,114961,114963,114965,114967,114969,114971],{"class":270,"line":286},[268,114960,80826],{"class":274},[268,114962,9206],{"class":282},[268,114964,10728],{"class":274},[268,114966,113794],{"class":278},[268,114968,616],{"class":274},[268,114970,41780],{"class":305},[268,114972,293],{"class":282},[268,114974,114975,114977,114979,114981,114983,114985,114987],{"class":270,"line":296},[268,114976,80826],{"class":274},[268,114978,2509],{"class":282},[268,114980,302],{"class":274},[268,114982,2382],{"class":282},[268,114984,106095],{"class":274},[268,114986,114758],{"class":278},[268,114988,293],{"class":282},[268,114990,114991,114993,114995,114997],{"class":270,"line":311},[268,114992,111958],{"class":278},[268,114994,622],{"class":282},[268,114996,114789],{"class":289},[268,114998,628],{"class":282},[268,115000,115001],{"class":270,"line":788},[268,115002,314],{"class":282},[23,115004,115006,115016,115022,115033],{"className":115005},[26],[28,115007,115009,109262,115011,115013,115014],{"className":115008},[31],[33,115010],{"disabled":35,"type":36},[39,115012,41844],{}," does not fit in a ",[39,115015,114808],{},[28,115017,115019,115021],{"className":115018},[31],[33,115020],{"disabled":35,"type":36}," Panics at runtime with an overflow error, same as arithmetic overflow",[28,115023,115025,355,115027,3990,115030,115032],{"className":115024},[31],[33,115026],{"disabled":35,"type":36},[39,115028,115029],{},"44",[39,115031,106095],{}," performs a truncating cast that keeps only the low 8 bits of the value's two's-complement representation, silently discarding the rest, in both debug and release",[28,115034,115036,355,115038,2833,115040,115042],{"className":115035},[31],[33,115037],{"disabled":35,"type":36},[39,115039,27522],{},[39,115041,106095],{}," saturates to the target type's maximum value",[66,115044,115045,115047,115056],{},[69,115046,71],{},[73,115048,115049,1004,115051,3990,115053,115055],{},[76,115050,78],{},[39,115052,115029],{},[39,115054,106095],{}," performs a truncating cast that keeps only the low 8 bits, silently discarding the rest, in both debug and release",[73,115057,115058,115060,115061,115063,115064,115066,115067,115069,115070,115073,115074,115077,115078,115081,115082,115084,115085,462],{},[76,115059,84],{}," Unlike arithmetic operators, ",[39,115062,106095],{}," numeric casts are ",[76,115065,95],{}," checked for overflow in either debug or release — ",[39,115068,41844],{}," in binary is ",[39,115071,115072],{},"0b1_0010_1100","; truncating to 8 bits keeps ",[39,115075,115076],{},"0b0010_1100 = 44",". This silent truncation (no panic, no error, consistent across profiles) is a well-known gotcha distinct from arithmetic overflow's debug-only panic behavior (Q3\u002FQ4) — if you want saturating or checked conversion instead, use ",[39,115079,115080],{},"u8::try_from(x)"," (returns ",[39,115083,110110],{},") or the saturating conversion methods, not a bare ",[39,115086,106095],{},[15,115088,115089,115097,115135],{},[18,115090,115092,115093,115096],{"id":115091},"q6-which-statement-correctly-describes-rusts-char-type","Q6. Which statement correctly describes Rust's ",[39,115094,115095],{},"char"," type?",[23,115098,115100,115108,115119,115127],{"className":115099},[26],[28,115101,115103,812,115105,115107],{"className":115102},[31],[33,115104],{"disabled":35,"type":36},[39,115106,115095],{}," is always exactly 1 byte, like in C",[28,115109,115111,812,115113,115115,115116,115118],{"className":115110},[31],[33,115112],{"disabled":35,"type":36},[39,115114,115095],{}," represents a single Unicode scalar value and is always 4 bytes in memory, which is not the same as \"one byte\" or even always \"one visual character\" (e.g. some emoji\u002Fgrapheme clusters require multiple ",[39,115117,115095],{},"s)",[28,115120,115122,812,115124,115126],{"className":115121},[31],[33,115123],{"disabled":35,"type":36},[39,115125,115095],{}," is a UTF-8 encoded byte sequence of variable length",[28,115128,115130,812,115132,115134],{"className":115129},[31],[33,115131],{"disabled":35,"type":36},[39,115133,115095],{}," can only represent ASCII characters",[66,115136,115137,115139,115146],{},[69,115138,71],{},[73,115140,115141,853,115143,115145],{},[76,115142,78],{},[39,115144,115095],{}," represents a single Unicode scalar value and is always 4 bytes in memory",[73,115147,115148,115150,115151,115153,115154,115156,115157,2758,115159,115161,115162,115164,115165,6232],{},[76,115149,84],{}," Rust's ",[39,115152,115095],{}," is a 32-bit value representing any Unicode Scalar Value (a subset of all Unicode code points, excluding surrogate halves), not a raw byte — this is different from indexing into a ",[39,115155,16721],{},"'s UTF-8 bytes, where individual bytes are ",[39,115158,114808],{},[39,115160,115095],{},". It's also not always one \"visual glyph\" — a grapheme cluster like a flag emoji or accented character built from combining marks can require multiple ",[39,115163,115095],{},"s to represent, which trips up naive character-counting code (contradicting the assumption in A that mirrors C's 1-byte ",[39,115166,115095],{},[15,115168,115169,115173,115254,115298],{"language":111909},[18,115170,115172],{"id":115171},"q7-what-is-the-difference-between-a-tuple-and-an-array-in-rust","Q7. What is the difference between a tuple and an array in Rust?",[257,115174,115175],{"language":111909},[260,115176,115178],{"className":111918,"code":115177,"language":111909,"meta":264,"style":264},"let t: (i32, f64, bool) = (1, 2.0, true);\nlet a: [i32; 3] = [1, 2, 3];\n",[39,115179,115180,115220],{"__ignoreMap":264},[268,115181,115182,115184,115186,115188,115190,115192,115194,115197,115199,115201,115203,115205,115207,115209,115211,115214,115216,115218],{"class":270,"line":271},[268,115183,240],{"class":274},[268,115185,32545],{"class":282},[268,115187,10728],{"class":274},[268,115189,2182],{"class":282},[268,115191,113860],{"class":278},[268,115193,42],{"class":282},[268,115195,115196],{"class":278},"f64",[268,115198,42],{"class":282},[268,115200,89412],{"class":278},[268,115202,6131],{"class":282},[268,115204,302],{"class":274},[268,115206,2182],{"class":282},[268,115208,2255],{"class":305},[268,115210,42],{"class":282},[268,115212,115213],{"class":305},"2.0",[268,115215,42],{"class":282},[268,115217,2185],{"class":305},[268,115219,628],{"class":282},[268,115221,115222,115224,115226,115228,115230,115232,115234,115236,115238,115240,115242,115244,115246,115248,115250,115252],{"class":270,"line":286},[268,115223,240],{"class":274},[268,115225,7203],{"class":282},[268,115227,10728],{"class":274},[268,115229,8710],{"class":282},[268,115231,113860],{"class":278},[268,115233,2272],{"class":282},[268,115235,3423],{"class":305},[268,115237,19897],{"class":282},[268,115239,302],{"class":274},[268,115241,8710],{"class":282},[268,115243,2255],{"class":305},[268,115245,42],{"class":282},[268,115247,2258],{"class":305},[268,115249,42],{"class":282},[268,115251,3423],{"class":305},[268,115253,8737],{"class":282},[23,115255,115257,115270,115286,115292],{"className":115256},[26],[28,115258,115260,115262,115263,186,115266,115269],{"className":115259},[31],[33,115261],{"disabled":35,"type":36}," They are identical; ",[39,115264,115265],{},"(i32, f64, bool)",[39,115267,115268],{},"[i32; 3]"," are just two syntaxes for the same thing",[28,115271,115273,115275,115276,115278,115279,42,115282,115285],{"className":115272},[31],[33,115274],{"disabled":35,"type":36}," A tuple can hold elements of different types with a fixed length known at compile time; an array holds elements of a single type with a fixed length known at compile time — arrays are indexed with ",[39,115277,3290],{},", tuples with ",[39,115280,115281],{},".0",[39,115283,115284],{},".1",", etc.",[28,115287,115289,115291],{"className":115288},[31],[33,115290],{"disabled":35,"type":36}," Arrays can hold mixed types, but tuples cannot",[28,115293,115295,115297],{"className":115294},[31],[33,115296],{"disabled":35,"type":36}," Tuples are heap-allocated and growable, while arrays are always stack-allocated and fixed-size",[66,115299,115300,115302,115315],{},[69,115301,71],{},[73,115303,115304,115306,115307,115309,115310,446,115312,115314],{},[76,115305,78],{}," B — A tuple can hold elements of different types with a fixed compile-time length; an array holds a single element type with a fixed compile-time length; arrays use ",[39,115308,3290],{}," indexing, tuples use ",[39,115311,115281],{},[39,115313,115284],{},"\u002Fetc.",[73,115316,115317,115319,115320,115323,115324,115327,115328,115330],{},[76,115318,84],{}," Both are fixed-size, stack-allocatable (unless boxed) compound types, but they differ in type homogeneity and access syntax — ",[39,115321,115322],{},"t.0"," accesses a tuple field, while ",[39,115325,115326],{},"a[0]"," accesses an array element. Option D is backwards regarding growability: neither is growable — that's what ",[39,115329,112877],{}," is for — and both are typically stack-allocated by default, not heap-allocated.",[15,115332,115333,115337,115390,115440],{"language":111909},[18,115334,115336],{"id":115335},"q8-what-happens-when-this-floating-point-comparison-runs","Q8. What happens when this floating-point comparison runs?",[257,115338,115339],{"language":111909},[260,115340,115342],{"className":111918,"code":115341,"language":111909,"meta":264,"style":264},"fn main() {\n    let x = 0.1 + 0.2;\n    println!(\"{}\", x == 0.3);\n}\n",[39,115343,115344,115352,115369,115386],{"__ignoreMap":264},[268,115345,115346,115348,115350],{"class":270,"line":271},[268,115347,37837],{"class":274},[268,115349,111928],{"class":278},[268,115351,283],{"class":282},[268,115353,115354,115356,115358,115360,115363,115365,115367],{"class":270,"line":286},[268,115355,80826],{"class":274},[268,115357,2382],{"class":282},[268,115359,302],{"class":274},[268,115361,115362],{"class":305}," 0.1",[268,115364,3350],{"class":274},[268,115366,3837],{"class":305},[268,115368,293],{"class":282},[268,115370,115371,115373,115375,115377,115380,115382,115384],{"class":270,"line":296},[268,115372,111958],{"class":278},[268,115374,622],{"class":282},[268,115376,113830],{"class":289},[268,115378,115379],{"class":282},", x ",[268,115381,3197],{"class":274},[268,115383,3842],{"class":305},[268,115385,628],{"class":282},[268,115387,115388],{"class":270,"line":311},[268,115389,314],{"class":282},[23,115391,115393,115405,115426,115434],{"className":115392},[26],[28,115394,115396,355,115398,4387,115400,115402,115403],{"className":115395},[31],[33,115397],{"disabled":35,"type":36},[39,115399,2185],{},[39,115401,3881],{}," is mathematically ",[39,115404,8537],{},[28,115406,115408,355,115410,115412,115413,42,115415,383,115417,115419,115420,11464,115422,93366,115424],{"className":115407},[31],[33,115409],{"disabled":35,"type":36},[39,115411,2986],{}," — IEEE 754 binary floating-point cannot represent ",[39,115414,3832],{},[39,115416,3933],{},[39,115418,8537],{}," exactly, so ",[39,115421,3881],{},[39,115423,3885],{},[39,115425,8537],{},[28,115427,115429,115431,115432],{"className":115428},[31],[33,115430],{"disabled":35,"type":36}," Compile error: floating-point values cannot be compared with ",[39,115433,3197],{},[28,115435,115437,115439],{"className":115436},[31],[33,115438],{"disabled":35,"type":36}," It depends on whether the build is debug or release",[66,115441,115442,115444,115460],{},[69,115443,71],{},[73,115445,115446,1727,115448,115412,115450,42,115452,383,115454,115419,115456,11464,115458],{},[76,115447,78],{},[39,115449,2986],{},[39,115451,3832],{},[39,115453,3933],{},[39,115455,8537],{},[39,115457,3881],{},[39,115459,3885],{},[73,115461,115462,115464,115465,115467,115468,115470,115471,115474,115475,115478],{},[76,115463,84],{}," This is Rust's version of the classic cross-language floating-point \"wat\": ",[39,115466,115196],{}," uses base-2 (binary) fractional representation, and decimal fractions like 0.1 are repeating binary fractions that get rounded to the nearest representable ",[39,115469,115196],{},", so accumulated rounding error makes ",[39,115472,115473],{},"0.1 + 0.2 != 0.3"," bit-for-bit. Unlike overflow (Q3\u002FQ4), this behavior is identical in debug and release (ruling out D) — the fix in production code is comparing with an epsilon tolerance (e.g. ",[39,115476,115477],{},"(x - 0.3).abs() \u003C f64::EPSILON",") or using a decimal\u002Ffixed-point type when exactness matters.",[15,115480,115481,115485,115551,115580],{"language":111909},[18,115482,115484],{"id":115483},"q9-what-is-the-result-of-indexing-an-array-out-of-bounds-with-a-compile-time-constant-index-as-shown-here","Q9. What is the result of indexing an array out of bounds with a compile-time-constant index, as shown here?",[257,115486,115487],{"language":111909},[260,115488,115490],{"className":111918,"code":115489,"language":111909,"meta":264,"style":264},"fn main() {\n    let a = [1, 2, 3];\n    let x = a[5];\n    println!(\"{x}\");\n}\n",[39,115491,115492,115500,115522,115537,115547],{"__ignoreMap":264},[268,115493,115494,115496,115498],{"class":270,"line":271},[268,115495,37837],{"class":274},[268,115497,111928],{"class":278},[268,115499,283],{"class":282},[268,115501,115502,115504,115506,115508,115510,115512,115514,115516,115518,115520],{"class":270,"line":286},[268,115503,80826],{"class":274},[268,115505,1243],{"class":282},[268,115507,302],{"class":274},[268,115509,8710],{"class":282},[268,115511,2255],{"class":305},[268,115513,42],{"class":282},[268,115515,2258],{"class":305},[268,115517,42],{"class":282},[268,115519,3423],{"class":305},[268,115521,8737],{"class":282},[268,115523,115524,115526,115528,115530,115533,115535],{"class":270,"line":296},[268,115525,80826],{"class":274},[268,115527,2382],{"class":282},[268,115529,302],{"class":274},[268,115531,115532],{"class":282}," a[",[268,115534,2429],{"class":305},[268,115536,8737],{"class":282},[268,115538,115539,115541,115543,115545],{"class":270,"line":311},[268,115540,111958],{"class":278},[268,115542,622],{"class":282},[268,115544,111963],{"class":289},[268,115546,628],{"class":282},[268,115548,115549],{"class":270,"line":788},[268,115550,314],{"class":282},[23,115552,115554,115560,115566,115574],{"className":115553},[26],[28,115555,115557,115559],{"className":115556},[31],[33,115558],{"disabled":35,"type":36}," It compiles and panics at runtime with an index-out-of-bounds message",[28,115561,115563,115565],{"className":115562},[31],[33,115564],{"disabled":35,"type":36}," Compile error — since both the array's length and the index are known constants at compile time, the compiler statically rejects this rather than deferring to a runtime panic",[28,115567,115569,115571,115572],{"className":115568},[31],[33,115570],{"disabled":35,"type":36}," It compiles and returns a default value of ",[39,115573,3307],{},[28,115575,115577,115579],{"className":115576},[31],[33,115578],{"disabled":35,"type":36}," It compiles and returns garbage\u002Fundefined memory contents, as in C",[66,115581,115582,115584,115589],{},[69,115583,71],{},[73,115585,115586,115588],{},[76,115587,78],{}," B — Compile error, because both the array's length and the index are known constants, letting the compiler statically reject it",[73,115590,115591,355,115593,115595,115596,115598,115599,115602],{},[76,115592,84],{},[76,115594,582],{}," when the index and array size are both compile-time constants, ",[39,115597,108612],{}," performs constant evaluation and rejects out-of-bounds access with a hard compile error (",[39,115600,115601],{},"this operation will panic at runtime"," \u002F index out of bounds lint promoted to a hard error) rather than waiting for a runtime panic. This is a genuine edge case beginners often get backwards — they expect all indexing errors to be runtime-only (as in the more general case of Q10, where the index is not a compile-time constant), but constant-folded indices are checked earlier. Undefined behavior (D) never occurs in safe Rust indexing, unlike C's raw array access.",[15,115604,115605,115609,115701,115736],{"language":111909},[18,115606,115608],{"id":115607},"q10-what-happens-with-a-runtime-computed-non-constant-out-of-bounds-index","Q10. What happens with a runtime-computed (non-constant) out-of-bounds index?",[257,115610,115611],{"language":111909},[260,115612,115614],{"className":111918,"code":115613,"language":111909,"meta":264,"style":264},"fn main() {\n    let a = [1, 2, 3];\n    let i = get_index();\n    println!(\"{}\", a[i]);\n}\n\nfn get_index() -> usize {\n    5\n}\n",[39,115615,115616,115624,115646,115659,115670,115674,115678,115692,115697],{"__ignoreMap":264},[268,115617,115618,115620,115622],{"class":270,"line":271},[268,115619,37837],{"class":274},[268,115621,111928],{"class":278},[268,115623,283],{"class":282},[268,115625,115626,115628,115630,115632,115634,115636,115638,115640,115642,115644],{"class":270,"line":286},[268,115627,80826],{"class":274},[268,115629,1243],{"class":282},[268,115631,302],{"class":274},[268,115633,8710],{"class":282},[268,115635,2255],{"class":305},[268,115637,42],{"class":282},[268,115639,2258],{"class":305},[268,115641,42],{"class":282},[268,115643,3423],{"class":305},[268,115645,8737],{"class":282},[268,115647,115648,115650,115652,115654,115657],{"class":270,"line":296},[268,115649,80826],{"class":274},[268,115651,9384],{"class":282},[268,115653,302],{"class":274},[268,115655,115656],{"class":278}," get_index",[268,115658,794],{"class":282},[268,115660,115661,115663,115665,115667],{"class":270,"line":311},[268,115662,111958],{"class":278},[268,115664,622],{"class":282},[268,115666,113830],{"class":289},[268,115668,115669],{"class":282},", a[i]);\n",[268,115671,115672],{"class":270,"line":788},[268,115673,314],{"class":282},[268,115675,115676],{"class":270,"line":1951},[268,115677,5033],{"emptyLinePlaceholder":35},[268,115679,115680,115682,115684,115686,115688,115690],{"class":270,"line":8955},[268,115681,37837],{"class":274},[268,115683,115656],{"class":278},[268,115685,16182],{"class":282},[268,115687,113308],{"class":274},[268,115689,113286],{"class":278},[268,115691,9914],{"class":282},[268,115693,115694],{"class":270,"line":8966},[268,115695,115696],{"class":305},"    5\n",[268,115698,115699],{"class":270,"line":8974},[268,115700,314],{"class":282},[23,115702,115704,115710,115716,115724],{"className":115703},[26],[28,115705,115707,115709],{"className":115706},[31],[33,115708],{"disabled":35,"type":36}," Compile error, identical to the constant-index case",[28,115711,115713,115715],{"className":115712},[31],[33,115714],{"disabled":35,"type":36}," It compiles successfully and panics at runtime with an \"index out of bounds\" message when executed",[28,115717,115719,115721,115722],{"className":115718},[31],[33,115720],{"disabled":35,"type":36}," It compiles and silently returns ",[39,115723,3307],{},[28,115725,115727,115729,115730,29324,115733],{"className":115726},[31],[33,115728],{"disabled":35,"type":36}," It compiles and wraps around to ",[39,115731,115732],{},"a[5 % 3]",[39,115734,115735],{},"a[2]",[66,115737,115738,115740,115745],{},[69,115739,71],{},[73,115741,115742,115744],{},[76,115743,78],{}," B — It compiles successfully and panics at runtime with an \"index out of bounds\" message when executed",[73,115746,115747,355,115749,183,115751,115753,115754,115757,115758,93077,115761,2182,115764,115766],{},[76,115748,84],{},[76,115750,582],{},[39,115752,9509],{},"'s value isn't known until runtime, the compiler cannot statically reject it as it did in Q9 — instead, array\u002Fslice indexing always performs a bounds check at runtime, panicking (",[39,115755,115756],{},"index out of bounds: the len is 3 but the index is 5",") rather than silently wrapping (D, a C-like buffer-overrun assumption) or returning a default (C). The safe alternative to avoid the panic is ",[39,115759,115760],{},"a.get(i)",[39,115762,115763],{},"Option\u003C&i32>",[39,115765,90944],{}," here) instead of panicking.",[15,115768,115769,115773,115836,115878],{"language":111909},[18,115770,115772],{"id":115771},"q11-what-is-the-result-of-this-signedunsigned-cast","Q11. What is the result of this signed\u002Funsigned cast?",[257,115774,115775],{"language":111909},[260,115776,115778],{"className":111918,"code":115777,"language":111909,"meta":264,"style":264},"fn main() {\n    let x: i32 = -1;\n    let y = x as u32;\n    println!(\"{y}\");\n}\n",[39,115779,115780,115788,115806,115822,115832],{"__ignoreMap":264},[268,115781,115782,115784,115786],{"class":270,"line":271},[268,115783,37837],{"class":274},[268,115785,111928],{"class":278},[268,115787,283],{"class":282},[268,115789,115790,115792,115794,115796,115798,115800,115802,115804],{"class":270,"line":286},[268,115791,80826],{"class":274},[268,115793,9206],{"class":282},[268,115795,10728],{"class":274},[268,115797,113794],{"class":278},[268,115799,616],{"class":274},[268,115801,6286],{"class":274},[268,115803,2255],{"class":305},[268,115805,293],{"class":282},[268,115807,115808,115810,115812,115814,115816,115818,115820],{"class":270,"line":296},[268,115809,80826],{"class":274},[268,115811,2509],{"class":282},[268,115813,302],{"class":274},[268,115815,2382],{"class":282},[268,115817,106095],{"class":274},[268,115819,112377],{"class":278},[268,115821,293],{"class":282},[268,115823,115824,115826,115828,115830],{"class":270,"line":311},[268,115825,111958],{"class":278},[268,115827,622],{"class":282},[268,115829,114789],{"class":289},[268,115831,628],{"class":282},[268,115833,115834],{"class":270,"line":788},[268,115835,314],{"class":282},[23,115837,115839,115845,115851,115870],{"className":115838},[26],[28,115840,115842,115844],{"className":115841},[31],[33,115843],{"disabled":35,"type":36}," Compile error: cannot cast a negative value to an unsigned type",[28,115846,115848,115850],{"className":115847},[31],[33,115849],{"disabled":35,"type":36}," Panics at runtime: negative value cannot be represented as unsigned",[28,115852,115854,355,115856,115859,115860,115862,115863,115866,115867],{"className":115853},[31],[33,115855],{"disabled":35,"type":36},[39,115857,115858],{},"4294967295"," — the cast reinterprets ",[39,115861,24416],{},"'s two's-complement bit pattern (",[39,115864,115865],{},"0xFFFFFFFF",") as an unsigned value, i.e. ",[39,115868,115869],{},"u32::MAX",[28,115871,115873,355,115875,115877],{"className":115872},[31],[33,115874],{"disabled":35,"type":36},[39,115876,3307],{},", because negative values saturate to the unsigned minimum",[66,115879,115880,115882,115893],{},[69,115881,71],{},[73,115883,115884,1004,115886,115859,115888,115890,115891],{},[76,115885,78],{},[39,115887,115858],{},[39,115889,24416],{},"'s two's-complement bit pattern as an unsigned value, i.e. ",[39,115892,115869],{},[73,115894,115895,115897,115898,115900,115901,115904,115905,115907,115908,115910,115911,115913,115914,115917,115918,115921],{},[76,115896,84],{}," As with the truncating cast in Q5, ",[39,115899,106095],{}," between integer types of the same width just reinterprets the bit pattern rather than doing \"safe\" numeric conversion — ",[39,115902,115903],{},"-1i32","'s bits are all ones, which as ",[39,115906,114625],{}," is the maximum value ",[39,115909,115858],{},". This silent, non-panicking reinterpretation (no compile error, no runtime panic, consistent in debug and release) is a frequent source of subtle bugs when developers assume ",[39,115912,106095],{}," behaves like a checked conversion; use ",[39,115915,115916],{},"u32::try_from(x)"," if you want a ",[39,115919,115920],{},"Result::Err"," on negative input instead.",[15,115923,115924,115930,116019,116067],{"language":111909},[18,115925,115927,115928,1685],{"id":115926},"q12-what-does-this-code-do-with-an-empty-tuple","Q12. What does this code do with an empty tuple ",[39,115929,16952],{},[257,115931,115932],{"language":111909},[260,115933,115935],{"className":111918,"code":115934,"language":111909,"meta":264,"style":264},"fn log_event(msg: &str) -> () {\n    println!(\"{msg}\");\n}\n\nfn main() {\n    let result = log_event(\"started\");\n    println!(\"{result:?}\");\n}\n",[39,115936,115937,115960,115971,115975,115979,115987,116004,116015],{"__ignoreMap":264},[268,115938,115939,115941,115944,115947,115949,115952,115954,115956,115958],{"class":270,"line":271},[268,115940,37837],{"class":274},[268,115942,115943],{"class":278}," log_event",[268,115945,115946],{"class":282},"(msg",[268,115948,10728],{"class":274},[268,115950,115951],{"class":274}," &",[268,115953,17109],{"class":278},[268,115955,6131],{"class":282},[268,115957,113308],{"class":274},[268,115959,12922],{"class":282},[268,115961,115962,115964,115966,115969],{"class":270,"line":286},[268,115963,111958],{"class":278},[268,115965,622],{"class":282},[268,115967,115968],{"class":289},"\"{msg}\"",[268,115970,628],{"class":282},[268,115972,115973],{"class":270,"line":296},[268,115974,314],{"class":282},[268,115976,115977],{"class":270,"line":311},[268,115978,5033],{"emptyLinePlaceholder":35},[268,115980,115981,115983,115985],{"class":270,"line":788},[268,115982,37837],{"class":274},[268,115984,111928],{"class":278},[268,115986,283],{"class":282},[268,115988,115989,115991,115993,115995,115997,115999,116002],{"class":270,"line":1951},[268,115990,80826],{"class":274},[268,115992,10881],{"class":282},[268,115994,302],{"class":274},[268,115996,115943],{"class":278},[268,115998,622],{"class":282},[268,116000,116001],{"class":289},"\"started\"",[268,116003,628],{"class":282},[268,116005,116006,116008,116010,116013],{"class":270,"line":8955},[268,116007,111958],{"class":278},[268,116009,622],{"class":282},[268,116011,116012],{"class":289},"\"{result:?}\"",[268,116014,628],{"class":282},[268,116016,116017],{"class":270,"line":8966},[268,116018,314],{"class":282},[23,116020,116022,116030,116046,116058],{"className":116021},[26],[28,116023,116025,109262,116027,116029],{"className":116024},[31],[33,116026],{"disabled":35,"type":36},[39,116028,16952],{}," is not a valid return type",[28,116031,116033,111978,116035,116038,116039,4387,116041,116043,116044],{"className":116032},[31],[33,116034],{"disabled":35,"type":36},[39,116036,116037],{},"started"," followed by ",[39,116040,16952],{},[39,116042,16952],{}," (the \"unit type\") is the zero-sized type conventionally used to mean \"no meaningful value,\" and it implements ",[39,116045,16523],{},[28,116047,116049,116051,116052,116054,116055,116057],{"className":116048},[31],[33,116050],{"disabled":35,"type":36}," It compiles but ",[39,116053,5631],{}," cannot be printed because ",[39,116056,16952],{}," has no fields",[28,116059,116061,355,116063,116066],{"className":116060},[31],[33,116062],{"disabled":35,"type":36},[39,116064,116065],{},"-> ()"," is redundant syntax error; functions with no return type must omit the arrow entirely",[66,116068,116069,116071,116085],{},[69,116070,71],{},[73,116072,116073,116075,116076,116038,116078,2272,116080,116082,116083],{},[76,116074,78],{}," B — It compiles and prints ",[39,116077,116037],{},[39,116079,16952],{},[39,116081,16952],{}," is the unit type conventionally used for \"no meaningful value,\" and it implements ",[39,116084,16523],{},[73,116086,116087,355,116089,116091,116092,116095,116096,116098,116099,116101,116102,10548,116104,116107,116108,116111],{},[76,116088,84],{},[39,116090,16952],{},", the unit type, is what a function implicitly returns when no ",[39,116093,116094],{},"-> Type"," is written at all (",[39,116097,116065],{}," here is just the explicit, equivalent spelling — idiomatically omitted, but not an error, contradicting D). It's a real, zero-sized value that implements ",[39,116100,16523],{}," (printing as literally ",[39,116103,16952],{},[39,116105,116106],{},"println!(\"{result:?}\")"," works fine — it's not the absence of a value like ",[39,116109,116110],{},"void"," conceptually implies in some other languages, but an actual (if trivial) value that can be bound, passed around, and matched on.",[15,116113,116114,116121,116164],{},[18,116115,116117,116118,116120],{"id":116116},"q13-what-is-the-maximum-safely-representable-integer-using-f64-such-that-all-integers-up-to-that-value-can-be-represented-exactly","Q13. What is the maximum safely representable integer using ",[39,116119,115196],{}," such that all integers up to that value can be represented exactly?",[23,116122,116124,116136,116147,116158],{"className":116123},[26],[28,116125,116127,355,116129,116132,116133,116135],{"className":116126},[31],[33,116128],{"disabled":35,"type":36},[39,116130,116131],{},"2^53"," (about 9 quadrillion), because ",[39,116134,115196],{}," has a 52-bit mantissa (53 bits with the implicit leading bit), beyond which not every integer has an exact representation",[28,116137,116139,355,116141,116143,116144,116146],{"className":116138},[31],[33,116140],{"disabled":35,"type":36},[39,116142,115196],{}," can represent all ",[39,116145,114610],{}," integers exactly with no limit, since it's a 64-bit type",[28,116148,116150,355,116152,116155,116156],{"className":116149},[31],[33,116151],{"disabled":35,"type":36},[39,116153,116154],{},"2^32",", matching ",[39,116157,115869],{},[28,116159,116161,116163],{"className":116160},[31],[33,116162],{"disabled":35,"type":36}," There is no such limit; floating point can represent any integer exactly",[66,116165,116166,116168,116177],{},[69,116167,71],{},[73,116169,116170,3459,116172,2833,116174,116176],{},[76,116171,78],{},[39,116173,116131],{},[39,116175,115196],{},"'s 52-bit mantissa (plus implicit leading bit) limits exact integer representation beyond that point",[73,116178,116179,116181,116182,116184,116185,116187,116188,116190,116191,116193,116194,9057,116196,116198,116199,116202,116203,446,116205,462],{},[76,116180,84],{}," An IEEE 754 ",[39,116183,115196],{}," has 1 sign bit, 11 exponent bits, and 52 explicit mantissa bits (53 bits of precision including the implicit leading ",[39,116186,2255],{},"), so integers beyond ",[39,116189,116131],{}," start silently losing precision when represented as ",[39,116192,115196],{}," — a tempting-but-wrong assumption (B) is that all 64-bit values fit, since ",[39,116195,115196],{},[104,116197,805],{}," bit width is 64 but its ",[104,116200,116201],{},"mantissa"," width is what actually limits integer precision, unlike a genuinely 64-bit-precision integer type like ",[39,116204,114610],{},[39,116206,116207],{},"u64",[15,116209,116210,116214,116272,116324],{"language":111909},[18,116211,116213],{"id":116212},"q14-what-happens-when-parsing-an-out-of-range-value-into-a-fixed-width-integer-type","Q14. What happens when parsing an out-of-range value into a fixed-width integer type?",[257,116215,116216],{"language":111909},[260,116217,116219],{"className":111918,"code":116218,"language":111909,"meta":264,"style":264},"fn main() {\n    let result: Result\u003Cu8, _> = \"300\".parse();\n    println!(\"{result:?}\");\n}\n",[39,116220,116221,116229,116258,116268],{"__ignoreMap":264},[268,116222,116223,116225,116227],{"class":270,"line":271},[268,116224,37837],{"class":274},[268,116226,111928],{"class":278},[268,116228,283],{"class":282},[268,116230,116231,116233,116235,116237,116240,116242,116244,116247,116249,116252,116254,116256],{"class":270,"line":286},[268,116232,80826],{"class":274},[268,116234,5583],{"class":282},[268,116236,10728],{"class":274},[268,116238,116239],{"class":278}," Result",[268,116241,1076],{"class":282},[268,116243,114808],{"class":278},[268,116245,116246],{"class":282},", _> ",[268,116248,302],{"class":274},[268,116250,116251],{"class":289}," \"300\"",[268,116253,462],{"class":274},[268,116255,22274],{"class":278},[268,116257,794],{"class":282},[268,116259,116260,116262,116264,116266],{"class":270,"line":296},[268,116261,111958],{"class":278},[268,116263,622],{"class":282},[268,116265,116012],{"class":289},[268,116267,628],{"class":282},[268,116269,116270],{"class":270,"line":311},[268,116271,314],{"class":282},[23,116273,116275,116287,116306,116314],{"className":116274},[26],[28,116276,116278,355,116280,116283,116284,116286],{"className":116277},[31],[33,116279],{"disabled":35,"type":36},[39,116281,116282],{},"Ok(44)",", applying the same truncation behavior as an ",[39,116285,106095],{}," cast",[28,116288,116290,355,116292,2833,116295,116298,116299,116302,116303,116305],{"className":116289},[31],[33,116291],{"disabled":35,"type":36},[39,116293,116294],{},"Err(ParseIntError { .. })",[39,116296,116297],{},".parse()"," performs a checked conversion and returns an ",[39,116300,116301],{},"Err"," when the value doesn't fit the target type, unlike ",[39,116304,106095],{}," which silently truncates",[28,116307,116309,116311,116312],{"className":116308},[31],[33,116310],{"disabled":35,"type":36}," It panics at runtime instead of returning a ",[39,116313,110110],{},[28,116315,116317,116319,116320,116323],{"className":116316},[31],[33,116318],{"disabled":35,"type":36}," Compile error, because ",[39,116321,116322],{},"\"300\""," is a string literal too large for the target type",[66,116325,116326,116328,116341],{},[69,116327,71],{},[73,116329,116330,1727,116332,2833,116334,116298,116336,116338,116339],{},[76,116331,78],{},[39,116333,116294],{},[39,116335,116297],{},[39,116337,116301],{}," when the value doesn't fit, unlike ",[39,116340,106095],{},[73,116342,116343,355,116345,116348,116349,116351,116352,116355,116356,116358,116359,116362,116363,116366,116367,116369,116370,116372,116373,116375,116376,42,116379,383,116381,446,116384,116387],{},[76,116344,84],{},[39,116346,116347],{},"str::parse::\u003Cu8>()"," explicitly checks that the parsed numeric value fits within ",[39,116350,114808],{},"'s range (",[39,116353,116354],{},"0..=255",") and returns ",[39,116357,116301],{}," (specifically a ",[39,116360,116361],{},"ParseIntError"," with kind ",[39,116364,116365],{},"PosOverflow",") rather than truncating — this is a deliberate contrast with ",[39,116368,106095],{},"'s silent truncation (Q5), and a good example of why ",[39,116371,116297],{}," is the safer choice for untrusted\u002Fexternal input. The correct way to handle this ",[39,116374,116301],{}," case is via ",[39,116377,116378],{},"match",[39,116380,1685],{},[39,116382,116383],{},".unwrap_or_default()",[39,116385,116386],{},".unwrap_or(default)"," depending on whether the caller can recover, rather than assuming parsing always succeeds.",[15,116389,116390,116402,116444],{},[18,116391,116393,116394,99,116397,116399,116400,1685],{"id":116392},"q15-when-should-you-prefer-an-explicit-width-integer-type-like-u16-or-i64-over-the-default-i32","Q15. When should you prefer an explicit-width integer type like ",[39,116395,116396],{},"u16",[39,116398,114610],{}," over the default ",[39,116401,113860],{},[23,116403,116405,116414,116432,116438],{"className":116404},[26],[28,116406,116408,116410,116411,116413],{"className":116407},[31],[33,116409],{"disabled":35,"type":36}," Never — always use ",[39,116412,113860],{}," everywhere for consistency regardless of the value's actual domain",[28,116415,116417,116419,116420,116422,116423,446,116425,116427,116428,116431],{"className":116416},[31],[33,116418],{"disabled":35,"type":36}," When the value's valid domain and required range are known and meaningful (e.g. a ",[39,116421,116396],{}," port number capped at 65535, or an ",[39,116424,114610],{},[39,116426,116207],{}," for a value that can exceed ",[39,116429,116430],{},"i32::MAX"," like a file size in bytes or a timestamp) — this documents intent and avoids both wasted space and overflow risk",[28,116433,116435,116437],{"className":116434},[31],[33,116436],{"disabled":35,"type":36}," Only when targeting embedded\u002Fno_std platforms; on desktop\u002Fserver code, width never matters",[28,116439,116441,116443],{"className":116440},[31],[33,116442],{"disabled":35,"type":36}," Always prefer the smallest type that compiles without error, regardless of whether the value could plausibly grow",[66,116445,116446,116448,116453],{},[69,116447,71],{},[73,116449,116450,116452],{},[76,116451,78],{}," B — When the value's valid domain and required range are known and meaningful, choosing an explicit width documents intent and avoids wasted space or overflow risk",[73,116454,116455,355,116457,11680,116459,116461,116462,446,116464,116466,116467,116469],{},[76,116456,84],{},[76,116458,930],{},[39,116460,116396],{}," for a network port or ",[39,116463,114610],{},[39,116465,116207],{}," for byte counts\u002Ftimestamps is self-documenting and prevents a class of bugs where a value that can legitimately exceed ",[39,116468,116430],{}," (about 2.1 billion — easily exceeded by file sizes or millisecond timestamps) silently overflows in release builds (recall Q4). Blindly picking the smallest type that merely compiles today (D) is a trap — it says nothing about whether the value could grow beyond that type's range in production, which is exactly the kind of \"compiles now, panics\u002Fwraps later\" bug this rule of thumb prevents.",[15,116471,116472,116482,116528],{},[18,116473,116475,116476,116478,116479,116481],{"id":116474},"q16-what-is-the-idiomatic-way-to-convert-between-numeric-types-when-the-values-validity-at-the-target-type-must-be-guaranteed-rather-than-assumed-eg-converting-a-user-supplied-i64-amount-into-a-u32-quantity-field","Q16. What is the idiomatic way to convert between numeric types when the value's validity at the target type must be guaranteed rather than assumed, e.g. converting a user-supplied ",[39,116477,114610],{}," amount into a ",[39,116480,114625],{}," quantity field?",[23,116483,116485,116493,116513,116522],{"className":116484},[26],[28,116486,116488,4207,116490,116492],{"className":116487},[31],[33,116489],{"disabled":35,"type":36},[39,116491,106095],{},", since it's the shortest syntax and Rust guarantees it never loses data",[28,116494,116496,4353,116498,116501,116502,116504,116505,42,116507,116509,116510,116512],{"className":116495},[31],[33,116497],{"disabled":35,"type":36},[39,116499,116500],{},"u32::try_from(value)",", which returns a ",[39,116503,110110],{}," that must be handled (via ",[39,116506,1685],{},[39,116508,116378],{},", or explicit ",[39,116511,113886],{}," with a justified message), making conversion failure an explicit, visible part of the control flow",[28,116514,116516,4353,116518,116521],{"className":116515},[31],[33,116517],{"disabled":35,"type":36},[39,116519,116520],{},"unsafe { std::mem::transmute(value) }"," to reinterpret the bits directly",[28,116523,116525,116527],{"className":116524},[31],[33,116526],{"disabled":35,"type":36}," Multiply and divide by powers of two manually to simulate the conversion",[66,116529,116530,116532,116541],{},[69,116531,71],{},[73,116533,116534,4409,116536,116501,116538,116540],{},[76,116535,78],{},[39,116537,116500],{},[39,116539,110110],{}," that must be handled, making conversion failure explicit",[73,116542,116543,355,116545,355,116547,446,116550,116553,116554,116556,116557,116559,116560,116562,116563,116566],{},[76,116544,84],{},[76,116546,582],{},[39,116548,116549],{},"TryFrom",[39,116551,116552],{},"TryInto"," conversions surface out-of-range or negative values as an ",[39,116555,116301],{}," at the call site instead of silently truncating\u002Freinterpreting bits the way ",[39,116558,106095],{}," does (Q5, Q11) — critical for values crossing a trust boundary (user input, network data, file parsing). ",[39,116561,106095],{}," (A) is the tempting-but-dangerous default precisely because it \"just works\" syntactically while silently corrupting out-of-range values with no warning; ",[39,116564,116565],{},"transmute"," (C) is unrelated and unsafe low-level bit reinterpretation, wildly inappropriate for a simple numeric conversion.",[15,116568,116569,116573,116614,116652],{"language":111909},[18,116570,116572],{"id":116571},"q17-what-is-the-idiomatic-and-safe-way-to-compare-two-floating-point-values-for-near-equality-avoiding-the-pitfall-in-q8","Q17. What is the idiomatic and safe way to compare two floating-point values for near-equality, avoiding the pitfall in Q8?",[257,116574,116575],{"language":111909},[260,116576,116578],{"className":111918,"code":116577,"language":111909,"meta":264,"style":264},"let a = 0.1_f64 + 0.2;\nlet b = 0.3_f64;\n",[39,116579,116580,116599],{"__ignoreMap":264},[268,116581,116582,116584,116586,116588,116591,116593,116595,116597],{"class":270,"line":271},[268,116583,240],{"class":274},[268,116585,1243],{"class":282},[268,116587,302],{"class":274},[268,116589,116590],{"class":305}," 0.1_",[268,116592,115196],{"class":278},[268,116594,3350],{"class":274},[268,116596,3837],{"class":305},[268,116598,293],{"class":282},[268,116600,116601,116603,116605,116607,116610,116612],{"class":270,"line":286},[268,116602,240],{"class":274},[268,116604,2209],{"class":282},[268,116606,302],{"class":274},[268,116608,116609],{"class":305}," 0.3_",[268,116611,115196],{"class":278},[268,116613,293],{"class":282},[23,116615,116617,116625,116634,116643],{"className":116616},[26],[28,116618,116620,355,116622,116624],{"className":116619},[31],[33,116621],{"disabled":35,"type":36},[39,116623,89282],{},", trusting exact equality since both are the same type",[28,116626,116628,355,116630,116633],{"className":116627},[31],[33,116629],{"disabled":35,"type":36},[39,116631,116632],{},"(a - b).abs() \u003C f64::EPSILON"," or a domain-appropriate tolerance, since binary floating-point arithmetic accumulates rounding error and exact equality is unreliable for computed values",[28,116635,116637,116639,116640,116642],{"className":116636},[31],[33,116638],{"disabled":35,"type":36}," Convert both to ",[39,116641,16721],{}," and compare the strings",[28,116644,116646,355,116648,116651],{"className":116645},[31],[33,116647],{"disabled":35,"type":36},[39,116649,116650],{},"a.round() == b.round()",", since rounding always eliminates floating-point error",[66,116653,116654,116656,116663],{},[69,116655,71],{},[73,116657,116658,1727,116660,116662],{},[76,116659,78],{},[39,116661,116632],{}," or a domain-appropriate tolerance, since binary floating-point arithmetic accumulates rounding error",[73,116664,116665,355,116667,183,116669,116671,116672,116674,116675,116678],{},[76,116666,84],{},[76,116668,930],{},[39,116670,115196],{}," cannot exactly represent most decimal fractions (Q8), idiomatic Rust (like most languages using IEEE 754) compares floats with an epsilon-based tolerance rather than ",[39,116673,3197],{},", especially after any arithmetic has occurred. Rounding first (D) is a fragile workaround that only coincidentally works for values far from a rounding boundary and breaks down near ",[39,116676,116677],{},"x.5"," boundaries or when more precision is actually needed; string comparison (C) is needlessly indirect and has its own formatting-precision pitfalls.",[15,116680,116681,116695,116741],{},[18,116682,116684,116685,116687,116688,116691,116692,1685],{"id":116683},"q18-a-function-needs-to-represent-a-2d-coordinate-pair-that-will-always-have-exactly-two-f64-values-and-no-more-what-is-more-idiomatic-a-tuple-f64-f64-or-a-two-element-vecf64","Q18. A function needs to represent \"a 2D coordinate pair\" that will always have exactly two ",[39,116686,115196],{}," values and no more. What is more idiomatic — a tuple ",[39,116689,116690],{},"(f64, f64)"," or a two-element ",[39,116693,116694],{},"Vec\u003Cf64>",[23,116696,116698,116706,116722,116732],{"className":116697},[26],[28,116699,116701,355,116703,116705],{"className":116700},[31],[33,116702],{"disabled":35,"type":36},[39,116704,116694],{},", since vectors are always more efficient than tuples",[28,116707,116709,116711,116712,116714,116715,116718,116719,116721],{"className":116708},[31],[33,116710],{"disabled":35,"type":36}," A tuple ",[39,116713,116690],{},", or better yet a small named ",[39,116716,116717],{},"struct Point { x: f64, y: f64 }"," — since the size (2) is fixed and known, a ",[39,116720,112877],{}," would incorrectly imply a runtime-variable length and adds unnecessary heap allocation and indirection",[28,116723,116725,116727,116728,116731],{"className":116724},[31],[33,116726],{"disabled":35,"type":36}," Neither; only arrays ",[39,116729,116730],{},"[f64; 2]"," are valid for fixed-size numeric data",[28,116733,116735,116737,116738,116740],{"className":116734},[31],[33,116736],{"disabled":35,"type":36}," It makes no practical difference; ",[39,116739,112877],{},", tuple, and array are fully interchangeable in all Rust APIs",[66,116742,116743,116745,116759],{},[69,116744,71],{},[73,116746,116747,116749,116750,116752,116753,116755,116756,116758],{},[76,116748,78],{}," B — A tuple ",[39,116751,116690],{},", or better a named ",[39,116754,116717],{}," — since size is fixed, ",[39,116757,112877],{}," wrongly implies variable length and adds needless heap allocation",[73,116760,116761,355,116763,355,116765,116768,116769,446,116771,64118,116773,446,116775,116777],{},[76,116762,84],{},[76,116764,930],{},[39,116766,116767],{},"Vec\u003CT>"," is heap-allocated and growable\u002Fshrinkable at runtime — reaching for it when the length is a fixed, compile-time-known constant (like a 2D point) is both a performance cost (unnecessary allocation\u002Findirection) and a readability\u002FAPI-design smell, since it implies the length could vary when it never does. A named struct is generally preferred over a bare tuple once fields have clear semantic roles (",[39,116770,2403],{},[39,116772,2909],{},[39,116774,115281],{},[39,116776,115284],{},"), improving self-documentation, though the tuple is not wrong, just less expressive.",[15,116779,116780,116787,116840],{},[18,116781,116783,116784,116786],{"id":116782},"q19-what-is-the-best-practice-way-to-handle-a-computation-that-might-overflow-in-a-context-where-overflow-represents-a-genuine-expected-possibility-eg-summing-user-supplied-quantities-that-could-exceed-u32max-rather-than-a-programmer-bug","Q19. What is the best-practice way to handle a computation that might overflow in a context where overflow represents a genuine, expected possibility (e.g. summing user-supplied quantities that could exceed ",[39,116785,115869],{},"), rather than a programmer bug?",[23,116788,116790,116796,116817,116830],{"className":116789},[26],[28,116791,116793,116795],{"className":116792},[31],[33,116794],{"disabled":35,"type":36}," Rely on debug-mode panics to catch it during testing and ship release builds as-is, trusting silent wraparound is fine for production",[28,116797,116799,4353,116801,93077,116804,2182,116807,116809,116810,446,116813,116816],{"className":116798},[31],[33,116800],{"disabled":35,"type":36},[39,116802,116803],{},"checked_add",[39,116805,116806],{},"Option\u003CT>",[39,116808,90944],{}," on overflow), or ",[39,116811,116812],{},"saturating_add",[39,116814,116815],{},"wrapping_add"," depending on whether the correct domain behavior is to clamp, wrap, or explicitly reject the overflowing case — chosen deliberately rather than relying on the default panic\u002Fwrap split between debug and release",[28,116818,116820,116822,116823,446,116826,116829],{"className":116819},[31],[33,116821],{"disabled":35,"type":36}," Always cast to ",[39,116824,116825],{},"i128",[39,116827,116828],{},"u128"," everywhere to make overflow effectively impossible in every context",[28,116831,116833,116835,116836,116839],{"className":116832},[31],[33,116834],{"disabled":35,"type":36}," Catch the debug-mode panic with ",[39,116837,116838],{},"std::panic::catch_unwind"," in production release builds",[66,116841,116842,116844,116859],{},[69,116843,71],{},[73,116845,116846,4409,116848,115081,116850,116853,116854,446,116856,116858],{},[76,116847,78],{},[39,116849,116803],{},[39,116851,116852],{},"Option","), or ",[39,116855,116812],{},[39,116857,116815],{}," depending on the correct domain behavior, chosen deliberately",[73,116860,116861,355,116863,116865,116866,446,116869,446,116872,116875,116876,116879],{},[76,116862,84],{},[76,116864,582],{}," relying on the implicit debug-panic\u002Frelease-wrap split (A) means the exact same overflow bug behaves completely differently between environments — code that \"worked\" in every debug test can silently corrupt data in production release builds. The explicit ",[39,116867,116868],{},"checked_*",[39,116870,116871],{},"saturating_*",[39,116873,116874],{},"wrapping_*"," family of methods makes the overflow-handling policy a deliberate, visible choice in the code rather than an accident of build profile; ",[39,116877,116878],{},"catch_unwind"," (D) is a heavyweight, inappropriate tool for ordinary expected-value validation, not a substitute for correct arithmetic handling.",[15,116881,116882,116892,116938],{},[18,116883,116885,116886,19439,116889,116891],{"id":116884},"q20-when-choosing-between-an-array-t-n-and-a-vect-for-function-parametersreturn-types-what-is-the-idiomatic-guidance","Q20. When choosing between an array ",[39,116887,116888],{},"[T; N]",[39,116890,116767],{}," for function parameters\u002Freturn types, what is the idiomatic guidance?",[23,116893,116895,116903,116918,116927],{"className":116894},[26],[28,116896,116898,4207,116900,116902],{"className":116897},[31],[33,116899],{"disabled":35,"type":36},[39,116901,116767],{}," even for fixed, compile-time-known sizes, since it's more \"flexible\" by default",[28,116904,116906,4353,116908,116910,116911,116914,116915,116917],{"className":116905},[31],[33,116907],{"disabled":35,"type":36},[39,116909,116888],{}," (or a slice ",[39,116912,116913],{},"&[T]",") when the length is fixed and known at compile time, giving stack allocation and compile-time length guarantees; reach for ",[39,116916,116767],{}," when the length is only known at runtime or needs to grow\u002Fshrink",[28,116919,116921,116923,116924,116926],{"className":116920},[31],[33,116922],{"disabled":35,"type":36}," Arrays and ",[39,116925,112877],{}," are chosen purely based on personal preference with no technical trade-offs",[28,116928,116930,355,116932,116934,116935,116937],{"className":116929},[31],[33,116931],{"disabled":35,"type":36},[39,116933,116888],{}," should be avoided entirely in idiomatic Rust in favor of ",[39,116936,116767],{}," for all collections",[66,116939,116940,116942,116954],{},[69,116941,71],{},[73,116943,116944,4409,116946,7255,116948,116950,116951,116953],{},[76,116945,78],{},[39,116947,116888],{},[39,116949,116913],{},") when the length is fixed and compile-time known; reach for ",[39,116952,116767],{}," when the length is runtime-determined or needs to grow\u002Fshrink",[73,116955,116956,355,116958,116960,116961,116963,116964,116967,116968,116970],{},[76,116957,84],{},[76,116959,930],{}," fixed-size arrays avoid heap allocation entirely and encode the exact length in the type system (catching size-mismatch bugs at compile time, as seen with Q9's constant-index rejection), which is strictly better than ",[39,116962,112877],{}," whenever the size genuinely never changes — e.g. ",[39,116965,116966],{},"[u8; 32]"," for a fixed-size hash digest. Defaulting to ",[39,116969,112877],{}," everywhere (A) throws away those compile-time guarantees and adds unnecessary heap allocation\u002Findirection for data whose size was never actually variable.",[2107,116972,116973],{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}",{"title":264,"searchDepth":286,"depth":286,"links":116975},[116976,116977,116979,116981,116983,116985,116987,116988,116989,116990,116991,116992,116994,116996,116997,116999,117001,117002,117004,117006],{"id":114579,"depth":296,"text":114580},{"id":114659,"depth":296,"text":116978},"Q2. What are isize and usize primarily used for?",{"id":114728,"depth":296,"text":116980},"Q3. What does this program print when run with cargo run (debug profile, the default)?",{"id":114857,"depth":296,"text":116982},"Q4. What is the correct way to describe integer overflow behavior in --release builds by default?",{"id":114937,"depth":296,"text":116984},"Q5. What does casting with as do in this example?",{"id":115091,"depth":296,"text":116986},"Q6. Which statement correctly describes Rust's char type?",{"id":115171,"depth":296,"text":115172},{"id":115335,"depth":296,"text":115336},{"id":115483,"depth":296,"text":115484},{"id":115607,"depth":296,"text":115608},{"id":115771,"depth":296,"text":115772},{"id":115926,"depth":296,"text":116993},"Q12. What does this code do with an empty tuple ()?",{"id":116116,"depth":296,"text":116995},"Q13. What is the maximum safely representable integer using f64 such that all integers up to that value can be represented exactly?",{"id":116212,"depth":296,"text":116213},{"id":116392,"depth":296,"text":116998},"Q15. When should you prefer an explicit-width integer type like u16 or i64 over the default i32?",{"id":116474,"depth":296,"text":117000},"Q16. What is the idiomatic way to convert between numeric types when the value's validity at the target type must be guaranteed rather than assumed, e.g. converting a user-supplied i64 amount into a u32 quantity field?",{"id":116571,"depth":296,"text":116572},{"id":116683,"depth":296,"text":117003},"Q18. A function needs to represent \"a 2D coordinate pair\" that will always have exactly two f64 values and no more. What is more idiomatic — a tuple (f64, f64) or a two-element Vec\u003Cf64>?",{"id":116782,"depth":296,"text":117005},"Q19. What is the best-practice way to handle a computation that might overflow in a context where overflow represents a genuine, expected possibility (e.g. summing user-supplied quantities that could exceed u32::MAX), rather than a programmer bug?",{"id":116884,"depth":296,"text":117007},"Q20. When choosing between an array [T; N] and a Vec\u003CT> for function parameters\u002Freturn types, what is the idiomatic guidance?",{},"\u002Frust\u002F04-data-types",{"title":114569,"description":264},"rust\u002F04-data-types","DlEQ7lynxxMPYEllpEyKXjq11_2P_hGWOQUocpBA8T8",{"id":117014,"title":117015,"body":117016,"description":264,"extension":2144,"meta":120676,"navigation":35,"path":120677,"seo":120678,"stem":120679,"__hash__":120680},"content\u002Frust\u002F05-functions.md","05 — Functions",{"type":8,"value":117017,"toc":120640},[117018,117021,117153,117297,117455,117602,117801,117965,118157,118318,118448,118654,118856,119097,119337,119586,119908,120004,120234,120316,120535,120637],[11,117019,117015],{"id":117020},"_05-functions",[15,117022,117023,117027,117061,117110],{"language":111909},[18,117024,117026],{"id":117025},"q1-what-happens-when-you-try-to-compile-this-function","Q1. What happens when you try to compile this function?",[257,117028,117029],{"language":111909},[260,117030,117032],{"className":111918,"code":117031,"language":111909,"meta":264,"style":264},"fn add(a, b) -> i32 {\n    a + b\n}\n",[39,117033,117034,117049,117057],{"__ignoreMap":264},[268,117035,117036,117038,117040,117043,117045,117047],{"class":270,"line":271},[268,117037,37837],{"class":274},[268,117039,1217],{"class":278},[268,117041,117042],{"class":282},"(a, b) ",[268,117044,113308],{"class":274},[268,117046,113794],{"class":278},[268,117048,9914],{"class":282},[268,117050,117051,117053,117055],{"class":270,"line":286},[268,117052,106789],{"class":282},[268,117054,1246],{"class":274},[268,117056,95559],{"class":282},[268,117058,117059],{"class":270,"line":296},[268,117060,314],{"class":282},[23,117062,117064,117079,117085,117097],{"className":117063},[26],[28,117065,117067,117069,117070,186,117072,117074,117075,117078],{"className":117066},[31],[33,117068],{"disabled":35,"type":36}," It compiles, but ",[39,117071,1223],{},[39,117073,1232],{}," are inferred as generic ",[39,117076,117077],{},"T: Add"," parameters.",[28,117080,117082,117084],{"className":117081},[31],[33,117083],{"disabled":35,"type":36}," It compiles only in debug builds; release builds require explicit types.",[28,117086,117088,117090,117091,117093,117094,117096],{"className":117087},[31],[33,117089],{"disabled":35,"type":36}," It fails to compile — Rust requires every function parameter to have an explicit type annotation; type inference like this only applies to closures and ",[39,117092,240],{}," bindings, never to ",[39,117095,37837],{}," parameter lists.",[28,117098,117100,117102,117103,186,117105,26085,117107,117109],{"className":117099},[31],[33,117101],{"disabled":35,"type":36}," It compiles fine — Rust infers ",[39,117104,1223],{},[39,117106,1232],{},[39,117108,113860],{}," from the return type and usage, just like closures do.",[66,117111,117112,117114,117119],{},[69,117113,71],{},[73,117115,117116,117118],{},[76,117117,78],{}," C — It fails to compile — Rust requires every function parameter to have an explicit type annotation.",[73,117120,117121,355,117123,117125,117126,117128,117129,117132,117133,117136,117137,117139,117140,117142,117143,117145,117146,117148,117149,117152],{},[76,117122,84],{},[76,117124,930],{}," the parser itself rejects this before type-checking even begins — every ",[39,117127,37837],{}," parameter must be written as ",[39,117130,117131],{},"name: Type",", full stop. This surprises people who've just seen closures like ",[39,117134,117135],{},"|a, b| a + b"," compile fine with types inferred from context: closures and ",[39,117138,240],{}," bindings support inference, but plain ",[39,117141,37837],{}," items never do, by design, since a function's signature is part of its public contract and shouldn't silently shift based on how it's called. Rules out D (no such inference exists for ",[39,117144,37837],{},") and B (nothing in ",[39,117147,37837],{}," syntax implies generics without explicit ",[39,117150,117151],{},"\u003CT>"," bounds); A's debug\u002Frelease split is invented — this is a hard parse error present in every build profile.",[15,117154,117155,117162,117205,117249],{"language":111909},[18,117156,117158,117159,117161],{"id":117157},"q2-this-function-is-declared-to-return-i32-what-happens-when-you-try-to-compile-it","Q2. This function is declared to return ",[39,117160,113860],{},". What happens when you try to compile it?",[257,117163,117164],{"language":111909},[260,117165,117167],{"className":111918,"code":117166,"language":111909,"meta":264,"style":264},"fn plus_one(x: i32) -> i32 {\n    x + 1;\n}\n",[39,117168,117169,117191,117201],{"__ignoreMap":264},[268,117170,117171,117173,117176,117179,117181,117183,117185,117187,117189],{"class":270,"line":271},[268,117172,37837],{"class":274},[268,117174,117175],{"class":278}," plus_one",[268,117177,117178],{"class":282},"(x",[268,117180,10728],{"class":274},[268,117182,113794],{"class":278},[268,117184,6131],{"class":282},[268,117186,113308],{"class":274},[268,117188,113794],{"class":278},[268,117190,9914],{"class":282},[268,117192,117193,117195,117197,117199],{"class":270,"line":286},[268,117194,111947],{"class":282},[268,117196,1246],{"class":274},[268,117198,2199],{"class":305},[268,117200,293],{"class":282},[268,117202,117203],{"class":270,"line":296},[268,117204,314],{"class":282},[23,117206,117208,117226,117235,117243],{"className":117207},[26],[28,117209,117211,117213,117214,117216,117217,117219,117220,117223,117224,462],{"className":117210},[31],[33,117212],{"disabled":35,"type":36}," It fails to compile with a type mismatch: expected ",[39,117215,113860],{},", found ",[39,117218,16952],{}," — the trailing semicolon turns ",[39,117221,117222],{},"x + 1"," into a statement, so the block's value becomes the unit type instead of the computed ",[39,117225,113860],{},[28,117227,117229,117231,117232,117234],{"className":117228},[31],[33,117230],{"disabled":35,"type":36}," It compiles and returns ",[39,117233,117222],{}," as expected.",[28,117236,117238,117240,117241,462],{"className":117237},[31],[33,117239],{"disabled":35,"type":36}," It compiles and always returns ",[39,117242,3307],{},[28,117244,117246,117248],{"className":117245},[31],[33,117247],{"disabled":35,"type":36}," It compiles with a warning but panics at runtime when called.",[66,117250,117251,117253,117262],{},[69,117252,71],{},[73,117254,117255,117257,117258,117216,117260,462],{},[76,117256,78],{}," A — It fails to compile with a type mismatch: expected ",[39,117259,113860],{},[39,117261,16952],{},[73,117263,117264,355,117266,117268,117269,117272,117273,21185,117275,117277,117278,117280,117281,117283,117284,1179,117287,117289,117290,117293,117294,4755],{},[76,117265,84],{},[76,117267,365],{}," this is the single most common first-week Rust trap. A function body's value is determined by its final expression ",[104,117270,117271],{},"if and only if"," that expression has no trailing semicolon; adding ",[39,117274,10769],{},[39,117276,117222],{}," converts it into a statement, and statements always evaluate to ",[39,117279,16952],{},". The block's overall value is then ",[39,117282,16952],{},", which doesn't match the declared ",[39,117285,117286],{},"-> i32",[39,117288,108612],{}," rejects it with ",[39,117291,117292],{},"mismatched types: expected i32, found ()",". It's not a runtime issue (rules out D — this is caught entirely at compile time) and there's no fallback to a default value (rules out C). The fix is either deleting the semicolon or writing ",[39,117295,117296],{},"return x + 1;",[15,117298,117299,117305,117378,117421],{"language":111909},[18,117300,117302,117303,1685],{"id":117301},"q3-is-this-function-valid-and-what-does-it-demonstrate-about-return","Q3. Is this function valid, and what does it demonstrate about ",[39,117304,9151],{},[257,117306,117307],{"language":111909},[260,117308,117310],{"className":111918,"code":117309,"language":111909,"meta":264,"style":264},"fn abs_diff(a: i32, b: i32) -> i32 {\n    if a > b {\n        return a - b;\n    }\n    b - a\n}\n",[39,117311,117312,117341,117352,117362,117366,117374],{"__ignoreMap":264},[268,117313,117314,117316,117319,117322,117324,117326,117329,117331,117333,117335,117337,117339],{"class":270,"line":271},[268,117315,37837],{"class":274},[268,117317,117318],{"class":278}," abs_diff",[268,117320,117321],{"class":282},"(a",[268,117323,10728],{"class":274},[268,117325,113794],{"class":278},[268,117327,117328],{"class":282},", b",[268,117330,10728],{"class":274},[268,117332,113794],{"class":278},[268,117334,6131],{"class":282},[268,117336,113308],{"class":274},[268,117338,113794],{"class":278},[268,117340,9914],{"class":282},[268,117342,117343,117345,117347,117349],{"class":270,"line":286},[268,117344,9686],{"class":274},[268,117346,1243],{"class":282},[268,117348,6435],{"class":274},[268,117350,117351],{"class":282}," b {\n",[268,117353,117354,117356,117358,117360],{"class":270,"line":296},[268,117355,11956],{"class":274},[268,117357,1243],{"class":282},[268,117359,6244],{"class":274},[268,117361,1249],{"class":282},[268,117363,117364],{"class":270,"line":311},[268,117365,11972],{"class":282},[268,117367,117368,117370,117372],{"class":270,"line":788},[268,117369,106808],{"class":282},[268,117371,6244],{"class":274},[268,117373,89708],{"class":282},[268,117375,117376],{"class":270,"line":1951},[268,117377,314],{"class":282},[23,117379,117381,117390,117399,117409],{"className":117380},[26],[28,117382,117384,117386,117387,117389],{"className":117383},[31],[33,117385],{"disabled":35,"type":36}," It fails to compile — every code path must end in an explicit ",[39,117388,9151],{}," statement, not a bare tail expression.",[28,117391,117393,117395,117396,117398],{"className":117392},[31],[33,117394],{"disabled":35,"type":36}," It fails to compile — mixing ",[39,117397,9151],{}," and implicit returns in the same function is not allowed.",[28,117400,117402,117404,117405,117408],{"className":117401},[31],[33,117403],{"disabled":35,"type":36}," It compiles, but the final ",[39,117406,117407],{},"b - a"," line is unreachable dead code that gets a compiler warning.",[28,117410,117412,117414,117415,117417,117418,117420],{"className":117411},[31],[33,117413],{"disabled":35,"type":36}," It compiles fine — ",[39,117416,9151],{}," is only required to exit a function before reaching its final expression; the last line ",[39,117419,117407],{},", with no semicolon, is just as valid an implicit return.",[66,117422,117423,117425,117433],{},[69,117424,71],{},[73,117426,117427,117429,117430,117432],{},[76,117428,78],{}," D — It compiles fine — ",[39,117431,9151],{}," is only required to exit a function before its final expression.",[73,117434,117435,117437,117438,117441,117442,117444,117445,117448,117449,117451,117452,117454],{},[76,117436,84],{}," Rust supports two equally valid ways to produce a function's return value: an explicit ",[39,117439,117440],{},"return expr;"," for early exits (as in the ",[39,117443,2179],{}," branch here), and an implicit tail expression with no semicolon for the \"falls through to the end\" case. Both can coexist freely in the same function — there's no rule requiring consistency between them (rules out B), and a bare tail expression is not merely tolerated but idiomatic (rules out A). The final line is very much reachable whenever ",[39,117446,117447],{},"a \u003C= b",", since the ",[39,117450,9151],{}," only fires inside the ",[39,117453,2179],{}," block (rules out C).",[15,117456,117457,117466,117539,117578],{"language":111909},[18,117458,44471,117460,117462,117463,117465],{"id":117459},"q4-square-is-called-in-main-before-its-definition-appears-in-the-file-what-happens",[39,117461,31493],{}," is called in ",[39,117464,111207],{}," before its definition appears in the file. What happens?",[257,117467,117468],{"language":111909},[260,117469,117471],{"className":111918,"code":117470,"language":111909,"meta":264,"style":264},"fn main() {\n    println!(\"{}\", square(5));\n}\n\nfn square(x: i32) -> i32 {\n    x * x\n}\n",[39,117472,117473,117481,117499,117503,117507,117527,117535],{"__ignoreMap":264},[268,117474,117475,117477,117479],{"class":270,"line":271},[268,117476,37837],{"class":274},[268,117478,111928],{"class":278},[268,117480,283],{"class":282},[268,117482,117483,117485,117487,117489,117491,117493,117495,117497],{"class":270,"line":286},[268,117484,111958],{"class":278},[268,117486,622],{"class":282},[268,117488,113830],{"class":289},[268,117490,42],{"class":282},[268,117492,31493],{"class":278},[268,117494,622],{"class":282},[268,117496,2429],{"class":305},[268,117498,4818],{"class":282},[268,117500,117501],{"class":270,"line":296},[268,117502,314],{"class":282},[268,117504,117505],{"class":270,"line":311},[268,117506,5033],{"emptyLinePlaceholder":35},[268,117508,117509,117511,117513,117515,117517,117519,117521,117523,117525],{"class":270,"line":788},[268,117510,37837],{"class":274},[268,117512,31438],{"class":278},[268,117514,117178],{"class":282},[268,117516,10728],{"class":274},[268,117518,113794],{"class":278},[268,117520,6131],{"class":282},[268,117522,113308],{"class":274},[268,117524,113794],{"class":278},[268,117526,9914],{"class":282},[268,117528,117529,117531,117533],{"class":270,"line":1951},[268,117530,111947],{"class":282},[268,117532,6134],{"class":274},[268,117534,93160],{"class":282},[268,117536,117537],{"class":270,"line":8955},[268,117538,314],{"class":282},[23,117540,117542,117548,117557,117566],{"className":117541},[26],[28,117543,117545,117547],{"className":117544},[31],[33,117546],{"disabled":35,"type":36}," Compile error — Rust requires functions to be declared or prototyped before use, like C.",[28,117549,117551,117553,117554,117556],{"className":117550},[31],[33,117552],{"disabled":35,"type":36}," It compiles and runs fine, printing ",[39,117555,31527],{}," — Rust resolves item names (functions, structs, and so on) within a scope regardless of their textual order, so forward references to later-defined functions are completely normal.",[28,117558,117560,117562,117563,117565],{"className":117559},[31],[33,117561],{"disabled":35,"type":36}," Compile error — only ",[39,117564,111207],{}," may be defined first; all helper functions must precede their first call site.",[28,117567,117569,117571,117572,117574,117575,462],{"className":117568},[31],[33,117570],{"disabled":35,"type":36}," It compiles but only if ",[39,117573,31493],{}," is marked ",[39,117576,117577],{},"pub",[66,117579,117580,117582,117589],{},[69,117581,71],{},[73,117583,117584,117586,117587,462],{},[76,117585,78],{}," B — It compiles and runs fine, printing ",[39,117588,31527],{},[73,117590,117591,355,117593,117595,117596,117598,117599,117601],{},[76,117592,84],{},[76,117594,930],{}," unlike C, which needs a prototype (or the definition itself) to appear before first use, Rust's compiler does a full pass over a scope's items — collecting function signatures, struct definitions, and so on — before checking any bodies, so the textual order of top-level items is irrelevant to name resolution. This lets you put ",[39,117597,111207],{}," at the top of a file with helpers defined below it, a very common and idiomatic layout. ",[39,117600,117577],{}," (option D) controls cross-module\u002Fcross-crate visibility, not same-file resolution order, so it's irrelevant here since both functions are in the same module (rules out D and A\u002FC, which both invent a C-like ordering requirement that doesn't exist in Rust).",[15,117603,117604,117614,117689,117754],{"language":111909},[18,117605,55220,117607,21182,117609,117611,117612,1685],{"id":117606},"q5-log-has-no-type-in-its-signature-what-happens-when-compiling-main",[39,117608,1356],{},[39,117610,116094],{}," in its signature. What happens when compiling ",[39,117613,111207],{},[257,117615,117616],{"language":111909},[260,117617,117619],{"className":111918,"code":117618,"language":111909,"meta":264,"style":264},"fn log(msg: &str) {\n    println!(\"{msg}\");\n}\n\nfn main() {\n    let x = log(\"hi\") + 1;\n}\n",[39,117620,117621,117637,117647,117651,117655,117663,117685],{"__ignoreMap":264},[268,117622,117623,117625,117627,117629,117631,117633,117635],{"class":270,"line":271},[268,117624,37837],{"class":274},[268,117626,16942],{"class":278},[268,117628,115946],{"class":282},[268,117630,10728],{"class":274},[268,117632,115951],{"class":274},[268,117634,17109],{"class":278},[268,117636,1235],{"class":282},[268,117638,117639,117641,117643,117645],{"class":270,"line":286},[268,117640,111958],{"class":278},[268,117642,622],{"class":282},[268,117644,115968],{"class":289},[268,117646,628],{"class":282},[268,117648,117649],{"class":270,"line":296},[268,117650,314],{"class":282},[268,117652,117653],{"class":270,"line":311},[268,117654,5033],{"emptyLinePlaceholder":35},[268,117656,117657,117659,117661],{"class":270,"line":788},[268,117658,37837],{"class":274},[268,117660,111928],{"class":278},[268,117662,283],{"class":282},[268,117664,117665,117667,117669,117671,117673,117675,117677,117679,117681,117683],{"class":270,"line":1951},[268,117666,80826],{"class":274},[268,117668,2382],{"class":282},[268,117670,302],{"class":274},[268,117672,16942],{"class":278},[268,117674,622],{"class":282},[268,117676,85975],{"class":289},[268,117678,6131],{"class":282},[268,117680,1246],{"class":274},[268,117682,2199],{"class":305},[268,117684,293],{"class":282},[268,117686,117687],{"class":270,"line":8955},[268,117688,314],{"class":282},[23,117690,117692,117710,117721,117742],{"className":117691},[26],[28,117693,117695,117697,117698,117700,117701,355,117703,117705,117706,7083,117708,462],{"className":117694},[31],[33,117696],{"disabled":35,"type":36}," It compiles — ",[39,117699,1356],{}," implicitly returns ",[39,117702,113860],{},[39,117704,3307],{}," when no return type is given, so ",[39,117707,2403],{},[39,117709,2255],{},[28,117711,117713,117715,117716,117718,117719,462],{"className":117712},[31],[33,117714],{"disabled":35,"type":36}," It compiles — Rust automatically discards ",[39,117717,1356],{},"'s return value and treats the expression as just ",[39,117720,2255],{},[28,117722,117724,117726,117727,117729,117730,137,117732,117734,117735,117738,117739,462],{"className":117723},[31],[33,117725],{"disabled":35,"type":36}," It fails to compile — ",[39,117728,1356],{},"'s implicit return type is the unit type ",[39,117731,16952],{},[39,117733,16952],{}," does not implement the ",[39,117736,117737],{},"Add"," trait needed for ",[39,117740,117741],{},"() + 1",[28,117743,117745,117747,117748,117750,117751,117753],{"className":117744},[31],[33,117746],{"disabled":35,"type":36}," It fails to compile because ",[39,117749,1356],{}," must have an explicit ",[39,117752,116065],{}," annotation to be callable at all.",[66,117755,117756,117758,117771],{},[69,117757,71],{},[73,117759,117760,117762,117763,117765,117766,59268,117768,117770],{},[76,117761,78],{}," C — It fails to compile — ",[39,117764,1356],{},"'s implicit return type is ",[39,117767,16952],{},[39,117769,117737],{}," implementation.",[73,117772,117773,117775,117776,117778,117779,117781,117782,117784,117785,117788,117789,5425,117792,117794,117795,117797,117798,117800],{},[76,117774,84],{}," Omitting ",[39,117777,116094],{}," entirely is exactly equivalent to writing ",[39,117780,116065],{}," — a function with no arrow always implicitly returns the unit type (rules out D, since the arrow is optional shorthand, not mandatory). ",[39,117783,16952],{}," is a real, if trivial, value — but it's a zero-sized marker type with no arithmetic trait implementations, so ",[39,117786,117787],{},"log(\"hi\") + 1"," fails to type-check with an error to the effect of \"cannot add ",[39,117790,117791],{},"{integer}",[39,117793,16952],{},".\" Nothing about calling a ",[39,117796,16952],{},"-returning function discards it into a usable numeric default (rules out A and B) — the unit value has to be explicitly used or ignored as ",[39,117799,16952],{},", not silently coerced into a number.",[15,117802,117803,117807,117872,117920],{"language":111909},[18,117804,117806],{"id":117805},"q6-what-does-this-program-print","Q6. What does this program print?",[257,117808,117809],{"language":111909},[260,117810,117812],{"className":111918,"code":117811,"language":111909,"meta":264,"style":264},"fn main() {\n    let y = {\n        let x = 3;\n        x + 1\n    };\n    println!(\"{y}\");\n}\n",[39,117813,117814,117822,117832,117844,117853,117858,117868],{"__ignoreMap":264},[268,117815,117816,117818,117820],{"class":270,"line":271},[268,117817,37837],{"class":274},[268,117819,111928],{"class":278},[268,117821,283],{"class":282},[268,117823,117824,117826,117828,117830],{"class":270,"line":286},[268,117825,80826],{"class":274},[268,117827,2509],{"class":282},[268,117829,302],{"class":274},[268,117831,9914],{"class":282},[268,117833,117834,117836,117838,117840,117842],{"class":270,"line":296},[268,117835,112735],{"class":274},[268,117837,2382],{"class":282},[268,117839,302],{"class":274},[268,117841,3396],{"class":305},[268,117843,293],{"class":282},[268,117845,117846,117849,117851],{"class":270,"line":311},[268,117847,117848],{"class":282},"        x ",[268,117850,1246],{"class":274},[268,117852,84787],{"class":305},[268,117854,117855],{"class":270,"line":788},[268,117856,117857],{"class":282},"    };\n",[268,117859,117860,117862,117864,117866],{"class":270,"line":1951},[268,117861,111958],{"class":278},[268,117863,622],{"class":282},[268,117865,114789],{"class":289},[268,117867,628],{"class":282},[268,117869,117870],{"class":270,"line":8955},[268,117871,314],{"class":282},[23,117873,117875,117888,117900,117912],{"className":117874},[26],[28,117876,117878,355,117880,117882,117883,117885,117886,462],{"className":117877},[31],[33,117879],{"disabled":35,"type":36},[39,117881,15049],{},", because the block's trailing expression ",[39,117884,117222],{}," (no semicolon) is the value the whole block evaluates to, and that value is assigned to ",[39,117887,2909],{},[28,117889,117891,117893,117894,117896,117897,117899],{"className":117890},[31],[33,117892],{"disabled":35,"type":36}," Compile error — a ",[39,117895,11010],{}," block cannot be assigned directly to a ",[39,117898,240],{}," binding.",[28,117901,117903,355,117905,2833,117907,117909,117910,462],{"className":117902},[31],[33,117904],{"disabled":35,"type":36},[39,117906,3423],{},[39,117908,2909],{}," binds to the inner ",[39,117911,2403],{},[28,117913,117915,117917,117918,462],{"className":117914},[31],[33,117916],{"disabled":35,"type":36}," It prints nothing — blocks used as expressions always evaluate to ",[39,117919,16952],{},[66,117921,117922,117924,117931],{},[69,117923,71],{},[73,117925,117926,3459,117928,117930],{},[76,117927,78],{},[39,117929,15049],{},", because the block's trailing expression is its value.",[73,117932,117933,117935,117936,117939,117940,117942,117943,117945,117946,117948,117949,117951,117952,117955,117956,117958,117959,117961,117962,117964],{},[76,117934,84],{}," A bare ",[39,117937,117938],{},"{ ... }"," block is itself an expression, governed by the exact same rule as function bodies (Q2, Q3): its value is its own trailing expression without a semicolon. Here that's ",[39,117941,117222],{},", which evaluates to ",[39,117944,15049],{}," inside the block, so ",[39,117947,2909],{}," binds to ",[39,117950,15049],{},". The inner ",[39,117953,117954],{},"let x = 3;"," is scoped entirely to the block and never leaks into the outer scope (rules out C — there is no outer ",[39,117957,2403],{}," to shadow or bind to). This is a genuine departure from C-family languages, where ",[39,117960,11010],{}," is purely a scoping construct with no value of its own (rules out B and D, which both assume block-as-value doesn't work or defaults to unit — it only defaults to unit if the block's last line ",[104,117963,10043],{}," end in a semicolon or has no trailing expression).",[15,117966,117967,117969,118082,118116],{"language":111909},[18,117968,112566],{"id":112565},[257,117970,117971],{"language":111909},[260,117972,117974],{"className":111918,"code":117973,"language":111909,"meta":264,"style":264},"fn factorial(n: u64) -> u64 {\n    if n == 0 {\n        1\n    } else {\n        n * factorial(n - 1)\n    }\n}\n\nfn main() {\n    println!(\"{}\", factorial(5));\n}\n",[39,117975,117976,117998,118010,118015,118023,118040,118044,118048,118052,118060,118078],{"__ignoreMap":264},[268,117977,117978,117980,117982,117985,117987,117990,117992,117994,117996],{"class":270,"line":271},[268,117979,37837],{"class":274},[268,117981,13335],{"class":278},[268,117983,117984],{"class":282},"(n",[268,117986,10728],{"class":274},[268,117988,117989],{"class":278}," u64",[268,117991,6131],{"class":282},[268,117993,113308],{"class":274},[268,117995,117989],{"class":278},[268,117997,9914],{"class":282},[268,117999,118000,118002,118004,118006,118008],{"class":270,"line":286},[268,118001,9686],{"class":274},[268,118003,13355],{"class":282},[268,118005,3197],{"class":274},[268,118007,5728],{"class":305},[268,118009,9914],{"class":282},[268,118011,118012],{"class":270,"line":296},[268,118013,118014],{"class":305},"        1\n",[268,118016,118017,118019,118021],{"class":270,"line":311},[268,118018,12485],{"class":282},[268,118020,9884],{"class":274},[268,118022,9914],{"class":282},[268,118024,118025,118028,118030,118032,118034,118036,118038],{"class":270,"line":788},[268,118026,118027],{"class":282},"        n ",[268,118029,6134],{"class":274},[268,118031,13335],{"class":278},[268,118033,13376],{"class":282},[268,118035,6244],{"class":274},[268,118037,2199],{"class":305},[268,118039,20702],{"class":282},[268,118041,118042],{"class":270,"line":1951},[268,118043,11972],{"class":282},[268,118045,118046],{"class":270,"line":8955},[268,118047,314],{"class":282},[268,118049,118050],{"class":270,"line":8966},[268,118051,5033],{"emptyLinePlaceholder":35},[268,118053,118054,118056,118058],{"class":270,"line":8974},[268,118055,37837],{"class":274},[268,118057,111928],{"class":278},[268,118059,283],{"class":282},[268,118061,118062,118064,118066,118068,118070,118072,118074,118076],{"class":270,"line":8985},[268,118063,111958],{"class":278},[268,118065,622],{"class":282},[268,118067,113830],{"class":289},[268,118069,42],{"class":282},[268,118071,13401],{"class":278},[268,118073,622],{"class":282},[268,118075,2429],{"class":305},[268,118077,4818],{"class":282},[268,118079,118080],{"class":270,"line":8990},[268,118081,314],{"class":282},[23,118083,118085,118092,118099,118109],{"className":118084},[26],[28,118086,118088,355,118090],{"className":118087},[31],[33,118089],{"disabled":35,"type":36},[39,118091,13912],{},[28,118093,118095,355,118097],{"className":118094},[31],[33,118096],{"disabled":35,"type":36},[39,118098,84338],{},[28,118100,118102,118104,118105,118108],{"className":118101},[31],[33,118103],{"disabled":35,"type":36}," Compile error — Rust does not support recursive function calls without an explicit ",[39,118106,118107],{},"#[recursive]"," attribute.",[28,118110,118112,355,118114],{"className":118111},[31],[33,118113],{"disabled":35,"type":36},[39,118115,13431],{},[66,118117,118118,118120,118126],{},[69,118119,71],{},[73,118121,118122,6901,118124,462],{},[76,118123,78],{},[39,118125,13431],{},[73,118127,118128,355,118130,118132,118133,118136,118137,4912,118140,6345,118142,118145,118146,118148,118149,830,118151,137,118154,118156],{},[76,118129,84],{},[39,118131,13453],{}," unwinds as ",[39,118134,118135],{},"5 * factorial(4) = 5 * 4 * factorial(3) = ... = 5 * 4 * 3 * 2 * 1 * factorial(0)",", and the base case ",[39,118138,118139],{},"n == 0",[39,118141,2255],{},[39,118143,118144],{},"5 * 4 * 3 * 2 * 1 = 120",". Rust supports ordinary recursion with no special opt-in attribute (rules out C — there's no such thing as ",[39,118147,118107],{},"; any function may call itself, limited only by available stack space for very deep recursion, not by any annotation). B and A are simple arithmetic slips (",[39,118150,84338],{},[39,118152,118153],{},"4!",[39,118155,13912],{}," doesn't correspond to any factorial in this chain).",[15,118158,118159,118166,118254,118281],{"language":111909},[18,118160,118162,118163,118165],{"id":118161},"q8-this-is-an-attempt-to-overload-parse-based-on-parameter-type-as-is-common-in-c-or-java-what-happens-when-this-module-is-compiled","Q8. This is an attempt to overload ",[39,118164,22274],{}," based on parameter type, as is common in C++ or Java. What happens when this module is compiled?",[257,118167,118168],{"language":111909},[260,118169,118171],{"className":111918,"code":118170,"language":111909,"meta":264,"style":264},"fn parse(input: &str) -> i32 {\n    input.len() as i32\n}\n\nfn parse(input: i32) -> i32 {\n    input * 2\n}\n",[39,118172,118173,118197,118213,118217,118221,118241,118250],{"__ignoreMap":264},[268,118174,118175,118177,118180,118183,118185,118187,118189,118191,118193,118195],{"class":270,"line":271},[268,118176,37837],{"class":274},[268,118178,118179],{"class":278}," parse",[268,118181,118182],{"class":282},"(input",[268,118184,10728],{"class":274},[268,118186,115951],{"class":274},[268,118188,17109],{"class":278},[268,118190,6131],{"class":282},[268,118192,113308],{"class":274},[268,118194,113794],{"class":278},[268,118196,9914],{"class":282},[268,118198,118199,118202,118204,118206,118208,118210],{"class":270,"line":286},[268,118200,118201],{"class":282},"    input",[268,118203,462],{"class":274},[268,118205,112611],{"class":278},[268,118207,16182],{"class":282},[268,118209,106095],{"class":274},[268,118211,118212],{"class":278}," i32\n",[268,118214,118215],{"class":270,"line":296},[268,118216,314],{"class":282},[268,118218,118219],{"class":270,"line":311},[268,118220,5033],{"emptyLinePlaceholder":35},[268,118222,118223,118225,118227,118229,118231,118233,118235,118237,118239],{"class":270,"line":788},[268,118224,37837],{"class":274},[268,118226,118179],{"class":278},[268,118228,118182],{"class":282},[268,118230,10728],{"class":274},[268,118232,113794],{"class":278},[268,118234,6131],{"class":282},[268,118236,113308],{"class":274},[268,118238,113794],{"class":278},[268,118240,9914],{"class":282},[268,118242,118243,118246,118248],{"class":270,"line":1951},[268,118244,118245],{"class":282},"    input ",[268,118247,6134],{"class":274},[268,118249,85329],{"class":305},[268,118251,118252],{"class":270,"line":8955},[268,118253,314],{"class":282},[23,118255,118257,118263,118269,118275],{"className":118256},[26],[28,118258,118260,118262],{"className":118259},[31],[33,118261],{"disabled":35,"type":36}," It compiles, and Rust picks the correct overload based on the argument type at each call site.",[28,118264,118266,118268],{"className":118265},[31],[33,118267],{"disabled":35,"type":36}," It fails to compile with a \"duplicate definitions\" error — Rust has no function overloading; two items with the same name cannot coexist in the same scope regardless of differing parameter types. Idiomatic alternatives are distinct function names, generics, or trait methods.",[28,118270,118272,118274],{"className":118271},[31],[33,118273],{"disabled":35,"type":36}," It compiles, but only the second definition is kept; the first is silently shadowed.",[28,118276,118278,118280],{"className":118277},[31],[33,118279],{"disabled":35,"type":36}," It compiles only if the two functions have different return types.",[66,118282,118283,118285,118290],{},[69,118284,71],{},[73,118286,118287,118289],{},[76,118288,78],{}," B — It fails to compile with a \"duplicate definitions\" error.",[73,118291,118292,355,118294,118296,118297,118299,118300,118303,118304,118306,118307,8828,118310,118313,118314,118317],{},[76,118293,84],{},[76,118295,930],{}," unlike C++ or Java, Rust resolves function calls purely by name within a scope, with no overload-resolution step based on argument types — so defining two items named ",[39,118298,22274],{}," in the same module is simply a name collision (",[39,118301,118302],{},"the name 'parse' is defined multiple times","), regardless of how their signatures differ. There's no silent-shadowing behavior for top-level items the way there is for ",[39,118305,240],{}," bindings (rules out C), and differing return types don't rescue it either (rules out D) — the conflict is purely on the name. The idiomatic fixes are distinct names (",[39,118308,118309],{},"parse_str",[39,118311,118312],{},"parse_int","), a generic function with a trait bound, or implementing a trait like ",[39,118315,118316],{},"FromStr"," per type.",[15,118319,118320,118324,118375,118423],{"language":111909},[18,118321,118323],{"id":118322},"q9-what-happens-when-this-code-is-compiled","Q9. What happens when this code is compiled?",[257,118325,118326],{"language":111909},[260,118327,118329],{"className":111918,"code":118328,"language":111909,"meta":264,"style":264},"fn connect(host: &str, port: u16 = 8080) {\n    println!(\"{host}:{port}\");\n}\n",[39,118330,118331,118360,118371],{"__ignoreMap":264},[268,118332,118333,118335,118337,118340,118342,118344,118346,118349,118351,118354,118356,118358],{"class":270,"line":271},[268,118334,37837],{"class":274},[268,118336,14238],{"class":278},[268,118338,118339],{"class":282},"(host",[268,118341,10728],{"class":274},[268,118343,115951],{"class":274},[268,118345,17109],{"class":278},[268,118347,118348],{"class":282},", port",[268,118350,10728],{"class":274},[268,118352,118353],{"class":278}," u16",[268,118355,616],{"class":274},[268,118357,14253],{"class":305},[268,118359,1235],{"class":282},[268,118361,118362,118364,118366,118369],{"class":270,"line":286},[268,118363,111958],{"class":278},[268,118365,622],{"class":282},[268,118367,118368],{"class":289},"\"{host}:{port}\"",[268,118370,628],{"class":282},[268,118372,118373],{"class":270,"line":296},[268,118374,314],{"class":282},[23,118376,118378,118391,118397,118407],{"className":118377},[26],[28,118379,118381,118383,118384,10527,118387,118390],{"className":118380},[31],[33,118382],{"disabled":35,"type":36}," It compiles, and calling ",[39,118385,118386],{},"connect(\"localhost\")",[39,118388,118389],{},"port = 8080"," automatically.",[28,118392,118394,118396],{"className":118393},[31],[33,118395],{"disabled":35,"type":36}," It compiles, but the default is only applied in debug builds.",[28,118398,118400,118402,118403,118406],{"className":118399},[31],[33,118401],{"disabled":35,"type":36}," It compiles, and ",[39,118404,118405],{},"= 8080"," is treated as an assertion that must hold for any caller-supplied port.",[28,118408,118410,118412,118413,118416,118417,186,118419,118422],{"className":118409},[31],[33,118411],{"disabled":35,"type":36}," It fails to compile — Rust has no default-parameter syntax at all; every parameter must be supplied explicitly at every call site. The idiomatic workarounds are an ",[39,118414,118415],{},"Option\u003Cu16>"," parameter, multiple clearly-named functions (e.g. ",[39,118418,14292],{},[39,118420,118421],{},"connect_with_port","), or the builder pattern.",[66,118424,118425,118427,118432],{},[69,118426,71],{},[73,118428,118429,118431],{},[76,118430,78],{}," D — It fails to compile — Rust has no default-parameter syntax at all.",[73,118433,118434,355,118436,355,118438,118441,118442,118444,118445,118447],{},[76,118435,84],{},[76,118437,930],{},[39,118439,118440],{},"param: Type = value"," in a function signature isn't valid Rust syntax at all — this is a hard parse error, not merely a missing feature caught later. Coming from Python or JavaScript, where default parameter values are routine, this is a genuine gap: Rust deliberately requires every call site to supply every parameter explicitly, so the workarounds are an ",[39,118443,116806],{}," parameter with an explicit fallback inside the body, multiple distinctly-named functions, or a builder for many optional settings. None of A, B, or C describe real Rust behavior — there is no build-profile-dependent default (B) and no assertion semantics for ",[39,118446,302],{}," in a parameter list (C).",[15,118449,118450,118454,118548,118606],{"language":111909},[18,118451,118453],{"id":118452},"q10-what-happens-when-this-is-compiled","Q10. What happens when this is compiled?",[257,118455,118456],{"language":111909},[260,118457,118459],{"className":111918,"code":118458,"language":111909,"meta":264,"style":264},"fn print_owned(s: String) {\n    println!(\"{s}\");\n}\n\nfn main() {\n    let greeting = String::from(\"hello\");\n    print_owned(greeting);\n    println!(\"{greeting}\");\n}\n",[39,118460,118461,118477,118488,118492,118496,118504,118525,118533,118544],{"__ignoreMap":264},[268,118462,118463,118465,118468,118471,118473,118475],{"class":270,"line":271},[268,118464,37837],{"class":274},[268,118466,118467],{"class":278}," print_owned",[268,118469,118470],{"class":282},"(s",[268,118472,10728],{"class":274},[268,118474,114407],{"class":278},[268,118476,1235],{"class":282},[268,118478,118479,118481,118483,118486],{"class":270,"line":286},[268,118480,111958],{"class":278},[268,118482,622],{"class":282},[268,118484,118485],{"class":289},"\"{s}\"",[268,118487,628],{"class":282},[268,118489,118490],{"class":270,"line":296},[268,118491,314],{"class":282},[268,118493,118494],{"class":270,"line":311},[268,118495,5033],{"emptyLinePlaceholder":35},[268,118497,118498,118500,118502],{"class":270,"line":788},[268,118499,37837],{"class":274},[268,118501,111928],{"class":278},[268,118503,283],{"class":282},[268,118505,118506,118508,118511,118513,118515,118517,118519,118521,118523],{"class":270,"line":1951},[268,118507,80826],{"class":274},[268,118509,118510],{"class":282}," greeting ",[268,118512,302],{"class":274},[268,118514,114407],{"class":278},[268,118516,84903],{"class":274},[268,118518,44539],{"class":278},[268,118520,622],{"class":282},[268,118522,4436],{"class":289},[268,118524,628],{"class":282},[268,118526,118527,118530],{"class":270,"line":8955},[268,118528,118529],{"class":278},"    print_owned",[268,118531,118532],{"class":282},"(greeting);\n",[268,118534,118535,118537,118539,118542],{"class":270,"line":8966},[268,118536,111958],{"class":278},[268,118538,622],{"class":282},[268,118540,118541],{"class":289},"\"{greeting}\"",[268,118543,628],{"class":282},[268,118545,118546],{"class":270,"line":8974},[268,118547,314],{"class":282},[23,118549,118551,118577,118585,118598],{"className":118550},[26],[28,118552,118554,118556,118557,118559,118560,118563,118564,118566,118567,118569,118570,118572,118573,118576],{"className":118553},[31],[33,118555],{"disabled":35,"type":36}," It fails to compile — passing ",[39,118558,42893],{}," by value into ",[39,118561,118562],{},"print_owned"," moves ownership of the ",[39,118565,16721],{}," into the function; ",[39,118568,42893],{}," is no longer valid in ",[39,118571,111207],{}," afterward, so the second ",[39,118574,118575],{},"println!"," triggers a \"use of moved value\" error.",[28,118578,118580,111978,118582,118584],{"className":118579},[31],[33,118581],{"disabled":35,"type":36},[39,118583,46280],{}," twice.",[28,118586,118588,117069,118590,118592,118593,118595,118596,37442],{"className":118587},[31],[33,118589],{"disabled":35,"type":36},[39,118591,42893],{}," is empty (",[39,118594,3294],{},") by the time the second ",[39,118597,118575],{},[28,118599,118601,117747,118603,118605],{"className":118600},[31],[33,118602],{"disabled":35,"type":36},[39,118604,16721],{}," cannot be passed as a function argument at all.",[66,118607,118608,118610,118621],{},[69,118609,71],{},[73,118611,118612,118614,118615,118617,118618,118620],{},[76,118613,78],{}," A — It fails to compile — passing ",[39,118616,42893],{}," by value moves it, and the second ",[39,118619,118575],{}," uses a moved value.",[73,118622,118623,355,118625,118627,118628,118630,118631,118633,118634,3990,118636,2018,118638,118640,118641,118643,118644,118647,118648,118650,118651,118653],{},[76,118624,84],{},[39,118626,16721],{}," is a heap-allocated, non-",[39,118629,114164],{}," type, so passing it by value into ",[39,118632,118562],{}," transfers ownership into the function's parameter ",[39,118635,25393],{},[39,118637,42893],{},[39,118639,111207],{}," is left uninitialized from the compiler's point of view, and any later use of it (the second ",[39,118642,118575],{},") is rejected at compile time with ",[39,118645,118646],{},"error[E0382]: use of moved value: 'greeting'",". This is a basic, unavoidable consequence of by-value parameter passing for owned types, not silent data loss (rules out C — the value isn't emptied at runtime, the code simply never runs because it doesn't compile) and ",[39,118649,16721],{}," is of course a perfectly ordinary argument type otherwise (rules out D). Contrast this with a ",[39,118652,114164],{}," type in the next question.",[15,118655,118656,118663,118745,118803],{"language":111909},[18,118657,118659,118660,118662],{"id":118658},"q11-unlike-the-string-example-what-happens-here","Q11. Unlike the ",[39,118661,16721],{}," example, what happens here?",[257,118664,118665],{"language":111909},[260,118666,118668],{"className":111918,"code":118667,"language":111909,"meta":264,"style":264},"fn print_value(n: i32) {\n    println!(\"{n}\");\n}\n\nfn main() {\n    let count = 5;\n    print_value(count);\n    println!(\"{count}\");\n}\n",[39,118669,118670,118685,118696,118700,118704,118712,118724,118731,118741],{"__ignoreMap":264},[268,118671,118672,118674,118677,118679,118681,118683],{"class":270,"line":271},[268,118673,37837],{"class":274},[268,118675,118676],{"class":278}," print_value",[268,118678,117984],{"class":282},[268,118680,10728],{"class":274},[268,118682,113794],{"class":278},[268,118684,1235],{"class":282},[268,118686,118687,118689,118691,118694],{"class":270,"line":286},[268,118688,111958],{"class":278},[268,118690,622],{"class":282},[268,118692,118693],{"class":289},"\"{n}\"",[268,118695,628],{"class":282},[268,118697,118698],{"class":270,"line":296},[268,118699,314],{"class":282},[268,118701,118702],{"class":270,"line":311},[268,118703,5033],{"emptyLinePlaceholder":35},[268,118705,118706,118708,118710],{"class":270,"line":788},[268,118707,37837],{"class":274},[268,118709,111928],{"class":278},[268,118711,283],{"class":282},[268,118713,118714,118716,118718,118720,118722],{"class":270,"line":1951},[268,118715,80826],{"class":274},[268,118717,10091],{"class":282},[268,118719,302],{"class":274},[268,118721,2387],{"class":305},[268,118723,293],{"class":282},[268,118725,118726,118729],{"class":270,"line":8955},[268,118727,118728],{"class":278},"    print_value",[268,118730,10157],{"class":282},[268,118732,118733,118735,118737,118739],{"class":270,"line":8966},[268,118734,111958],{"class":278},[268,118736,622],{"class":282},[268,118738,113119],{"class":289},[268,118740,628],{"class":282},[268,118742,118743],{"class":270,"line":8974},[268,118744,314],{"class":282},[23,118746,118748,118757,118772,118791],{"className":118747},[26],[28,118749,118751,118753,118754,118756],{"className":118750},[31],[33,118752],{"disabled":35,"type":36}," It fails to compile with the same \"use of moved value\" error as passing a ",[39,118755,16721],{}," by value.",[28,118758,118760,117069,118762,7083,118764,2018,118766,118768,118769,118771],{"className":118759},[31],[33,118761],{"disabled":35,"type":36},[39,118763,10191],{},[39,118765,3307],{},[39,118767,111207],{}," after the call, since ownership still transfers even for ",[39,118770,114164],{}," types.",[28,118773,118775,111978,118777,118779,118780,118782,118783,118785,118786,2018,118788,118790],{"className":118774},[31],[33,118776],{"disabled":35,"type":36},[39,118778,2429],{}," twice — ",[39,118781,113860],{}," implements the ",[39,118784,114164],{}," trait, so passing it by value copies the bits into the function; the original ",[39,118787,10191],{},[39,118789,111207],{}," remains valid and usable afterward.",[28,118792,118794,118796,118797,118799,118800,118802],{"className":118793},[31],[33,118795],{"disabled":35,"type":36}," It compiles only because ",[39,118798,10191],{}," happens to be a small value; larger integers like ",[39,118801,116825],{}," would move instead.",[66,118804,118805,118807,118819],{},[69,118806,71],{},[73,118808,118809,118811,118812,118814,118815,830,118817,462],{},[76,118810,78],{}," C — It compiles and prints ",[39,118813,2429],{}," twice, since ",[39,118816,113860],{},[39,118818,114164],{},[73,118820,118821,118823,118824,42,118826,42,118828,137,118830,118832,118833,118835,118836,118838,118839,118841,118842,118844,118845,118847,118848,118850,118851,26085,118853,118855],{},[76,118822,84],{}," Simple, fixed-size scalar types like ",[39,118825,113860],{},[39,118827,89412],{},[39,118829,115095],{},[39,118831,115196],{}," implement the ",[39,118834,114164],{}," trait, which changes what \"passing by value\" means: instead of moving ownership (Q10), the bits are duplicated, leaving both the original ",[39,118837,10191],{}," and the function's local ",[39,118840,4599],{}," as independently valid, usable values. This directly contrasts with the ",[39,118843,16721],{}," case — the difference is entirely about the type implementing ",[39,118846,114164],{},", not about the specific value (rules out D — ",[39,118849,116825],{}," is just as ",[39,118852,114164],{},[39,118854,113860],{},"; magnitude is irrelevant, only the type matters) and there's no ownership transfer to \"reset\" the original to a default (rules out B).",[15,118857,118858,118871,118986,119039],{"language":111909},[18,118859,56351,118861,118864,118865,118867,118868,1685],{"id":118860},"q12-bail-is-declared-to-return-the-never-type-and-always-panics-what-does-this-let-the-compiler-do-with-classify",[39,118862,118863],{},"bail"," is declared to return ",[39,118866,5418],{}," (the \"never\" type) and always panics. What does this let the compiler do with ",[39,118869,118870],{},"classify",[257,118872,118873],{"language":111909},[260,118874,118876],{"className":111918,"code":118875,"language":111909,"meta":264,"style":264},"fn bail(msg: &str) -> ! {\n    panic!(\"{msg}\");\n}\n\nfn classify(n: i32) -> i32 {\n    if n >= 0 {\n        n\n    } else {\n        bail(\"negative numbers are not supported\")\n    }\n}\n",[39,118877,118878,118901,118912,118916,118920,118941,118953,118958,118966,118978,118982],{"__ignoreMap":264},[268,118879,118880,118882,118885,118887,118889,118891,118893,118895,118897,118899],{"class":270,"line":271},[268,118881,37837],{"class":274},[268,118883,118884],{"class":278}," bail",[268,118886,115946],{"class":282},[268,118888,10728],{"class":274},[268,118890,115951],{"class":274},[268,118892,17109],{"class":278},[268,118894,6131],{"class":282},[268,118896,113308],{"class":274},[268,118898,5384],{"class":274},[268,118900,9914],{"class":282},[268,118902,118903,118906,118908,118910],{"class":270,"line":286},[268,118904,118905],{"class":278},"    panic!",[268,118907,622],{"class":282},[268,118909,115968],{"class":289},[268,118911,628],{"class":282},[268,118913,118914],{"class":270,"line":296},[268,118915,314],{"class":282},[268,118917,118918],{"class":270,"line":311},[268,118919,5033],{"emptyLinePlaceholder":35},[268,118921,118922,118924,118927,118929,118931,118933,118935,118937,118939],{"class":270,"line":788},[268,118923,37837],{"class":274},[268,118925,118926],{"class":278}," classify",[268,118928,117984],{"class":282},[268,118930,10728],{"class":274},[268,118932,113794],{"class":278},[268,118934,6131],{"class":282},[268,118936,113308],{"class":274},[268,118938,113794],{"class":278},[268,118940,9914],{"class":282},[268,118942,118943,118945,118947,118949,118951],{"class":270,"line":1951},[268,118944,9686],{"class":274},[268,118946,13355],{"class":282},[268,118948,6779],{"class":274},[268,118950,5728],{"class":305},[268,118952,9914],{"class":282},[268,118954,118955],{"class":270,"line":8955},[268,118956,118957],{"class":282},"        n\n",[268,118959,118960,118962,118964],{"class":270,"line":8966},[268,118961,12485],{"class":282},[268,118963,9884],{"class":274},[268,118965,9914],{"class":282},[268,118967,118968,118971,118973,118976],{"class":270,"line":8974},[268,118969,118970],{"class":278},"        bail",[268,118972,622],{"class":282},[268,118974,118975],{"class":289},"\"negative numbers are not supported\"",[268,118977,20702],{"class":282},[268,118979,118980],{"class":270,"line":8985},[268,118981,11972],{"class":282},[268,118983,118984],{"class":270,"line":8990},[268,118985,314],{"class":282},[23,118987,118989,119003,119017,119027],{"className":118988},[26],[28,118990,118992,118994,118995,118997,118998,186,119000,119002],{"className":118991},[31],[33,118993],{"disabled":35,"type":36}," It fails to compile — the two branches of the ",[39,118996,2179],{}," return different types (",[39,118999,113860],{},[39,119001,5418],{},"), which normally must match exactly.",[28,119004,119006,117697,119008,119010,119011,119013,119014,119016],{"className":119005},[31],[33,119007],{"disabled":35,"type":36},[39,119009,5418],{}," is a special type that coerces to whatever type is expected in context (here ",[39,119012,113860],{},"), because a call to a function returning ",[39,119015,5418],{}," never actually produces a value to be wrong about, so it can stand in for any branch type.",[28,119018,119020,119022,119023,119026],{"className":119019},[31],[33,119021],{"disabled":35,"type":36}," It compiles, but only because ",[39,119024,119025],{},"panic!"," is a macro exempt from normal type-checking rules.",[28,119028,119030,119032,119033,119035,119036,119038],{"className":119029},[31],[33,119031],{"disabled":35,"type":36}," It fails to compile unless ",[39,119034,118863],{},"'s return type is changed to match ",[39,119037,113860],{}," exactly.",[66,119040,119041,119043,119051],{},[69,119042,71],{},[73,119044,119045,119047,119048,119050],{},[76,119046,78],{}," B — It compiles — ",[39,119049,5418],{}," coerces to whatever type is expected in context.",[73,119052,119053,355,119055,355,119057,119059,119060,119062,119063,446,119065,99,119067,119069,119070,119072,119073,446,119075,119077,119078,119081,119082,119084,119085,119087,119088,119090,119091,119094,119095,6232],{},[76,119054,84],{},[76,119056,930],{},[39,119058,5418],{},", the \"never\" type, marks a function (or expression) that never returns control to its caller — it always panics, exits the process, or loops forever. Because a diverging call genuinely never produces a value, the compiler is free to let ",[39,119061,5418],{}," unify with any type an ",[39,119064,2179],{},[39,119066,9884],{},[39,119068,116378],{}," branch needs, here ",[39,119071,113860],{},", since there's no risk of a mismatched value actually surfacing at runtime. This is a deliberate special case, not a general relaxation of the rule that ",[39,119074,2179],{},[39,119076,9884],{}," branches must agree in type (rules out A, which describes the ",[104,119079,119080],{},"normal"," rule that ",[39,119083,5418],{}," is specifically exempt from) — and it has nothing to do with ",[39,119086,119025],{}," being a macro (rules out C; the special-casing lives in the type system's treatment of ",[39,119089,5418],{}," itself, and applies equally to any ",[39,119092,119093],{},"-> !"," function, not just ones using ",[39,119096,119025],{},[15,119098,119099,119106,119235,119293],{"language":111909},[18,119100,119102,119103,119105],{"id":119101},"q13-what-does-this-program-print-and-what-does-it-demonstrate-about-plain-fn-items","Q13. What does this program print, and what does it demonstrate about plain ",[39,119104,37837],{}," items?",[257,119107,119108],{"language":111909},[260,119109,119111],{"className":111918,"code":119110,"language":111909,"meta":264,"style":264},"fn square(x: i32) -> i32 {\n    x * x\n}\n\nfn apply(f: fn(i32) -> i32, value: i32) -> i32 {\n    f(value)\n}\n\nfn main() {\n    println!(\"{}\", apply(square, 4));\n}\n",[39,119112,119113,119133,119141,119145,119149,119188,119196,119200,119204,119212,119231],{"__ignoreMap":264},[268,119114,119115,119117,119119,119121,119123,119125,119127,119129,119131],{"class":270,"line":271},[268,119116,37837],{"class":274},[268,119118,31438],{"class":278},[268,119120,117178],{"class":282},[268,119122,10728],{"class":274},[268,119124,113794],{"class":278},[268,119126,6131],{"class":282},[268,119128,113308],{"class":274},[268,119130,113794],{"class":278},[268,119132,9914],{"class":282},[268,119134,119135,119137,119139],{"class":270,"line":286},[268,119136,111947],{"class":282},[268,119138,6134],{"class":274},[268,119140,93160],{"class":282},[268,119142,119143],{"class":270,"line":296},[268,119144,314],{"class":282},[268,119146,119147],{"class":270,"line":311},[268,119148,5033],{"emptyLinePlaceholder":35},[268,119150,119151,119153,119156,119159,119161,119163,119165,119167,119169,119171,119173,119176,119178,119180,119182,119184,119186],{"class":270,"line":788},[268,119152,37837],{"class":274},[268,119154,119155],{"class":278}," apply",[268,119157,119158],{"class":282},"(f",[268,119160,10728],{"class":274},[268,119162,37900],{"class":274},[268,119164,622],{"class":282},[268,119166,113860],{"class":278},[268,119168,6131],{"class":282},[268,119170,113308],{"class":274},[268,119172,113794],{"class":278},[268,119174,119175],{"class":282},", value",[268,119177,10728],{"class":274},[268,119179,113794],{"class":278},[268,119181,6131],{"class":282},[268,119183,113308],{"class":274},[268,119185,113794],{"class":278},[268,119187,9914],{"class":282},[268,119189,119190,119193],{"class":270,"line":1951},[268,119191,119192],{"class":278},"    f",[268,119194,119195],{"class":282},"(value)\n",[268,119197,119198],{"class":270,"line":8955},[268,119199,314],{"class":282},[268,119201,119202],{"class":270,"line":8966},[268,119203,5033],{"emptyLinePlaceholder":35},[268,119205,119206,119208,119210],{"class":270,"line":8974},[268,119207,37837],{"class":274},[268,119209,111928],{"class":278},[268,119211,283],{"class":282},[268,119213,119214,119216,119218,119220,119222,119224,119227,119229],{"class":270,"line":8985},[268,119215,111958],{"class":278},[268,119217,622],{"class":282},[268,119219,113830],{"class":289},[268,119221,42],{"class":282},[268,119223,34637],{"class":278},[268,119225,119226],{"class":282},"(square, ",[268,119228,15049],{"class":305},[268,119230,4818],{"class":282},[268,119232,119233],{"class":270,"line":8990},[268,119234,314],{"class":282},[23,119236,119238,119247,119259,119276],{"className":119237},[26],[28,119239,119241,119243,119244,119246],{"className":119240},[31],[33,119242],{"disabled":35,"type":36}," Compile error — ",[39,119245,31493],{}," is a function, not a value, and cannot be passed as an argument without wrapping it in a closure first.",[28,119248,119250,119243,119252,119254,119255,119258],{"className":119249},[31],[33,119251],{"disabled":35,"type":36},[39,119253,34637],{},"'s parameter type ",[39,119256,119257],{},"fn(i32) -> i32"," is invalid syntax; function pointer types don't exist in Rust.",[28,119260,119262,355,119264,119266,119267,119269,119270,62857,119272,119275],{"className":119261},[31],[33,119263],{"disabled":35,"type":36},[39,119265,84186],{}," — but only because ",[39,119268,34637],{}," implicitly converts ",[39,119271,31493],{},[39,119273,119274],{},"Box\u003Cdyn Fn(i32) -> i32>"," behind the scenes.",[28,119277,119279,355,119281,119283,119284,119286,119287,119289,119290,119292],{"className":119278},[31],[33,119280],{"disabled":35,"type":36},[39,119282,84186],{}," — a plain ",[39,119285,37837],{}," item like ",[39,119288,31493],{}," coerces to a function pointer of type ",[39,119291,119257],{},", a distinct concrete type from closures, and can be passed around, stored in variables, and called like any other value.",[66,119294,119295,119297,119306],{},[69,119296,71],{},[73,119298,119299,6901,119301,3990,119303,119305],{},[76,119300,78],{},[39,119302,84186],{},[39,119304,31493],{}," coerces to a function pointer and is called like any other value.",[73,119307,119308,119310,119311,119313,119314,3990,119317,6204,119320,119323,119324,446,119327,446,119330,119333,119334,119336],{},[76,119309,84],{}," A named ",[39,119312,37837],{}," item can be referenced by its bare name and coerces to the concrete function-pointer type ",[39,119315,119316],{},"fn(ArgTypes) -> RetType",[39,119318,119319],{},"apply(square, 4)",[39,119321,119322],{},"square(4) = 16",". This is a real, lightweight, zero-allocation value type distinct from the ",[39,119325,119326],{},"Fn",[39,119328,119329],{},"FnMut",[39,119331,119332],{},"FnOnce"," closure traits (covered separately later) — no boxing or dynamic dispatch is involved here (rules out C), and function pointer types are entirely ordinary, valid Rust syntax used throughout callback-style APIs (rules out B). Functions absolutely are first-class values in this sense — passing ",[39,119335,31493],{}," directly, with no closure wrapper needed, is exactly the point (rules out A).",[15,119338,119339,119343,119464,119519],{"language":111909},[18,119340,119342],{"id":119341},"q14-what-does-this-program-print","Q14. What does this program print?",[257,119344,119345],{"language":111909},[260,119346,119348],{"className":111918,"code":119347,"language":111909,"meta":264,"style":264},"const fn double(x: usize) -> usize {\n    x * 2\n}\n\nconst LEN: usize = double(4);\n\nfn main() {\n    let buffer = [0u8; LEN];\n    println!(\"{}\", buffer.len());\n}\n",[39,119349,119350,119372,119380,119384,119388,119409,119413,119421,119443,119460],{"__ignoreMap":264},[268,119351,119352,119354,119356,119358,119360,119362,119364,119366,119368,119370],{"class":270,"line":271},[268,119353,243],{"class":274},[268,119355,37900],{"class":274},[268,119357,41156],{"class":278},[268,119359,117178],{"class":282},[268,119361,10728],{"class":274},[268,119363,113286],{"class":278},[268,119365,6131],{"class":282},[268,119367,113308],{"class":274},[268,119369,113286],{"class":278},[268,119371,9914],{"class":282},[268,119373,119374,119376,119378],{"class":270,"line":286},[268,119375,111947],{"class":282},[268,119377,6134],{"class":274},[268,119379,85329],{"class":305},[268,119381,119382],{"class":270,"line":296},[268,119383,314],{"class":282},[268,119385,119386],{"class":270,"line":311},[268,119387,5033],{"emptyLinePlaceholder":35},[268,119389,119390,119392,119395,119397,119399,119401,119403,119405,119407],{"class":270,"line":788},[268,119391,243],{"class":274},[268,119393,119394],{"class":305}," LEN",[268,119396,10728],{"class":274},[268,119398,113286],{"class":278},[268,119400,616],{"class":274},[268,119402,41156],{"class":278},[268,119404,622],{"class":282},[268,119406,15049],{"class":305},[268,119408,628],{"class":282},[268,119410,119411],{"class":270,"line":1951},[268,119412,5033],{"emptyLinePlaceholder":35},[268,119414,119415,119417,119419],{"class":270,"line":8955},[268,119416,37837],{"class":274},[268,119418,111928],{"class":278},[268,119420,283],{"class":282},[268,119422,119423,119425,119428,119430,119432,119434,119436,119438,119441],{"class":270,"line":8966},[268,119424,80826],{"class":274},[268,119426,119427],{"class":282}," buffer ",[268,119429,302],{"class":274},[268,119431,8710],{"class":282},[268,119433,3307],{"class":305},[268,119435,114808],{"class":278},[268,119437,2272],{"class":282},[268,119439,119440],{"class":305},"LEN",[268,119442,8737],{"class":282},[268,119444,119445,119447,119449,119451,119454,119456,119458],{"class":270,"line":8974},[268,119446,111958],{"class":278},[268,119448,622],{"class":282},[268,119450,113830],{"class":289},[268,119452,119453],{"class":282},", buffer",[268,119455,462],{"class":274},[268,119457,112611],{"class":278},[268,119459,8174],{"class":282},[268,119461,119462],{"class":270,"line":8985},[268,119463,314],{"class":282},[23,119465,119467,119487,119496,119508],{"className":119466},[26],[28,119468,119470,355,119472,119474,119475,26085,119477,119479,119480,119483,119484,119486],{"className":119469},[31],[33,119471],{"disabled":35,"type":36},[39,119473,10664],{}," — marking ",[39,119476,41177],{},[39,119478,113374],{}," makes it eligible for compile-time evaluation, so ",[39,119481,119482],{},"double(4)"," can be used to compute ",[39,119485,119440],{},", which in turn can be used as a fixed array length.",[28,119488,119490,119492,119493,119495],{"className":119489},[31],[33,119491],{"disabled":35,"type":36}," Compile error — function calls are never allowed in a ",[39,119494,243],{}," initializer, only literal values.",[28,119497,119499,119243,119501,119503,119504,119507],{"className":119498},[31],[33,119500],{"disabled":35,"type":36},[39,119502,41177],{}," would need to be ",[39,119505,119506],{},"unsafe fn"," to be evaluated at compile time.",[28,119509,119511,355,119513,119515,119516,119518],{"className":119510},[31],[33,119512],{"disabled":35,"type":36},[39,119514,10664],{},", but only at runtime — ",[39,119517,113374],{}," is purely a documentation hint and has no effect on when the function actually executes.",[66,119520,119521,119523,119535],{},[69,119522,71],{},[73,119524,119525,3459,119527,3990,119529,119531,119532,119534],{},[76,119526,78],{},[39,119528,10664],{},[39,119530,113374],{}," makes ",[39,119533,41177],{}," usable in compile-time contexts like an array length.",[73,119536,119537,355,119539,21599,119541,119543,119544,119546,119547,119549,119550,119553,119554,119556,119557,119559,119560,119563,119564,6131,119566,119568,119569,2758,119571,119573,119574,119576,119577,119579,119580,119582,119583,119585],{},[76,119538,84],{},[76,119540,438],{},[39,119542,243],{}," keyword on a function is what makes it eligible for evaluation during compilation, not just at runtime — ",[39,119545,119482],{}," can appear in a ",[39,119548,243],{}," initializer and inside ",[39,119551,119552],{},"[0u8; LEN]","'s array-length position because ",[39,119555,119440],{}," is itself fully resolved to ",[39,119558,10664],{}," before codegen. An ",[104,119561,119562],{},"ordinary"," (non-",[39,119565,243],{},[39,119567,37837],{}," genuinely cannot be called from a const context (that restriction is real — it just doesn't apply here, which is what rules out B, since it describes plain ",[39,119570,37837],{},[39,119572,113374],{},"). There's no ",[39,119575,112499],{}," requirement for compile-time evaluation (rules out C — ",[39,119578,113374],{}," is fully safe), and ",[39,119581,113374],{}," is far from cosmetic: it directly controls whether the function ",[104,119584,11176],{}," run at compile time when the context demands it, though it may still be called normally at runtime too (rules out D).",[15,119587,119588,119603,119795,119853],{"language":111909},[18,119589,119591,119592,119595,119596,119599,119600,1685],{"id":119590},"q15-why-does-largest-require-the-t-partialord-bound-instead-of-being-written-as-fn-largesttlist-t-t","Q15. Why does ",[39,119593,119594],{},"largest"," require the ",[39,119597,119598],{},"T: PartialOrd"," bound instead of being written as ",[39,119601,119602],{},"fn largest\u003CT>(list: &[T]) -> T",[257,119604,119605],{"language":111909},[260,119606,119608],{"className":111918,"code":119607,"language":111909,"meta":264,"style":264},"fn largest\u003CT: PartialOrd + Copy>(list: &[T]) -> T {\n    let mut largest = list[0];\n    for &item in list {\n        if item > largest {\n            largest = item;\n        }\n    }\n    largest\n}\n\nfn main() {\n    let numbers = vec![34, 50, 25, 100, 65];\n    println!(\"{}\", largest(&numbers));\n}\n",[39,119609,119610,119652,119670,119684,119697,119707,119712,119716,119721,119725,119729,119737,119772,119791],{"__ignoreMap":264},[268,119611,119612,119614,119617,119619,119621,119623,119626,119628,119631,119634,119636,119638,119640,119642,119645,119647,119650],{"class":270,"line":271},[268,119613,37837],{"class":274},[268,119615,119616],{"class":278}," largest",[268,119618,1076],{"class":282},[268,119620,102486],{"class":278},[268,119622,10728],{"class":274},[268,119624,119625],{"class":278}," PartialOrd",[268,119627,3350],{"class":274},[268,119629,119630],{"class":278}," Copy",[268,119632,119633],{"class":282},">(list",[268,119635,10728],{"class":274},[268,119637,115951],{"class":274},[268,119639,15175],{"class":282},[268,119641,102486],{"class":278},[268,119643,119644],{"class":282},"]) ",[268,119646,113308],{"class":274},[268,119648,119649],{"class":278}," T",[268,119651,9914],{"class":282},[268,119653,119654,119656,119658,119661,119663,119666,119668],{"class":270,"line":286},[268,119655,80826],{"class":274},[268,119657,113071],{"class":274},[268,119659,119660],{"class":282}," largest ",[268,119662,302],{"class":274},[268,119664,119665],{"class":282}," list[",[268,119667,3307],{"class":305},[268,119669,8737],{"class":282},[268,119671,119672,119674,119676,119679,119681],{"class":270,"line":296},[268,119673,80840],{"class":274},[268,119675,115951],{"class":274},[268,119677,119678],{"class":282},"item ",[268,119680,20749],{"class":274},[268,119682,119683],{"class":282}," list {\n",[268,119685,119686,119689,119692,119694],{"class":270,"line":311},[268,119687,119688],{"class":274},"        if",[268,119690,119691],{"class":282}," item ",[268,119693,6435],{"class":274},[268,119695,119696],{"class":282}," largest {\n",[268,119698,119699,119702,119704],{"class":270,"line":788},[268,119700,119701],{"class":282},"            largest ",[268,119703,302],{"class":274},[268,119705,119706],{"class":282}," item;\n",[268,119708,119709],{"class":270,"line":1951},[268,119710,119711],{"class":282},"        }\n",[268,119713,119714],{"class":270,"line":8955},[268,119715,11972],{"class":282},[268,119717,119718],{"class":270,"line":8966},[268,119719,119720],{"class":282},"    largest\n",[268,119722,119723],{"class":270,"line":8974},[268,119724,314],{"class":282},[268,119726,119727],{"class":270,"line":8985},[268,119728,5033],{"emptyLinePlaceholder":35},[268,119730,119731,119733,119735],{"class":270,"line":8990},[268,119732,37837],{"class":274},[268,119734,111928],{"class":278},[268,119736,283],{"class":282},[268,119738,119739,119741,119744,119746,119748,119750,119753,119755,119757,119759,119761,119763,119765,119767,119770],{"class":270,"line":8997},[268,119740,80826],{"class":274},[268,119742,119743],{"class":282}," numbers ",[268,119745,302],{"class":274},[268,119747,112905],{"class":278},[268,119749,15175],{"class":282},[268,119751,119752],{"class":305},"34",[268,119754,42],{"class":282},[268,119756,32109],{"class":305},[268,119758,42],{"class":282},[268,119760,31527],{"class":305},[268,119762,42],{"class":282},[268,119764,13912],{"class":305},[268,119766,42],{"class":282},[268,119768,119769],{"class":305},"65",[268,119771,8737],{"class":282},[268,119773,119774,119776,119778,119780,119782,119784,119786,119788],{"class":270,"line":9002},[268,119775,111958],{"class":278},[268,119777,622],{"class":282},[268,119779,113830],{"class":289},[268,119781,42],{"class":282},[268,119783,119594],{"class":278},[268,119785,622],{"class":282},[268,119787,85350],{"class":274},[268,119789,119790],{"class":282},"numbers));\n",[268,119792,119793],{"class":270,"line":14676},[268,119794,314],{"class":282},[23,119796,119798,119813,119835,119844],{"className":119797},[26],[28,119799,119801,119803,119804,119807,119808,119810,119811,462],{"className":119800},[31],[33,119802],{"disabled":35,"type":36}," It doesn't actually need the bound — ",[39,119805,119806],{},"PartialOrd"," is inferred automatically for any ",[39,119809,102486],{}," used with ",[39,119812,6435],{},[28,119814,119816,119818,119819,119821,119822,119824,119825,119827,119828,119830,119831,119834],{"className":119815},[31],[33,119817],{"disabled":35,"type":36}," Without a bound, ",[39,119820,102486],{}," is completely unconstrained, and the compiler has no guarantee that the ",[39,119823,6435],{}," operator (which requires ",[39,119826,119806],{},") is implemented for whatever concrete type ",[39,119829,102486],{}," ends up being — the bound is what makes ",[39,119832,119833],{},"item > largest"," valid to even write.",[28,119836,119838,119840,119841,119843],{"className":119837},[31],[33,119839],{"disabled":35,"type":36}," The bound is only cosmetic documentation; removing it would still compile since ",[39,119842,6435],{}," works on all types by default.",[28,119845,119847,119849,119850,119852],{"className":119846},[31],[33,119848],{"disabled":35,"type":36}," The bound is required only because the list contains integers; generic functions over ",[39,119851,16721],{}," or custom structs never need it.",[66,119854,119855,119857,119867],{},[69,119856,71],{},[73,119858,119859,119861,119862,119864,119865,462],{},[76,119860,78],{}," B — Without the bound, the compiler can't guarantee ",[39,119863,6435],{}," is implemented for ",[39,119866,102486],{},[73,119868,119869,117935,119871,119873,119874,119876,119877,119879,119880,119882,119883,119885,119886,119888,119889,119891,119892,119894,119895,355,119897,119899,119900,119902,119903,119905,119906,462],{},[76,119870,84],{},[39,119872,102486],{}," with no bounds could be instantiated with ",[104,119875,21375],{}," type, including ones with no comparison operators defined at all — so the compiler must reject ",[39,119878,119833],{}," unless the signature itself promises that whatever ",[39,119881,102486],{}," is, it supports ",[39,119884,119806],{}," (which is what ",[39,119887,6435],{}," desugars to). This is true regardless of which concrete type ",[39,119890,119594],{}," is eventually called with, including integers (rules out D, which mistakenly treats the requirement as integer-specific) — the same signature is called here with ",[39,119893,113860],{}," but the bound is what makes it work generically for ",[104,119896,21375],{},[39,119898,119806],{}," type. Nothing about trait bounds is automatic or optional cosmetic decoration (rules out A and C) — omitting ",[39,119901,119806],{}," produces a real compile error the moment ",[39,119904,6435],{}," is used on an unconstrained ",[39,119907,102486],{},[15,119909,119910,119922,119965],{},[18,119911,119913,119914,119917,119918,119921],{"id":119912},"q16-a-function-create_user-conceptually-wants-an-optional-nickname-that-defaults-to-the-users-real-name-when-not-provided-rust-has-no-default-argument-syntax-whats-the-idiomatic-way-to-model-this","Q16. A function ",[39,119915,119916],{},"create_user"," conceptually wants an optional ",[39,119919,119920],{},"nickname"," that defaults to the user's real name when not provided. Rust has no default-argument syntax. What's the idiomatic way to model this?",[23,119923,119925,119934,119946,119959],{"className":119924},[26],[28,119926,119928,119930,119931,119933],{"className":119927},[31],[33,119929],{"disabled":35,"type":36}," Overload ",[39,119932,119916],{}," with two versions, one taking a nickname and one without, and rely on the compiler to disambiguate by call site.",[28,119935,119937,101465,119939,119942,119943,119945],{"className":119936},[31],[33,119938],{"disabled":35,"type":36},[39,119940,119941],{},"nickname: &str"," and require every caller to pass an empty string ",[39,119944,3294],{}," to mean \"no nickname.\"",[28,119947,119949,101465,119951,119954,119955,119958],{"className":119948},[31],[33,119950],{"disabled":35,"type":36},[39,119952,119953],{},"nickname: Option\u003C&str>"," (or provide a companion function like ",[39,119956,119957],{},"create_user_with_nickname","), and resolve the fallback to the real name explicitly inside the function body — making the \"no nickname supplied\" case an explicit, visible part of the signature and logic rather than hidden default-argument magic.",[28,119960,119962,119964],{"className":119961},[31],[33,119963],{"disabled":35,"type":36}," Use a macro to generate the missing default value at compile time, since only macros can simulate default arguments in Rust.",[66,119966,119967,119969,119978],{},[69,119968,71],{},[73,119970,119971,119973,119974,119977],{},[76,119972,78],{}," C — Accept ",[39,119975,119976],{},"Option\u003C&str>"," (or a companion function) and resolve the fallback explicitly.",[73,119979,119980,355,119982,119984,119985,119987,119988,99,119990,119993,119994,119997,119998,120000,120001,120003],{},[76,119981,84],{},[76,119983,930],{}," since Rust has neither default parameters nor overloading (Q8, Q9), the idiomatic way to express \"this value is optional, with a computed fallback\" is ",[39,119986,116806],{}," in the signature — the caller passes ",[39,119989,90944],{},[39,119991,119992],{},"Some(value)"," explicitly, and the function body handles both cases visibly, typically with ",[39,119995,119996],{},".unwrap_or_else(...)",". Overloading (A) isn't available in Rust at all, as established in Q8. An empty-string sentinel (B) is a classic anti-pattern: it conflates \"no value was given\" with \"a valid-looking but empty value,\" and nothing stops a caller from passing ",[39,119999,3294],{}," by mistake with a completely different intent. A macro (D) is unnecessary machinery for a problem ",[39,120002,116806],{}," already solves cleanly.",[15,120005,120006,120022,120113,120173],{"language":111909},[18,120007,120009,120010,120012,120013,120015,120016,120019,120020,1685],{"id":120008},"q17-both-match-arms-here-have-to-produce-a-value-of-the-same-type-for-the-match-to-type-check-why-does-this-compile-even-though-the-err-arms-panic-never-produces-an-i32","Q17. Both match arms here have to produce a value of the same type for the ",[39,120011,116378],{}," to type-check. Why does this compile even though the ",[39,120014,116301],{}," arm's ",[39,120017,120018],{},"panic!(...)"," never produces an ",[39,120021,113860],{},[257,120023,120024],{"language":111909},[260,120025,120027],{"className":111918,"code":120026,"language":111909,"meta":264,"style":264},"fn parse_or_die(input: &str) -> i32 {\n    match input.parse::\u003Ci32>() {\n        Ok(n) => n,\n        Err(_) => panic!(\"invalid number: {input}\"),\n    }\n}\n",[39,120028,120029,120052,120072,120085,120105,120109],{"__ignoreMap":264},[268,120030,120031,120033,120036,120038,120040,120042,120044,120046,120048,120050],{"class":270,"line":271},[268,120032,37837],{"class":274},[268,120034,120035],{"class":278}," parse_or_die",[268,120037,118182],{"class":282},[268,120039,10728],{"class":274},[268,120041,115951],{"class":274},[268,120043,17109],{"class":278},[268,120045,6131],{"class":282},[268,120047,113308],{"class":274},[268,120049,113794],{"class":278},[268,120051,9914],{"class":282},[268,120053,120054,120057,120059,120061,120063,120065,120067,120069],{"class":270,"line":286},[268,120055,120056],{"class":274},"    match",[268,120058,17937],{"class":282},[268,120060,462],{"class":274},[268,120062,22274],{"class":278},[268,120064,84903],{"class":274},[268,120066,1076],{"class":282},[268,120068,113860],{"class":278},[268,120070,120071],{"class":282},">() {\n",[268,120073,120074,120077,120080,120082],{"class":270,"line":296},[268,120075,120076],{"class":278},"        Ok",[268,120078,120079],{"class":282},"(n) ",[268,120081,9414],{"class":274},[268,120083,120084],{"class":282}," n,\n",[268,120086,120087,120090,120093,120095,120098,120100,120103],{"class":270,"line":311},[268,120088,120089],{"class":278},"        Err",[268,120091,120092],{"class":282},"(_) ",[268,120094,9414],{"class":274},[268,120096,120097],{"class":278}," panic!",[268,120099,622],{"class":282},[268,120101,120102],{"class":289},"\"invalid number: {input}\"",[268,120104,17159],{"class":282},[268,120106,120107],{"class":270,"line":788},[268,120108,11972],{"class":282},[268,120110,120111],{"class":270,"line":1951},[268,120112,314],{"class":282},[23,120114,120116,120132,120140,120156],{"className":120115},[26],[28,120117,120119,120121,120122,4912,120124,120126,120127,120015,120130,462],{"className":120118},[31],[33,120120],{"disabled":35,"type":36}," It doesn't compile — ",[39,120123,119025],{},[39,120125,16721],{},", which mismatches the ",[39,120128,120129],{},"Ok",[39,120131,113860],{},[28,120133,120135,355,120137,120139],{"className":120134},[31],[33,120136],{"disabled":35,"type":36},[39,120138,119025],{}," is special-cased by the match exhaustiveness checker to be silently skipped during type-checking.",[28,120141,120143,120145,120146,120149,120150,120152,120153,120155],{"className":120142},[31],[33,120144],{"disabled":35,"type":36}," It only compiles because ",[39,120147,120148],{},"parse_or_die","'s return type is inferred from the ",[39,120151,120129],{}," arm alone, and the ",[39,120154,116301],{}," arm's type is never checked.",[28,120157,120159,355,120161,120163,120164,120166,120167,120169,120170,120172],{"className":120158},[31],[33,120160],{"disabled":35,"type":36},[39,120162,120018],{}," has type ",[39,120165,5418],{}," (never), and like any diverging expression, ",[39,120168,5418],{}," coerces to match whatever type the other arms settle on — here ",[39,120171,113860],{}," — because a diverging arm never actually returns control to produce a mismatched value.",[66,120174,120175,120177,120186],{},[69,120176,71],{},[73,120178,120179,6901,120181,120163,120183,120185],{},[76,120180,78],{},[39,120182,120018],{},[39,120184,5418],{},", which coerces to match the other arms' type.",[73,120187,120188,355,120190,120192,120193,7255,120195,42,120198,42,120201,120204,120205,120207,120208,120210,120211,137,120213,120215,120216,120218,120219,120221,120222,120224,120225,120227,120228,120230,120231,120233],{},[76,120189,84],{},[76,120191,930],{}," this is the same never-type coercion from Q12, now shown in its most common real-world form — using ",[39,120194,119025],{},[39,120196,120197],{},"unreachable!",[39,120199,120200],{},"todo!",[39,120202,120203],{},".expect(...)","'s internal panic) as one arm of a ",[39,120206,116378],{}," whose other arms produce a real value. ",[39,120209,120018],{}," expands to code with type ",[39,120212,5418],{},[39,120214,5418],{}," unifies with any expected type, so the whole ",[39,120217,116378],{}," expression's type comes out as ",[39,120220,113860],{}," even though one arm can never actually produce an ",[39,120223,113860],{},". It's not that the arm goes unchecked (rules out B and C — every arm genuinely is type-checked; ",[39,120226,5418],{}," participates in that check, it isn't exempted from it) and ",[39,120229,119025],{}," certainly doesn't return ",[39,120232,16721],{}," — it never returns at all (rules out A).",[15,120235,120236,120244,120291],{},[18,120237,120239,120240,120243],{"id":120238},"q18-a-servernew-constructor-conceptually-could-take-up-to-six-independent-optional-settings-timeout-retries-tls-max-connections-and-so-on-given-rust-has-neither-default-arguments-nor-overloading-whats-considered-the-more-idiomatic-design-as-the-number-of-optional-settings-grows","Q18. A ",[39,120241,120242],{},"Server::new"," constructor conceptually could take up to six independent optional settings (timeout, retries, TLS, max connections, and so on). Given Rust has neither default arguments nor overloading, what's considered the more idiomatic design as the number of optional settings grows?",[23,120245,120247,120264,120273,120279],{"className":120246},[26],[28,120248,120250,120252,120253,120255,120256,120259,120260,120263],{"className":120249},[31],[33,120251],{"disabled":35,"type":36}," For a small number of optional settings, ",[39,120254,116806],{}," parameters (or a couple of named constructor functions) are fine; as the count grows, the builder pattern (a separate ",[39,120257,120258],{},"ServerBuilder"," with chainable setter methods and a final ",[39,120261,120262],{},".build()",") scales better by avoiding an unwieldy parameter list while keeping each call site self-documenting.",[28,120265,120267,120269,120270,120272],{"className":120266},[31],[33,120268],{"disabled":35,"type":36}," A single function with six ",[39,120271,116806],{}," parameters is always preferred, no matter how many optional settings exist.",[28,120274,120276,120278],{"className":120275},[31],[33,120277],{"disabled":35,"type":36}," Always use the builder pattern, even for a single optional parameter, since it's the only idiomatic Rust pattern for optional values.",[28,120280,120282,120284,120285,120287,120288,120290],{"className":120281},[31],[33,120283],{"disabled":35,"type":36}," Define the struct's fields as ",[39,120286,117577],{}," and let callers construct it directly with struct-update syntax, since this is strictly superior to both ",[39,120289,116806],{}," parameters and the builder pattern in every case.",[66,120292,120293,120295,120303],{},[69,120294,71],{},[73,120296,120297,120299,120300,120302],{},[76,120298,78],{}," A — Small counts favor ",[39,120301,116806],{}," params or named functions; larger counts favor the builder pattern.",[73,120304,120305,355,120307,120309,120310,120312,120313,120315],{},[76,120306,84],{},[76,120308,930],{}," this is a judgment call that scales with complexity — a couple of ",[39,120311,116806],{}," parameters (Q16) or a couple of clearly-named constructors stay readable, but a six-parameter function (positional or not) becomes error-prone and hard to read at the call site, which is exactly the problem the builder pattern solves by naming each setting via a chained method call. Absolutist answers are the tell for the wrong choice here: always using six ",[39,120314,116806],{}," params (B) ignores how unwieldy that gets, always reaching for a builder even for one flag (C) is needless ceremony, and treating public struct-update construction as \"strictly superior... in every case\" (D) ignores that it bypasses validation and forces every field to be independently public, which a constructor or builder can avoid.",[15,120317,120318,120328,120420,120488],{"language":111909},[18,120319,120321,120322,120324,120325,120327],{"id":120320},"q19-in-javascript-or-python-a-nested-function-like-multiply-would-close-over-factor-from-the-enclosing-scope-automatically-what-happens-when-this-rust-code-is-compiled","Q19. In JavaScript or Python, a nested function like ",[39,120323,81949],{}," would close over ",[39,120326,41112],{}," from the enclosing scope automatically. What happens when this Rust code is compiled?",[257,120329,120330],{"language":111909},[260,120331,120333],{"className":111918,"code":120332,"language":111909,"meta":264,"style":264},"fn main() {\n    let factor = 10;\n\n    fn multiply(x: i32) -> i32 {\n        x * factor\n    }\n\n    println!(\"{}\", multiply(5));\n}\n",[39,120334,120335,120343,120356,120360,120381,120390,120394,120398,120416],{"__ignoreMap":264},[268,120336,120337,120339,120341],{"class":270,"line":271},[268,120338,37837],{"class":274},[268,120340,111928],{"class":278},[268,120342,283],{"class":282},[268,120344,120345,120347,120350,120352,120354],{"class":270,"line":286},[268,120346,80826],{"class":274},[268,120348,120349],{"class":282}," factor ",[268,120351,302],{"class":274},[268,120353,306],{"class":305},[268,120355,293],{"class":282},[268,120357,120358],{"class":270,"line":296},[268,120359,5033],{"emptyLinePlaceholder":35},[268,120361,120362,120365,120367,120369,120371,120373,120375,120377,120379],{"class":270,"line":311},[268,120363,120364],{"class":274},"    fn",[268,120366,82006],{"class":278},[268,120368,117178],{"class":282},[268,120370,10728],{"class":274},[268,120372,113794],{"class":278},[268,120374,6131],{"class":282},[268,120376,113308],{"class":274},[268,120378,113794],{"class":278},[268,120380,9914],{"class":282},[268,120382,120383,120385,120387],{"class":270,"line":788},[268,120384,117848],{"class":282},[268,120386,6134],{"class":274},[268,120388,120389],{"class":282}," factor\n",[268,120391,120392],{"class":270,"line":1951},[268,120393,11972],{"class":282},[268,120395,120396],{"class":270,"line":8955},[268,120397,5033],{"emptyLinePlaceholder":35},[268,120399,120400,120402,120404,120406,120408,120410,120412,120414],{"class":270,"line":8966},[268,120401,111958],{"class":278},[268,120403,622],{"class":282},[268,120405,113830],{"class":289},[268,120407,42],{"class":282},[268,120409,81949],{"class":278},[268,120411,622],{"class":282},[268,120413,2429],{"class":305},[268,120415,4818],{"class":282},[268,120417,120418],{"class":270,"line":8974},[268,120419,314],{"class":282},[23,120421,120423,120434,120447,120476],{"className":120422},[26],[28,120424,120426,111978,120428,120430,120431,120433],{"className":120425},[31],[33,120427],{"disabled":35,"type":36},[39,120429,32109],{}," — nested ",[39,120432,37837],{}," items behave exactly like closures and capture enclosing local variables automatically.",[28,120435,120437,117069,120439,120441,120442,23506,120444,120446],{"className":120436},[31],[33,120438],{"disabled":35,"type":36},[39,120440,41112],{}," is treated as ",[39,120443,3307],{},[39,120445,81949],{}," since it wasn't explicitly passed in.",[28,120448,120450,120452,120453,120455,120456,120458,120459,120461,120462,120464,120465,42,120467,120469,120470,120473,120474,462],{"className":120449},[31],[33,120451],{"disabled":35,"type":36}," It fails to compile — a plain ",[39,120454,37837],{}," item, even one nested inside another function, never implicitly captures variables from its enclosing scope; ",[39,120457,41112],{}," is simply not in scope inside ",[39,120460,81949],{},"'s body, giving a \"cannot find value ",[39,120463,41112],{},"\" error. To capture ",[39,120466,41112],{},[39,120468,81949],{}," would need to be rewritten as a closure (",[39,120471,120472],{},"|x| x * factor",") instead of a plain ",[39,120475,37837],{},[28,120477,120479,120481,120482,120484,120485,120487],{"className":120478},[31],[33,120480],{"disabled":35,"type":36}," It fails to compile because nested ",[39,120483,37837],{}," items cannot reference ",[39,120486,113860],{}," parameters at all.",[66,120489,120490,120492,120500],{},[69,120491,71],{},[73,120493,120494,120496,120497,120499],{},[76,120495,78],{}," C — It fails to compile — a plain ",[39,120498,37837],{}," never implicitly captures its enclosing scope.",[73,120501,120502,355,120504,120506,120507,2182,120509,120511,120512,120515,120516,120518,120519,120521,120522,120524,120525,120527,120528,120530,120531,120534],{},[76,120503,84],{},[76,120505,365],{}," this is a frequent surprise for developers coming from JavaScript or Python, where a nested function definition is a closure by default. Rust draws a hard line between function ",[104,120508,56380],{},[39,120510,37837],{},") and closures (",[39,120513,120514],{},"|...| ...","): a ",[39,120517,37837],{},", whether at module scope or nested inside another function, has no implicit environment — it can only see its own parameters, its own locals, and other items, never a local variable from an enclosing function body. ",[39,120520,41112],{}," genuinely isn't visible inside ",[39,120523,81949],{},", giving a compile-time \"cannot find value\" error, not a runtime ",[39,120526,3307],{}," (rules out B, which imagines a silent fallback that doesn't exist) and definitely not automatic capture (rules out A). Nested ",[39,120529,37837],{}," items are completely legal and commonly used for local helpers (rules out D) — the restriction is specifically about capturing outer ",[104,120532,120533],{},"variables",", not about referencing parameter types.",[15,120536,120537,120546,120591],{},[18,120538,120540,120541,120543,120544,1685],{"id":120539},"q20-which-statement-correctly-describes-a-key-limitation-of-const-fn-compared-to-an-ordinary-fn","Q20. Which statement correctly describes a key limitation of ",[39,120542,113374],{}," compared to an ordinary ",[39,120545,37837],{},[23,120547,120549,120558,120572,120580],{"className":120548},[26],[28,120550,120552,120554,120555,120557],{"className":120551},[31],[33,120553],{"disabled":35,"type":36}," There is no difference at all — ",[39,120556,113374],{}," is purely a marker with no effect on what the function body may contain.",[28,120559,120561,812,120563,120565,120566,120568,120569,120571],{"className":120560},[31],[33,120562],{"disabled":35,"type":36},[39,120564,113374],{}," is restricted to operations the compiler can guarantee are evaluable at compile time (no arbitrary heap allocation, no calls to non-",[39,120567,243],{}," functions, limited trait usage, and so on); it is a strict subset of what an ordinary ",[39,120570,37837],{}," may do, in exchange for being usable in const contexts like array lengths.",[28,120573,120575,812,120577,120579],{"className":120574},[31],[33,120576],{"disabled":35,"type":36},[39,120578,113374],{}," can only be called at compile time; calling it at runtime with a non-constant argument is a compile error.",[28,120581,120583,812,120585,120587,120588,120590],{"className":120582},[31],[33,120584],{"disabled":35,"type":36},[39,120586,113374],{}," automatically becomes ",[39,120589,112499],{}," because compile-time execution bypasses the borrow checker.",[66,120592,120593,120595,120602],{},[69,120594,71],{},[73,120596,120597,1727,120599,120601],{},[76,120598,78],{},[39,120600,113374],{}," is restricted to a subset of compile-time-evaluable operations, in exchange for const-context usability.",[73,120603,120604,355,120606,355,120608,120610,120611,120613,120614,120616,120617,120619,120620,446,120622,120624,120625,120627,120628,120630,120631,120633,120634,120636],{},[76,120605,84],{},[76,120607,438],{},[39,120609,113374],{}," is a genuine trade-off, not a free-lunch marker (rules out A) — its body must stick to operations the compiler can prove are evaluable at compile time, which historically excludes things like arbitrary heap allocation or calling non-",[39,120612,243],{}," functions (the exact boundary of what's permitted has grown across Rust editions, but it remains narrower than what an ordinary ",[39,120615,37837],{}," allows). In exchange, a ",[39,120618,113374],{}," gains the ability to appear in const contexts such as array lengths (Q14) or ",[39,120621,243],{},[39,120623,31581],{}," initializers. A common misconception is that this makes it compile-time-",[104,120626,3117],{}," (C) — in fact a ",[39,120629,113374],{}," is dual-purpose: called with a ",[39,120632,243],{},"-eligible argument, it may run at compile time; called with an ordinary runtime value, it just runs as a normal function at runtime, no error involved. It also has nothing to do with ",[39,120635,112499],{}," or the borrow checker (rules out D) — const evaluation is fully safety-checked, just under a more restricted rule set.",[2107,120638,120639],{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html .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 .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}",{"title":264,"searchDepth":286,"depth":286,"links":120641},[120642,120643,120645,120647,120649,120651,120652,120653,120655,120656,120657,120659,120661,120663,120664,120666,120668,120670,120672,120674],{"id":117025,"depth":296,"text":117026},{"id":117157,"depth":296,"text":120644},"Q2. This function is declared to return i32. What happens when you try to compile it?",{"id":117301,"depth":296,"text":120646},"Q3. Is this function valid, and what does it demonstrate about return?",{"id":117459,"depth":296,"text":120648},"Q4. square is called in main before its definition appears in the file. What happens?",{"id":117606,"depth":296,"text":120650},"Q5. log has no -> Type in its signature. What happens when compiling main?",{"id":117805,"depth":296,"text":117806},{"id":112565,"depth":296,"text":112566},{"id":118161,"depth":296,"text":120654},"Q8. This is an attempt to overload parse based on parameter type, as is common in C++ or Java. What happens when this module is compiled?",{"id":118322,"depth":296,"text":118323},{"id":118452,"depth":296,"text":118453},{"id":118658,"depth":296,"text":120658},"Q11. Unlike the String example, what happens here?",{"id":118860,"depth":296,"text":120660},"Q12. bail is declared to return ! (the \"never\" type) and always panics. What does this let the compiler do with classify?",{"id":119101,"depth":296,"text":120662},"Q13. What does this program print, and what does it demonstrate about plain fn items?",{"id":119341,"depth":296,"text":119342},{"id":119590,"depth":296,"text":120665},"Q15. Why does largest require the T: PartialOrd bound instead of being written as fn largest\u003CT>(list: &[T]) -> T?",{"id":119912,"depth":296,"text":120667},"Q16. A function create_user conceptually wants an optional nickname that defaults to the user's real name when not provided. Rust has no default-argument syntax. What's the idiomatic way to model this?",{"id":120008,"depth":296,"text":120669},"Q17. Both match arms here have to produce a value of the same type for the match to type-check. Why does this compile even though the Err arm's panic!(...) never produces an i32?",{"id":120238,"depth":296,"text":120671},"Q18. A Server::new constructor conceptually could take up to six independent optional settings (timeout, retries, TLS, max connections, and so on). Given Rust has neither default arguments nor overloading, what's considered the more idiomatic design as the number of optional settings grows?",{"id":120320,"depth":296,"text":120673},"Q19. In JavaScript or Python, a nested function like multiply would close over factor from the enclosing scope automatically. What happens when this Rust code is compiled?",{"id":120539,"depth":296,"text":120675},"Q20. Which statement correctly describes a key limitation of const fn compared to an ordinary fn?",{},"\u002Frust\u002F05-functions",{"title":117015,"description":264},"rust\u002F05-functions","kljDDX0vkWpF4KQD8NwrigxXEeZhBNo7AezXiIA809E",{"id":120682,"title":120683,"body":120684,"description":264,"extension":2144,"meta":122904,"navigation":35,"path":122905,"seo":122906,"stem":122907,"__hash__":122908},"content\u002Frust\u002F10-lifetimes.md","10 — Lifetimes",{"type":8,"value":120685,"toc":122867},[120686,120689,120768,120840,120906,120974,121116,121181,121284,121398,121589,121901,122123,122197,122292,122387,122459,122508,122589,122690,122768,122864],[11,120687,120683],{"id":120688},"_10-lifetimes",[15,120690,120691,120699,120738],{},[18,120692,120694,120695,120698],{"id":120693},"q1-what-does-the-signature-fn-longestax-a-str-y-a-str-a-str-actually-promise-to-the-caller","Q1. What does the signature ",[39,120696,120697],{},"fn longest\u003C'a>(x: &'a str, y: &'a str) -> &'a str"," actually promise to the caller?",[23,120700,120702,120713,120719,120728],{"className":120701},[26],[28,120703,120705,120707,120708,186,120710,120712],{"className":120704},[31],[33,120706],{"disabled":35,"type":36}," That ",[39,120709,2403],{},[39,120711,2909],{}," live exactly as long as each other",[28,120714,120716,120718],{"className":120715},[31],[33,120717],{"disabled":35,"type":36}," That the returned reference is valid for at least as long as the shorter of the two input borrows overlap",[28,120720,120722,120724,120725,120727],{"className":120721},[31],[33,120723],{"disabled":35,"type":36}," That the function allocates a new string with a ",[39,120726,112492],{}," lifetime",[28,120729,120731,120707,120733,186,120735,120737],{"className":120730},[31],[33,120732],{"disabled":35,"type":36},[39,120734,2403],{},[39,120736,2909],{}," must be declared in the same scope",[66,120739,120740,120742,120747],{},[69,120741,71],{},[73,120743,120744,120746],{},[76,120745,78],{}," B — That the returned reference is valid for at least as long as the shorter of the two input borrows overlap",[73,120748,120749,355,120751,120754,120755,186,120757,120759,120760,186,120762,120764,120765,120767],{},[76,120750,84],{},[39,120752,120753],{},"'a"," is not a concrete duration; it's a constraint the compiler solves for at each call site — it becomes the intersection (overlap) of however long ",[39,120756,2403],{},[39,120758,2909],{}," are actually borrowed for. The returned reference is only guaranteed valid within that overlap. A is wrong because ",[39,120761,2403],{},[39,120763,2909],{}," can have different concrete lifetimes; the annotation just forces the compiler to pick the smaller one for ",[39,120766,120753],{},". C is wrong because lifetime parameters describe borrows of existing data, not allocation. D is wrong — lifetimes are about how long borrows are valid, not lexical co-location.",[15,120769,120770,120778,120813],{},[18,120771,120773,120774,120777],{"id":120772},"q2-given-fn-first_words-str-str-why-does-this-compile-without-any-explicit-lifetime-annotations","Q2. Given ",[39,120775,120776],{},"fn first_word(s: &str) -> &str",", why does this compile without any explicit lifetime annotations?",[23,120779,120781,120787,120793,120805],{"className":120780},[26],[28,120782,120784,120786],{"className":120783},[31],[33,120785],{"disabled":35,"type":36}," The function doesn't return a reference, so no lifetime is needed",[28,120788,120790,120792],{"className":120789},[31],[33,120791],{"disabled":35,"type":36}," Lifetime elision rule: a single input reference's lifetime is automatically assigned to all elided output lifetimes",[28,120794,120796,120798,120799,120801,120802],{"className":120795},[31],[33,120797],{"disabled":35,"type":36}," The Rust compiler infers lifetimes only for ",[39,120800,112302],{},", never for ",[39,120803,120804],{},"&T",[28,120806,120808,12848,120810,120812],{"className":120807},[31],[33,120809],{"disabled":35,"type":36},[39,120811,25393],{}," is immutable, lifetimes are not checked",[66,120814,120815,120817,120822],{},[69,120816,71],{},[73,120818,120819,120821],{},[76,120820,78],{}," B — Lifetime elision rule: a single input reference's lifetime is automatically assigned to all elided output lifetimes",[73,120823,120824,120826,120827,120830,120831,120833,120834,120836,120837,120839],{},[76,120825,84],{}," This is desugared by the compiler to ",[39,120828,120829],{},"fn first_word\u003C'a>(s: &'a str) -> &'a str",". The elision rules exist so common patterns don't require boilerplate. A is false — the return type is clearly ",[39,120832,112302],{},", a reference. C is false — elision applies uniformly to any ",[39,120835,120804],{},", not just ",[39,120838,112302],{},". D is false — mutability is irrelevant to lifetime elision; the rule is purely about counting input reference parameters.",[15,120841,120842,120849,120883],{},[18,120843,105406,120845,120848],{"id":120844},"q3-why-does-fn-combinex-str-y-str-str-fail-to-compile-as-written",[39,120846,120847],{},"fn combine(x: &str, y: &str) -> &str"," fail to compile as written?",[23,120850,120852,120858,120867,120877],{"className":120851},[26],[28,120853,120855,120857],{"className":120854},[31],[33,120856],{"disabled":35,"type":36}," It doesn't — this compiles fine using elision",[28,120859,120861,120863,120864,120866],{"className":120860},[31],[33,120862],{"disabled":35,"type":36}," There are two input lifetimes and no ",[39,120865,112964],{},", so elision cannot determine which one the output should borrow from",[28,120868,120870,355,120872,120874,120875],{"className":120869},[31],[33,120871],{"disabled":35,"type":36},[39,120873,112302],{}," return types always require ",[39,120876,112492],{},[28,120878,120880,120882],{"className":120879},[31],[33,120881],{"disabled":35,"type":36}," Rust forbids functions with two reference parameters",[66,120884,120885,120887,120894],{},[69,120886,71],{},[73,120888,120889,120891,120892,120866],{},[76,120890,78],{}," B — There are two input lifetimes and no ",[39,120893,112964],{},[73,120895,120896,120898,120899,120901,120902,120905],{},[76,120897,84],{}," Elision rule 2 (single input lifetime applied to output) only fires when there is exactly one input reference. Rule 3 (use ",[39,120900,112964],{},"'s lifetime) only fires for methods. With two unrelated reference parameters and neither rule applicable, the compiler refuses to guess and demands an explicit ",[39,120903,120904],{},"fn combine\u003C'a>(x: &'a str, y: &'a str) -> &'a str"," (or distinct lifetimes if only one feeds the output). A is wrong — this genuinely fails with \"missing lifetime specifier.\" C and D are fabricated restrictions that don't exist in Rust.",[15,120907,120908,120918,120948],{},[18,120909,97054,120911,120914,120915,120917],{"id":120910},"q4-in-impla-parsera-fn-peekself-other-str-str-which-lifetime-does-the-returned-str-borrow-from-per-elision-rule-3",[39,120912,120913],{},"impl\u003C'a> Parser\u003C'a> { fn peek(&self, other: &str) -> &str { ... } }",", which lifetime does the returned ",[39,120916,112302],{}," borrow from, per elision rule 3?",[23,120919,120921,120929,120936,120942],{"className":120920},[26],[28,120922,120924,355,120926,120928],{"className":120923},[31],[33,120925],{"disabled":35,"type":36},[39,120927,33735],{},"'s lifetime",[28,120930,120932,355,120934,120928],{"className":120931},[31],[33,120933],{"disabled":35,"type":36},[39,120935,112964],{},[28,120937,120939,120941],{"className":120938},[31],[33,120940],{"disabled":35,"type":36}," A fresh anonymous lifetime unrelated to either parameter",[28,120943,120945,120947],{"className":120944},[31],[33,120946],{"disabled":35,"type":36}," This is ambiguous and fails to compile",[66,120949,120950,120952,120958],{},[69,120951,71],{},[73,120953,120954,1727,120956,120928],{},[76,120955,78],{},[39,120957,112964],{},[73,120959,120960,120962,120963,99,120965,120967,120968,120970,120971,120973],{},[76,120961,84],{}," Elision rule 3 states that when a method has multiple input lifetimes but one of them is ",[39,120964,112964],{},[39,120966,113013],{},", the lifetime of ",[39,120969,87099],{}," is assigned to all elided output lifetimes — this matches the common case where a method returns a borrow of its own fields. A is the tempting-but-wrong guess many make when reading ",[39,120972,33735],{}," as \"the last parameter, so it must apply.\" C and D ignore that rule 3 exists specifically to resolve this case without an error.",[15,120975,120976,120980,121041,121080],{"language":111909},[18,120977,120979],{"id":120978},"q5-why-does-the-following-fail-to-compile","Q5. Why does the following fail to compile?",[257,120981,120982],{"language":111909},[260,120983,120985],{"className":111918,"code":120984,"language":111909,"meta":264,"style":264},"fn make_owner() -> &str {\n    let s = String::from(\"temp\");\n    &s[..]\n}\n",[39,120986,120987,121004,121025,121037],{"__ignoreMap":264},[268,120988,120989,120991,120994,120996,120998,121000,121002],{"class":270,"line":271},[268,120990,37837],{"class":274},[268,120992,120993],{"class":278}," make_owner",[268,120995,16182],{"class":282},[268,120997,113308],{"class":274},[268,120999,115951],{"class":274},[268,121001,17109],{"class":278},[268,121003,9914],{"class":282},[268,121005,121006,121008,121010,121012,121014,121016,121018,121020,121023],{"class":270,"line":286},[268,121007,80826],{"class":274},[268,121009,72278],{"class":282},[268,121011,302],{"class":274},[268,121013,114407],{"class":278},[268,121015,84903],{"class":274},[268,121017,44539],{"class":278},[268,121019,622],{"class":282},[268,121021,121022],{"class":289},"\"temp\"",[268,121024,628],{"class":282},[268,121026,121027,121030,121033,121035],{"class":270,"line":296},[268,121028,121029],{"class":274},"    &",[268,121031,121032],{"class":282},"s[",[268,121034,86888],{"class":274},[268,121036,89183],{"class":282},[268,121038,121039],{"class":270,"line":311},[268,121040,314],{"class":282},[23,121042,121044,121053,121061,121070],{"className":121043},[26],[28,121045,121047,355,121049,121052],{"className":121046},[31],[33,121048],{"disabled":35,"type":36},[39,121050,121051],{},"String::from"," cannot be indexed with a range",[28,121054,121056,355,121058,121060],{"className":121055},[31],[33,121057],{"disabled":35,"type":36},[39,121059,25393],{}," is dropped at the end of the function, so the returned reference would dangle",[28,121062,121064,121066,121067,121069],{"className":121063},[31],[33,121065],{"disabled":35,"type":36}," The function is missing a ",[39,121068,112025],{}," keyword",[28,121071,121073,355,121075,121077,121078],{"className":121072},[31],[33,121074],{"disabled":35,"type":36},[39,121076,112302],{}," cannot be constructed from a ",[39,121079,16721],{},[66,121081,121082,121084,121090],{},[69,121083,71],{},[73,121085,121086,1727,121088,121060],{},[76,121087,78],{},[39,121089,25393],{},[73,121091,121092,355,121094,121096,121097,121099,121100,121102,121103,121106,121107,121109,121110,2182,121112,121115],{},[76,121093,84],{},[39,121095,25393],{}," is a local ",[39,121098,16721],{}," owned by the function's stack frame; once the function returns, ",[39,121101,25393],{}," is deallocated. Returning ",[39,121104,121105],{},"&s[..]"," would produce a reference to freed memory, so the borrow checker rejects it with \"cannot return reference to local variable.\" ",[76,121108,582],{}," this is exactly the class of bug lifetimes exist to prevent at compile time instead of at runtime as a use-after-free. The fix is to return an owned ",[39,121111,16721],{},[39,121113,121114],{},"fn make_owner() -> String","). A and D are false — both operations are valid Rust; C is irrelevant, mutability doesn't affect ownership\u002Fdrop timing.",[15,121117,121118,121129,121156],{},[18,121119,121121,121122,121124,121125,121128],{"id":121120},"q6-what-does-the-static-lifetime-bound-on-a-reference-as-in-x-static-str-guarantee","Q6. What does the ",[39,121123,112492],{}," lifetime bound on a reference, as in ",[39,121126,121127],{},"x: &'static str",", guarantee?",[23,121130,121132,121138,121144,121150],{"className":121131},[26],[28,121133,121135,121137],{"className":121134},[31],[33,121136],{"disabled":35,"type":36}," The value is heap-allocated",[28,121139,121141,121143],{"className":121140},[31],[33,121142],{"disabled":35,"type":36}," The reference's data is valid for the entire remainder of the program's execution",[28,121145,121147,121149],{"className":121146},[31],[33,121148],{"disabled":35,"type":36}," The value cannot be a string literal",[28,121151,121153,121155],{"className":121152},[31],[33,121154],{"disabled":35,"type":36}," The variable is thread-local",[66,121157,121158,121160,121165],{},[69,121159,71],{},[73,121161,121162,121164],{},[76,121163,78],{}," B — The reference's data is valid for the entire remainder of the program's execution",[73,121166,121167,355,121169,121171,121172,121174,121175,121177,121178,121180],{},[76,121168,84],{},[39,121170,112492],{}," means the borrow does not need to be dropped before the program ends — the referenced data outlives everything else. String literals are the canonical example because they're baked into the binary's read-only data section. A is wrong — ",[39,121173,112492],{}," says nothing about heap vs. stack vs. static memory, only about duration. C is backwards — literals are the most common source of ",[39,121176,112492],{}," references. D is unrelated — ",[39,121179,112492],{}," has nothing to do with threading.",[15,121182,121183,121187,121231,121260],{"language":111909},[18,121184,121186],{"id":121185},"q7-why-must-this-struct-definition-include-an-explicit-lifetime-parameter","Q7. Why must this struct definition include an explicit lifetime parameter?",[257,121188,121189],{"language":111909},[260,121190,121192],{"className":111918,"code":121191,"language":111909,"meta":264,"style":264},"struct Excerpt\u003C'a> {\n    part: &'a str,\n}\n",[39,121193,121194,121210,121227],{"__ignoreMap":264},[268,121195,121196,121199,121202,121205,121207],{"class":270,"line":271},[268,121197,121198],{"class":274},"struct",[268,121200,121201],{"class":278}," Excerpt",[268,121203,121204],{"class":282},"\u003C'",[268,121206,1223],{"class":278},[268,121208,121209],{"class":282},"> {\n",[268,121211,121212,121215,121217,121219,121221,121223,121225],{"class":270,"line":286},[268,121213,121214],{"class":282},"    part",[268,121216,10728],{"class":274},[268,121218,115951],{"class":274},[268,121220,52434],{"class":282},[268,121222,1223],{"class":278},[268,121224,15854],{"class":278},[268,121226,1789],{"class":282},[268,121228,121229],{"class":270,"line":296},[268,121230,314],{"class":282},[23,121232,121234,121240,121246,121254],{"className":121233},[26],[28,121235,121237,121239],{"className":121236},[31],[33,121238],{"disabled":35,"type":36}," All structs in Rust require at least one generic parameter",[28,121241,121243,121245],{"className":121242},[31],[33,121244],{"disabled":35,"type":36}," A struct that holds a reference must declare how long that reference is valid for, tied to the struct's own lifetime",[28,121247,121249,355,121251,121253],{"className":121248},[31],[33,121250],{"disabled":35,"type":36},[39,121252,112302],{}," fields are only allowed in enums, not structs",[28,121255,121257,121259],{"className":121256},[31],[33,121258],{"disabled":35,"type":36}," It's optional style, not a compiler requirement",[66,121261,121262,121264,121269],{},[69,121263,71],{},[73,121265,121266,121268],{},[76,121267,78],{}," B — A struct that holds a reference must declare how long that reference is valid for, tied to the struct's own lifetime",[73,121270,121271,121273,121274,121277,121278,121280,121281,121283],{},[76,121272,84],{}," Whenever a struct stores a borrowed reference instead of owned data, the compiler needs to know the reference can't outlive the data it points to, and that no instance of ",[39,121275,121276],{},"Excerpt"," can outlive ",[39,121279,120753],{},". Omitting the annotation is a hard compile error (\"missing lifetime specifier\"), not a style choice — D is wrong. A is a fabricated rule; plenty of structs have zero generic parameters. C is false — the restriction applies to any reference field, not specifically ",[39,121282,112302],{}," in enums.",[15,121285,121286,121297,121346],{},[18,121287,121289,121290,121293,121294,121296],{"id":121288},"q8-a-junior-developer-claims-if-i-add-a-t-static-bound-to-a-generic-function-every-value-passed-in-must-be-created-before-main-starts-like-a-string-literal-is-this-accurate","Q8. A junior developer claims: \"If I add a ",[39,121291,121292],{},"T: 'static"," bound to a generic function, every value passed in must be created before ",[39,121295,102577],{}," starts, like a string literal.\" Is this accurate?",[23,121298,121300,121308,121325,121335],{"className":121299},[26],[28,121301,121303,90786,121305,121307],{"className":121302},[31],[33,121304],{"disabled":35,"type":36},[39,121306,112492],{}," bounds always require compile-time-constant data",[28,121309,121311,88201,121313,121315,121316,121318,121319,121321,121322,121324],{"className":121310},[31],[33,121312],{"disabled":35,"type":36},[39,121314,121292],{}," just means ",[39,121317,102486],{}," contains no borrowed references shorter than ",[39,121320,112492],{},"; an owned, heap-allocated ",[39,121323,16721],{}," created at runtime satisfies it fine",[28,121326,121328,88201,121330,121332,121333],{"className":121327},[31],[33,121329],{"disabled":35,"type":36},[39,121331,121292],{}," means the value must be ",[39,121334,114164],{},[28,121336,121338,121340,121341,186,121343,121345],{"className":121337},[31],[33,121339],{"disabled":35,"type":36}," Yes, but only for ",[39,121342,16721],{},[39,121344,112877],{}," types specifically",[66,121347,121348,121350,121363],{},[69,121349,71],{},[73,121351,121352,121354,121355,121315,121357,121318,121359,121321,121361,121324],{},[76,121353,78],{}," B — No — ",[39,121356,121292],{},[39,121358,102486],{},[39,121360,112492],{},[39,121362,16721],{},[73,121364,121365,121367,121368,121370,121371,121373,121374,121376,121377,42,121379,383,121382,121384,121385,121387,121388,121390,121391,186,121394,121397],{},[76,121366,84],{}," This is one of the most common Rust misconceptions. ",[39,121369,121292],{}," does not mean \"lives forever\" or \"known at compile time\" — it means \"if ",[39,121372,102486],{}," contains any references, those references must be ",[39,121375,112492],{},".\" Owned types like ",[39,121378,16721],{},[39,121380,121381],{},"Vec\u003Cu8>",[39,121383,113860],{}," trivially satisfy ",[39,121386,121292],{}," because they own their data outright and contain no borrows at all, regardless of when they're created. ",[76,121389,930],{}," this bound shows up constantly on ",[39,121392,121393],{},"thread::spawn",[39,121395,121396],{},"Box\u003Cdyn Trait>"," precisely to rule out dangling borrows across thread\u002Fheap boundaries, not to force compile-time construction. A, C, and D invent restrictions that don't exist.",[15,121399,121400,121404,121492,121545],{"language":111909},[18,121401,121403],{"id":121402},"q9-consider-this-function-under-non-lexical-lifetimes-nll-why-does-it-compile","Q9. Consider this function under Non-Lexical Lifetimes (NLL). Why does it compile?",[257,121405,121406],{"language":111909},[260,121407,121409],{"className":111918,"code":121408,"language":111909,"meta":264,"style":264},"fn main() {\n    let mut v = vec![1, 2, 3];\n    let first = &v[0];\n    println!(\"{first}\");\n    v.push(4);\n}\n",[39,121410,121411,121419,121445,121463,121474,121488],{"__ignoreMap":264},[268,121412,121413,121415,121417],{"class":270,"line":271},[268,121414,37837],{"class":274},[268,121416,111928],{"class":278},[268,121418,283],{"class":282},[268,121420,121421,121423,121425,121427,121429,121431,121433,121435,121437,121439,121441,121443],{"class":270,"line":286},[268,121422,80826],{"class":274},[268,121424,113071],{"class":274},[268,121426,112900],{"class":282},[268,121428,302],{"class":274},[268,121430,112905],{"class":278},[268,121432,15175],{"class":282},[268,121434,2255],{"class":305},[268,121436,42],{"class":282},[268,121438,2258],{"class":305},[268,121440,42],{"class":282},[268,121442,3423],{"class":305},[268,121444,8737],{"class":282},[268,121446,121447,121449,121452,121454,121456,121459,121461],{"class":270,"line":296},[268,121448,80826],{"class":274},[268,121450,121451],{"class":282}," first ",[268,121453,302],{"class":274},[268,121455,115951],{"class":274},[268,121457,121458],{"class":282},"v[",[268,121460,3307],{"class":305},[268,121462,8737],{"class":282},[268,121464,121465,121467,121469,121472],{"class":270,"line":311},[268,121466,111958],{"class":278},[268,121468,622],{"class":282},[268,121470,121471],{"class":289},"\"{first}\"",[268,121473,628],{"class":282},[268,121475,121476,121478,121480,121482,121484,121486],{"class":270,"line":788},[268,121477,112924],{"class":282},[268,121479,462],{"class":274},[268,121481,12499],{"class":278},[268,121483,622],{"class":282},[268,121485,15049],{"class":305},[268,121487,628],{"class":282},[268,121489,121490],{"class":270,"line":1951},[268,121491,314],{"class":282},[23,121493,121495,121507,121522,121535],{"className":121494},[26],[28,121496,121498,120121,121500,121502,121503,30040,121505,58241],{"className":121497},[31],[33,121499],{"disabled":35,"type":36},[39,121501,12590],{}," still borrows ",[39,121504,52799],{},[39,121506,12499],{},[28,121508,121510,121512,121513,121515,121516,121518,121519,121521],{"className":121509},[31],[33,121511],{"disabled":35,"type":36}," NLL ends ",[39,121514,12590],{},"'s borrow at its last use (the ",[39,121517,118575],{},"), so the mutable borrow in ",[39,121520,12499],{}," doesn't conflict",[28,121523,121525,355,121527,121530,121531,830,121533],{"className":121524},[31],[33,121526],{"disabled":35,"type":36},[39,121528,121529],{},"v[0]"," copies the value instead of borrowing, since ",[39,121532,113860],{},[39,121534,114164],{},[28,121536,121538,355,121540,121542,121543],{"className":121537},[31],[33,121539],{"disabled":35,"type":36},[39,121541,12499],{}," doesn't require a mutable borrow of ",[39,121544,52799],{},[66,121546,121547,121549,121560],{},[69,121548,71],{},[73,121550,121551,121553,121554,121515,121556,121518,121558,121521],{},[76,121552,78],{}," B — NLL ends ",[39,121555,12590],{},[39,121557,118575],{},[39,121559,12499],{},[73,121561,121562,121564,121565,121568,121569,121571,121572,121575,121576,5125,121578,121580,121581,121584,121585,71990,121587,462],{},[76,121563,84],{}," Before NLL (pre-2018 borrow checker), a reference's lifetime extended to the end of its lexical scope, so this would have failed. NLL changed the analysis to end a borrow's ",[104,121566,121567],{},"lifetime"," at its last actual use, which can be well before the closing brace — lifetime and scope are related but not identical. ",[76,121570,930],{}," this is exactly why \"lifetime\" and \"scope\" are distinct concepts; scope is lexical, lifetime is usage-based. A is the pre-NLL answer and a common outdated assumption. C is a red herring — indexing does borrow, ",[39,121573,121574],{},"i32: Copy"," doesn't change that ",[39,121577,121529],{},[39,121579,112877],{}," desugars through ",[39,121582,121583],{},"Index",", though the copy happens right after the borrow, which is exactly why the borrow can end immediately. D is false — ",[39,121586,113010],{},[39,121588,113013],{},[15,121590,121591,121595,121798,121841],{"language":111909},[18,121592,121594],{"id":121593},"q10-whats-wrong-with-this-attempt-at-an-early-return-function","Q10. What's wrong with this attempt at an early-return function?",[257,121596,121597],{"language":111909},[260,121598,121600],{"className":111918,"code":121599,"language":111909,"meta":264,"style":264},"fn shortest\u003C'a>(x: &'a str, y: &'a str) -> &'a str {\n    if x.len() \u003C y.len() { x } else { y }\n}\n\nfn caller() -> &'static str {\n    let long_lived = String::from(\"hello world\");\n    let result;\n    {\n        let short_lived = String::from(\"hi\");\n        result = shortest(long_lived.as_str(), short_lived.as_str());\n    }\n    result\n}\n",[39,121601,121602,121653,121678,121682,121686,121707,121729,121735,121739,121760,121785,121789,121794],{"__ignoreMap":264},[268,121603,121604,121606,121609,121611,121613,121616,121618,121620,121622,121624,121626,121629,121631,121633,121635,121637,121639,121641,121643,121645,121647,121649,121651],{"class":270,"line":271},[268,121605,37837],{"class":274},[268,121607,121608],{"class":278}," shortest",[268,121610,121204],{"class":282},[268,121612,1223],{"class":278},[268,121614,121615],{"class":282},">(x",[268,121617,10728],{"class":274},[268,121619,115951],{"class":274},[268,121621,52434],{"class":282},[268,121623,1223],{"class":278},[268,121625,15854],{"class":278},[268,121627,121628],{"class":282},", y",[268,121630,10728],{"class":274},[268,121632,115951],{"class":274},[268,121634,52434],{"class":282},[268,121636,1223],{"class":278},[268,121638,15854],{"class":278},[268,121640,6131],{"class":282},[268,121642,113308],{"class":274},[268,121644,115951],{"class":274},[268,121646,52434],{"class":282},[268,121648,1223],{"class":278},[268,121650,15854],{"class":278},[268,121652,9914],{"class":282},[268,121654,121655,121657,121659,121661,121663,121666,121668,121670,121673,121675],{"class":270,"line":286},[268,121656,9686],{"class":274},[268,121658,9206],{"class":282},[268,121660,462],{"class":274},[268,121662,112611],{"class":278},[268,121664,121665],{"class":282},"() \u003C y",[268,121667,462],{"class":274},[268,121669,112611],{"class":278},[268,121671,121672],{"class":282},"() { x } ",[268,121674,9884],{"class":274},[268,121676,121677],{"class":282}," { y }\n",[268,121679,121680],{"class":270,"line":296},[268,121681,314],{"class":282},[268,121683,121684],{"class":270,"line":311},[268,121685,5033],{"emptyLinePlaceholder":35},[268,121687,121688,121690,121693,121695,121697,121699,121701,121703,121705],{"class":270,"line":788},[268,121689,37837],{"class":274},[268,121691,121692],{"class":278}," caller",[268,121694,16182],{"class":282},[268,121696,113308],{"class":274},[268,121698,115951],{"class":274},[268,121700,52434],{"class":282},[268,121702,31581],{"class":278},[268,121704,15854],{"class":278},[268,121706,9914],{"class":282},[268,121708,121709,121711,121714,121716,121718,121720,121722,121724,121727],{"class":270,"line":1951},[268,121710,80826],{"class":274},[268,121712,121713],{"class":282}," long_lived ",[268,121715,302],{"class":274},[268,121717,114407],{"class":278},[268,121719,84903],{"class":274},[268,121721,44539],{"class":278},[268,121723,622],{"class":282},[268,121725,121726],{"class":289},"\"hello world\"",[268,121728,628],{"class":282},[268,121730,121731,121733],{"class":270,"line":8955},[268,121732,80826],{"class":274},[268,121734,10895],{"class":282},[268,121736,121737],{"class":270,"line":8966},[268,121738,112730],{"class":282},[268,121740,121741,121743,121746,121748,121750,121752,121754,121756,121758],{"class":270,"line":8974},[268,121742,112735],{"class":274},[268,121744,121745],{"class":282}," short_lived ",[268,121747,302],{"class":274},[268,121749,114407],{"class":278},[268,121751,84903],{"class":274},[268,121753,44539],{"class":278},[268,121755,622],{"class":282},[268,121757,85975],{"class":289},[268,121759,628],{"class":282},[268,121761,121762,121764,121766,121768,121771,121773,121776,121779,121781,121783],{"class":270,"line":8985},[268,121763,95512],{"class":282},[268,121765,302],{"class":274},[268,121767,121608],{"class":278},[268,121769,121770],{"class":282},"(long_lived",[268,121772,462],{"class":274},[268,121774,121775],{"class":278},"as_str",[268,121777,121778],{"class":282},"(), short_lived",[268,121780,462],{"class":274},[268,121782,121775],{"class":278},[268,121784,8174],{"class":282},[268,121786,121787],{"class":270,"line":8990},[268,121788,11972],{"class":282},[268,121790,121791],{"class":270,"line":8997},[268,121792,121793],{"class":282},"    result\n",[268,121795,121796],{"class":270,"line":9002},[268,121797,314],{"class":282},[23,121799,121801,121807,121822,121831],{"className":121800},[26],[28,121802,121804,121806],{"className":121803},[31],[33,121805],{"disabled":35,"type":36}," Nothing — this compiles and runs fine",[28,121808,121810,355,121812,121814,121815,121818,121819,121821],{"className":121809},[31],[33,121811],{"disabled":35,"type":36},[39,121813,5631],{}," may borrow ",[39,121816,121817],{},"short_lived",", which is dropped at the end of the inner block, so using ",[39,121820,5631],{}," afterward is a dangling-reference error",[28,121823,121825,355,121827,121830],{"className":121824},[31],[33,121826],{"disabled":35,"type":36},[39,121828,121829],{},"shortest"," needs two separate lifetime parameters, one per argument",[28,121832,121834,355,121836,121838,121839],{"className":121833},[31],[33,121835],{"disabled":35,"type":36},[39,121837,121051],{}," cannot be passed to a function expecting ",[39,121840,112302],{},[66,121842,121843,121845,121855],{},[69,121844,71],{},[73,121846,121847,1727,121849,121814,121851,121818,121853,121821],{},[76,121848,78],{},[39,121850,5631],{},[39,121852,121817],{},[39,121854,5631],{},[73,121856,121857,12848,121859,121861,121862,121864,121865,121867,121868,121870,121871,121873,121874,121876,121877,121879,121880,121882,121883,121885,121886,121888,121889,121891,121892,121894,121895,5434,121898,121900],{},[76,121858,84],{},[39,121860,121829],{}," ties both inputs to the ",[104,121863,22779],{}," lifetime ",[39,121866,120753],{},", the compiler must conservatively assume the returned reference could point into either argument. Since ",[39,121869,121817],{}," doesn't outlive the inner block, ",[39,121872,120753],{}," is constrained to that shorter scope, and using ",[39,121875,5631],{}," after the block ends is rejected as \"",[39,121878,121817],{}," does not live long enough.\" ",[76,121881,582],{}," the compiler can't know at compile time which branch of the ",[39,121884,2179],{}," will run, so it must assume the worst case. The fix is to shrink the scope of ",[39,121887,5631],{},"'s use to inside the block, or to have ",[39,121890,121829],{}," return an owned ",[39,121893,16721],{},". C would actually make it worse — separate lifetimes would still require a return type tied to one of them, and the compiler still can't know statically which. D is false — ",[39,121896,121897],{},"&String",[39,121899,112302],{}," via deref coercion.",[15,121902,121903,121910,122021,122073],{"language":111909},[18,121904,121906,121907,121909],{"id":121905},"q11-why-does-this-match-based-function-fail-to-compile","Q11. Why does this ",[39,121908,116378],{},"-based function fail to compile?",[257,121911,121912],{"language":111909},[260,121913,121915],{"className":111918,"code":121914,"language":111909,"meta":264,"style":264},"fn pick\u003C'a>(flag: bool, a: &'a str) -> &'a str {\n    if flag {\n        a\n    } else {\n        let local = String::from(\"fallback\");\n        &local\n    }\n}\n",[39,121916,121917,121963,121970,121975,121983,122005,122013,122017],{"__ignoreMap":264},[268,121918,121919,121921,121924,121926,121928,121931,121933,121936,121939,121941,121943,121945,121947,121949,121951,121953,121955,121957,121959,121961],{"class":270,"line":271},[268,121920,37837],{"class":274},[268,121922,121923],{"class":278}," pick",[268,121925,121204],{"class":282},[268,121927,1223],{"class":278},[268,121929,121930],{"class":282},">(flag",[268,121932,10728],{"class":274},[268,121934,121935],{"class":278}," bool",[268,121937,121938],{"class":282},", a",[268,121940,10728],{"class":274},[268,121942,115951],{"class":274},[268,121944,52434],{"class":282},[268,121946,1223],{"class":278},[268,121948,15854],{"class":278},[268,121950,6131],{"class":282},[268,121952,113308],{"class":274},[268,121954,115951],{"class":274},[268,121956,52434],{"class":282},[268,121958,1223],{"class":278},[268,121960,15854],{"class":278},[268,121962,9914],{"class":282},[268,121964,121965,121967],{"class":270,"line":286},[268,121966,9686],{"class":274},[268,121968,121969],{"class":282}," flag {\n",[268,121971,121972],{"class":270,"line":296},[268,121973,121974],{"class":282},"        a\n",[268,121976,121977,121979,121981],{"class":270,"line":311},[268,121978,12485],{"class":282},[268,121980,9884],{"class":274},[268,121982,9914],{"class":282},[268,121984,121985,121987,121990,121992,121994,121996,121998,122000,122003],{"class":270,"line":788},[268,121986,112735],{"class":274},[268,121988,121989],{"class":282}," local ",[268,121991,302],{"class":274},[268,121993,114407],{"class":278},[268,121995,84903],{"class":274},[268,121997,44539],{"class":278},[268,121999,622],{"class":282},[268,122001,122002],{"class":289},"\"fallback\"",[268,122004,628],{"class":282},[268,122006,122007,122010],{"class":270,"line":1951},[268,122008,122009],{"class":274},"        &",[268,122011,122012],{"class":282},"local\n",[268,122014,122015],{"class":270,"line":8955},[268,122016,11972],{"class":282},[268,122018,122019],{"class":270,"line":8966},[268,122020,314],{"class":282},[23,122022,122024,122034,122050,122063],{"className":122023},[26],[28,122025,122027,355,122029,446,122031,122033],{"className":122026},[31],[33,122028],{"disabled":35,"type":36},[39,122030,2179],{},[39,122032,9884],{}," branches must return the same literal value",[28,122035,122037,4396,122039,122041,122042,122044,122045,122047,122048],{"className":122036},[31],[33,122038],{"disabled":35,"type":36},[39,122040,9884],{}," branch returns a reference to ",[39,122043,84780],{},", which is dropped when the branch scope ends — it cannot satisfy the ",[39,122046,120753],{}," bound tied to ",[39,122049,1223],{},[28,122051,122053,355,122055,122057,122058,2758,122061],{"className":122052},[31],[33,122054],{"disabled":35,"type":36},[39,122056,93613],{}," must be ",[39,122059,122060],{},"&bool",[39,122062,89412],{},[28,122064,122066,355,122068,122070,122071],{"className":122065},[31],[33,122067],{"disabled":35,"type":36},[39,122069,16721],{}," cannot be shadowed with ",[39,122072,240],{},[66,122074,122075,122077,122089],{},[69,122076,71],{},[73,122078,122079,57091,122081,122041,122083,122044,122085,122047,122087],{},[76,122080,78],{},[39,122082,9884],{},[39,122084,84780],{},[39,122086,120753],{},[39,122088,1223],{},[73,122090,122091,122093,122094,122096,122097,122099,122100,122103,122104,122106,122107,122109,122110,122112,122113,122116,122117,122119,122120,122122],{},[76,122092,84],{}," The function signature promises a return value valid for ",[39,122095,120753],{}," (the lifetime of ",[39,122098,1223],{},"), but ",[39,122101,122102],{},"&local"," is only valid for the tiny scope of the ",[39,122105,9884],{}," block. The compiler flags \"",[39,122108,84780],{}," does not live long enough\" because no lifetime annotation can make a truly local value outlive its own creation. The correct fix is to return an owned ",[39,122111,16721],{}," from both branches (changing the signature to ",[39,122114,122115],{},"-> String",", cloning ",[39,122118,1223],{}," in the ",[39,122121,2179],{}," branch) rather than trying to force a shared borrow. A, C, and D describe non-existent restrictions.",[15,122124,122125,122139,122175],{},[18,122126,122128,122129,122132,122133,122136,122137,1685],{"id":122127},"q12-which-scenario-genuinely-requires-a-struct-with-two-independent-lifetime-parameters-eg-struct-paira-b-instead-of-one-shared-a","Q12. Which scenario genuinely requires a struct with ",[76,122130,122131],{},"two independent"," lifetime parameters, e.g. ",[39,122134,122135],{},"struct Pair\u003C'a, 'b>",", instead of one shared ",[39,122138,120753],{},[23,122140,122142,122148,122154,122166],{"className":122141},[26],[28,122143,122145,122147],{"className":122144},[31],[33,122146],{"disabled":35,"type":36}," Never — using a single shared lifetime is always equivalent and preferred",[28,122149,122151,122153],{"className":122150},[31],[33,122152],{"disabled":35,"type":36}," When the two borrowed fields come from sources with different, unrelated lifetimes, and a method needs to return a reference tied to only one of them",[28,122155,122157,122159,122160,122162,122163],{"className":122156},[31],[33,122158],{"disabled":35,"type":36}," When one field is ",[39,122161,112302],{}," and the other is ",[39,122164,122165],{},"&[u8]",[28,122167,122169,122171,122172],{"className":122168},[31],[33,122170],{"disabled":35,"type":36}," When the struct also derives ",[39,122173,122174],{},"Clone",[66,122176,122177,122179,122184],{},[69,122178,71],{},[73,122180,122181,122183],{},[76,122182,78],{}," B — When the two borrowed fields come from sources with different, unrelated lifetimes, and a method needs to return a reference tied to only one of them",[73,122185,122186,122188,122189,122191,122192,7507,122194,122196],{},[76,122187,84],{}," Collapsing both fields to a single ",[39,122190,120753],{}," forces the compiler to use the shorter of the two lifetimes everywhere, which needlessly restricts callers when the fields are genuinely independent (e.g., one long-lived config string and one short-lived per-request buffer). Separate parameters let each field's borrow be tracked precisely. A is the tempting simplification that works until a caller hits an over-restrictive borrow error. C is false — the underlying type (",[39,122193,112302],{},[39,122195,122165],{},") has nothing to do with how many lifetime parameters are needed. D is unrelated to lifetimes at all.",[15,122198,122199,122209,122254],{},[18,122200,122202,122203,122206,122207,1685],{"id":122201},"q13-what-does-the-bound-fn-processt-debug-aitem-t-communicate-about-t","Q13. What does the bound ",[39,122204,122205],{},"fn process\u003CT: Debug + 'a>(item: T)"," communicate about ",[39,122208,102486],{},[23,122210,122212,122220,122231,122243],{"className":122211},[26],[28,122213,122215,355,122217,122219],{"className":122214},[31],[33,122216],{"disabled":35,"type":36},[39,122218,102486],{}," must be a reference type",[28,122221,122223,122225,122226,122228,122229],{"className":122222},[31],[33,122224],{"disabled":35,"type":36}," Any references contained within ",[39,122227,102486],{}," must live at least as long as ",[39,122230,120753],{},[28,122232,122234,355,122236,122238,122239,122242],{"className":122233},[31],[33,122235],{"disabled":35,"type":36},[39,122237,102486],{}," must implement the ",[39,122240,122241],{},"Lifetime"," trait",[28,122244,122246,355,122248,122250,122251,122253],{"className":122245},[31],[33,122247],{"disabled":35,"type":36},[39,122249,120753],{}," is ignored because ",[39,122252,102486],{}," is passed by value",[66,122255,122256,122258,122267],{},[69,122257,71],{},[73,122259,122260,122262,122263,122228,122265],{},[76,122261,78],{}," B — Any references contained within ",[39,122264,102486],{},[39,122266,120753],{},[73,122268,122269,122271,122272,122275,122276,122278,122279,122281,122282,122285,122286,122288,122289,122291],{},[76,122270,84],{}," A lifetime bound on a generic type parameter (",[39,122273,122274],{},"T: 'a",") constrains any borrows nested inside ",[39,122277,102486],{}," — whether ",[39,122280,102486],{}," itself is a reference or an owned type that happens to hold one (like ",[39,122283,122284],{},"struct Wrapper\u003C'a>(&'a i32)","). It does ",[76,122287,95],{}," require ",[39,122290,102486],{}," itself to be a reference type, so A is wrong. C invents a nonexistent trait — lifetimes are not traits. D is wrong — even owned generic types can embed references, so the bound still matters regardless of pass-by-value.",[15,122293,122294,122302,122354],{},[18,122295,122297,122298,122301],{"id":122296},"q14-what-is-the-lifetime-of-the-string-literal-in-let-s-static-str-hello-and-why","Q14. What is the lifetime of the string literal in ",[39,122299,122300],{},"let s: &'static str = \"hello\";",", and why?",[23,122303,122305,122320,122328,122340],{"className":122304},[26],[28,122306,122308,122310,122311,122313,122314,122316,122317,122319],{"className":122307},[31],[33,122309],{"disabled":35,"type":36}," It's ",[39,122312,112492],{}," because all ",[39,122315,112302],{}," variables default to ",[39,122318,112492],{}," unless annotated otherwise",[28,122321,122323,122310,122325,122327],{"className":122322},[31],[33,122324],{"disabled":35,"type":36},[39,122326,112492],{}," because the literal's bytes are embedded directly in the compiled binary's read-only memory, which exists for the whole program run",[28,122329,122331,122333,122334,122336,122337,122339],{"className":122330},[31],[33,122332],{"disabled":35,"type":36}," It's tied to the scope of ",[39,122335,25393],{}," only, and ",[39,122338,112492],{}," here is just an alias with no special meaning",[28,122341,122343,122310,122345,122347,122348,122350,122351,122353],{"className":122342},[31],[33,122344],{"disabled":35,"type":36},[39,122346,112492],{}," only in ",[39,122349,110189],{}," builds; in ",[39,122352,98079],{}," builds it's dropped at end of scope",[66,122355,122356,122358,122365],{},[69,122357,71],{},[73,122359,122360,122362,122363,122327],{},[76,122361,78],{}," B — It's ",[39,122364,112492],{},[73,122366,122367,122369,122370,122372,122373,122375,122376,122378,122379,355,122381,122383,122384,122386],{},[76,122368,84],{}," String literals are stored in the binary itself, not on the heap or stack, so a ",[39,122371,112302],{}," pointing at one is trivially valid for the program's entire lifetime — this is why literals are the textbook example of ",[39,122374,112492],{}," data. A is false — general ",[39,122377,112302],{}," variables are ",[104,122380,95],{},[39,122382,112492],{}," by default; only specific sources like literals are. C understates what ",[39,122385,112492],{}," means; it's a real, checked guarantee, not cosmetic. D is fabricated — build profile has no bearing on this.",[15,122388,122389,122397,122433],{},[18,122390,122392,122393,122396],{"id":122391},"q15-a-public-api-function-currently-returns-a-str-borrowed-from-an-input-forcing-every-caller-to-keep-the-input-alive-as-long-as-the-result-whats-the-idiomatic-best-practice-when-the-borrow-relationship-isnt-essential-to-the-apis-purpose","Q15. A public API function currently returns ",[39,122394,122395],{},"&'a str"," borrowed from an input, forcing every caller to keep the input alive as long as the result. What's the idiomatic best practice when the borrow relationship isn't essential to the API's purpose?",[23,122398,122400,122406,122415,122423],{"className":122399},[26],[28,122401,122403,122405],{"className":122402},[31],[33,122404],{"disabled":35,"type":36}," Always keep borrowing return types — allocating is un-idiomatic in Rust",[28,122407,122409,122411,122412,122414],{"className":122408},[31],[33,122410],{"disabled":35,"type":36}," Return an owned ",[39,122413,16721],{}," instead, accepting the extra allocation, so callers aren't forced into awkward lifetime juggling",[28,122416,122418,77484,122420,122422],{"className":122417},[31],[33,122419],{"disabled":35,"type":36},[39,122421,112492],{}," to force the caller to leak the input",[28,122424,122426,122428,122429,122432],{"className":122425},[31],[33,122427],{"disabled":35,"type":36}," Wrap the return type in ",[39,122430,122431],{},"Rc\u003Cstr>"," regardless of whether sharing is needed",[66,122434,122435,122437,122444],{},[69,122436,71],{},[73,122438,122439,122441,122442,122414],{},[76,122440,78],{}," B — Return an owned ",[39,122443,16721],{},[73,122445,122446,355,122448,122450,122451,446,122453,122455,122456,122458],{},[76,122447,84],{},[76,122449,930],{}," Rust does favor borrowing when it's cheap and natural, but API ergonomics matter — if borrowing propagates a lifetime parameter through public structs and function signatures just to save one allocation, it's usually not worth the complexity for callers. A overstates the \"avoid allocation at all costs\" mentality; even the standard library returns owned ",[39,122452,16721],{},[39,122454,112877],{}," constantly. C is nonsensical — ",[39,122457,112492],{}," cannot be conjured onto arbitrary borrowed data without genuinely leaking or owning it. D adds unnecessary reference-counting overhead and API surface when sharing isn't actually required.",[15,122460,122461,122465,122492],{},[18,122462,122464],{"id":122463},"q16-when-should-you-reach-for-an-explicit-lifetime-annotation-instead-of-relying-on-elision","Q16. When should you reach for an explicit lifetime annotation instead of relying on elision?",[23,122466,122468,122474,122480,122486],{"className":122467},[26],[28,122469,122471,122473],{"className":122470},[31],[33,122472],{"disabled":35,"type":36}," Whenever a function takes more than zero parameters",[28,122475,122477,122479],{"className":122476},[31],[33,122478],{"disabled":35,"type":36}," Only when the elision rules cannot uniquely determine the output lifetime, or when a struct\u002Fimpl block needs to tie multiple borrows together explicitly",[28,122481,122483,122485],{"className":122482},[31],[33,122484],{"disabled":35,"type":36}," Every function that returns any value at all",[28,122487,122489,122491],{"className":122488},[31],[33,122490],{"disabled":35,"type":36}," Never — explicit lifetimes are a deprecated Rust 2015 feature",[66,122493,122494,122496,122501],{},[69,122495,71],{},[73,122497,122498,122500],{},[76,122499,78],{}," B — Only when the elision rules cannot uniquely determine the output lifetime, or when a struct\u002Fimpl block needs to tie multiple borrows together explicitly",[73,122502,122503,355,122505,122507],{},[76,122504,84],{},[76,122506,930],{}," the elision rules exist precisely so idiomatic Rust rarely needs visible lifetime syntax; reaching for it should be a deliberate signal that the compiler genuinely needs disambiguation (two-plus input references feeding one output, or a struct storing borrowed fields). A and C wildly over-apply the rule and would make trivial functions unnecessarily verbose. D is false — explicit lifetimes are a core, actively used part of the language, not deprecated.",[15,122509,122510,122518,122556],{},[18,122511,122513,122514,122517],{"id":122512},"q17-why-is-casually-adding-dyn-trait-static-or-its-implicit-default-to-every-trait-object-in-a-long-lived-cache-considered-a-code-smell-when-the-objects-actually-hold-short-lived-borrowed-data","Q17. Why is casually adding ",[39,122515,122516],{},"dyn Trait + 'static"," (or its implicit default) to every trait object in a long-lived cache considered a code smell when the objects actually hold short-lived borrowed data?",[23,122519,122521,122530,122536,122545],{"className":122520},[26],[28,122522,122524,122526,122527,122529],{"className":122523},[31],[33,122525],{"disabled":35,"type":36}," It isn't a smell — ",[39,122528,112492],{}," should always be the default for trait objects",[28,122531,122533,122535],{"className":122532},[31],[33,122534],{"disabled":35,"type":36}," It forces every value stored in the cache to be owned (or leaked), which can silently balloon memory or force unnecessary cloning just to satisfy the bound",[28,122537,122539,355,122541,122544],{"className":122538},[31],[33,122540],{"disabled":35,"type":36},[39,122542,122543],{},"dyn Trait"," objects cannot have lifetime bounds at all",[28,122546,122548,355,122550,122552,122553,122555],{"className":122547},[31],[33,122549],{"disabled":35,"type":36},[39,122551,112492],{}," on trait objects only affects ",[39,122554,16523],{}," formatting",[66,122557,122558,122560,122565],{},[69,122559,71],{},[73,122561,122562,122564],{},[76,122563,78],{}," B — It forces every value stored in the cache to be owned (or leaked), which can silently balloon memory or force unnecessary cloning just to satisfy the bound",[73,122566,122567,355,122569,4001,122571,122574,122575,122578,122579,122581,122582,122584,122585,122588],{},[76,122568,84],{},[39,122570,121396],{},[39,122572,122573],{},"Box\u003Cdyn Trait + 'static>"," unless you write a shorter bound like ",[39,122576,122577],{},"Box\u003Cdyn Trait + 'a>",". Reaching for the default without thinking means anything with a borrowed lifetime can no longer be boxed as that trait object without first cloning into an owned form — a common surprise when refactoring borrowing code into a trait-object-based design. ",[76,122580,438],{}," unnecessary clones to satisfy an overly broad ",[39,122583,112492],{}," bound are a frequent, easy-to-miss cost. A is the naive default that causes exactly this problem. C is false — ",[39,122586,122587],{},"dyn Trait + 'a"," is valid syntax. D is fabricated.",[15,122590,122591,122604,122642],{},[18,122592,122594,122595,122597,122598,122600,122601,122603],{"id":122593},"q18-a-method-takes-self-and-an-unrelated-str-parameter-and-needs-to-return-a-reference-borrowed-from-the-parameter-not-from-self-why-cant-you-rely-on-elision-here","Q18. A method takes ",[39,122596,112964],{}," and an unrelated ",[39,122599,112302],{}," parameter, and needs to return a reference borrowed from the parameter, not from ",[39,122602,87099],{},". Why can't you rely on elision here?",[23,122605,122607,122619,122625,122633],{"className":122606},[26],[28,122608,122610,122612,122613,122615,122616,122618],{"className":122609},[31],[33,122611],{"disabled":35,"type":36}," Elision rule 3 always binds the output to ",[39,122614,112964],{},"'s lifetime when ",[39,122617,87099],{}," is present, regardless of what you actually want to return — so you must write explicit lifetimes to override it",[28,122620,122622,122624],{"className":122621},[31],[33,122623],{"disabled":35,"type":36}," Methods never support lifetime elision",[28,122626,122628,355,122630,122632],{"className":122627},[31],[33,122629],{"disabled":35,"type":36},[39,122631,112302],{}," parameters are exempt from elision",[28,122634,122636,122638,122639,122641],{"className":122635},[31],[33,122637],{"disabled":35,"type":36}," This works fine with elision as long as the method has a ",[39,122640,113013],{}," receiver instead",[66,122643,122644,122646,122655],{},[69,122645,71],{},[73,122647,122648,122650,122651,122615,122653,122618],{},[76,122649,78],{}," A — Elision rule 3 always binds the output to ",[39,122652,112964],{},[39,122654,87099],{},[73,122656,122657,122659,122660,446,122662,446,122664,122666,122667,122669,122670,122672,122673,122676,122677,122679,122680,122682,122683,137,122685,122687,122688,462],{},[76,122658,84],{}," Rule 3 is a fixed heuristic, not a smart inference — it fires whenever a method has a ",[39,122661,87099],{},[39,122663,112964],{},[39,122665,113013],{}," receiver plus other reference parameters, and unconditionally assigns ",[39,122668,87099],{},"'s lifetime to the elided output. If you actually intend to return something borrowed from the ",[104,122671,33735],{}," parameter, you must write ",[39,122674,122675],{},"fn f\u003C'a, 'b>(&'a self, s: &'b str) -> &'b str"," explicitly, or the code either fails to compile (if ",[39,122678,87099],{},"'s and the intended lifetime genuinely diverge) or silently over-constrains callers to keep ",[39,122681,87099],{}," alive longer than necessary. B, C, and D are fabricated — elision works on methods too, applies to any ",[39,122684,120804],{},[39,122686,113013],{}," follows the identical rule 3 as ",[39,122689,112964],{},[15,122691,122692,122702,122739],{},[18,122693,122695,122696,122698,122699,122701],{"id":122694},"q19-in-a-builder-pattern-struct-why-is-it-usually-better-to-store-owned-string-fields-rather-than-a-str-fields-tied-to-the-builders-lifetime","Q19. In a builder-pattern struct, why is it usually better to store owned ",[39,122697,16721],{}," fields rather than ",[39,122700,122395],{}," fields tied to the builder's lifetime?",[23,122703,122705,122713,122719,122729],{"className":122704},[26],[28,122706,122708,355,122710,122712],{"className":122707},[31],[33,122709],{"disabled":35,"type":36},[39,122711,122395],{}," fields are always a compile error inside structs",[28,122714,122716,122718],{"className":122715},[31],[33,122717],{"disabled":35,"type":36}," Owned fields let the built value (and the builder itself) be returned from functions, stored in collections, or moved across threads without dragging a lifetime parameter through every type that uses the builder",[28,122720,122722,355,122724,122726,122727],{"className":122721},[31],[33,122723],{"disabled":35,"type":36},[39,122725,16721],{}," is faster to compare than ",[39,122728,112302],{},[28,122730,122732,122734,122735,122738],{"className":122731},[31],[33,122733],{"disabled":35,"type":36}," Borrowed fields make ",[39,122736,122737],{},"derive(Clone)"," impossible",[66,122740,122741,122743,122748],{},[69,122742,71],{},[73,122744,122745,122747],{},[76,122746,78],{}," B — Owned fields let the built value (and the builder itself) be returned from functions, stored in collections, or moved across threads without dragging a lifetime parameter through every type that uses the builder",[73,122749,122750,355,122752,122754,122755,122758,122759,122761,122762,122764,122765,122767],{},[76,122751,84],{},[76,122753,930],{}," this is a widely recommended Rust API-design tradeoff — a ",[39,122756,122757],{},"Config\u003C'a>"," builder that borrows its strings infects every function signature and struct that holds a ",[39,122760,98075],{}," with the same ",[39,122763,120753],{},", which is rarely worth the saved allocations for something constructed once and used broadly. A is false — borrowed fields compile fine, they're just viral. C is an unrelated, generally false claim (comparison cost is similar). D is false — ",[39,122766,122174],{}," works on borrowed fields too, it just clones the reference (a pointer copy), not the data.",[15,122769,122770,122778,122822],{},[18,122771,122773,122774,122777],{"id":122772},"q20-code-review-flags-this-function-fn-cache_keyaa-self-id-u32-a-str-used-to-look-up-and-return-a-formatted-key-the-reviewer-says-this-design-is-a-lifetime-trap-waiting-to-bite-the-next-person-who-calls-it-in-a-loop-whats-the-most-likely-underlying-issue","Q20. Code review flags this function: ",[39,122775,122776],{},"fn cache_key\u003C'a>(&'a self, id: u32) -> &'a str",", used to look up and return a formatted key. The reviewer says \"this design is a lifetime trap waiting to bite the next person who calls it in a loop.\" What's the most likely underlying issue?",[23,122779,122781,122799,122807,122816],{"className":122780},[26],[28,122782,122784,122786,122787,122789,122790,122792,122793,122795,122796,122798],{"className":122783},[31],[33,122785],{"disabled":35,"type":36}," Returning ",[39,122788,122395],{}," tied to ",[39,122791,112964],{}," means the borrow of ",[39,122794,87099],{}," must stay alive as long as the returned key is used, which can prevent later mutable access to ",[39,122797,87099],{}," (e.g., inserting into the same cache) within that same scope",[28,122800,122802,355,122804,122806],{"className":122801},[31],[33,122803],{"disabled":35,"type":36},[39,122805,114625],{}," parameters cannot be used inside lifetime-annotated functions",[28,122808,122810,122812,122813,12177],{"className":122809},[31],[33,122811],{"disabled":35,"type":36}," The function should return ",[39,122814,122815],{},"Result\u003C&str, Error>",[28,122817,122819,122821],{"className":122818},[31],[33,122820],{"disabled":35,"type":36}," There is no real issue — the reviewer is being overly cautious",[66,122823,122824,122826,122839],{},[69,122825,71],{},[73,122827,122828,122830,122831,122789,122833,122792,122835,122795,122837,122798],{},[76,122829,78],{}," A — Returning ",[39,122832,122395],{},[39,122834,112964],{},[39,122836,87099],{},[39,122838,87099],{},[73,122840,122841,122843,122844,122847,122848,122850,122851,122854,122855,122857,122858,122860,122861,122863],{},[76,122842,84],{}," This is the classic \"read borrow blocks a later write borrow\" trap: if ",[39,122845,122846],{},"cache_key"," returns a reference borrowed from ",[39,122849,87099],{},", and the caller then tries ",[39,122852,122853],{},"self.insert(...)"," (which needs ",[39,122856,113013],{},") while still holding that returned key, the borrow checker rejects it — even though the two operations don't actually alias the same memory at runtime. ",[76,122859,930],{}," the fix is usually to return an owned ",[39,122862,16721],{}," (or clone before mutating), trading a small allocation for an API that doesn't force awkward borrow-scope gymnastics on every caller. B is a fabricated restriction — primitive parameters don't interact with lifetime annotations. C addresses error handling, not the lifetime coupling being described. D dismisses a real, common production footgun.",[2107,122865,122866],{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-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 .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 .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}",{"title":264,"searchDepth":286,"depth":286,"links":122868},[122869,122871,122873,122875,122877,122878,122880,122881,122883,122884,122885,122887,122889,122891,122893,122895,122896,122898,122900,122902],{"id":120693,"depth":296,"text":122870},"Q1. What does the signature fn longest\u003C'a>(x: &'a str, y: &'a str) -> &'a str actually promise to the caller?",{"id":120772,"depth":296,"text":122872},"Q2. Given fn first_word(s: &str) -> &str, why does this compile without any explicit lifetime annotations?",{"id":120844,"depth":296,"text":122874},"Q3. Why does fn combine(x: &str, y: &str) -> &str fail to compile as written?",{"id":120910,"depth":296,"text":122876},"Q4. In impl\u003C'a> Parser\u003C'a> { fn peek(&self, other: &str) -> &str { ... } }, which lifetime does the returned &str borrow from, per elision rule 3?",{"id":120978,"depth":296,"text":120979},{"id":121120,"depth":296,"text":122879},"Q6. What does the 'static lifetime bound on a reference, as in x: &'static str, guarantee?",{"id":121185,"depth":296,"text":121186},{"id":121288,"depth":296,"text":122882},"Q8. A junior developer claims: \"If I add a T: 'static bound to a generic function, every value passed in must be created before main() starts, like a string literal.\" Is this accurate?",{"id":121402,"depth":296,"text":121403},{"id":121593,"depth":296,"text":121594},{"id":121905,"depth":296,"text":122886},"Q11. Why does this match-based function fail to compile?",{"id":122127,"depth":296,"text":122888},"Q12. Which scenario genuinely requires a struct with two independent lifetime parameters, e.g. struct Pair\u003C'a, 'b>, instead of one shared 'a?",{"id":122201,"depth":296,"text":122890},"Q13. What does the bound fn process\u003CT: Debug + 'a>(item: T) communicate about T?",{"id":122296,"depth":296,"text":122892},"Q14. What is the lifetime of the string literal in let s: &'static str = \"hello\";, and why?",{"id":122391,"depth":296,"text":122894},"Q15. A public API function currently returns &'a str borrowed from an input, forcing every caller to keep the input alive as long as the result. What's the idiomatic best practice when the borrow relationship isn't essential to the API's purpose?",{"id":122463,"depth":296,"text":122464},{"id":122512,"depth":296,"text":122897},"Q17. Why is casually adding dyn Trait + 'static (or its implicit default) to every trait object in a long-lived cache considered a code smell when the objects actually hold short-lived borrowed data?",{"id":122593,"depth":296,"text":122899},"Q18. A method takes &self and an unrelated &str parameter, and needs to return a reference borrowed from the parameter, not from self. Why can't you rely on elision here?",{"id":122694,"depth":296,"text":122901},"Q19. In a builder-pattern struct, why is it usually better to store owned String fields rather than &'a str fields tied to the builder's lifetime?",{"id":122772,"depth":296,"text":122903},"Q20. Code review flags this function: fn cache_key\u003C'a>(&'a self, id: u32) -> &'a str, used to look up and return a formatted key. The reviewer says \"this design is a lifetime trap waiting to bite the next person who calls it in a loop.\" What's the most likely underlying issue?",{},"\u002Frust\u002F10-lifetimes",{"title":120683,"description":264},"rust\u002F10-lifetimes","DYwCiSkjpVSAW2PyUof6H10m_t2OT5BB6DikxO4FDKg",{"id":122910,"title":122911,"body":122912,"description":264,"extension":2144,"meta":125225,"navigation":35,"path":125226,"seo":125227,"stem":125228,"__hash__":125229},"content\u002Frust\u002F11-structs.md","11 — Structs",{"type":8,"value":122913,"toc":125203},[122914,122917,123102,123199,123282,123471,123543,123756,123820,124068,124151,124350,124439,125200],[11,122915,122911],{"id":122916},"_11-structs",[15,122918,122919,122927,123004,123054],{"language":111909},[18,122920,122922,122923,122926],{"id":122921},"q1-given-struct-user-name-string-age-u8-active-bool-what-does-struct-update-syntax-do-here","Q1. Given ",[39,122924,122925],{},"struct User { name: String, age: u8, active: bool }",", what does struct update syntax do here?",[257,122928,122929],{"language":111909},[260,122930,122932],{"className":111918,"code":122931,"language":111909,"meta":264,"style":264},"let base = User { name: String::from(\"Alice\"), age: 30, active: true };\nlet updated = User { age: 31, ..base };\n",[39,122933,122934,122978],{"__ignoreMap":264},[268,122935,122936,122938,122940,122942,122945,122948,122950,122952,122954,122956,122958,122961,122964,122966,122969,122972,122974,122976],{"class":270,"line":271},[268,122937,240],{"class":274},[268,122939,13781],{"class":282},[268,122941,302],{"class":274},[268,122943,122944],{"class":278}," User",[268,122946,122947],{"class":282}," { name",[268,122949,10728],{"class":274},[268,122951,114407],{"class":278},[268,122953,84903],{"class":274},[268,122955,44539],{"class":278},[268,122957,622],{"class":282},[268,122959,122960],{"class":289},"\"Alice\"",[268,122962,122963],{"class":282},"), age",[268,122965,10728],{"class":274},[268,122967,122968],{"class":305}," 30",[268,122970,122971],{"class":282},", active",[268,122973,10728],{"class":274},[268,122975,7905],{"class":305},[268,122977,2790],{"class":282},[268,122979,122980,122982,122985,122987,122989,122992,122994,122997,122999,123001],{"class":270,"line":286},[268,122981,240],{"class":274},[268,122983,122984],{"class":282}," updated ",[268,122986,302],{"class":274},[268,122988,122944],{"class":278},[268,122990,122991],{"class":282}," { age",[268,122993,10728],{"class":274},[268,122995,122996],{"class":305}," 31",[268,122998,42],{"class":282},[268,123000,86888],{"class":274},[268,123002,123003],{"class":282},"base };\n",[23,123005,123007,123017,123035,123046],{"className":123006},[26],[28,123008,123010,74675,123012,123014,123015],{"className":123009},[31],[33,123011],{"disabled":35,"type":36},[39,123013,13764],{}," in place, changing only ",[39,123016,59116],{},[28,123018,123020,123022,123023,123026,123027,137,123029,123031,123032],{"className":123019},[31],[33,123021],{"disabled":35,"type":36}," It creates a new ",[39,123024,123025],{},"User",", copying\u002Fmoving every field not explicitly listed from ",[39,123028,13764],{},[39,123030,59116],{}," overrides ",[39,123033,123034],{},"base.age",[28,123036,123038,110612,123040,123042,123043],{"className":123037},[31],[33,123039],{"disabled":35,"type":36},[39,123041,13764],{}," and the new fields into a ",[39,123044,123045],{},"HashMap",[28,123047,123049,117747,123051,123053],{"className":123048},[31],[33,123050],{"disabled":35,"type":36},[39,123052,86888],{}," requires all fields to be listed",[66,123055,123056,123058,123071],{},[69,123057,71],{},[73,123059,123060,123062,123063,123026,123065,137,123067,123031,123069],{},[76,123061,78],{}," B — It creates a new ",[39,123064,123025],{},[39,123066,13764],{},[39,123068,59116],{},[39,123070,123034],{},[73,123072,123073,355,123075,123078,123079,123081,123082,123085,123086,123088,123089,123091,123092,123094,123095,123097,123098,123101],{},[76,123074,84],{},[39,123076,123077],{},"..base"," fills in every remaining field from ",[39,123080,13764],{},", field-by-field, as if you'd written ",[39,123083,123084],{},"name: base.name, active: base.active"," yourself. It does not mutate ",[39,123087,13764],{}," — it constructs an entirely new value. A is wrong because ",[39,123090,13764],{}," is left untouched (aside from any fields moved out of it, see later questions). C is a fabricated behavior; struct update syntax has nothing to do with ",[39,123093,123045],{},". D is wrong — ",[39,123096,123077],{}," is exactly the mechanism that lets you ",[104,123099,123100],{},"avoid"," listing every field.",[15,123103,123104,123108,123131,123172],{"language":111909},[18,123105,123107],{"id":123106},"q2-what-kind-of-struct-is-this-and-how-do-you-construct-one","Q2. What kind of struct is this, and how do you construct one?",[257,123109,123110],{"language":111909},[260,123111,123113],{"className":111918,"code":123112,"language":111909,"meta":264,"style":264},"struct Point(f64, f64);\n",[39,123114,123115],{"__ignoreMap":264},[268,123116,123117,123119,123121,123123,123125,123127,123129],{"class":270,"line":271},[268,123118,121198],{"class":274},[268,123120,30134],{"class":278},[268,123122,622],{"class":282},[268,123124,115196],{"class":278},[268,123126,42],{"class":282},[268,123128,115196],{"class":278},[268,123130,628],{"class":282},[23,123132,123134,123143,123157,123166],{"className":123133},[26],[28,123135,123137,123139,123140],{"className":123136},[31],[33,123138],{"disabled":35,"type":36}," A unit struct; construct with ",[39,123141,123142],{},"Point;",[28,123144,123146,123148,123149,123152,123153,186,123155],{"className":123145},[31],[33,123147],{"disabled":35,"type":36}," A tuple struct; construct with ",[39,123150,123151],{},"Point(1.0, 2.0)",", and access fields with ",[39,123154,115281],{},[39,123156,115284],{},[28,123158,123160,123162,123163],{"className":123159},[31],[33,123161],{"disabled":35,"type":36}," An enum variant; construct with ",[39,123164,123165],{},"Point::new(1.0, 2.0)",[28,123167,123169,123171],{"className":123168},[31],[33,123170],{"disabled":35,"type":36}," Invalid syntax — structs require named fields",[66,123173,123174,123176,123187],{},[69,123175,71],{},[73,123177,123178,123180,123181,123152,123183,186,123185],{},[76,123179,78],{}," B — A tuple struct; construct with ",[39,123182,123151],{},[39,123184,115281],{},[39,123186,115284],{},[73,123188,123189,123191,123192,123194,123195,123198],{},[76,123190,84],{}," Tuple structs have a name but unnamed, positionally-indexed fields, giving you a distinct type (unlike a plain ",[39,123193,116690],{}," tuple) while keeping tuple-like ergonomics. A confuses this with a unit struct (",[39,123196,123197],{},"struct Marker;",", zero fields). C is false — this is not enum syntax at all. D is wrong — tuple structs with unnamed positional fields are valid, standard Rust.",[15,123200,123201,123205,123221,123253],{"language":111909},[18,123202,123204],{"id":123203},"q3-what-is-a-unit-struct-and-what-is-it-typically-used-for","Q3. What is a \"unit struct,\" and what is it typically used for?",[257,123206,123207],{"language":111909},[260,123208,123210],{"className":111918,"code":123209,"language":111909,"meta":264,"style":264},"struct Meters;\n",[39,123211,123212],{"__ignoreMap":264},[268,123213,123214,123216,123219],{"class":270,"line":271},[268,123215,121198],{"class":274},[268,123217,123218],{"class":278}," Meters",[268,123220,293],{"class":282},[23,123222,123224,123230,123236,123244],{"className":123223},[26],[28,123225,123227,123229],{"className":123226},[31],[33,123228],{"disabled":35,"type":36}," A struct with exactly one field",[28,123231,123233,123235],{"className":123232},[31],[33,123234],{"disabled":35,"type":36}," A zero-sized struct with no fields at all, commonly used as a marker type or to implement a trait with no data",[28,123237,123239,123241,123242,8705],{"className":123238},[31],[33,123240],{"disabled":35,"type":36}," A struct that can only hold ",[39,123243,114808],{},[28,123245,123247,123249,123250],{"className":123246},[31],[33,123248],{"disabled":35,"type":36}," Shorthand for ",[39,123251,123252],{},"struct Meters { value: () }",[66,123254,123255,123257,123262],{},[69,123256,71],{},[73,123258,123259,123261],{},[76,123260,78],{}," B — A zero-sized struct with no fields at all, commonly used as a marker type or to implement a trait with no data",[73,123263,123264,355,123266,123269,123270,123272,123273,830,123276,104223,123278,123281],{},[76,123265,84],{},[39,123267,123268],{},"struct Meters;"," declares a type with zero size and zero fields — it exists purely at the type level, useful for marker types, phantom-type tags, or as a target for trait implementations where behavior matters but data doesn't. A confuses it with a newtype\u002Ftuple struct holding one value. C is fabricated. D is close conceptually but wrong mechanically — a unit struct has no field at all, not an explicit ",[39,123271,16952],{}," field; ",[39,123274,123275],{},"size_of::\u003CMeters>()",[39,123277,3307],{},[39,123279,123280],{},"size_of::\u003C()>()",", but they are different types.",[15,123283,123284,123292,123384,123436],{"language":111909},[18,123285,123287,123288,123291],{"id":123286},"q4-whats-the-essential-difference-between-these-two-impl-block-items","Q4. What's the essential difference between these two ",[39,123289,123290],{},"impl"," block items?",[257,123293,123294],{"language":111909},[260,123295,123297],{"className":111918,"code":123296,"language":111909,"meta":264,"style":264},"impl Rectangle {\n    fn area(&self) -> u32 { self.width * self.height }\n    fn square(size: u32) -> Rectangle { Rectangle { width: size, height: size } }\n}\n",[39,123298,123299,123307,123343,123380],{"__ignoreMap":264},[268,123300,123301,123303,123305],{"class":270,"line":271},[268,123302,123290],{"class":274},[268,123304,32222],{"class":278},[268,123306,9914],{"class":282},[268,123308,123309,123311,123313,123315,123317,123319,123321,123323,123325,123327,123329,123331,123334,123336,123338,123340],{"class":270,"line":286},[268,123310,120364],{"class":274},[268,123312,32275],{"class":278},[268,123314,622],{"class":282},[268,123316,85350],{"class":274},[268,123318,87099],{"class":305},[268,123320,6131],{"class":282},[268,123322,113308],{"class":274},[268,123324,112377],{"class":278},[268,123326,20200],{"class":282},[268,123328,87099],{"class":305},[268,123330,462],{"class":274},[268,123332,123333],{"class":282},"width ",[268,123335,6134],{"class":274},[268,123337,96472],{"class":305},[268,123339,462],{"class":274},[268,123341,123342],{"class":282},"height }\n",[268,123344,123345,123347,123349,123352,123354,123356,123358,123360,123362,123364,123367,123370,123372,123375,123377],{"class":270,"line":296},[268,123346,120364],{"class":274},[268,123348,31438],{"class":278},[268,123350,123351],{"class":282},"(size",[268,123353,10728],{"class":274},[268,123355,112377],{"class":278},[268,123357,6131],{"class":282},[268,123359,113308],{"class":274},[268,123361,32222],{"class":278},[268,123363,20200],{"class":282},[268,123365,123366],{"class":278},"Rectangle",[268,123368,123369],{"class":282}," { width",[268,123371,10728],{"class":274},[268,123373,123374],{"class":282}," size, height",[268,123376,10728],{"class":274},[268,123378,123379],{"class":282}," size } }\n",[268,123381,123382],{"class":270,"line":311},[268,123383,314],{"class":282},[23,123385,123387,123398,123420,123426],{"className":123386},[26],[28,123388,123390,355,123392,123394,123395,123397],{"className":123389},[31],[33,123391],{"disabled":35,"type":36},[39,123393,32374],{}," is an associated function; ",[39,123396,31493],{}," is a method",[28,123399,123401,355,123403,123405,123406,123408,123409,5789,123412,123414,123415,123408,123417,2690],{"className":123400},[31],[33,123402],{"disabled":35,"type":36},[39,123404,32374],{}," is a method (takes ",[39,123407,87099],{},", called as ",[39,123410,123411],{},"rect.area()",[39,123413,31493],{}," is an associated function (no ",[39,123416,87099],{},[39,123418,123419],{},"Rectangle::square(5)",[28,123421,123423,123425],{"className":123422},[31],[33,123424],{"disabled":35,"type":36}," Both are methods, just with different return types",[28,123427,123429,355,123431,123433,123434,67669],{"className":123428},[31],[33,123430],{"disabled":35,"type":36},[39,123432,31493],{}," cannot be called without first creating a ",[39,123435,123366],{},[66,123437,123438,123440,123456],{},[69,123439,71],{},[73,123441,123442,1727,123444,123405,123446,123408,123448,5789,123450,123414,123452,123408,123454,2690],{},[76,123443,78],{},[39,123445,32374],{},[39,123447,87099],{},[39,123449,123411],{},[39,123451,31493],{},[39,123453,87099],{},[39,123455,123419],{},[73,123457,123458,123460,123461,123463,123464,123467,123468,123470],{},[76,123459,84],{}," The presence or absence of a ",[39,123462,87099],{}," parameter is exactly what distinguishes a method from an associated function in Rust terminology. ",[39,123465,123466],{},"Rectangle::new","-style constructors are the classic associated-function use case, since you don't yet have an instance to call a method on. A has the terms backwards. C ignores the defining distinction. D is backwards — associated functions are exactly the tool for building the ",[104,123469,12590],{}," instance, callable without any existing value.",[15,123472,123473,123483,123516],{},[18,123474,123476,123477,123480,123481,1685],{"id":123475},"q5-which-method-receiver-should-fn-describeself-string-use-if-it-only-needs-to-read-fields-and-return-a-new-owned-string","Q5. Which method receiver should ",[39,123478,123479],{},"fn describe(&self) -> String"," use if it only needs to read fields and return a new owned ",[39,123482,16721],{},[23,123484,123486,123494,123501,123508],{"className":123485},[26],[28,123487,123489,355,123491,123493],{"className":123488},[31],[33,123490],{"disabled":35,"type":36},[39,123492,87099],{}," (take ownership)",[28,123495,123497,355,123499],{"className":123496},[31],[33,123498],{"disabled":35,"type":36},[39,123500,113013],{},[28,123502,123504,355,123506],{"className":123503},[31],[33,123505],{"disabled":35,"type":36},[39,123507,112964],{},[28,123509,123511,355,123513],{"className":123510},[31],[33,123512],{"disabled":35,"type":36},[39,123514,123515],{},"&&self",[66,123517,123518,123520,123526],{},[69,123519,71],{},[73,123521,123522,1004,123524],{},[76,123523,78],{},[39,123525,112964],{},[73,123527,123528,123530,123531,123533,123534,123536,123537,123539,123540,123542],{},[76,123529,84],{}," Reading fields without needing to mutate or consume the struct calls for an immutable borrow, ",[39,123532,112964],{}," — this is by far the most common receiver, and it lets the caller keep using the instance afterward. ",[39,123535,87099],{}," (A) would consume the instance, making it unusable after the call, which is unnecessary overhead and an ergonomics regression if the caller wanted to keep the value. ",[39,123538,113013],{}," (B) would needlessly require the caller to have (or make) a mutable binding when no mutation happens. ",[39,123541,123515],{}," (D) is not valid receiver syntax.",[15,123544,123545,123555,123657,123703],{"language":111909},[18,123546,123548,123549,123551,123552,123554],{"id":123547},"q6-what-does-calling-a-method-that-takes-self-by-value-not-self-do-to-the-original-variable","Q6. What does calling a method that takes ",[39,123550,87099],{}," (by value, not ",[39,123553,112964],{},") do to the original variable?",[257,123556,123557],{"language":111909},[260,123558,123560],{"className":111918,"code":123559,"language":111909,"meta":264,"style":264},"struct Wrapper(String);\nimpl Wrapper {\n    fn into_inner(self) -> String { self.0 }\n}\nlet w = Wrapper(String::from(\"data\"));\nlet s = w.into_inner();\n",[39,123561,123562,123575,123583,123610,123614,123640],{"__ignoreMap":264},[268,123563,123564,123566,123569,123571,123573],{"class":270,"line":271},[268,123565,121198],{"class":274},[268,123567,123568],{"class":278}," Wrapper",[268,123570,622],{"class":282},[268,123572,16721],{"class":278},[268,123574,628],{"class":282},[268,123576,123577,123579,123581],{"class":270,"line":286},[268,123578,123290],{"class":274},[268,123580,123568],{"class":278},[268,123582,9914],{"class":282},[268,123584,123585,123587,123590,123592,123594,123596,123598,123600,123602,123604,123606,123608],{"class":270,"line":296},[268,123586,120364],{"class":274},[268,123588,123589],{"class":278}," into_inner",[268,123591,622],{"class":282},[268,123593,87099],{"class":305},[268,123595,6131],{"class":282},[268,123597,113308],{"class":274},[268,123599,114407],{"class":278},[268,123601,20200],{"class":282},[268,123603,87099],{"class":305},[268,123605,462],{"class":274},[268,123607,3307],{"class":305},[268,123609,29394],{"class":282},[268,123611,123612],{"class":270,"line":311},[268,123613,314],{"class":282},[268,123615,123616,123618,123621,123623,123625,123627,123629,123631,123633,123635,123638],{"class":270,"line":788},[268,123617,240],{"class":274},[268,123619,123620],{"class":282}," w ",[268,123622,302],{"class":274},[268,123624,123568],{"class":278},[268,123626,622],{"class":282},[268,123628,16721],{"class":278},[268,123630,84903],{"class":274},[268,123632,44539],{"class":278},[268,123634,622],{"class":282},[268,123636,123637],{"class":289},"\"data\"",[268,123639,4818],{"class":282},[268,123641,123642,123644,123646,123648,123650,123652,123655],{"class":270,"line":1951},[268,123643,240],{"class":274},[268,123645,72278],{"class":282},[268,123647,302],{"class":274},[268,123649,32067],{"class":282},[268,123651,462],{"class":274},[268,123653,123654],{"class":278},"into_inner",[268,123656,794],{"class":282},[23,123658,123660,123669,123683,123691],{"className":123659},[26],[28,123661,123663,355,123665,123668],{"className":123662},[31],[33,123664],{"disabled":35,"type":36},[39,123666,123667],{},"w"," is still usable after the call, since Rust copies structs implicitly",[28,123670,123672,355,123674,123676,123677,123679,123680,123682],{"className":123671},[31],[33,123673],{"disabled":35,"type":36},[39,123675,123667],{}," is moved into ",[39,123678,123654],{},", so using ",[39,123681,123667],{}," again after this line is a compile error",[28,123684,123686,355,123688,123690],{"className":123685},[31],[33,123687],{"disabled":35,"type":36},[39,123689,123667],{}," is automatically cloned before the call",[28,123692,123694,123696,123697,123700,123701],{"className":123693},[31],[33,123695],{"disabled":35,"type":36}," This only compiles if ",[39,123698,123699],{},"Wrapper"," derives ",[39,123702,114164],{},[66,123704,123705,123707,123717],{},[69,123706,71],{},[73,123708,123709,1727,123711,123676,123713,123679,123715,123682],{},[76,123710,78],{},[39,123712,123667],{},[39,123714,123654],{},[39,123716,123667],{},[73,123718,123719,812,123721,123723,123724,123726,123727,123729,123730,57690,123732,123734,123735,123737,123738,123740,123741,355,123743,123746,123747,42,123749,123751,123752,355,123754,462],{},[76,123720,84],{},[39,123722,87099],{},"-by-value receiver takes ownership, exactly like passing ",[39,123725,123667],{}," to any function that takes ",[39,123728,123699],{}," by value — ",[39,123731,123699],{},[39,123733,16721],{},", which is not ",[39,123736,114164],{},", so this is a move, not a copy. Any later use of ",[39,123739,123667],{}," triggers \"use of moved value.\" A is the common mistaken assumption from languages with reference semantics by default. C is false — Rust never inserts implicit clones. D is backwards — if ",[39,123742,123699],{},[104,123744,123745],{},"did"," derive ",[39,123748,114164],{},[39,123750,123667],{}," would still be usable afterward because the value gets copied instead of moved, but that's not the case here since it contains a non-",[39,123753,114164],{},[39,123755,16721],{},[15,123757,123758,123765,123792],{},[18,123759,123761,123762,123764],{"id":123760},"q7-what-visibility-do-struct-fields-have-by-default-inside-their-own-module-if-declared-without-a-pub-keyword","Q7. What visibility do struct fields have by default, inside their own module, if declared without a ",[39,123763,117577],{}," keyword?",[23,123766,123768,123774,123780,123786],{"className":123767},[26],[28,123769,123771,123773],{"className":123770},[31],[33,123772],{"disabled":35,"type":36}," Public everywhere by default",[28,123775,123777,123779],{"className":123776},[31],[33,123778],{"disabled":35,"type":36}," Private — accessible only within the module the struct is defined in (and its descendants)",[28,123781,123783,123785],{"className":123782},[31],[33,123784],{"disabled":35,"type":36}," Public within the same crate only, regardless of module",[28,123787,123789,123791],{"className":123788},[31],[33,123790],{"disabled":35,"type":36}," Fields have no visibility concept; only whole structs can be public or private",[66,123793,123794,123796,123801],{},[69,123795,71],{},[73,123797,123798,123800],{},[76,123799,78],{}," B — Private — accessible only within the module the struct is defined in (and its descendants)",[73,123802,123803,123805,123806,123808,123809,123812,123813,123816,123817,123819],{},[76,123804,84],{}," Struct fields are private by default, even if the struct itself is ",[39,123807,117577],{}," — this is a frequent surprise for newcomers who mark ",[39,123810,123811],{},"pub struct Foo"," and then can't access ",[39,123814,123815],{},"foo.bar"," from another module until they also add ",[39,123818,117577],{}," to the field itself. A is wrong and is the exact misconception this trips people on. C invents a crate-wide default that doesn't exist. D is false — Rust does apply per-field visibility, independent of the struct's own visibility.",[15,123821,123822,123833,123934,123989],{"language":111909},[18,123823,123825,123826,123828,123829,123832],{"id":123824},"q8-what-happens-when-you-use-struct-update-syntax-where-the-base-struct-contains-a-non-copy-field-that-you-dont-override","Q8. What happens when you use struct update syntax where the base struct contains a non-",[39,123827,114164],{}," field that you ",[104,123830,123831],{},"don't"," override?",[257,123834,123835],{"language":111909},[260,123836,123838],{"className":111918,"code":123837,"language":111909,"meta":264,"style":264},"struct Config { name: String, retries: u32 }\nlet base = Config { name: String::from(\"svc\"), retries: 3 };\nlet updated = Config { retries: 5, ..base };\nprintln!(\"{}\", base.name);\n",[39,123839,123840,123861,123895,123918],{"__ignoreMap":264},[268,123841,123842,123844,123846,123848,123850,123852,123855,123857,123859],{"class":270,"line":271},[268,123843,121198],{"class":274},[268,123845,97944],{"class":278},[268,123847,122947],{"class":282},[268,123849,10728],{"class":274},[268,123851,114407],{"class":278},[268,123853,123854],{"class":282},", retries",[268,123856,10728],{"class":274},[268,123858,112377],{"class":278},[268,123860,29394],{"class":282},[268,123862,123863,123865,123867,123869,123871,123873,123875,123877,123879,123881,123883,123886,123889,123891,123893],{"class":270,"line":286},[268,123864,240],{"class":274},[268,123866,13781],{"class":282},[268,123868,302],{"class":274},[268,123870,97944],{"class":278},[268,123872,122947],{"class":282},[268,123874,10728],{"class":274},[268,123876,114407],{"class":278},[268,123878,84903],{"class":274},[268,123880,44539],{"class":278},[268,123882,622],{"class":282},[268,123884,123885],{"class":289},"\"svc\"",[268,123887,123888],{"class":282},"), retries",[268,123890,10728],{"class":274},[268,123892,3396],{"class":305},[268,123894,2790],{"class":282},[268,123896,123897,123899,123901,123903,123905,123908,123910,123912,123914,123916],{"class":270,"line":296},[268,123898,240],{"class":274},[268,123900,122984],{"class":282},[268,123902,302],{"class":274},[268,123904,97944],{"class":278},[268,123906,123907],{"class":282}," { retries",[268,123909,10728],{"class":274},[268,123911,2387],{"class":305},[268,123913,42],{"class":282},[268,123915,86888],{"class":274},[268,123917,123003],{"class":282},[268,123919,123920,123922,123924,123926,123929,123931],{"class":270,"line":311},[268,123921,118575],{"class":278},[268,123923,622],{"class":282},[268,123925,113830],{"class":289},[268,123927,123928],{"class":282},", base",[268,123930,462],{"class":274},[268,123932,123933],{"class":282},"name);\n",[23,123935,123937,123949,123968,123976],{"className":123936},[26],[28,123938,123940,112958,123942,123945,123946,123948],{"className":123939},[31],[33,123941],{"disabled":35,"type":36},[39,123943,123944],{},"base.name"," is still accessible because ",[39,123947,123077],{}," only borrows",[28,123950,123952,123954,123955,123957,123958,46500,123960,1179,123962,123964,123965,123967],{"className":123951},[31],[33,123953],{"disabled":35,"type":36}," Fails to compile — ",[39,123956,14605],{}," is moved out of ",[39,123959,13764],{},[39,123961,23520],{},[39,123963,13764],{}," (or at least ",[39,123966,123944],{},") can no longer be used as a whole",[28,123969,123971,355,123973,123975],{"className":123970},[31],[33,123972],{"disabled":35,"type":36},[39,123974,123944],{}," is silently cloned automatically",[28,123977,123979,50010,123981,123983,123984,123986,123987],{"className":123978},[31],[33,123980],{"disabled":35,"type":36},[39,123982,7423],{}," fails, since ",[39,123985,114625],{}," isn't ",[39,123988,114164],{},[66,123990,123991,123993,124008],{},[69,123992,71],{},[73,123994,123995,123997,123998,123957,124000,46500,124002,1179,124004,123964,124006,123967],{},[76,123996,78],{}," B — Fails to compile — ",[39,123999,14605],{},[39,124001,13764],{},[39,124003,23520],{},[39,124005,13764],{},[39,124007,123944],{},[73,124009,124010,355,124012,124014,124015,124017,124018,124020,124021,81504,124023,124025,124026,124028,124029,9138,124032,124034,124035,124037,124038,124040,124041,124043,124044,124047,124048,124051,124052,830,124054,2182,124056,124058,124059,124061,124062,124064,124065,124067],{},[76,124011,84],{},[39,124013,123077],{}," moves every non-overridden, non-",[39,124016,114164],{}," field out of ",[39,124019,13764],{}," field-by-field. Since ",[39,124022,14605],{},[39,124024,16721],{},") isn't ",[39,124027,114164],{},", it's moved into ",[39,124030,124031],{},"updated.name",[39,124033,13764],{}," partially moved — the compiler then rejects ",[39,124036,123944],{}," (and any whole-",[39,124039,13764],{}," use) with \"value borrowed here after partial move\" \u002F \"use of moved value.\" ",[76,124042,930],{}," the fix is to ",[39,124045,124046],{},".clone()"," the field explicitly if you need both, e.g. ",[39,124049,124050],{},"name: base.name.clone(), ..base",". Note ",[39,124053,7423],{},[39,124055,114625],{},[39,124057,114164],{},"), so overriding it doesn't move anything — but that's irrelevant since it was overridden, not taken from ",[39,124060,13764],{},", and D wrongly claims only ",[39,124063,7423],{}," is the problem when the real issue is ",[39,124066,14605],{},". A and C both falsely assume Rust performs implicit borrowing\u002Fcloning here.",[15,124069,124070,124088,124124],{},[18,124071,124073,124074,124077,124078,124080,124081,124084,124085,1685],{"id":124072},"q9-calling-rectanglesquare0-on-a-tuple-free-square-associated-function-that-builds-rectangle-width-size-height-size-what-happens-with-size-0","Q9. Calling ",[39,124075,124076],{},"Rectangle::square(0)"," on a tuple-free ",[39,124079,31493],{}," associated function that builds ",[39,124082,124083],{},"Rectangle { width: size, height: size }"," — what happens with ",[39,124086,124087],{},"size = 0",[23,124089,124091,124097,124103,124115],{"className":124090},[26],[28,124092,124094,124096],{"className":124093},[31],[33,124095],{"disabled":35,"type":36}," Compile error — struct fields cannot be zero",[28,124098,124100,124102],{"className":124099},[31],[33,124101],{"disabled":35,"type":36}," Panics at runtime because zero-area rectangles are invalid",[28,124104,124106,124108,124109,2029,124111,124114],{"className":124105},[31],[33,124107],{"disabled":35,"type":36}," Compiles and runs fine, producing a ",[39,124110,123366],{},[39,124112,124113],{},"width: 0, height: 0","; nothing about the type prevents degenerate values",[28,124116,124118,124120,124121,124123],{"className":124117},[31],[33,124119],{"disabled":35,"type":36}," Returns ",[39,124122,90944],{}," since the rectangle would be empty",[66,124125,124126,124128,124137],{},[69,124127,71],{},[73,124129,124130,124132,124133,2029,124135,124114],{},[76,124131,78],{}," C — Compiles and runs fine, producing a ",[39,124134,123366],{},[39,124136,124113],{},[73,124138,124139,124141,124142,124144,124145,124147,124148,124150],{},[76,124140,84],{}," Plain struct fields with primitive types like ",[39,124143,114625],{}," accept any value in their range, including ",[39,124146,3307],{}," — the struct itself enforces no domain invariant unless you add validation logic (e.g., a fallible constructor returning ",[39,124149,110110],{},", or a newtype with private fields and a checked constructor). This is an edge case worth internalizing: structs alone don't guarantee \"sensible\" values. A, B, and D all invent validation that plain struct construction does not perform.",[15,124152,124153,124157,124247,124298],{"language":111909},[18,124154,124156],{"id":124155},"q10-whats-the-pitfall-in-this-destructuring-pattern-using-struct-update-syntax-combined-with-a-method-call","Q10. What's the pitfall in this destructuring pattern using struct update syntax combined with a method call?",[257,124158,124159],{"language":111909},[260,124160,124162],{"className":111918,"code":124161,"language":111909,"meta":264,"style":264},"struct Session { token: String, expires_in: u32 }\nimpl Session {\n    fn refreshed(self, new_token: String) -> Session {\n        Session { token: new_token, ..self }\n    }\n}\n",[39,124163,124164,124187,124195,124221,124239,124243],{"__ignoreMap":264},[268,124165,124166,124168,124171,124174,124176,124178,124181,124183,124185],{"class":270,"line":271},[268,124167,121198],{"class":274},[268,124169,124170],{"class":278}," Session",[268,124172,124173],{"class":282}," { token",[268,124175,10728],{"class":274},[268,124177,114407],{"class":278},[268,124179,124180],{"class":282},", expires_in",[268,124182,10728],{"class":274},[268,124184,112377],{"class":278},[268,124186,29394],{"class":282},[268,124188,124189,124191,124193],{"class":270,"line":286},[268,124190,123290],{"class":274},[268,124192,124170],{"class":278},[268,124194,9914],{"class":282},[268,124196,124197,124199,124202,124204,124206,124209,124211,124213,124215,124217,124219],{"class":270,"line":296},[268,124198,120364],{"class":274},[268,124200,124201],{"class":278}," refreshed",[268,124203,622],{"class":282},[268,124205,87099],{"class":305},[268,124207,124208],{"class":282},", new_token",[268,124210,10728],{"class":274},[268,124212,114407],{"class":278},[268,124214,6131],{"class":282},[268,124216,113308],{"class":274},[268,124218,124170],{"class":278},[268,124220,9914],{"class":282},[268,124222,124223,124226,124228,124230,124233,124235,124237],{"class":270,"line":311},[268,124224,124225],{"class":278},"        Session",[268,124227,124173],{"class":282},[268,124229,10728],{"class":274},[268,124231,124232],{"class":282}," new_token, ",[268,124234,86888],{"class":274},[268,124236,87099],{"class":305},[268,124238,29394],{"class":282},[268,124240,124241],{"class":270,"line":788},[268,124242,11972],{"class":282},[268,124244,124245],{"class":270,"line":1951},[268,124246,314],{"class":282},[23,124248,124250,124260,124276,124287],{"className":124249},[26],[28,124251,124253,124255,124256,124259],{"className":124252},[31],[33,124254],{"disabled":35,"type":36}," This never compiles — ",[39,124257,124258],{},"..self"," cannot be used inside a method",[28,124261,124263,355,124265,124267,124268,124271,124272,124275],{"className":124262},[31],[33,124264],{"disabled":35,"type":36},[39,124266,87099],{}," is consumed by value here, so ",[39,124269,124270],{},"refreshed"," can only be called once per ",[39,124273,124274],{},"Session"," instance (each call requires ownership, matching the \"produce a new session, discard the old\" intent)",[28,124277,124279,355,124281,124284,124285],{"className":124278},[31],[33,124280],{"disabled":35,"type":36},[39,124282,124283],{},"expires_in"," is silently reset to ",[39,124286,3307],{},[28,124288,124290,355,124292,124295,124296],{"className":124289},[31],[33,124291],{"disabled":35,"type":36},[39,124293,124294],{},"new_token"," must implement ",[39,124297,114164],{},[66,124299,124300,124302,124312],{},[69,124301,71],{},[73,124303,124304,1727,124306,124267,124308,124271,124310,124275],{},[76,124305,78],{},[39,124307,87099],{},[39,124309,124270],{},[39,124311,124274],{},[73,124313,124314,124316,124317,124319,124320,124322,124323,124325,124326,124328,124329,124331,124332,124334,124335,124337,124338,124340,124341,124343,124344,124346,124347,124349],{},[76,124315,84],{}," Taking ",[39,124318,87099],{}," by value is a deliberate, idiomatic choice for \"transform and replace\" APIs — it deliberately prevents the caller from accidentally reusing the stale ",[39,124321,124274],{}," after refreshing, since the old value is moved into the method and never returned. ",[39,124324,124258],{}," inside the struct literal simply copies\u002Fmoves ",[39,124327,87099],{},"'s remaining fields (",[39,124330,124283],{},") into the new instance, exactly like the earlier update-syntax examples, just now with ",[39,124333,87099],{}," as the base. A is false — ",[39,124336,124258],{}," is valid anywhere a struct literal appears, including method bodies. C is fabricated; ",[39,124339,124283],{}," carries over unchanged. D is false — ",[39,124342,124294],{}," is being moved in directly as a field value, not through update syntax, and ",[39,124345,16721],{}," need not be ",[39,124348,114164],{}," for that.",[15,124351,124352,124366,124410],{},[18,124353,124355,124356,186,124359,124362,124363,1685],{"id":124354},"q11-two-struct-types-happen-to-have-identical-field-names-and-types-struct-metersf64-and-struct-feetf64-what-happens-if-you-try-let-m-meters-feet30","Q11. Two struct types happen to have identical field names and types: ",[39,124357,124358],{},"struct Meters(f64)",[39,124360,124361],{},"struct Feet(f64)",". What happens if you try ",[39,124364,124365],{},"let m: Meters = Feet(3.0);",[23,124367,124369,124378,124391,124404],{"className":124368},[26],[28,124370,124372,124374,124375,124377],{"className":124371},[31],[33,124373],{"disabled":35,"type":36}," Compiles fine — both wrap an ",[39,124376,115196],{},", so they're structurally interchangeable",[28,124379,124381,124383,124384,186,124387,124390],{"className":124380},[31],[33,124382],{"disabled":35,"type":36}," Compile error — Rust's type system is nominal, not structural; ",[39,124385,124386],{},"Meters",[39,124388,124389],{},"Feet"," are distinct types even with identical layout",[28,124392,124394,124396,124397,124400,124401],{"className":124393},[31],[33,124395],{"disabled":35,"type":36}," Compiles, but ",[39,124398,124399],{},"m.0"," will be ",[39,124402,124403],{},"0.0",[28,124405,124407,124409],{"className":124406},[31],[33,124408],{"disabled":35,"type":36}," Only fails at runtime with a type-mismatch panic",[66,124411,124412,124414,124423],{},[69,124413,71],{},[73,124415,124416,124418,124419,186,124421,124390],{},[76,124417,78],{}," B — Compile error — Rust's type system is nominal, not structural; ",[39,124420,124386],{},[39,124422,124389],{},[73,124424,124425,124427,124428,186,124430,124432,124433,124435,124436,124438],{},[76,124426,84],{}," This is precisely the value of the newtype pattern: even though ",[39,124429,124386],{},[39,124431,124389],{}," are both single-field tuple structs wrapping ",[39,124434,115196],{}," with identical memory layout, Rust treats them as unrelated types by name\u002Fdeclaration, not by shape. ",[76,124437,582],{}," this is what prevents unit-confusion bugs (e.g., mixing up meters and feet) at compile time rather than in production. A describes structural typing, which languages like TypeScript use but Rust does not. C and D invent runtime behaviors that don't apply — this is caught at compile time, full stop, with \"mismatched types.\"",[15,124440,124441,124445],{"language":111909},[18,124442,124444],{"id":124443},"q12-what-happens-when-a-structs-field-is-itself-a-reference-and-the-structs-owner-tries-to-outlive-the-borrowed-data","Q12. What happens when a struct's field is itself a reference and the struct's owner tries to outlive the borrowed data?",[257,124446,124447,124450,124456,124458,124509,107924,124547,124651,124720,124839,124945,125023,125125],{"language":111909},[73,124448,124449],{},"struct Highlight\u003C'a> { text: &'a str }",[260,124451,124454],{"className":124452,"code":124453,"language":107798},[107796],"::\n\n- [ ] The struct owns a copy of the text, so no lifetime issue exists\n- [ ] Nothing shown here fails by itself, but any attempt to construct a `Highlight` whose `text` outlives the source string is rejected at compile time — the struct can never outlive the data it borrows\n- [ ] This struct definition itself fails to compile\n- [ ] `'a` defaults to `'static` automatically\n\n\u003Cdetails>\n\u003Csummary>Show Answer\u003C\u002Fsummary>\n\n**Answer:** B — Nothing shown here fails by itself, but any attempt to construct a `Highlight` whose `text` outlives the source string is rejected at compile time — the struct can never outlive the data it borrows\n\n**Explanation:** The struct definition itself is valid Rust (tying the struct's lifetime parameter to the borrowed field), but any use site that tries to keep a `Highlight` alive longer than the `&str` it points into will be rejected — this is the struct-holds-a-reference case that ties directly back to explicit lifetime annotations. A is wrong — `&'a str` is a borrow, not an owned copy. C is wrong — the definition compiles fine on its own. D is false — lifetimes on struct fields are never silently defaulted to `'static`; they must be satisfied by whatever data is actually borrowed.\n\n\u003C\u002Fdetails>\n::\n\n::question-wrapper{language=\"rust\"}\n### Q13. `#[derive(Debug)]` is added to a struct containing a field of a type that doesn't implement `Debug`. What happens?\n\n::code-wrapper{language=\"rust\"}\n```rust\nstruct RawSocket(*mut u8);\n#[derive(Debug)]\nstruct Connection {\n    id: u32,\n    socket: RawSocket,\n}\n",[39,124455,124453],{"__ignoreMap":264},[73,124457,84903],{},[23,124459,124461,124473,124487,124500],{"className":124460},[26],[28,124462,124464,124466,124467,124470,124471],{"className":124463},[31],[33,124465],{"disabled":35,"type":36}," It compiles; ",[39,124468,124469],{},"derive(Debug)"," silently skips fields that don't implement ",[39,124472,16523],{},[28,124474,124476,117726,124478,124480,124481,137,124483,124486],{"className":124475},[31],[33,124477],{"disabled":35,"type":36},[39,124479,124469],{}," requires every field's type to also implement ",[39,124482,16523],{},[39,124484,124485],{},"RawSocket"," doesn't",[28,124488,124490,124492,124493,124496,124497],{"className":124489},[31],[33,124491],{"disabled":35,"type":36}," It compiles but panics the first time ",[39,124494,124495],{},"{:?}"," is used on a ",[39,124498,124499],{},"Connection",[28,124501,124503,124505,124506,124508],{"className":124502},[31],[33,124504],{"disabled":35,"type":36}," Raw pointers always implement ",[39,124507,16523],{},", so this compiles without issue",[66,124510,124511,124513,124520],{},[69,124512,71],{},[73,124514,124515,124517,124518,124508],{},[76,124516,78],{}," D — Raw pointers always implement ",[39,124519,16523],{},[73,124521,124522,124524,124525,124528,124529,29029,124531,124533,124534,124536,124537,124539,124540,124542,124543,124546],{},[76,124523,84],{}," This is a genuine gotcha: ",[39,124526,124527],{},"*mut u8"," (and other raw pointer types) ",[104,124530,11210],{},[39,124532,16523],{}," in the standard library, printing as a hex address — so ",[39,124535,124485],{},", despite looking like it wraps something exotic, actually satisfies the derive requirement here, and the whole thing compiles fine. The broader rule that trips people up is real (B describes the general case correctly for types that truly lack ",[39,124538,16523],{},", such as function-pointer-heavy or certain FFI-opaque types), but it doesn't apply to this specific example because raw pointers are one of the types that do implement ",[39,124541,16523],{},". A is false — ",[39,124544,124545],{},"derive"," never silently skips fields; it fails the whole derive if any field is missing a required impl. C invents a runtime failure where the real failure (when it does happen) is a compile error, not a panic.",[15,124548,124549,124556,124602],{},[18,124550,7516,124552,124555],{"id":124551},"q14-what-does-rectangle-width-10-defaultdefault-require-in-order-to-compile",[39,124553,124554],{},"Rectangle { width: 10, ..Default::default() }"," require in order to compile?",[23,124557,124559,124569,124588,124596],{"className":124558},[26],[28,124560,124562,124564,124565,124568],{"className":124561},[31],[33,124563],{"disabled":35,"type":36}," Nothing extra — ",[39,124566,124567],{},"Default::default()"," always works for any struct",[28,124570,124572,355,124574,124576,124577,124580,124581,14552,124584,124587],{"className":124571},[31],[33,124573],{"disabled":35,"type":36},[39,124575,123366],{}," must implement (or derive) the ",[39,124578,124579],{},"Default"," trait, since ",[39,124582,124583],{},"..Default::default()",[39,124585,124586],{},"Rectangle::default()"," to supply the other fields",[28,124589,124591,355,124593,124595],{"className":124590},[31],[33,124592],{"disabled":35,"type":36},[39,124594,32233],{}," must be removed from the struct entirely",[28,124597,124599,124601],{"className":124598},[31],[33,124600],{"disabled":35,"type":36}," This syntax is only valid for tuple structs",[66,124603,124604,124606,124618],{},[69,124605,71],{},[73,124607,124608,1727,124610,124576,124612,124580,124614,14552,124616,124587],{},[76,124609,78],{},[39,124611,123366],{},[39,124613,124579],{},[39,124615,124583],{},[39,124617,124586],{},[73,124619,124620,124622,124623,124625,124626,124628,124629,124632,124633,124635,124636,124638,124639,3295,124641,124644,124645,124647,124648,124650],{},[76,124621,84],{}," Type inference figures out that ",[39,124624,124567],{}," here must produce a ",[39,124627,123366],{}," (because it's used as the base in a ",[39,124630,124631],{},"Rectangle { .. }"," literal), then calls ",[39,124634,124586],{},". If ",[39,124637,123366],{}," doesn't implement ",[39,124640,124579],{},[39,124642,124643],{},"#[derive(Default)]"," or a manual ",[39,124646,123290],{},"), this fails to compile with a trait-bound error, not silently falling back to zeroed memory. A is wrong for exactly that reason. C misunderstands the syntax — ",[39,124649,32233],{}," stays as an explicit override. D is false — struct update syntax works with named-field structs like this example, not just tuple structs.",[15,124652,124653,124663,124694],{},[18,124654,124656,124657,124660,124661,1685],{"id":124655},"q15-when-designing-a-public-api-why-is-it-generally-best-practice-to-keep-struct-fields-private-and-expose-associated-function-constructors-plus-accessor-methods-rather-than-making-all-fields-pub","Q15. When designing a public API, why is it generally best practice to keep struct fields ",[76,124658,124659],{},"private"," and expose associated-function constructors plus accessor methods, rather than making all fields ",[39,124662,117577],{},[23,124664,124666,124672,124678,124688],{"className":124665},[26],[28,124667,124669,124671],{"className":124668},[31],[33,124670],{"disabled":35,"type":36}," Private fields are faster at runtime than public ones",[28,124673,124675,124677],{"className":124674},[31],[33,124676],{"disabled":35,"type":36}," Private fields let you enforce invariants at construction\u002Fmutation time and change the internal representation later without breaking downstream code",[28,124679,124681,124683,124684,124687],{"className":124680},[31],[33,124682],{"disabled":35,"type":36}," Rust requires private fields for ",[39,124685,124686],{},"#[derive(Debug)]"," to work",[28,124689,124691,124693],{"className":124690},[31],[33,124692],{"disabled":35,"type":36}," Public fields are not allowed on structs that implement any trait",[66,124695,124696,124698,124703],{},[69,124697,71],{},[73,124699,124700,124702],{},[76,124701,78],{}," B — Private fields let you enforce invariants at construction\u002Fmutation time and change the internal representation later without breaking downstream code",[73,124704,124705,355,124707,124709,124710,124712,124713,124716,124717,124719],{},[76,124706,84],{},[76,124708,930],{}," this is the standard \"encapsulation\" argument applied to Rust — a ",[39,124711,117577],{}," field can be set to any value satisfying its type from anywhere, bypassing any validation logic, and it locks the struct's internal layout into your public API forever (a semver-breaking change to alter later). Exposing a constructor (",[39,124714,124715],{},"Config::new(...)"," returning ",[39,124718,110110],{}," if validation can fail) and getters\u002Fsetters keeps the door open for future changes. A is false — there's no runtime cost difference between public and private field access. C and D are fabricated constraints.",[15,124721,124722,124726,124761,124797],{"language":111909},[18,124723,124725],{"id":124724},"q16-a-method-needs-to-mutate-one-field-of-a-struct-but-the-struct-is-large-and-cloning-it-would-be-wasteful-which-receiver-is-idiomatic","Q16. A method needs to mutate one field of a struct but the struct is large and cloning it would be wasteful. Which receiver is idiomatic?",[257,124727,124728],{"language":111909},[260,124729,124731],{"className":111918,"code":124730,"language":111909,"meta":264,"style":264},"struct Cache { entries: Vec\u003CString>, hits: u64 }\n",[39,124732,124733],{"__ignoreMap":264},[268,124734,124735,124737,124740,124743,124745,124748,124750,124752,124755,124757,124759],{"class":270,"line":271},[268,124736,121198],{"class":274},[268,124738,124739],{"class":278}," Cache",[268,124741,124742],{"class":282}," { entries",[268,124744,10728],{"class":274},[268,124746,124747],{"class":278}," Vec",[268,124749,1076],{"class":282},[268,124751,16721],{"class":278},[268,124753,124754],{"class":282},">, hits",[268,124756,10728],{"class":274},[268,124758,117989],{"class":278},[268,124760,29394],{"class":282},[23,124762,124764,124773,124782,124791],{"className":124763},[26],[28,124765,124767,355,124769,124772],{"className":124766},[31],[33,124768],{"disabled":35,"type":36},[39,124770,124771],{},"fn record_hit(self)"," — take by value, mutate, then the caller must reassign the return value",[28,124774,124776,355,124778,124781],{"className":124775},[31],[33,124777],{"disabled":35,"type":36},[39,124779,124780],{},"fn record_hit(&mut self)"," — mutate the field directly through a mutable borrow",[28,124783,124785,355,124787,124790],{"className":124784},[31],[33,124786],{"disabled":35,"type":36},[39,124788,124789],{},"fn record_hit(&self)"," — using interior mutability is always the right default even without needing it",[28,124792,124794,124796],{"className":124793},[31],[33,124795],{"disabled":35,"type":36}," Clone the struct, mutate the clone, and return it, leaving the original untouched",[66,124798,124799,124801,124807],{},[69,124800,71],{},[73,124802,124803,1727,124805,124781],{},[76,124804,78],{},[39,124806,124780],{},[73,124808,124809,355,124811,355,124813,124815,124816,42,124818,124820,124821,124824,124825,124828,124829,124831,124832,124834,124835,124838],{},[76,124810,84],{},[76,124812,930],{},[39,124814,113013],{}," is exactly the tool for \"mutate in place without giving up ownership or reallocating\" — it's the standard, zero-cost choice for methods like ",[39,124817,12499],{},[39,124819,56023],{},", or counters like ",[39,124822,124823],{},"hits += 1",". A works but forces every caller into an awkward ",[39,124826,124827],{},"cache = cache.record_hit();"," pattern for no benefit when in-place mutation is possible. C is a common overcorrection — reaching for ",[39,124830,113034],{},"\u002Finterior mutability by default adds runtime borrow-checking overhead and complexity that plain ",[39,124833,113013],{}," avoids when you already have exclusive access. D wastes an entire clone of ",[39,124836,124837],{},"entries: Vec\u003CString>"," just to increment a counter — needless allocation and copying.",[15,124840,124841,124857,124903],{},[18,124842,124844,124845,124847,124848,124851,124852,124716,124854,1685],{"id":124843},"q17-reviewing-a-pr-you-see-a-builder-struct-where-every-setter-method-consumes-and-returns-self-by-value-fn-with_retriesmut-self-n-u32-self-selfretries-n-self-why-is-this-the-idiomatic-pattern-for-builders-rather-than-using-mut-self-returning-mut-self","Q17. Reviewing a PR, you see a builder struct where every setter method consumes and returns ",[39,124846,87099],{}," by value: ",[39,124849,124850],{},"fn with_retries(mut self, n: u32) -> Self { self.retries = n; self }",". Why is this the idiomatic pattern for builders, rather than using ",[39,124853,113013],{},[39,124855,124856],{},"&mut Self",[23,124858,124860,124869,124885,124897],{"className":124859},[26],[28,124861,124863,124865,124866,124868],{"className":124862},[31],[33,124864],{"disabled":35,"type":36}," It isn't idiomatic — ",[39,124867,113013],{}," chaining is strictly better and should be preferred",[28,124870,124872,124316,124874,124876,124877,124880,124881,124884],{"className":124871},[31],[33,124873],{"disabled":35,"type":36},[39,124875,87099],{}," by value enables fluent, chainable one-liner construction (",[39,124878,124879],{},"Builder::new().with_retries(3).with_timeout(5).build()",") that can be built as a single expression, including from a function's tail-return position, without needing an intermediate ",[39,124882,124883],{},"let mut"," binding",[28,124886,124888,355,124890,124892,124893,124896],{"className":124887},[31],[33,124889],{"disabled":35,"type":36},[39,124891,87099],{},"-by-value is required because ",[39,124894,124895],{},"Self"," cannot appear as a return type otherwise",[28,124898,124900,124902],{"className":124899},[31],[33,124901],{"disabled":35,"type":36}," There's no difference between the two approaches in any circumstance",[66,124904,124905,124907,124918],{},[69,124906,71],{},[73,124908,124909,124911,124912,124876,124914,124880,124916,124884],{},[76,124910,78],{}," B — Taking ",[39,124913,87099],{},[39,124915,124879],{},[39,124917,124883],{},[73,124919,124920,355,124922,124924,124925,124928,124929,124932,124933,124935,124936,124938,124939,124941,124942,124944],{},[76,124921,84],{},[76,124923,930],{}," the by-value builder pattern is idiomatic specifically because it composes into a single expression — useful in contexts like a function's implicit return (",[39,124926,124927],{},"fn make() -> Config { Config::builder().with_retries(3).build() }",") where you can't easily have a ",[39,124930,124931],{},"let mut b = ...;"," statement. The ",[39,124934,113013],{}," -> ",[39,124937,124856],{}," chaining style also works and avoids repeated moves, but requires an owned ",[39,124940,124883],{}," binding up front and doesn't work as cleanly in expression position, which is why by-value chaining is the more commonly seen idiom for builders. A overstates it as strictly better in all cases — both are valid, with different tradeoffs. C is a fabricated restriction; ",[39,124943,124895],{}," return types work fine with any receiver. D dismisses a real, meaningful ergonomic difference.",[15,124946,124947,124959,124990],{},[18,124948,124950,124951,124954,124955,124958],{"id":124949},"q18-whats-the-best-practice-reason-to-prefer-an-associated-function-like-pointorigin-point-over-requiring-callers-to-write-point-x-00-y-00-directly-everywhere","Q18. What's the best-practice reason to prefer an associated function like ",[39,124952,124953],{},"Point::origin() -> Point"," over requiring callers to write ",[39,124956,124957],{},"Point { x: 0.0, y: 0.0 }"," directly everywhere?",[23,124960,124962,124970,124976,124982],{"className":124961},[26],[28,124963,124965,355,124967,124969],{"className":124964},[31],[33,124966],{"disabled":35,"type":36},[39,124968,124957],{}," is not valid syntax",[28,124971,124973,124975],{"className":124972},[31],[33,124974],{"disabled":35,"type":36}," It centralizes the \"what does a default\u002Fspecial-case value look like\" decision in one place, and keeps working even if you later make the fields private or add new fields",[28,124977,124979,124981],{"className":124978},[31],[33,124980],{"disabled":35,"type":36}," Associated functions run faster than struct literals",[28,124983,124985,124987,124988],{"className":124984},[31],[33,124986],{"disabled":35,"type":36}," It's required for the struct to implement ",[39,124989,114164],{},[66,124991,124992,124994,124999],{},[69,124993,71],{},[73,124995,124996,124998],{},[76,124997,78],{}," B — It centralizes the \"what does a default\u002Fspecial-case value look like\" decision in one place, and keeps working even if you later make the fields private or add new fields",[73,125000,125001,355,125003,125005,125006,125008,125009,125012,125013,125015,125016,125019,125020,125022],{},[76,125002,84],{},[76,125004,930],{}," this is the same encapsulation argument as constructors generally — if ",[39,125007,33997],{}," gains a third field ",[39,125010,125011],{},"z: f64"," later, every call site that manually wrote ",[39,125014,124957],{}," breaks, but a single ",[39,125017,125018],{},"Point::origin()"," definition only needs updating once. It also keeps working if fields become private. A is false — direct struct-literal syntax works fine when fields are public. C is a fabricated performance claim; both compile to equivalent code. D is unrelated — ",[39,125021,114164],{}," is an independent derive, unaffected by whether you use a literal or a constructor function.",[15,125024,125025,125039,125081],{},[18,125026,125028,125029,125032,125033,125035,125036,1685],{"id":125027},"q19-in-review-someone-suggests-changing-fn-totalself-f64-which-sums-two-fields-to-instead-take-self-by-value-arguing-its-simpler-why-would-that-be-a-worse-choice-for-a-getter-style-method-used-inside-a-loop-like-for-item-in-items-sum-itemtotal","Q19. In review, someone suggests changing ",[39,125030,125031],{},"fn total(&self) -> f64"," (which sums two fields) to instead take ",[39,125034,87099],{}," by value, arguing \"it's simpler.\" Why would that be a worse choice for a getter-style method used inside a loop like ",[39,125037,125038],{},"for item in &items { sum += item.total(); }",[23,125040,125042,125050,125067,125075],{"className":125041},[26],[28,125043,125045,125047,125048,11426],{"className":125044},[31],[33,125046],{"disabled":35,"type":36}," It would fail to compile in a ",[39,125049,6926],{},[28,125051,125053,124316,125055,125057,125058,125060,125061,8268,125063,125066],{"className":125052},[31],[33,125054],{"disabled":35,"type":36},[39,125056,87099],{}," by value would move ",[39,125059,14793],{}," out of the collection on the first iteration (or, since ",[39,125062,14793],{},[39,125064,125065],{},"&Item",", force an extra deref\u002Fclone), which is unnecessary overhead and friction for a method that never needs to consume the value",[28,125068,125070,355,125072,125074],{"className":125069},[31],[33,125071],{"disabled":35,"type":36},[39,125073,115196],{}," cannot be returned from a by-value method",[28,125076,125078,125080],{"className":125077},[31],[33,125079],{"disabled":35,"type":36}," There is no difference — both compile to identical machine code",[66,125082,125083,125085,125097],{},[69,125084,71],{},[73,125086,125087,124911,125089,125057,125091,125060,125093,8268,125095,125066],{},[76,125088,78],{},[39,125090,87099],{},[39,125092,14793],{},[39,125094,14793],{},[39,125096,125065],{},[73,125098,125099,355,125101,125103,125104,125106,125107,125110,125111,125113,125114,125117,125118,125120,125121,125124],{},[76,125100,84],{},[76,125102,930],{}," the general principle is: only take ",[39,125105,87099],{}," by value when the method genuinely needs ownership (e.g., transforming into a different type, or a builder's terminal ",[39,125108,125109],{},"build()","). A pure read like summing fields for a total should use ",[39,125112,112964],{},", so it can be called repeatedly on borrowed items (as in ",[39,125115,125116],{},"for item in &items",") without consuming anything. Switching to by-value ",[39,125119,87099],{}," would, at minimum, require cloning ",[39,125122,125123],{},"Item"," at each call site to satisfy ownership, adding needless allocation\u002Fcopy overhead in a hot loop. A is false — it can be made to compile (with clones), it's just wasteful. C is a fabricated restriction on return types. D dismisses a real, meaningful runtime cost difference.",[15,125126,125127,125134,125167],{},[18,125128,125130,125131,125133],{"id":125129},"q20-a-struct-has-grown-to-8-fields-and-a-refactor-wants-to-add-a-9th-while-preserving-all-existing-call-sites-that-construct-it-with-a-full-field-list-no-update-syntax-whats-the-best-practice-tradeoff-to-flag-in-review","Q20. A struct has grown to 8 fields, and a refactor wants to add a 9th while preserving all existing call sites that construct it with a full field list (no ",[39,125132,86888],{}," update syntax). What's the best-practice tradeoff to flag in review?",[23,125135,125137,125143,125153,125161],{"className":125136},[26],[28,125138,125140,125142],{"className":125139},[31],[33,125141],{"disabled":35,"type":36}," Nothing to flag — adding a field to a struct is always backward compatible",[28,125144,125146,125148,125149,125152],{"className":125145},[31],[33,125147],{"disabled":35,"type":36}," Adding a field is a breaking change for any code using exhaustive struct-literal construction (every call site must add the new field, or the struct should switch to a builder\u002Fconstructor pattern, or mark itself ",[39,125150,125151],{},"#[non_exhaustive]"," for external consumers)",[28,125154,125156,125158,125159],{"className":125155},[31],[33,125157],{"disabled":35,"type":36}," Fields can only be added if the struct implements ",[39,125160,124579],{},[28,125162,125164,125166],{"className":125163},[31],[33,125165],{"disabled":35,"type":36}," This requires bumping the struct to a tuple struct instead",[66,125168,125169,125171,125178],{},[69,125170,71],{},[73,125172,125173,125175,125176,125152],{},[76,125174,78],{}," B — Adding a field is a breaking change for any code using exhaustive struct-literal construction (every call site must add the new field, or the struct should switch to a builder\u002Fconstructor pattern, or mark itself ",[39,125177,125151],{},[73,125179,125180,355,125182,125184,125185,125188,125189,99,125191,125193,125194,125196,125197,125199],{},[76,125181,84],{},[76,125183,930],{}," unlike adding a method (which is always additive and non-breaking), adding a field to a struct that callers construct with ",[39,125186,125187],{},"StructName { a, b, c, ... }"," literal syntax breaks every one of those call sites unless they use ",[39,125190,124583],{},[39,125192,123077],{}," update syntax to fill in the gap. This is exactly why widely-consumed public structs either expose a constructor\u002Fbuilder instead of public fields, or are annotated ",[39,125195,125151],{}," so external crates are forced to use a constructor and can't exhaustively list fields at all. A is the naive assumption that bites maintainers of public crates. C invents an unrelated requirement — ",[39,125198,124579],{}," doesn't automatically shield existing literals. D is a non-sequitur; switching to a tuple struct doesn't address the exhaustive-construction problem and loses named-field readability.",[2107,125201,125202],{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}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 pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}",{"title":264,"searchDepth":286,"depth":286,"links":125204},[125205,125207,125208,125209,125211,125213,125215,125217,125219,125221,125222,125224],{"id":122921,"depth":296,"text":125206},"Q1. Given struct User { name: String, age: u8, active: bool }, what does struct update syntax do here?",{"id":123106,"depth":296,"text":123107},{"id":123203,"depth":296,"text":123204},{"id":123286,"depth":296,"text":125210},"Q4. What's the essential difference between these two impl block items?",{"id":123475,"depth":296,"text":125212},"Q5. Which method receiver should fn describe(&self) -> String use if it only needs to read fields and return a new owned String?",{"id":123547,"depth":296,"text":125214},"Q6. What does calling a method that takes self (by value, not &self) do to the original variable?",{"id":123760,"depth":296,"text":125216},"Q7. What visibility do struct fields have by default, inside their own module, if declared without a pub keyword?",{"id":123824,"depth":296,"text":125218},"Q8. What happens when you use struct update syntax where the base struct contains a non-Copy field that you don't override?",{"id":124072,"depth":296,"text":125220},"Q9. Calling Rectangle::square(0) on a tuple-free square associated function that builds Rectangle { width: size, height: size } — what happens with size = 0?",{"id":124155,"depth":296,"text":124156},{"id":124354,"depth":296,"text":125223},"Q11. Two struct types happen to have identical field names and types: struct Meters(f64) and struct Feet(f64). What happens if you try let m: Meters = Feet(3.0);?",{"id":124443,"depth":296,"text":124444},{},"\u002Frust\u002F11-structs",{"title":122911,"description":264},"rust\u002F11-structs","uoqtWBfqPq9klBF9_vgiNJWmIG7UvmEa7wCcvv1VxQs",{"id":125231,"title":125232,"body":125233,"description":264,"extension":2144,"meta":127893,"navigation":35,"path":127894,"seo":127895,"stem":127896,"__hash__":127897},"content\u002Frust\u002F12-enums.md","12 — Enums",{"type":8,"value":125234,"toc":127854},[125235,125238,125340,125432,125567,125744,125836,125903,126152,126326,126426,126567,126641,126867,126972,127214,127332,127438,127528,127645,127741,127851],[11,125236,125232],{"id":125237},"_12-enums",[15,125239,125240,125249,125291],{},[18,125241,125243,125244,125246,125247,1685],{"id":125242},"q1-why-does-rust-use-optiont-instead-of-allowing-references-and-values-to-be-null","Q1. Why does Rust use ",[39,125245,116806],{}," instead of allowing references and values to be ",[39,125248,2650],{},[23,125250,125252,125260,125268,125276],{"className":125251},[26],[28,125253,125255,355,125257,125259],{"className":125254},[31],[33,125256],{"disabled":35,"type":36},[39,125258,2650],{}," is reserved as a keyword for future use",[28,125261,125263,355,125265,125267],{"className":125262},[31],[33,125264],{"disabled":35,"type":36},[39,125266,116806],{}," forces the compiler to make you explicitly handle the \"no value\" case at compile time, eliminating null-pointer-style runtime errors",[28,125269,125271,355,125273,125275],{"className":125270},[31],[33,125272],{"disabled":35,"type":36},[39,125274,116806],{}," is faster than a nullable pointer in every case",[28,125277,125279,125281,125282,125284,125285,125287,125288,125290],{"className":125278},[31],[33,125280],{"disabled":35,"type":36}," Rust does support ",[39,125283,2650],{},", but only for raw pointers used in ",[39,125286,112499],{}," code, and ",[39,125289,116806],{}," is just a convenience wrapper on top",[66,125292,125293,125295,125301],{},[69,125294,71],{},[73,125296,125297,1727,125299,125267],{},[76,125298,78],{},[39,125300,116806],{},[73,125302,125303,125305,125306,6320,125308,99,125311,125313,125314,42,125316,42,125319,42,125321,125323,125324,125326,125327,125329,125330,125333,125334,125336,125337,125339],{},[76,125304,84],{}," By encoding absence as a distinct type (",[39,125307,116806],{},[39,125309,125310],{},"Some(T)",[39,125312,90944],{},") rather than a special sentinel value any reference could silently hold, the compiler forces every caller to handle both cases (via ",[39,125315,116378],{},[39,125317,125318],{},"if let",[39,125320,1685],{},[39,125322,110107],{},", etc.) before extracting the inner ",[39,125325,102486],{},". This eliminates an entire class of null-dereference bugs at compile time. A is a distractor — ",[39,125328,2650],{}," isn't a reserved keyword tied to this. C overstates a general performance claim; the point is safety, not universal speed superiority (though ",[39,125331,125332],{},"Option\u003C&T>"," is often the same size as a raw pointer thanks to niche optimization, addressed later). D is false — safe Rust references (",[39,125335,120804],{},") genuinely cannot be null; there is no hidden null state for them outside of raw pointers in ",[39,125338,112499],{}," code, which are a fundamentally different type.",[15,125341,125342,125350,125397],{},[18,125343,125345,125346,125349],{"id":125344},"q2-what-are-the-two-variants-of-resultt-e-and-what-does-each-represent","Q2. What are the two variants of ",[39,125347,125348],{},"Result\u003CT, E>",", and what does each represent?",[23,125351,125353,125366,125375,125386],{"className":125352},[26],[28,125354,125356,355,125358,125361,125362,125365],{"className":125355},[31],[33,125357],{"disabled":35,"type":36},[39,125359,125360],{},"Ok(T)"," for success, ",[39,125363,125364],{},"Err(E)"," for failure",[28,125367,125369,355,125371,125361,125373,125365],{"className":125368},[31],[33,125370],{"disabled":35,"type":36},[39,125372,125310],{},[39,125374,90944],{},[28,125376,125378,355,125380,186,125383],{"className":125377},[31],[33,125379],{"disabled":35,"type":36},[39,125381,125382],{},"Pass(T)",[39,125384,125385],{},"Fail(E)",[28,125387,125389,355,125391,186,125394],{"className":125388},[31],[33,125390],{"disabled":35,"type":36},[39,125392,125393],{},"Valid(T)",[39,125395,125396],{},"Invalid(String)",[66,125398,125399,125401,125409],{},[69,125400,71],{},[73,125402,125403,3459,125405,125361,125407,125365],{},[76,125404,78],{},[39,125406,125360],{},[39,125408,125364],{},[73,125410,125411,355,125413,125415,125416,125418,125419,125421,125422,125424,125425,125427,125428,446,125430,462],{},[76,125412,84],{},[39,125414,125348],{}," is the standard library's two-variant enum for fallible operations: ",[39,125417,125360],{}," wraps the success value, ",[39,125420,125364],{}," wraps the error value, and the generic ",[39,125423,47786],{}," lets each API choose its own error type. B is the tempting mix-up with ",[39,125426,116806],{},"'s variant names — a very common naming confusion for newcomers. C and D are plausible-sounding but fabricated variant names; the standard library specifically uses ",[39,125429,120129],{},[39,125431,116301],{},[15,125433,125434,125438,125516,125546],{"language":111909},[18,125435,125437],{"id":125436},"q3-whats-the-memory-representation-implication-of-an-enum-with-data-carrying-variants-of-different-sizes-like-this-one","Q3. What's the memory representation implication of an enum with data-carrying variants of different sizes, like this one?",[257,125439,125440],{"language":111909},[260,125441,125443],{"className":111918,"code":125442,"language":111909,"meta":264,"style":264},"enum Message {\n    Quit,\n    Move { x: i32, y: i32 },\n    Write(String),\n    ChangeColor(i32, i32, i32),\n}\n",[39,125444,125445,125455,125462,125482,125493,125512],{"__ignoreMap":264},[268,125446,125447,125450,125453],{"class":270,"line":271},[268,125448,125449],{"class":274},"enum",[268,125451,125452],{"class":278}," Message",[268,125454,9914],{"class":282},[268,125456,125457,125460],{"class":270,"line":286},[268,125458,125459],{"class":278},"    Quit",[268,125461,1789],{"class":282},[268,125463,125464,125467,125470,125472,125474,125476,125478,125480],{"class":270,"line":296},[268,125465,125466],{"class":278},"    Move",[268,125468,125469],{"class":282}," { x",[268,125471,10728],{"class":274},[268,125473,113794],{"class":278},[268,125475,121628],{"class":282},[268,125477,10728],{"class":274},[268,125479,113794],{"class":278},[268,125481,20042],{"class":282},[268,125483,125484,125487,125489,125491],{"class":270,"line":311},[268,125485,125486],{"class":278},"    Write",[268,125488,622],{"class":282},[268,125490,16721],{"class":278},[268,125492,17159],{"class":282},[268,125494,125495,125498,125500,125502,125504,125506,125508,125510],{"class":270,"line":788},[268,125496,125497],{"class":278},"    ChangeColor",[268,125499,622],{"class":282},[268,125501,113860],{"class":278},[268,125503,42],{"class":282},[268,125505,113860],{"class":278},[268,125507,42],{"class":282},[268,125509,113860],{"class":278},[268,125511,17159],{"class":282},[268,125513,125514],{"class":270,"line":1951},[268,125515,314],{"class":282},[23,125517,125519,125525,125531,125537],{"className":125518},[26],[28,125520,125522,125524],{"className":125521},[31],[33,125523],{"disabled":35,"type":36}," Each variant gets its own independent memory allocation",[28,125526,125528,125530],{"className":125527},[31],[33,125529],{"disabled":35,"type":36}," The enum's total size is at least large enough to hold its largest variant, plus a discriminant tag to identify which variant is active",[28,125532,125534,125536],{"className":125533},[31],[33,125535],{"disabled":35,"type":36}," The enum is always exactly the size of a pointer, regardless of variant contents",[28,125538,125540,355,125542,125545],{"className":125539},[31],[33,125541],{"disabled":35,"type":36},[39,125543,125544],{},"Quit"," (no data) makes the whole enum zero-sized",[66,125547,125548,125550,125555],{},[69,125549,71],{},[73,125551,125552,125554],{},[76,125553,78],{}," B — The enum's total size is at least large enough to hold its largest variant, plus a discriminant tag to identify which variant is active",[73,125556,125557,125559,125560,99,125563,125566],{},[76,125558,84],{}," Rust enums are tagged unions: the compiler reserves enough space for the largest variant (here, ",[39,125561,125562],{},"Write(String)",[39,125564,125565],{},"ChangeColor(i32,i32,i32)",", whichever is bigger) plus a discriminant to track which variant is currently stored, and every instance uses that same fixed size no matter which variant it holds. A describes a completely different allocation strategy Rust doesn't use for stack-resident enums. C is a fabricated simplification. D is wrong — one zero-sized variant among several data-carrying variants doesn't shrink the enum; the size is driven by the largest variant, not the smallest.",[15,125568,125569,125581,125638,125673],{"language":111909},[18,125570,105620,125572,125575,125576,125578,125579,1685],{"id":125571},"q4-given-let-msg-messagewritestringfromhi-how-do-you-correctly-destructure-it-in-a-match-without-moving-msg",[39,125573,125574],{},"let msg = Message::Write(String::from(\"hi\"));",", how do you correctly destructure it in a ",[39,125577,116378],{}," without moving ",[39,125580,33187],{},[257,125582,125583],{"language":111909},[260,125584,125586],{"className":111918,"code":125585,"language":111909,"meta":264,"style":264},"enum Message { Write(String), Quit }\nlet msg = Message::Write(String::from(\"hi\"));\n",[39,125587,125588,125609],{"__ignoreMap":264},[268,125589,125590,125592,125594,125596,125599,125601,125603,125605,125607],{"class":270,"line":271},[268,125591,125449],{"class":274},[268,125593,125452],{"class":278},[268,125595,20200],{"class":282},[268,125597,125598],{"class":278},"Write",[268,125600,622],{"class":282},[268,125602,16721],{"class":278},[268,125604,33111],{"class":282},[268,125606,125544],{"class":278},[268,125608,29394],{"class":282},[268,125610,125611,125613,125616,125618,125620,125622,125624,125626,125628,125630,125632,125634,125636],{"class":270,"line":286},[268,125612,240],{"class":274},[268,125614,125615],{"class":282}," msg ",[268,125617,302],{"class":274},[268,125619,125452],{"class":278},[268,125621,84903],{"class":274},[268,125623,125598],{"class":278},[268,125625,622],{"class":282},[268,125627,16721],{"class":278},[268,125629,84903],{"class":274},[268,125631,44539],{"class":278},[268,125633,622],{"class":282},[268,125635,85975],{"class":289},[268,125637,4818],{"class":282},[23,125639,125641,125649,125657,125665],{"className":125640},[26],[28,125642,125644,355,125646],{"className":125643},[31],[33,125645],{"disabled":35,"type":36},[39,125647,125648],{},"match msg { Message::Write(s) => println!(\"{s}\"), Message::Quit => {} }",[28,125650,125652,355,125654],{"className":125651},[31],[33,125653],{"disabled":35,"type":36},[39,125655,125656],{},"match &msg { Message::Write(s) => println!(\"{s}\"), Message::Quit => {} }",[28,125658,125660,355,125662],{"className":125659},[31],[33,125661],{"disabled":35,"type":36},[39,125663,125664],{},"match msg { Write(s) => println!(\"{s}\"), Quit => {} }",[28,125666,125668,355,125670],{"className":125667},[31],[33,125669],{"disabled":35,"type":36},[39,125671,125672],{},"if msg == Message::Write { ... }",[66,125674,125675,125677,125683],{},[69,125676,71],{},[73,125678,125679,1727,125681],{},[76,125680,78],{},[39,125682,125656],{},[73,125684,125685,125687,125688,125691,125692,125694,125695,125697,125698,125700,125701,125703,125704,22769,125706,46500,125708,125710,125711,125713,125714,125717,125718,125721,125722,125724,125725,125727,125728,125730,125731,125734,125735,125738,125739,125741,125742,462],{},[76,125686,84],{}," Matching on ",[39,125689,125690],{},"&msg"," (a reference) makes the pattern match against borrowed data — ",[39,125693,25393],{}," is then bound as ",[39,125696,121897],{}," via match ergonomics, and ",[39,125699,33187],{}," itself is not moved, so it remains usable afterward. Option A matches on ",[39,125702,33187],{}," by value, which moves the ",[39,125705,16721],{},[39,125707,33187],{},[39,125709,25393],{},", making ",[39,125712,33187],{}," (or at least the moved-out field) unusable afterward — a real gotcha covered further in the edge-case questions. C omits the ",[39,125715,125716],{},"Message::"," path qualifier, which only works if the variants were brought into scope via ",[39,125719,125720],{},"use Message::*",", not by default — as bare code it fails to compile with \"cannot find value ",[39,125723,125598],{},"\". D confuses enums with ",[39,125726,116378],{}," for a boolean-style ",[39,125729,3197],{}," comparison; ",[39,125732,125733],{},"Message::Write"," isn't comparable this way without deriving ",[39,125736,125737],{},"PartialEq",", and even then this particular syntax is invalid since ",[39,125740,125598],{}," alone (without its data) isn't a complete pattern for ",[39,125743,3197],{},[15,125745,125746,125757,125794],{},[18,125747,125749,125750,6033,125752,125754,125755,1685],{"id":125748},"q5-what-does-calling-unwrap-on-optiont-do-when-the-value-is-none","Q5. What does calling ",[39,125751,110107],{},[39,125753,116806],{}," do when the value is ",[39,125756,90944],{},[23,125758,125760,125766,125778,125786],{"className":125759},[26],[28,125761,125763,125765],{"className":125762},[31],[33,125764],{"disabled":35,"type":36}," Returns the type's default value",[28,125767,125769,125771,125772,5125,125775,125777],{"className":125768},[31],[33,125770],{"disabled":35,"type":36}," Panics immediately with a message like \"called ",[39,125773,125774],{},"Option::unwrap()",[39,125776,90944],{}," value\"",[28,125779,125781,124120,125783,125785],{"className":125780},[31],[33,125782],{"disabled":35,"type":36},[39,125784,90944],{}," unchanged",[28,125787,125789,125791,125792],{"className":125788},[31],[33,125790],{"disabled":35,"type":36}," Silently converts to ",[39,125793,115920],{},[66,125795,125796,125798,125807],{},[69,125797,71],{},[73,125799,125800,125802,125803,5125,125805,125777],{},[76,125801,78],{}," B — Panics immediately with a message like \"called ",[39,125804,125774],{},[39,125806,90944],{},[73,125808,125809,355,125811,125813,125814,446,125817,125819,125820,7255,125822,89923,125824,125827,125828,125830,125831,186,125833,125835],{},[76,125810,84],{},[39,125812,110107],{}," is explicitly the \"I am certain this is ",[39,125815,125816],{},"Some",[39,125818,120129],{},", and if I'm wrong, crash loudly\" escape hatch — on ",[39,125821,90944],{},[39,125823,116301],{},[39,125825,125826],{},"Result::unwrap()",") it triggers a panic that unwinds (or aborts, depending on panic strategy) the current thread. A and C invent silent fallback behaviors that ",[39,125829,110107],{}," specifically does not provide (that's what ",[39,125832,116383],{},[39,125834,116386],{}," are for). D is a fabricated cross-type conversion that doesn't happen automatically.",[15,125837,125838,125842,125877],{},[18,125839,125841],{"id":125840},"q6-whats-the-correct-way-to-define-an-enum-variant-that-carries-multiple-named-fields-similar-to-a-struct","Q6. What's the correct way to define an enum variant that carries multiple named fields, similar to a struct?",[23,125843,125845,125853,125859,125867],{"className":125844},[26],[28,125846,125848,355,125850],{"className":125847},[31],[33,125849],{"disabled":35,"type":36},[39,125851,125852],{},"enum Shape { Circle(f64), Rectangle { width: f64, height: f64 } }",[28,125854,125856,125858],{"className":125855},[31],[33,125857],{"disabled":35,"type":36}," Named fields aren't allowed in enum variants; only tuple-style data is supported",[28,125860,125862,355,125864],{"className":125861},[31],[33,125863],{"disabled":35,"type":36},[39,125865,125866],{},"enum Shape { Circle: f64, Rectangle: (f64, f64) }",[28,125868,125870,125872,125873,125876],{"className":125869},[31],[33,125871],{"disabled":35,"type":36}," You must define a separate ",[39,125874,125875],{},"struct Rectangle"," and reference it by name only",[66,125878,125879,125881,125887],{},[69,125880,71],{},[73,125882,125883,3459,125885],{},[76,125884,78],{},[39,125886,125852],{},[73,125888,125889,125891,125892,125895,125896,125899,125900,125902],{},[76,125890,84],{}," Rust enum variants can mix tuple-style data (",[39,125893,125894],{},"Circle(f64)",") and struct-style named fields (",[39,125897,125898],{},"Rectangle { width: f64, height: f64 }",") within the same enum — each variant chooses its own shape independently. B is false; struct-like variants are a core, commonly used feature. C uses invalid syntax — variant definitions don't use ",[39,125901,10728],{}," this way. D unnecessarily forces an external struct definition when inline struct-like variants are supported directly.",[15,125904,125905,125916,126037,126085],{"language":111909},[18,125906,3000,125908,125910,125911,125913,125914,1685],{"id":125907},"q7-what-does-do-when-applied-to-a-resultt-e-inside-a-function-that-itself-returns-resultt-e",[39,125909,1685],{}," do when applied to a ",[39,125912,125348],{}," inside a function that itself returns ",[39,125915,125348],{},[257,125917,125918],{"language":111909},[260,125919,125921],{"className":111918,"code":125920,"language":111909,"meta":264,"style":264},"fn read_count(path: &str) -> Result\u003Cu32, std::num::ParseIntError> {\n    let contents = std::fs::read_to_string(path).unwrap_or_default();\n    let n: u32 = contents.trim().parse()?;\n    Ok(n)\n}\n",[39,125922,125923,125963,125994,126025,126033],{"__ignoreMap":264},[268,125924,125925,125927,125930,125933,125935,125937,125939,125941,125943,125945,125947,125949,125952,125954,125957,125959,125961],{"class":270,"line":271},[268,125926,37837],{"class":274},[268,125928,125929],{"class":278}," read_count",[268,125931,125932],{"class":282},"(path",[268,125934,10728],{"class":274},[268,125936,115951],{"class":274},[268,125938,17109],{"class":278},[268,125940,6131],{"class":282},[268,125942,113308],{"class":274},[268,125944,116239],{"class":278},[268,125946,1076],{"class":282},[268,125948,114625],{"class":278},[268,125950,125951],{"class":282},", std",[268,125953,84903],{"class":274},[268,125955,125956],{"class":282},"num",[268,125958,84903],{"class":274},[268,125960,116361],{"class":278},[268,125962,121209],{"class":282},[268,125964,125965,125967,125970,125972,125975,125977,125979,125981,125984,125987,125989,125992],{"class":270,"line":286},[268,125966,80826],{"class":274},[268,125968,125969],{"class":282}," contents ",[268,125971,302],{"class":274},[268,125973,125974],{"class":278}," std",[268,125976,84903],{"class":274},[268,125978,41],{"class":278},[268,125980,84903],{"class":274},[268,125982,125983],{"class":278},"read_to_string",[268,125985,125986],{"class":282},"(path)",[268,125988,462],{"class":274},[268,125990,125991],{"class":278},"unwrap_or_default",[268,125993,794],{"class":282},[268,125995,125996,125998,126000,126002,126004,126006,126009,126011,126013,126015,126017,126019,126021,126023],{"class":270,"line":296},[268,125997,80826],{"class":274},[268,125999,26428],{"class":282},[268,126001,10728],{"class":274},[268,126003,112377],{"class":278},[268,126005,616],{"class":274},[268,126007,126008],{"class":282}," contents",[268,126010,462],{"class":274},[268,126012,18832],{"class":278},[268,126014,16952],{"class":282},[268,126016,462],{"class":274},[268,126018,22274],{"class":278},[268,126020,16952],{"class":282},[268,126022,1685],{"class":274},[268,126024,293],{"class":282},[268,126026,126027,126030],{"class":270,"line":311},[268,126028,126029],{"class":278},"    Ok",[268,126031,126032],{"class":282},"(n)\n",[268,126034,126035],{"class":270,"line":788},[268,126036,314],{"class":282},[23,126038,126040,126048,126071,126077],{"className":126039},[26],[28,126041,126043,107213,126045,126047],{"className":126042},[31],[33,126044],{"disabled":35,"type":36},[39,126046,116301],{},", it panics immediately",[28,126049,126051,107213,126053,126056,126057,126059,126060,126063,126064,126066,126067,126070],{"className":126050},[31],[33,126052],{"disabled":35,"type":36},[39,126054,126055],{},"Ok(v)",", it unwraps to ",[39,126058,52799],{},"; on ",[39,126061,126062],{},"Err(e)",", it returns early from the function with ",[39,126065,126062],{}," (converted via ",[39,126068,126069],{},"From"," if needed)",[28,126072,126074,126076],{"className":126073},[31],[33,126075],{"disabled":35,"type":36}," It logs the error and continues with a default value",[28,126078,126080,126082,126083],{"className":126079},[31],[33,126081],{"disabled":35,"type":36}," It only works inside ",[39,126084,102577],{},[66,126086,126087,126089,126104],{},[69,126088,71],{},[73,126090,126091,126093,126094,126056,126096,126059,126098,126063,126100,126066,126102,126070],{},[76,126092,78],{}," B — On ",[39,126095,126055],{},[39,126097,52799],{},[39,126099,126062],{},[39,126101,126062],{},[39,126103,126069],{},[73,126105,126106,4396,126108,126110,126111,126114,126115,126117,126118,126120,126121,126123,126124,126126,126127,126129,126130,446,126133,126136,126137,126139,126140,126142,126143,126145,126146,126148,126149,126151],{},[76,126107,84],{},[39,126109,1685],{}," operator is sugar for \"unwrap on success, early-return on failure,\" and it also calls ",[39,126112,126113],{},"From::from"," on the error to convert it into the function's declared error type if they differ. A is wrong — ",[39,126116,1685],{}," explicitly does ",[104,126119,95],{}," panic; that's what distinguishes it from ",[39,126122,110107],{},". C invents logging\u002Fdefault behavior that ",[39,126125,1685],{}," does not perform. D is a common misconception — ",[39,126128,1685],{}," works in any function whose return type implements the necessary ",[39,126131,126132],{},"Try",[39,126134,126135],{},"FromResidual"," mechanics (any ",[39,126138,110110],{},"- or ",[39,126141,116852],{},"-returning function, not just ",[39,126144,111207],{},", though ",[39,126147,111207],{}," can also return ",[39,126150,110110],{}," since Rust 2018).",[15,126153,126154,126166,126236,126282],{"language":111909},[18,126155,126157,126158,5125,126160,126162,126163,126165],{"id":126156},"q8-what-happens-when-you-call-unwrap-on-a-resulterr-in-production-code-with-no-catch_unwind-or-panic-hook-configured","Q8. What happens when you call ",[39,126159,110107],{},[39,126161,115920],{}," in production code with no ",[39,126164,116878],{}," or panic hook configured?",[257,126167,126168],{"language":111909},[260,126169,126171],{"className":111918,"code":126170,"language":111909,"meta":264,"style":264},"fn parse_port(s: &str) -> u16 {\n    s.parse().unwrap()\n}\nlet port = parse_port(\"not_a_number\");\n",[39,126172,126173,126196,126214,126218],{"__ignoreMap":264},[268,126174,126175,126177,126180,126182,126184,126186,126188,126190,126192,126194],{"class":270,"line":271},[268,126176,37837],{"class":274},[268,126178,126179],{"class":278}," parse_port",[268,126181,118470],{"class":282},[268,126183,10728],{"class":274},[268,126185,115951],{"class":274},[268,126187,17109],{"class":278},[268,126189,6131],{"class":282},[268,126191,113308],{"class":274},[268,126193,118353],{"class":278},[268,126195,9914],{"class":282},[268,126197,126198,126201,126203,126205,126207,126209,126212],{"class":270,"line":286},[268,126199,126200],{"class":282},"    s",[268,126202,462],{"class":274},[268,126204,22274],{"class":278},[268,126206,16952],{"class":282},[268,126208,462],{"class":274},[268,126210,126211],{"class":278},"unwrap",[268,126213,47668],{"class":282},[268,126215,126216],{"class":270,"line":296},[268,126217,314],{"class":282},[268,126219,126220,126222,126225,126227,126229,126231,126234],{"class":270,"line":311},[268,126221,240],{"class":274},[268,126223,126224],{"class":282}," port ",[268,126226,302],{"class":274},[268,126228,126179],{"class":278},[268,126230,622],{"class":282},[268,126232,126233],{"class":289},"\"not_a_number\"",[268,126235,628],{"class":282},[23,126237,126239,126248,126254,126266],{"className":126238},[26],[28,126240,126242,355,126244,7083,126246],{"className":126241},[31],[33,126243],{"disabled":35,"type":36},[39,126245,14248],{},[39,126247,3307],{},[28,126249,126251,126253],{"className":126250},[31],[33,126252],{"disabled":35,"type":36}," The thread panics and, by default, unwinds — if this happens on the main thread, the process terminates with a non-zero exit code and a panic message printed to stderr",[28,126255,126257,126259,126260,126263,126264],{"className":126256},[31],[33,126258],{"disabled":35,"type":36}," The compiler rejects this code because ",[39,126261,126262],{},"parse_port","'s return type doesn't mention ",[39,126265,110110],{},[28,126267,126269,355,126271,126274,126275,126278,126279,126281],{"className":126268},[31],[33,126270],{"disabled":35,"type":36},[39,126272,126273],{},"parse()"," silently returns ",[39,126276,126277],{},"65535"," (max ",[39,126280,116396],{},") for invalid input",[66,126283,126284,126286,126291],{},[69,126285,71],{},[73,126287,126288,126290],{},[76,126289,78],{}," B — The thread panics and, by default, unwinds — if this happens on the main thread, the process terminates with a non-zero exit code and a panic message printed to stderr",[73,126292,126293,355,126295,4912,126298,137,126300,126302,126303,126305,126306,126309,126310,110107,126313,1685,126316,126319,126320,116378,126323,126325],{},[76,126294,84],{},[39,126296,126297],{},"\"not_a_number\".parse::\u003Cu16>()",[39,126299,116301],{},[39,126301,110107],{}," on an ",[39,126304,116301],{}," panics with a message like ",[39,126307,126308],{},"called \\","Result::unwrap()` on an `Err` value: ParseIntError { ... }",[39,126311,126312],{},". In a real service, this is exactly the kind of ",[39,126314,126315],{},"that takes down a request handler (or the whole process, if on the main thread and not caught) on malformed input. **Debug:** the correct production handling is to propagate the error with",[39,126317,126318],{},"(changing the return type to","Result\u003Cu16, ParseIntError>",[39,126321,126322],{},") or handle it explicitly with ",[39,126324,446],{},"unwrap_or` and a sensible fallback or error response, rather than trusting external input to always parse cleanly. A, C, and D all invent silent-failure behaviors; Rust does not silently coerce a failed parse into a default numeric value.",[15,126327,126328,126339,126384],{},[18,126329,126331,126332,126334,126335,126338],{"id":126330},"q9-what-is-the-size-in-bytes-of-optioni32-on-a-64-bit-platform-compared-to-i32-alone-and-why","Q9. What is the size, in bytes, of ",[39,126333,115763],{}," on a 64-bit platform, compared to ",[39,126336,126337],{},"&i32"," alone, and why?",[23,126340,126342,126356,126365,126373],{"className":126341},[26],[28,126343,126345,126347,126348,126350,126351,53650,126353,126355],{"className":126344},[31],[33,126346],{"disabled":35,"type":36}," 16 bytes for ",[39,126349,115763],{}," vs 8 bytes for ",[39,126352,126337],{},[39,126354,116852],{}," tag doubles the size",[28,126357,126359,126361,126362,126364],{"className":126358},[31],[33,126360],{"disabled":35,"type":36}," 8 bytes for both — the compiler uses \"niche optimization,\" repurposing the fact that a valid reference can never be the all-zero bit pattern to represent ",[39,126363,90944],{}," as that otherwise-impossible value",[28,126366,126368,355,126370,126372],{"className":126367},[31],[33,126369],{"disabled":35,"type":36},[39,126371,115763],{}," cannot be constructed since references can't be optional",[28,126374,126376,126378,126379,126381,126382],{"className":126375},[31],[33,126377],{"disabled":35,"type":36}," 9 bytes for ",[39,126380,115763],{}," (8 for the pointer + 1 tag byte, unpadded) vs 8 bytes for ",[39,126383,126337],{},[66,126385,126386,126388,126395],{},[69,126387,71],{},[73,126389,126390,126392,126393,126364],{},[76,126391,78],{}," B — 8 bytes for both — the compiler uses \"niche optimization,\" repurposing the fact that a valid reference can never be the all-zero bit pattern to represent ",[39,126394,90944],{},[73,126396,126397,355,126399,126401,126402,126404,126405,126407,126408,126410,126411,126413,126414,2338,126416,42,126419,126422,126423,126425],{},[76,126398,84],{},[76,126400,438],{}," this is a genuinely surprising and important Rust optimization — because a real ",[39,126403,120804],{}," reference is guaranteed non-null, ",[39,126406,125332],{}," doesn't need a separate discriminant byte at all; the compiler encodes ",[39,126409,90944],{}," as the bit pattern that a real reference could never have (all zeros), making ",[39,126412,125332],{}," exactly pointer-sized. This is why ",[39,126415,125332],{},[39,126417,126418],{},"Option\u003CBox\u003CT>>",[39,126420,126421],{},"Option\u003CNonZeroU32>",", etc.) is often used as a zero-overhead nullable pointer. A is the naive \"tag always adds size\" assumption that's true for many enums but not this niche-optimized case. C is false — ",[39,126424,125332],{}," is a completely standard, common pattern. D invents padding math that doesn't reflect how niche optimization actually works here.",[15,126427,126428,126438,126504,126540],{"language":111909},[18,126429,126431,126432,126434,126435,126437],{"id":126430},"q10-what-does-an-empty-match-on-optiont-that-omits-the-none-arm-do","Q10. What does an empty match on ",[39,126433,116806],{}," that omits the ",[39,126436,90944],{}," arm do?",[257,126439,126440],{"language":111909},[260,126441,126443],{"className":111918,"code":126442,"language":111909,"meta":264,"style":264},"fn describe(x: Option\u003Ci32>) -> String {\n    match x {\n        Some(n) => n.to_string(),\n    }\n}\n",[39,126444,126445,126471,126478,126496,126500],{"__ignoreMap":264},[268,126446,126447,126449,126451,126453,126455,126458,126460,126462,126465,126467,126469],{"class":270,"line":271},[268,126448,37837],{"class":274},[268,126450,9852],{"class":278},[268,126452,117178],{"class":282},[268,126454,10728],{"class":274},[268,126456,126457],{"class":278}," Option",[268,126459,1076],{"class":282},[268,126461,113860],{"class":278},[268,126463,126464],{"class":282},">) ",[268,126466,113308],{"class":274},[268,126468,114407],{"class":278},[268,126470,9914],{"class":282},[268,126472,126473,126475],{"class":270,"line":286},[268,126474,120056],{"class":274},[268,126476,126477],{"class":282}," x {\n",[268,126479,126480,126483,126485,126487,126489,126491,126494],{"class":270,"line":296},[268,126481,126482],{"class":278},"        Some",[268,126484,120079],{"class":282},[268,126486,9414],{"class":274},[268,126488,26428],{"class":282},[268,126490,462],{"class":274},[268,126492,126493],{"class":278},"to_string",[268,126495,43644],{"class":282},[268,126497,126498],{"class":270,"line":311},[268,126499,11972],{"class":282},[268,126501,126502],{"class":270,"line":788},[268,126503,314],{"class":282},[23,126505,126507,126515,126524,126534],{"className":126506},[26],[28,126508,126510,126512,126513],{"className":126509},[31],[33,126511],{"disabled":35,"type":36}," Compiles, returning an empty string for ",[39,126514,90944],{},[28,126516,126518,126520,126521,126523],{"className":126517},[31],[33,126519],{"disabled":35,"type":36}," Fails to compile — \"non-exhaustive patterns: ",[39,126522,90944],{}," not covered\"",[28,126525,126527,126529,126530,830,126532],{"className":126526},[31],[33,126528],{"disabled":35,"type":36}," Compiles, but panics at runtime if ",[39,126531,2403],{},[39,126533,90944],{},[28,126535,126537,126539],{"className":126536},[31],[33,126538],{"disabled":35,"type":36}," Compiles only in debug builds",[66,126541,126542,126544,126551],{},[69,126543,71],{},[73,126545,126546,126548,126549,126523],{},[76,126547,78],{}," B — Fails to compile — \"non-exhaustive patterns: ",[39,126550,90944],{},[73,126552,126553,115150,126555,126557,126558,126560,126561,126563,126564,126566],{},[76,126554,84],{},[39,126556,116378],{}," requires exhaustiveness — every possible variant of the matched type must be covered (or a wildcard ",[39,126559,52315],{}," catch-all provided) — and the compiler statically checks this against the enum's known variant set at compile time, so a missing ",[39,126562,90944],{}," arm on ",[39,126565,116806],{}," is a hard compile error, not a runtime concern. A and C both imagine runtime fallback behavior that never gets the chance to run because compilation fails first. D is false — exhaustiveness checking is not conditional on build profile; it's a fundamental part of type checking.",[15,126568,126569,126576,126606],{},[18,126570,56175,126572,126575],{"id":126571},"q11-enum-never-an-enum-with-zero-variants-what-can-you-do-with-a-value-of-this-type",[39,126573,126574],{},"enum Never {}"," — an enum with zero variants — what can you do with a value of this type?",[23,126577,126579,126588,126594,126600],{"className":126578},[26],[28,126580,126582,126584,126585],{"className":126581},[31],[33,126583],{"disabled":35,"type":36}," Construct it with ",[39,126586,126587],{},"Never::default()",[28,126589,126591,126593],{"className":126590},[31],[33,126592],{"disabled":35,"type":36}," Nothing — it's impossible to construct a value of this type, since there are no variants to build; it's used to statically prove a code path is unreachable",[28,126595,126597,126599],{"className":126596},[31],[33,126598],{"disabled":35,"type":36}," It behaves exactly like a unit struct",[28,126601,126603,126605],{"className":126602},[31],[33,126604],{"disabled":35,"type":36}," It's a compile error to define an enum with no variants",[66,126607,126608,126610,126615],{},[69,126609,71],{},[73,126611,126612,126614],{},[76,126613,78],{}," B — Nothing — it's impossible to construct a value of this type, since there are no variants to build; it's used to statically prove a code path is unreachable",[73,126616,126617,126619,126620,126623,126624,126627,126628,126630,126631,126634,126635,126637,126638,126640],{},[76,126618,84],{}," An enum with zero variants (like the standard library's ",[39,126621,126622],{},"std::convert::Infallible",", which is essentially this) has no possible values at all — it's an \"uninhabited type.\" This is genuinely useful: e.g., ",[39,126625,126626],{},"Result\u003CT, Infallible>"," tells the compiler (and a reader) that the error branch can never actually occur, and ",[39,126629,116378],{}," exhaustiveness checking can then treat that branch as impossible to reach. A is wrong — there's no variant to construct, so no ",[39,126632,126633],{},"default()"," could exist. C is wrong — a unit struct ",[104,126636,11176],{}," be constructed (it has exactly one, trivial value); a zero-variant enum has ",[104,126639,16678],{}," values at all. D is false — this is valid, if unusual, Rust and compiles fine.",[15,126642,126643,126647,126760,126813],{"language":111909},[18,126644,126646],{"id":126645},"q12-whats-the-pitfall-in-this-match-guard-combined-with-binding-when-matching-against-a-mutable-reference","Q12. What's the pitfall in this match guard combined with binding, when matching against a mutable reference?",[257,126648,126649],{"language":111909},[260,126650,126652],{"className":111918,"code":126651,"language":111909,"meta":264,"style":264},"enum Status { Pending, Active(u32), Done }\nlet mut status = Status::Active(5);\nmatch &mut status {\n    Status::Active(n) if *n > 3 => *n += 1,\n    _ => {}\n}\n",[39,126653,126654,126682,126704,126714,126747,126756],{"__ignoreMap":264},[268,126655,126656,126658,126661,126663,126666,126668,126671,126673,126675,126677,126680],{"class":270,"line":271},[268,126657,125449],{"class":274},[268,126659,126660],{"class":278}," Status",[268,126662,20200],{"class":282},[268,126664,126665],{"class":278},"Pending",[268,126667,42],{"class":282},[268,126669,126670],{"class":278},"Active",[268,126672,622],{"class":282},[268,126674,114625],{"class":278},[268,126676,33111],{"class":282},[268,126678,126679],{"class":278},"Done",[268,126681,29394],{"class":282},[268,126683,126684,126686,126688,126690,126692,126694,126696,126698,126700,126702],{"class":270,"line":286},[268,126685,240],{"class":274},[268,126687,113071],{"class":274},[268,126689,13064],{"class":282},[268,126691,302],{"class":274},[268,126693,126660],{"class":278},[268,126695,84903],{"class":274},[268,126697,126670],{"class":278},[268,126699,622],{"class":282},[268,126701,2429],{"class":305},[268,126703,628],{"class":282},[268,126705,126706,126708,126711],{"class":270,"line":296},[268,126707,116378],{"class":274},[268,126709,126710],{"class":274}," &mut",[268,126712,126713],{"class":282}," status {\n",[268,126715,126716,126719,126721,126723,126725,126727,126729,126731,126733,126735,126737,126739,126741,126743,126745],{"class":270,"line":311},[268,126717,126718],{"class":278},"    Status",[268,126720,84903],{"class":274},[268,126722,126670],{"class":278},[268,126724,120079],{"class":282},[268,126726,2179],{"class":274},[268,126728,6108],{"class":274},[268,126730,90140],{"class":282},[268,126732,6435],{"class":274},[268,126734,3396],{"class":305},[268,126736,14969],{"class":274},[268,126738,6108],{"class":274},[268,126740,90140],{"class":282},[268,126742,14575],{"class":274},[268,126744,2199],{"class":305},[268,126746,1789],{"class":282},[268,126748,126749,126752,126754],{"class":270,"line":788},[268,126750,126751],{"class":282},"    _ ",[268,126753,9414],{"class":274},[268,126755,30486],{"class":282},[268,126757,126758],{"class":270,"line":1951},[268,126759,314],{"class":282},[23,126761,126763,126769,126790,126805],{"className":126762},[26],[28,126764,126766,126768],{"className":126765},[31],[33,126767],{"disabled":35,"type":36}," This fails to compile — you cannot mutate through a match binding",[28,126770,126772,355,126774,126776,126777,126780,126781,1179,126784,126787,126788],{"className":126771},[31],[33,126773],{"disabled":35,"type":36},[39,126775,4599],{}," binds as ",[39,126778,126779],{},"&mut u32"," due to match ergonomics on ",[39,126782,126783],{},"&mut status",[39,126785,126786],{},"*n += 1"," correctly mutates the field in place, incrementing it to ",[39,126789,13663],{},[28,126791,126793,126795,126796,126799,126800,183,126802,126804],{"className":126792},[31],[33,126794],{"disabled":35,"type":36}," The guard ",[39,126797,126798],{},"if *n > 3"," always evaluates to ",[39,126801,2986],{},[39,126803,4599],{}," hasn't been dereferenced yet at that point",[28,126806,126808,355,126810,126812],{"className":126807},[31],[33,126809],{"disabled":35,"type":36},[39,126811,13305],{}," must first be cloned before matching",[66,126814,126815,126817,126831],{},[69,126816,71],{},[73,126818,126819,1727,126821,126776,126823,126780,126825,1179,126827,126787,126829],{},[76,126820,78],{},[39,126822,4599],{},[39,126824,126779],{},[39,126826,126783],{},[39,126828,126786],{},[39,126830,13663],{},[73,126832,126833,126835,126836,126838,126839,22773,126842,26085,126844,126846,126847,126850,126851,126853,126854,126856,126857,126859,126860,126863,126864,126866],{},[76,126834,84],{}," Match ergonomics automatically adjusts binding modes when matching on a reference: matching ",[39,126837,126783],{}," against ",[39,126840,126841],{},"Status::Active(n)",[39,126843,4599],{},[39,126845,126779],{}," rather than requiring you to write ",[39,126848,126849],{},"Status::Active(ref mut n)"," manually. The guard ",[39,126852,126798],{}," correctly dereferences to compare the underlying value, and ",[39,126855,126786],{}," mutates it through the reference — perfectly valid and idiomatic. A is wrong — mutation through a match binding is exactly what ",[39,126858,114510],{}," matching enables. C misunderstands dereferencing — ",[39,126861,126862],{},"*n"," in the guard reads the current value just fine, it doesn't require a prior explicit step. D is unnecessary — no clone is needed since matching on ",[39,126865,126783],{}," borrows rather than moves.",[15,126868,126869,126881,126922],{},[18,126870,126872,126873,126876,126877,126880],{"id":126871},"q13-in-enum-shape-circlef64-squaref64-is-circle20-circle20-valid-and-under-what-condition","Q13. In ",[39,126874,126875],{},"enum Shape { Circle(f64), Square(f64) }",", is ",[39,126878,126879],{},"Circle(2.0) == Circle(2.0)"," valid, and under what condition?",[23,126882,126884,126893,126908,126914],{"className":126883},[26],[28,126885,126887,126889,126890,126892],{"className":126886},[31],[33,126888],{"disabled":35,"type":36}," Always valid — all enums support ",[39,126891,3197],{}," by default",[28,126894,126896,126898,126899,126901,126902,126904,126905,126907],{"className":126895},[31],[33,126897],{"disabled":35,"type":36}," Only valid if ",[39,126900,33031],{}," derives (or manually implements) ",[39,126903,125737],{},"; without it, ",[39,126906,3197],{}," on enum values is a compile error",[28,126909,126911,126913],{"className":126910},[31],[33,126912],{"disabled":35,"type":36}," Only valid for enums with no data-carrying variants",[28,126915,126917,126919,126920],{"className":126916},[31],[33,126918],{"disabled":35,"type":36}," Always invalid — enums can only be compared with ",[39,126921,116378],{},[66,126923,126924,126926,126937],{},[69,126925,71],{},[73,126927,126928,126930,126931,126901,126933,126904,126935,126907],{},[76,126929,78],{}," B — Only valid if ",[39,126932,33031],{},[39,126934,125737],{},[39,126936,3197],{},[73,126938,126939,126941,126942,126945,126946,126948,126949,446,126951,126953,126954,126956,126957,126959,126960,126962,126963,446,126965,126968,126969,126971],{},[76,126940,84],{}," Rust does not give any type — struct or enum — automatic equality comparison; ",[39,126943,126944],{},"#[derive(PartialEq)]"," (or a manual ",[39,126947,123290],{},") is required before ",[39,126950,3197],{},[39,126952,7733],{}," can be used, and the compiler will reject ",[39,126955,126879],{}," with \"binary operation ",[39,126958,3197],{}," cannot be applied\" if the derive is missing. A is the common false assumption carried over from languages with default structural equality. C is fabricated — data-carrying variants can absolutely be compared once ",[39,126961,125737],{}," is derived (it compares variant tag and then inner data). D overstates things — ",[39,126964,116378],{},[39,126966,126967],{},"matches!"," are alternatives for checking variant identity without full data equality, but ",[39,126970,3197],{}," works fine too once derived.",[15,126973,126974,126985,127097,127149],{"language":111909},[18,126975,126977,126978,126981,126982,126984],{"id":126976},"q14-what-happens-if-you-match-on-optionstring-and-try-to-move-the-inner-string-out-inside-the-match-arm","Q14. What happens if you match on ",[39,126979,126980],{},"&Option\u003CString>"," and try to move the inner ",[39,126983,16721],{}," out inside the match arm?",[257,126986,126987],{"language":111909},[260,126988,126990],{"className":111918,"code":126989,"language":111909,"meta":264,"style":264},"let maybe_name: Option\u003CString> = Some(String::from(\"Ferris\"));\nmatch &maybe_name {\n    Some(s) => {\n        let owned: String = *s;\n        println!(\"{owned}\");\n    }\n    None => {}\n}\n",[39,126991,126992,127030,127039,127051,127069,127080,127084,127093],{"__ignoreMap":264},[268,126993,126994,126996,126999,127001,127003,127005,127007,127010,127012,127015,127017,127019,127021,127023,127025,127028],{"class":270,"line":271},[268,126995,240],{"class":274},[268,126997,126998],{"class":282}," maybe_name",[268,127000,10728],{"class":274},[268,127002,126457],{"class":278},[268,127004,1076],{"class":282},[268,127006,16721],{"class":278},[268,127008,127009],{"class":282},"> ",[268,127011,302],{"class":274},[268,127013,127014],{"class":278}," Some",[268,127016,622],{"class":282},[268,127018,16721],{"class":278},[268,127020,84903],{"class":274},[268,127022,44539],{"class":278},[268,127024,622],{"class":282},[268,127026,127027],{"class":289},"\"Ferris\"",[268,127029,4818],{"class":282},[268,127031,127032,127034,127036],{"class":270,"line":286},[268,127033,116378],{"class":274},[268,127035,115951],{"class":274},[268,127037,127038],{"class":282},"maybe_name {\n",[268,127040,127041,127044,127047,127049],{"class":270,"line":296},[268,127042,127043],{"class":278},"    Some",[268,127045,127046],{"class":282},"(s) ",[268,127048,9414],{"class":274},[268,127050,9914],{"class":282},[268,127052,127053,127055,127058,127060,127062,127064,127066],{"class":270,"line":311},[268,127054,112735],{"class":274},[268,127056,127057],{"class":282}," owned",[268,127059,10728],{"class":274},[268,127061,114407],{"class":278},[268,127063,616],{"class":274},[268,127065,6108],{"class":274},[268,127067,127068],{"class":282},"s;\n",[268,127070,127071,127073,127075,127078],{"class":270,"line":788},[268,127072,112752],{"class":278},[268,127074,622],{"class":282},[268,127076,127077],{"class":289},"\"{owned}\"",[268,127079,628],{"class":282},[268,127081,127082],{"class":270,"line":1951},[268,127083,11972],{"class":282},[268,127085,127086,127089,127091],{"class":270,"line":8955},[268,127087,127088],{"class":278},"    None",[268,127090,14969],{"class":274},[268,127092,30486],{"class":282},[268,127094,127095],{"class":270,"line":8966},[268,127096,314],{"class":282},[23,127098,127100,127110,127130,127141],{"className":127099},[26],[28,127101,127103,112958,127105,36768,127108],{"className":127102},[31],[33,127104],{"disabled":35,"type":36},[39,127106,127107],{},"*s",[39,127109,16721],{},[28,127111,127113,123954,127115,830,127117,127119,127120,123986,127122,1179,127124,127126,127127,12177],{"className":127112},[31],[33,127114],{"disabled":35,"type":36},[39,127116,25393],{},[39,127118,121897],{}," here, and ",[39,127121,16721],{},[39,127123,114164],{},[39,127125,127107],{}," would attempt an illegal move out of a reference; use ",[39,127128,127129],{},"s.clone()",[28,127131,127133,355,127135,7083,127138,127140],{"className":127132},[31],[33,127134],{"disabled":35,"type":36},[39,127136,127137],{},"maybe_name",[39,127139,90944],{}," after this match",[28,127142,127144,127146,127147,85884],{"className":127143},[31],[33,127145],{"disabled":35,"type":36}," This only fails in ",[39,127148,112499],{},[66,127150,127151,127153,127169],{},[69,127152,71],{},[73,127154,127155,123997,127157,830,127159,127119,127161,123986,127163,1179,127165,127126,127167,12177],{},[76,127156,78],{},[39,127158,25393],{},[39,127160,121897],{},[39,127162,16721],{},[39,127164,114164],{},[39,127166,127107],{},[39,127168,127129],{},[73,127170,127171,127173,127174,127177,127178,26085,127180,2758,127182,127184,127185,127187,127188,127190,127191,127193,127194,127196,127197,127199,127200,127202,127203,127205,127206,127208,127209,127211,127212,462],{},[76,127172,84],{}," Because the match scrutinee is ",[39,127175,127176],{},"&maybe_name",", match ergonomics binds ",[39,127179,25393],{},[39,127181,121897],{},[39,127183,16721],{},". Dereferencing with ",[39,127186,127107],{}," to produce an owned ",[39,127189,16721],{}," would require moving data out from behind a reference, which the borrow checker forbids (\"cannot move out of ",[39,127192,127107],{}," which is behind a shared reference\") since the original ",[39,127195,127137],{}," still owns that data. The fix is ",[39,127198,127129],{}," to get an owned copy, or restructure to match on ",[39,127201,127137],{}," by value if you intend to consume it. A is wrong — ",[39,127204,16721],{}," does not implement ",[39,127207,114164],{}," (it manages heap data), so ",[39,127210,127107],{}," cannot silently copy. C is fabricated. D is false — this is a plain compile-time borrow-checker rejection, unrelated to ",[39,127213,112499],{},[15,127215,127216,127227,127277],{},[18,127217,127219,127220,127223,127224,127226],{"id":127218},"q15-when-designing-a-function-that-can-fail-why-is-returning-resultt-myerror-generally-preferred-over-returning-optiont-and-discarding-the-reason-for-failure","Q15. When designing a function that can fail, why is returning ",[39,127221,127222],{},"Result\u003CT, MyError>"," generally preferred over returning ",[39,127225,116806],{}," and discarding the reason for failure?",[23,127228,127230,127241,127259,127267],{"className":127229},[26],[28,127231,127233,355,127235,127237,127238,127240],{"className":127232},[31],[33,127234],{"disabled":35,"type":36},[39,127236,116806],{}," cannot be used with the ",[39,127239,1685],{}," operator at all",[28,127242,127244,355,127246,127248,127249,127252,127253,127255,127256,127258],{"className":127243},[31],[33,127245],{"disabled":35,"type":36},[39,127247,125348],{}," preserves ",[104,127250,127251],{},"why"," the operation failed, which callers (and logs\u002Ferror messages) often need, whereas ",[39,127254,116806],{}," only signals ",[104,127257,7690],{}," it failed",[28,127260,127262,355,127264,127266],{"className":127261},[31],[33,127263],{"disabled":35,"type":36},[39,127265,116806],{}," is deprecated in modern Rust",[28,127268,127270,355,127272,127274,127275],{"className":127269},[31],[33,127271],{"disabled":35,"type":36},[39,127273,125348],{}," is always smaller in memory than ",[39,127276,116806],{},[66,127278,127279,127281,127293],{},[69,127280,71],{},[73,127282,127283,1727,127285,127248,127287,127252,127289,127255,127291,127258],{},[76,127284,78],{},[39,127286,125348],{},[104,127288,127251],{},[39,127290,116806],{},[104,127292,7690],{},[73,127294,127295,355,127297,127299,127300,127302,127303,127306,127307,127309,127310,127312,127313,127315,127316,127318,127319,127321,127322,127324,127325,127327,127328,186,127330,462],{},[76,127296,84],{},[76,127298,930],{}," the general guideline is: use ",[39,127301,116806],{}," when absence is a normal, expected, reason-less outcome (e.g., ",[39,127304,127305],{},"HashMap::get"," — the key simply wasn't there), and use ",[39,127308,125348],{}," when failure needs an explanation a caller might inspect, log, or match on (e.g., parse errors, I\u002FO errors, validation failures). Collapsing a rich error into ",[39,127311,116806],{}," throws away diagnostic information callers may need later. A is false — ",[39,127314,1685],{}," works on ",[39,127317,116806],{}," too, propagating ",[39,127320,90944],{}," in a function that itself returns ",[39,127323,116852],{},". C is false — ",[39,127326,116806],{}," is a completely standard, actively used type, not deprecated. D is not a real or relevant comparison; sizes depend entirely on ",[39,127329,102486],{},[39,127331,47786],{},[15,127333,127334,127344,127399],{},[18,127335,127337,127338,7501,127341,127343],{"id":127336},"q16-code-review-flags-a-public-function-returning-resultuser-string-where-string-is-just-a-human-readable-error-message-whats-the-idiomatic-improvement-and-why","Q16. Code review flags a public function returning ",[39,127339,127340],{},"Result\u003CUser, String>",[39,127342,16721],{}," is just a human-readable error message. What's the idiomatic improvement, and why?",[23,127345,127347,127356,127377,127387],{"className":127346},[26],[28,127348,127350,127352,127353,127355],{"className":127349},[31],[33,127351],{"disabled":35,"type":36}," Leave it as-is — ",[39,127354,16721],{}," errors are always sufficient",[28,127357,127359,127361,127362,127365,127366,127369,127370,7507,127373,127376],{"className":127358},[31],[33,127360],{"disabled":35,"type":36}," Define a proper error enum implementing ",[39,127363,127364],{},"std::error::Error"," (and typically ",[39,127367,127368],{},"Display",") so callers can programmatically distinguish failure kinds (e.g., ",[39,127371,127372],{},"UserError::NotFound",[39,127374,127375],{},"UserError::InvalidEmail",") instead of parsing message text",[28,127378,127380,127382,127383,127386],{"className":127379},[31],[33,127381],{"disabled":35,"type":36}," Switch to ",[39,127384,127385],{},"Result\u003CUser, ()>"," since the message isn't needed",[28,127388,127390,127392,127393,5887,127396,127398],{"className":127389},[31],[33,127391],{"disabled":35,"type":36}," Change it to ",[39,127394,127395],{},"Option\u003CUser>",[39,127397,16721],{}," errors aren't real errors",[66,127400,127401,127403,127416],{},[69,127402,71],{},[73,127404,127405,127407,127408,127365,127410,127369,127412,7507,127414,127376],{},[76,127406,78],{}," B — Define a proper error enum implementing ",[39,127409,127364],{},[39,127411,127368],{},[39,127413,127372],{},[39,127415,127375],{},[73,127417,127418,355,127420,355,127422,127424,127425,127428,127429,127431,127432,127434,127435,127437],{},[76,127419,84],{},[76,127421,930],{},[39,127423,16721],{},"-typed errors are a common quick-and-dirty starting point, but they force any caller that needs to branch on failure kind to parse or ",[39,127426,127427],{},".contains()"," a message string, which is brittle and breaks silently if the wording changes. A structured error enum lets callers ",[39,127430,116378],{}," on variants directly and lets the type system enforce handling all known failure kinds. A dismisses a real, well-known anti-pattern. C throws away the diagnostic message entirely, making debugging harder. D conflates \"has a reason\" (an error) with \"has no reason\" (",[39,127433,116852],{},"'s use case) — the message shows this function does have failure reasons, so ",[39,127436,116852],{}," is the wrong direction entirely.",[15,127439,127440,127450,127492],{},[18,127441,1676,127443,127446,127447,127449],{"id":127442},"q17-why-is-if-let-somex-maybe_value-often-preferred-over-a-full-match-when-you-only-care-about-one-variant-and-want-to-ignore-the-rest",[39,127444,127445],{},"if let Some(x) = maybe_value { ... }"," often preferred over a full ",[39,127448,116378],{}," when you only care about one variant and want to ignore the rest?",[23,127451,127453,127464,127472,127482],{"className":127452},[26],[28,127454,127456,355,127458,127460,127461,127463],{"className":127455},[31],[33,127457],{"disabled":35,"type":36},[39,127459,116378],{}," cannot ignore variants; ",[39,127462,125318],{}," is required whenever you don't want every arm",[28,127465,127467,355,127469,127471],{"className":127466},[31],[33,127468],{"disabled":35,"type":36},[39,127470,125318],{}," is more concise for the single-pattern case, at the cost of losing the compiler's exhaustiveness guarantee for any variants you're not handling",[28,127473,127475,355,127477,127479,127480],{"className":127474},[31],[33,127476],{"disabled":35,"type":36},[39,127478,125318],{}," is faster at runtime than ",[39,127481,116378],{},[28,127483,127485,355,127487,186,127489,127491],{"className":127484},[31],[33,127486],{"disabled":35,"type":36},[39,127488,125318],{},[39,127490,116378],{}," are interchangeable with no tradeoffs whatsoever",[66,127493,127494,127496,127502],{},[69,127495,71],{},[73,127497,127498,1727,127500,127471],{},[76,127499,78],{},[39,127501,125318],{},[73,127503,127504,355,127506,355,127508,127510,127511,127513,127514,127517,127518,127520,127521,127524,127525,127527],{},[76,127505,84],{},[76,127507,930],{},[39,127509,127445],{}," desugars to a ",[39,127512,116378],{}," with one meaningful arm and an implicit ",[39,127515,127516],{},"_ => {}"," — great ergonomics when you truly only care about one case, but it means if a new enum variant is added later, the compiler won't force you to reconsider this call site the way an exhaustive ",[39,127519,116378],{}," would. This is a genuine tradeoff to weigh, not a strict upgrade. A is false — ",[39,127522,127523],{},"match _ => {}"," handles the \"ignore the rest\" case just fine within a full ",[39,127526,116378],{},". C is a fabricated performance claim; they compile to equivalent code. D dismisses the real exhaustiveness tradeoff just described.",[15,127529,127530,127548,127586],{},[18,127531,127533,127534,127537,127538,127540,127541,127543,127544,127547],{"id":127532},"q18-whats-the-best-practice-reason-to-prefer-let-somex-opt-else-return-let-else-over-a-match-with-an-unreachablepanicking-else-arm-when-you-need-x-bound-in-the-surrounding-scope-rather-than-nested-inside-a-block","Q18. What's the best-practice reason to prefer ",[39,127535,127536],{},"let Some(x) = opt else { return; };"," (\"let-else\") over a ",[39,127539,116378],{}," with an unreachable\u002Fpanicking else-arm, when you need ",[39,127542,2403],{}," bound in the ",[104,127545,127546],{},"surrounding"," scope rather than nested inside a block?",[23,127549,127551,127560,127570,127578],{"className":127550},[26],[28,127552,127554,355,127556,127559],{"className":127553},[31],[33,127555],{"disabled":35,"type":36},[39,127557,127558],{},"let else"," is the only way to bind a variable from a pattern match at all",[28,127561,127563,355,127565,15479,127567,127569],{"className":127562},[31],[33,127564],{"disabled":35,"type":36},[39,127566,127558],{},[39,127568,2403],{}," usable in the rest of the enclosing function body without an extra nested block or indentation level, while still forcing the \"else\" (failure) path to diverge (return, break, panic, etc.)",[28,127571,127573,355,127575,127577],{"className":127572},[31],[33,127574],{"disabled":35,"type":36},[39,127576,116378],{}," cannot diverge in its arms",[28,127579,127581,355,127583,127585],{"className":127580},[31],[33,127582],{"disabled":35,"type":36},[39,127584,127558],{}," automatically logs a warning when the else branch runs",[66,127587,127588,127590,127598],{},[69,127589,71],{},[73,127591,127592,1727,127594,15479,127596,127569],{},[76,127593,78],{},[39,127595,127558],{},[39,127597,2403],{},[73,127599,127600,355,127602,127604,127605,127607,127608,127610,127611,127613,127614,127616,127617,127619,127620,127622,127623,127625,127626,127628,127629,127631,127632,186,127634,127636,127637,127639,127640,446,127642,127644],{},[76,127601,84],{},[76,127603,930],{}," with a plain ",[39,127606,116378],{},", binding ",[39,127609,2403],{}," for use ",[104,127612,1747],{}," the match block requires either nesting the rest of the logic inside the ",[39,127615,125816],{}," arm (extra indentation) or declaring ",[39,127618,2403],{}," outside and assigning inside (awkward with non-",[39,127621,114164],{},"\u002Fnon-default types). ",[39,127624,127558],{}," solves this cleanly: the happy-path binding flows into the normal scope, and the compiler enforces that the ",[39,127627,9884],{}," block must diverge (never fall through), so ",[39,127630,2403],{}," is always known to be initialized past that point. A is false — ",[39,127633,125318],{},[39,127635,116378],{}," can both bind variables too. C is false — ",[39,127638,116378],{}," arms can absolutely diverge with ",[39,127641,9151],{},[39,127643,119025],{},"\u002Fetc.; that's exactly what makes the older equivalent pattern work. D is fabricated; no automatic logging happens.",[15,127646,127647,127665,127706],{},[18,127648,127650,127651,127654,127655,127657,127658,42,127661,127664],{"id":127649},"q19-a-team-is-deciding-between-representing-http-methods-as-enum-method-get-post-put-delete-versus-as-string-values-like-get-post-whats-the-best-practice-argument-for-the-enum","Q19. A team is deciding between representing HTTP methods as ",[39,127652,127653],{},"enum Method { Get, Post, Put, Delete }"," versus as ",[39,127656,16721],{}," values like ",[39,127659,127660],{},"\"GET\"",[39,127662,127663],{},"\"POST\"",". What's the best-practice argument for the enum?",[23,127666,127668,127676,127689,127700],{"className":127667},[26],[28,127669,127671,355,127673,127675],{"className":127670},[31],[33,127672],{"disabled":35,"type":36},[39,127674,16721],{}," comparisons are always slower, so the enum is purely a performance choice",[28,127677,127679,127681,127682,127685,127686,127688],{"className":127678},[31],[33,127680],{"disabled":35,"type":36}," The enum makes invalid states like ",[39,127683,127684],{},"Method::from(\"PATCH_TYPO\")"," unrepresentable — the compiler enforces that only the known, valid variants exist, and ",[39,127687,116378],{}," exhaustiveness ensures every call site handles all of them (or is forced to update when a new one is added)",[28,127690,127692,355,127694,127696,127697,127699],{"className":127691},[31],[33,127693],{"disabled":35,"type":36},[39,127695,16721],{}," cannot be used in a ",[39,127698,116378],{}," statement at all",[28,127701,127703,127705],{"className":127702},[31],[33,127704],{"disabled":35,"type":36}," Enums are required for anything sent over a network",[66,127707,127708,127710,127719],{},[69,127709,71],{},[73,127711,127712,127714,127715,127685,127717,127688],{},[76,127713,78],{}," B — The enum makes invalid states like ",[39,127716,127684],{},[39,127718,116378],{},[73,127720,127721,355,127723,127725,127726,127728,127729,127732,127733,127735,127736,446,127738,127740],{},[76,127722,84],{},[76,127724,930],{}," this is the \"make illegal states unrepresentable\" principle that enums are especially good at — a ",[39,127727,16721],{}," can hold literally any text, pushing validation to runtime (and every call site must remember to validate), while ",[39,127730,127731],{},"Method::Get"," is guaranteed by the type system to be one of the defined variants, with typos caught at compile time. A is a plausible-sounding but secondary justification; the primary win here is correctness\u002Fsafety, not raw comparison speed (though it can help too). C is false — ",[39,127734,116378],{}," does work on ",[39,127737,16721],{},[39,127739,112302],{}," via literal patterns, it's just less safe since it can't be exhaustive over \"all possible strings\" in a meaningful way. D is a fabricated blanket rule; plenty of network-serialized data uses strings, though enums are still often preferred internally with a serialization layer at the boundary.",[15,127742,127743,127755,127799],{},[18,127744,127746,127747,127750,127751,127754],{"id":127745},"q20-a-struct-field-is-typed-optionvecstring-to-represent-either-no-tags-or-a-list-of-tags-a-reviewer-suggests-changing-it-to-just-vecstring-using-an-empty-vec-for-no-tags-whats-the-tradeoff-to-consider","Q20. A struct field is typed ",[39,127748,127749],{},"Option\u003CVec\u003CString>>"," to represent \"either no tags, or a list of tags.\" A reviewer suggests changing it to just ",[39,127752,127753],{},"Vec\u003CString>"," (using an empty vec for \"no tags\"). What's the tradeoff to consider?",[23,127756,127758,127764,127781,127789],{"className":127757},[26],[28,127759,127761,127763],{"className":127760},[31],[33,127762],{"disabled":35,"type":36}," There's no difference — both represent \"no tags\" identically in every context",[28,127765,127767,355,127769,127771,127772,127775,127776,446,127778,127780],{"className":127766},[31],[33,127768],{"disabled":35,"type":36},[39,127770,127749],{}," distinguishes \"explicitly no tags were provided\u002Floaded\" from \"tags haven't been fetched\u002Fset yet,\" a distinction ",[39,127773,127774],{},"Vec::new()"," alone can't express, but at the cost of an extra ",[39,127777,125816],{},[39,127779,90944],{}," unwrap at every use site",[28,127782,127784,355,127786,127788],{"className":127783},[31],[33,127785],{"disabled":35,"type":36},[39,127787,127753],{}," cannot ever be empty, so this comparison is invalid",[28,127790,127792,355,127794,127796,127797],{"className":127791},[31],[33,127793],{"disabled":35,"type":36},[39,127795,127749],{}," is always more memory-efficient than ",[39,127798,127753],{},[66,127800,127801,127803,127815],{},[69,127802,71],{},[73,127804,127805,1727,127807,127771,127809,127775,127811,446,127813,127780],{},[76,127806,78],{},[39,127808,127749],{},[39,127810,127774],{},[39,127812,125816],{},[39,127814,90944],{},[73,127816,127817,355,127819,127821,127822,20968,127824,33111,127826,127829,127830,127832,127833,127835,127836,127838,127839,127841,127842,127844,127845,127847,127848,127850],{},[76,127818,84],{},[76,127820,930],{}," this is a genuine, common judgment call — if \"not yet loaded\" and \"loaded but empty\" are meaningfully different states in your domain (e.g., lazily-fetched data, optional JSON fields distinguishing ",[39,127823,2650],{},[39,127825,3290],{},[39,127827,127828],{},"Option\u003CVec\u003CT>>"," captures that distinction the type system can enforce. If they're not meaningfully different, plain ",[39,127831,116767],{}," (empty vec = no tags) is simpler and avoids the extra layer of unwrapping\u002Fmatching at every call site — an empty ",[39,127834,112877],{}," is already a perfectly valid, well-supported \"nothing here\" state, so wrapping it in ",[39,127837,116852],{}," for no reason is a common overcomplication. A ignores a real semantic distinction that matters in some domains. C is false — an empty ",[39,127840,112877],{}," is completely valid and common. D is a fabricated blanket memory claim that depends on context (e.g., ",[39,127843,127828],{}," adds a discriminant unless niche-optimized, and ",[39,127846,112877],{},"'s pointer typically isn't null-representable the same simple way ",[39,127849,120804],{}," is, so this generalization doesn't reliably hold).",[2107,127852,127853],{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html .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 .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}",{"title":264,"searchDepth":286,"depth":286,"links":127855},[127856,127858,127860,127861,127863,127865,127866,127868,127870,127872,127874,127876,127877,127879,127881,127883,127885,127887,127889,127891],{"id":125242,"depth":296,"text":127857},"Q1. Why does Rust use Option\u003CT> instead of allowing references and values to be null?",{"id":125344,"depth":296,"text":127859},"Q2. What are the two variants of Result\u003CT, E>, and what does each represent?",{"id":125436,"depth":296,"text":125437},{"id":125571,"depth":296,"text":127862},"Q4. Given let msg = Message::Write(String::from(\"hi\"));, how do you correctly destructure it in a match without moving msg?",{"id":125748,"depth":296,"text":127864},"Q5. What does calling .unwrap() on Option\u003CT> do when the value is None?",{"id":125840,"depth":296,"text":125841},{"id":125907,"depth":296,"text":127867},"Q7. What does ? do when applied to a Result\u003CT, E> inside a function that itself returns Result\u003CT, E>?",{"id":126156,"depth":296,"text":127869},"Q8. What happens when you call .unwrap() on a Result::Err in production code with no catch_unwind or panic hook configured?",{"id":126330,"depth":296,"text":127871},"Q9. What is the size, in bytes, of Option\u003C&i32> on a 64-bit platform, compared to &i32 alone, and why?",{"id":126430,"depth":296,"text":127873},"Q10. What does an empty match on Option\u003CT> that omits the None arm do?",{"id":126571,"depth":296,"text":127875},"Q11. enum Never {} — an enum with zero variants — what can you do with a value of this type?",{"id":126645,"depth":296,"text":126646},{"id":126871,"depth":296,"text":127878},"Q13. In enum Shape { Circle(f64), Square(f64) }, is Circle(2.0) == Circle(2.0) valid, and under what condition?",{"id":126976,"depth":296,"text":127880},"Q14. What happens if you match on &Option\u003CString> and try to move the inner String out inside the match arm?",{"id":127218,"depth":296,"text":127882},"Q15. When designing a function that can fail, why is returning Result\u003CT, MyError> generally preferred over returning Option\u003CT> and discarding the reason for failure?",{"id":127336,"depth":296,"text":127884},"Q16. Code review flags a public function returning Result\u003CUser, String> where String is just a human-readable error message. What's the idiomatic improvement, and why?",{"id":127442,"depth":296,"text":127886},"Q17. Why is if let Some(x) = maybe_value { ... } often preferred over a full match when you only care about one variant and want to ignore the rest?",{"id":127532,"depth":296,"text":127888},"Q18. What's the best-practice reason to prefer let Some(x) = opt else { return; }; (\"let-else\") over a match with an unreachable\u002Fpanicking else-arm, when you need x bound in the surrounding scope rather than nested inside a block?",{"id":127649,"depth":296,"text":127890},"Q19. A team is deciding between representing HTTP methods as enum Method { Get, Post, Put, Delete } versus as String values like \"GET\", \"POST\". What's the best-practice argument for the enum?",{"id":127745,"depth":296,"text":127892},"Q20. A struct field is typed Option\u003CVec\u003CString>> to represent \"either no tags, or a list of tags.\" A reviewer suggests changing it to just Vec\u003CString> (using an empty vec for \"no tags\"). What's the tradeoff to consider?",{},"\u002Frust\u002F12-enums",{"title":125232,"description":264},"rust\u002F12-enums","HT0QXHGT2tbDHDxngAjTFAzO1oSyWeczYNysOsNIGL4",{"id":127899,"title":127900,"body":127901,"description":264,"extension":2144,"meta":130701,"navigation":35,"path":130702,"seo":130703,"stem":130704,"__hash__":130705},"content\u002Frust\u002F19-smart-pointers.md","19 — Smart Pointers",{"type":8,"value":127902,"toc":130664},[127903,127906,128043,128124,128212,128278,128351,128590,128660,128874,129021,129117,129207,129327,129655,129741,129825,129922,129995,130106,130320,130662],[11,127904,127900],{"id":127905},"_19-smart-pointers",[15,127907,127908,127916,127965,128002],{"language":111909},[18,127909,127911,127912,127915],{"id":127910},"q1-what-problem-does-boxt-primarily-solve-for-a-type-like-this","Q1. What problem does ",[39,127913,127914],{},"Box\u003CT>"," primarily solve for a type like this?",[257,127917,127918],{"language":111909},[260,127919,127921],{"className":111918,"code":127920,"language":111909,"meta":264,"style":264},"enum List {\n    Cons(i32, Box\u003CList>),\n    Nil,\n}\n",[39,127922,127923,127932,127954,127961],{"__ignoreMap":264},[268,127924,127925,127927,127930],{"class":270,"line":271},[268,127926,125449],{"class":274},[268,127928,127929],{"class":278}," List",[268,127931,9914],{"class":282},[268,127933,127934,127937,127939,127941,127943,127946,127948,127951],{"class":270,"line":286},[268,127935,127936],{"class":278},"    Cons",[268,127938,622],{"class":282},[268,127940,113860],{"class":278},[268,127942,42],{"class":282},[268,127944,127945],{"class":278},"Box",[268,127947,1076],{"class":282},[268,127949,127950],{"class":278},"List",[268,127952,127953],{"class":282},">),\n",[268,127955,127956,127959],{"class":270,"line":296},[268,127957,127958],{"class":278},"    Nil",[268,127960,1789],{"class":282},[268,127962,127963],{"class":270,"line":311},[268,127964,314],{"class":282},[23,127966,127968,127977,127986,127992],{"className":127967},[26],[28,127969,127971,104514,127973,29029,127975],{"className":127970},[31],[33,127972],{"disabled":35,"type":36},[39,127974,127950],{},[39,127976,114164],{},[28,127978,127980,127982,127983,127985],{"className":127979},[31],[33,127981],{"disabled":35,"type":36}," It gives ",[39,127984,127950],{}," a known, fixed size at compile time by putting the recursive part on the heap",[28,127987,127989,127991],{"className":127988},[31],[33,127990],{"disabled":35,"type":36}," It makes the enum thread-safe",[28,127993,127995,127997,127998,89923,128000],{"className":127994},[31],[33,127996],{"disabled":35,"type":36}," It automatically derives ",[39,127999,122174],{},[39,128001,127950],{},[66,128003,128004,128006,128013],{},[69,128005,71],{},[73,128007,128008,128010,128011,127985],{},[76,128009,78],{}," B — It gives ",[39,128012,127950],{},[73,128014,128015,128017,128018,128020,128021,128023,128024,3277,128027,128030,128031,128033,128034,128036,128037,128039,128040,128042],{},[76,128016,84],{}," Without indirection, ",[39,128019,127950],{}," would need to contain a ",[39,128022,127950],{}," inline, giving it infinite size — the compiler cannot compute ",[39,128025,128026],{},"size_of::\u003CList>()",[39,128028,128029],{},"Box\u003CList>"," stores a single pointer-sized value (the heap address) inline instead, so the enum's size is fixed regardless of how deep the list grows. ",[76,128032,17613],{},": this is a compile-time size problem, not a runtime one — code with an unboxed recursive variant is rejected before it ever runs. It has nothing to do with ",[39,128035,114164],{},", thread safety, or ",[39,128038,122174],{},", none of which ",[39,128041,127945],{}," grants automatically.",[15,128044,128045,128053,128084],{},[18,128046,128048,128049,128052],{"id":128047},"q2-what-is-rct-used-for","Q2. What is ",[39,128050,128051],{},"Rc\u003CT>"," used for?",[23,128054,128056,128062,128068,128074],{"className":128055},[26],[28,128057,128059,128061],{"className":128058},[31],[33,128060],{"disabled":35,"type":36}," Enabling shared ownership of heap data within a single thread via reference counting",[28,128063,128065,128067],{"className":128064},[31],[33,128066],{"disabled":35,"type":36}," Enabling shared mutable access across threads",[28,128069,128071,128073],{"className":128070},[31],[33,128072],{"disabled":35,"type":36}," Automatic garbage collection of cyclic data structures",[28,128075,128077,128079,128080,8574,128082],{"className":128076},[31],[33,128078],{"disabled":35,"type":36}," Making a type ",[39,128081,114164],{},[39,128083,122174],{},[66,128085,128086,128088,128093],{},[69,128087,71],{},[73,128089,128090,128092],{},[76,128091,78],{}," A — Enabling shared ownership of heap data within a single thread via reference counting",[73,128094,128095,355,128097,128099,128100,128103,128104,1783,128106,128108,128109,5893,128112,128115,128116,446,128118,128120,128121,128123],{},[76,128096,84],{},[39,128098,128051],{}," (\"reference counted\") lets multiple owners share the same heap allocation; each ",[39,128101,128102],{},"clone()"," bumps a counter, and the value is dropped once the count reaches zero. ",[76,128105,17613],{},[39,128107,128051],{},"'s counter increments are not atomic, so it is neither ",[39,128110,128111],{},"Send",[39,128113,128114],{},"Sync"," — sharing one across threads is a compile error, which rules out B. It does not collect cycles (rules out C, see the leak question later in this file), and it does not affect ",[39,128117,114164],{},[39,128119,122174],{}," derivation semantics beyond providing its own cheap ",[39,128122,122174],{}," impl.",[15,128125,128126,128137,128176],{},[18,128127,128129,128130,128133,128134,1685],{"id":128128},"q3-given-let-b-rcclonea-what-is-idiomatic-about-writing-it-this-way-instead-of-let-b-aclone","Q3. Given ",[39,128131,128132],{},"let b = Rc::clone(&a);",", what is idiomatic about writing it this way instead of ",[39,128135,128136],{},"let b = a.clone();",[23,128138,128140,128149,128155,128164],{"className":128139},[26],[28,128141,128143,355,128145,128148],{"className":128142},[31],[33,128144],{"disabled":35,"type":36},[39,128146,128147],{},"Rc::clone"," is faster because it skips the reference count",[28,128150,128152,128154],{"className":128151},[31],[33,128153],{"disabled":35,"type":36}," Nothing — they are different operations with different results",[28,128156,128158,355,128160,128163],{"className":128157},[31],[33,128159],{"disabled":35,"type":36},[39,128161,128162],{},"Rc::clone(&a)"," makes it visually clear at the call site that this is a cheap pointer\u002Frefcount clone, not a deep data clone",[28,128165,128167,355,128169,128172,128173,128175],{"className":128166},[31],[33,128168],{"disabled":35,"type":36},[39,128170,128171],{},"a.clone()"," would move ",[39,128174,1223],{}," instead of borrowing it",[66,128177,128178,128180,128186],{},[69,128179,71],{},[73,128181,128182,1004,128184,128163],{},[76,128183,78],{},[39,128185,128162],{},[73,128187,128188,128190,128191,128193,128194,128196,128197,128199,128200,128203,128204,26924,128206,128208,128209,128211],{},[76,128189,84],{}," Both calls do exactly the same thing — increment the strong count and return a new ",[39,128192,128051],{}," pointing at the same allocation. ",[76,128195,17307],{},": Rust style favors ",[39,128198,128162],{}," as documentation-by-convention, distinguishing \"cheap, shared-ownership clone\" from a ",[39,128201,128202],{},"T::clone()"," that might be an expensive deep copy. It's purely a readability convention, not a performance difference (rules out A), the operations are identical (rules out B), and ",[39,128205,128171],{},[39,128207,112964],{}," so it borrows, it never moves ",[39,128210,1223],{}," (rules out D).",[15,128213,128214,128221,128256],{},[18,128215,128217,128218,128220],{"id":128216},"q4-when-does-the-value-inside-an-rct-actually-get-dropped","Q4. When does the value inside an ",[39,128219,128051],{}," actually get dropped?",[23,128222,128224,128234,128240,128248],{"className":128223},[26],[28,128225,128227,128229,128230,128233],{"className":128226},[31],[33,128228],{"disabled":35,"type":36}," As soon as any single ",[39,128231,128232],{},"Rc"," handle to it goes out of scope",[28,128235,128237,128239],{"className":128236},[31],[33,128238],{"disabled":35,"type":36}," Only when the strong count drops to zero",[28,128241,128243,128245,128246,58241],{"className":128242},[31],[33,128244],{"disabled":35,"type":36}," Immediately when ",[39,128247,128147],{},[28,128249,128251,98872,128253,128255],{"className":128250},[31],[33,128252],{"disabled":35,"type":36},[39,128254,128232],{}," values are leaked by design",[66,128257,128258,128260,128265],{},[69,128259,71],{},[73,128261,128262,128264],{},[76,128263,78],{}," B — Only when the strong count drops to zero",[73,128266,128267,4715,128269,128271,128272,128274,128275,128277],{},[76,128268,84],{},[39,128270,128232],{}," clone increments a shared strong count; dropping any one handle decrements it, and the inner value's destructor only runs when that count hits zero. A is the tempting-but-wrong beginner assumption — it confuses \"one handle drops\" with \"the value drops,\" which only coincide when there was exactly one owner left. ",[39,128273,128147],{}," increments, it never triggers a drop (rules out C), and ",[39,128276,128232],{}," values are reclaimed normally (rules out D) — unless a reference cycle prevents the count from ever reaching zero, which is a separate leak scenario covered later.",[15,128279,128280,128290,128320],{},[18,128281,67628,128283,128286,128287,128289],{"id":128282},"q5-what-does-refcellt-provide-that-a-plain-t-behind-a-shared-reference-does-not",[39,128284,128285],{},"RefCell\u003CT>"," provide that a plain ",[39,128288,102486],{}," behind a shared reference does not?",[23,128291,128293,128299,128308,128314],{"className":128292},[26],[28,128294,128296,128298],{"className":128295},[31],[33,128297],{"disabled":35,"type":36}," Compile-time enforcement of Rust's borrow rules, just faster",[28,128300,128302,128304,128305,128307],{"className":128301},[31],[33,128303],{"disabled":35,"type":36}," Interior mutability — the ability to mutate data through a shared (",[39,128306,85350],{},") reference, with borrow rules checked at runtime instead of compile time",[28,128309,128311,128313],{"className":128310},[31],[33,128312],{"disabled":35,"type":36}," Thread-safe mutability across multiple threads",[28,128315,128317,128319],{"className":128316},[31],[33,128318],{"disabled":35,"type":36}," Automatic synchronization equivalent to a mutex",[66,128321,128322,128324,128331],{},[69,128323,71],{},[73,128325,128326,128328,128329,128307],{},[76,128327,78],{}," B — Interior mutability — the ability to mutate data through a shared (",[39,128330,85350],{},[73,128332,128333,355,128335,128337,128338,186,128341,128344,128345,128347,128348,128350],{},[76,128334,84],{},[39,128336,128285],{}," moves Rust's \"one mutable borrow XOR many shared borrows\" rule from compile time to runtime: ",[39,128339,128340],{},"borrow()",[39,128342,128343],{},"borrow_mut()"," track active borrows and panic if violated. ",[76,128346,17613],{},": this trades a compile error for a runtime panic — it does not weaken the rule, it just enforces it later. It is single-threaded only (no ",[39,128349,128114],{}," for its guards in the way a mutex provides), so it is not a threading primitive (rules out C and D), and it is strictly runtime checking, not a faster compile-time check (rules out A).",[15,128352,128353,128357,128502,128543],{"language":111909},[18,128354,128356],{"id":128355},"q6-why-does-this-code-fail-to-compile","Q6. Why does this code fail to compile?",[257,128358,128359],{"language":111909},[260,128360,128362],{"className":111918,"code":128361,"language":111909,"meta":264,"style":264},"use std::rc::Rc;\nuse std::thread;\n\nfn main() {\n    let data = Rc::new(vec![1, 2, 3]);\n    let handle = thread::spawn(move || {\n        println!(\"{:?}\", data);\n    });\n    handle.join().unwrap();\n}\n",[39,128363,128364,128381,128392,128396,128404,128439,128465,128477,128481,128498],{"__ignoreMap":264},[268,128365,128366,128368,128370,128372,128375,128377,128379],{"class":270,"line":271},[268,128367,108694],{"class":274},[268,128369,125974],{"class":278},[268,128371,84903],{"class":274},[268,128373,128374],{"class":278},"rc",[268,128376,84903],{"class":274},[268,128378,128232],{"class":278},[268,128380,293],{"class":282},[268,128382,128383,128385,128387,128389],{"class":270,"line":286},[268,128384,108694],{"class":274},[268,128386,125974],{"class":278},[268,128388,84903],{"class":274},[268,128390,128391],{"class":282},"thread;\n",[268,128393,128394],{"class":270,"line":296},[268,128395,5033],{"emptyLinePlaceholder":35},[268,128397,128398,128400,128402],{"class":270,"line":311},[268,128399,37837],{"class":274},[268,128401,111928],{"class":278},[268,128403,283],{"class":282},[268,128405,128406,128408,128411,128413,128416,128418,128420,128422,128425,128427,128429,128431,128433,128435,128437],{"class":270,"line":788},[268,128407,80826],{"class":274},[268,128409,128410],{"class":282}," data ",[268,128412,302],{"class":274},[268,128414,128415],{"class":278}," Rc",[268,128417,84903],{"class":274},[268,128419,2689],{"class":278},[268,128421,622],{"class":282},[268,128423,128424],{"class":278},"vec!",[268,128426,15175],{"class":282},[268,128428,2255],{"class":305},[268,128430,42],{"class":282},[268,128432,2258],{"class":305},[268,128434,42],{"class":282},[268,128436,3423],{"class":305},[268,128438,15180],{"class":282},[268,128440,128441,128443,128446,128448,128451,128453,128455,128457,128460,128463],{"class":270,"line":1951},[268,128442,80826],{"class":274},[268,128444,128445],{"class":282}," handle ",[268,128447,302],{"class":274},[268,128449,128450],{"class":278}," thread",[268,128452,84903],{"class":274},[268,128454,107122],{"class":278},[268,128456,622],{"class":282},[268,128458,128459],{"class":274},"move",[268,128461,128462],{"class":274}," ||",[268,128464,9914],{"class":282},[268,128466,128467,128469,128471,128474],{"class":270,"line":8955},[268,128468,112752],{"class":278},[268,128470,622],{"class":282},[268,128472,128473],{"class":289},"\"{:?}\"",[268,128475,128476],{"class":282},", data);\n",[268,128478,128479],{"class":270,"line":8966},[268,128480,35432],{"class":282},[268,128482,128483,128486,128488,128490,128492,128494,128496],{"class":270,"line":8974},[268,128484,128485],{"class":282},"    handle",[268,128487,462],{"class":274},[268,128489,18112],{"class":278},[268,128491,16952],{"class":282},[268,128493,462],{"class":274},[268,128495,126211],{"class":278},[268,128497,794],{"class":282},[268,128499,128500],{"class":270,"line":8985},[268,128501,314],{"class":282},[23,128503,128505,128514,128524,128535],{"className":128504},[26],[28,128506,128508,355,128510,128513],{"className":128507},[31],[33,128509],{"disabled":35,"type":36},[39,128511,128512],{},"Vec\u003Ci32>"," cannot be sent between threads",[28,128515,128517,355,128519,127205,128521,128523],{"className":128516},[31],[33,128518],{"disabled":35,"type":36},[39,128520,128051],{},[39,128522,128111],{},", because its non-atomic refcount would cause a data race if incremented from multiple threads",[28,128525,128527,355,128529,128531,128532,128534],{"className":128526},[31],[33,128528],{"disabled":35,"type":36},[39,128530,121393],{}," requires a ",[39,128533,112492],{}," closure and this one isn't",[28,128536,128538,355,128540,128542],{"className":128537},[31],[33,128539],{"disabled":35,"type":36},[39,128541,118575],{}," cannot be used inside a spawned thread",[66,128544,128545,128547,128555],{},[69,128546,71],{},[73,128548,128549,1727,128551,127205,128553,128523],{},[76,128550,78],{},[39,128552,128051],{},[39,128554,128111],{},[73,128556,128557,355,128559,128561,128562,446,128564,89923,128566,128568,128569,128572,128573,128575,128576,128578,128579,128581,128582,128584,128585,128587,128588,462],{},[76,128558,84],{},[39,128560,128051],{},"'s clone\u002Fdrop increments and decrements a plain (non-atomic) counter; if two threads did that concurrently it would be a data race, so the standard library simply withholds ",[39,128563,128111],{},[39,128565,128114],{},[39,128567,128051],{}," and the compiler rejects moving it into another thread. The fix is ",[39,128570,128571],{},"Arc\u003CT>",", which uses atomic operations for its counters. ",[39,128574,128512],{}," itself is perfectly ",[39,128577,128111],{}," (rules out A), the closure is ",[39,128580,112492],{}," here since ",[39,128583,21188],{}," is moved in and owns its data (rules out C), and ",[39,128586,118575],{}," is fine inside threads (rules out D) — the error is specifically about ",[39,128589,128232],{},[15,128591,128592,128598,128627],{},[18,128593,128595,128596,114665],{"id":128594},"q7-what-is-boxdyn-trait-primarily-used-for","Q7. What is ",[39,128597,121396],{},[23,128599,128601,128607,128613,128621],{"className":128600},[26],[28,128602,128604,128606],{"className":128603},[31],[33,128605],{"disabled":35,"type":36}," Storing a trait object with a size known only at runtime, enabling dynamic dispatch through a heap-allocated pointer",[28,128608,128610,128612],{"className":128609},[31],[33,128611],{"disabled":35,"type":36}," Making a trait's methods run faster via static dispatch",[28,128614,128616,128618,128619],{"className":128615},[31],[33,128617],{"disabled":35,"type":36}," Automatically implementing the trait for ",[39,128620,127945],{},[28,128622,128624,128626],{"className":128623},[31],[33,128625],{"disabled":35,"type":36}," Sharing ownership of a trait object across threads",[66,128628,128629,128631,128636],{},[69,128630,71],{},[73,128632,128633,128635],{},[76,128634,78],{}," A — Storing a trait object with a size known only at runtime, enabling dynamic dispatch through a heap-allocated pointer",[73,128637,128638,355,128640,128642,128643,128645,128646,128649,128650,128652,128653,128656,128657,128659],{},[76,128639,84],{},[39,128641,122543],{}," is unsized (different implementors have different sizes), so it can't be stored by value; ",[39,128644,121396],{}," gives it a fixed-size, heap-allocated home and dispatches method calls through a vtable at runtime. That's the opposite of static dispatch — ",[39,128647,128648],{},"dyn"," implies dynamic dispatch, which is typically slightly slower than monomorphized generics, not faster (rules out B). ",[39,128651,127945],{}," doesn't implement the trait itself, it just stores something that does (rules out C), and ownership sharing across threads is ",[39,128654,128655],{},"Arc\u003Cdyn Trait + Send + Sync>","'s job, not plain ",[39,128658,127945],{},"'s (rules out D).",[15,128661,128662,128666,128779,128819],{"language":111909},[18,128663,128665],{"id":128664},"q8-what-happens-when-this-code-runs","Q8. What happens when this code runs?",[257,128667,128668],{"language":111909},[260,128669,128671],{"className":111918,"code":128670,"language":111909,"meta":264,"style":264},"use std::cell::RefCell;\n\nfn main() {\n    let cell = RefCell::new(5);\n    let _b1 = cell.borrow_mut();\n    let _b2 = cell.borrow_mut();\n    println!(\"{}\", *_b1);\n}\n",[39,128672,128673,128690,128694,128702,128724,128743,128760,128775],{"__ignoreMap":264},[268,128674,128675,128677,128679,128681,128684,128686,128688],{"class":270,"line":271},[268,128676,108694],{"class":274},[268,128678,125974],{"class":278},[268,128680,84903],{"class":274},[268,128682,128683],{"class":278},"cell",[268,128685,84903],{"class":274},[268,128687,113034],{"class":278},[268,128689,293],{"class":282},[268,128691,128692],{"class":270,"line":286},[268,128693,5033],{"emptyLinePlaceholder":35},[268,128695,128696,128698,128700],{"class":270,"line":296},[268,128697,37837],{"class":274},[268,128699,111928],{"class":278},[268,128701,283],{"class":282},[268,128703,128704,128706,128709,128711,128714,128716,128718,128720,128722],{"class":270,"line":311},[268,128705,80826],{"class":274},[268,128707,128708],{"class":282}," cell ",[268,128710,302],{"class":274},[268,128712,128713],{"class":278}," RefCell",[268,128715,84903],{"class":274},[268,128717,2689],{"class":278},[268,128719,622],{"class":282},[268,128721,2429],{"class":305},[268,128723,628],{"class":282},[268,128725,128726,128728,128731,128733,128736,128738,128741],{"class":270,"line":788},[268,128727,80826],{"class":274},[268,128729,128730],{"class":282}," _b1 ",[268,128732,302],{"class":274},[268,128734,128735],{"class":282}," cell",[268,128737,462],{"class":274},[268,128739,128740],{"class":278},"borrow_mut",[268,128742,794],{"class":282},[268,128744,128745,128747,128750,128752,128754,128756,128758],{"class":270,"line":1951},[268,128746,80826],{"class":274},[268,128748,128749],{"class":282}," _b2 ",[268,128751,302],{"class":274},[268,128753,128735],{"class":282},[268,128755,462],{"class":274},[268,128757,128740],{"class":278},[268,128759,794],{"class":282},[268,128761,128762,128764,128766,128768,128770,128772],{"class":270,"line":8955},[268,128763,111958],{"class":278},[268,128765,622],{"class":282},[268,128767,113830],{"class":289},[268,128769,42],{"class":282},[268,128771,6134],{"class":274},[268,128773,128774],{"class":282},"_b1);\n",[268,128776,128777],{"class":270,"line":8966},[268,128778,314],{"class":282},[23,128780,128782,128792,128801,128810],{"className":128781},[26],[28,128783,128785,106471,128787,3990,128789,128791],{"className":128784},[31],[33,128786],{"disabled":35,"type":36},[39,128788,2429],{},[39,128790,113034],{}," allows nested mutable borrows within the same scope",[28,128793,128795,128797,128798,128800],{"className":128794},[31],[33,128796],{"disabled":35,"type":36}," It panics at the second ",[39,128799,128343],{}," call with \"already borrowed: BorrowMutError\"",[28,128802,128804,117747,128806,71990,128808],{"className":128803},[31],[33,128805],{"disabled":35,"type":36},[39,128807,113034],{},[39,128809,112499],{},[28,128811,128813,128815,128816],{"className":128812},[31],[33,128814],{"disabled":35,"type":36}," It silently returns a stale value for ",[39,128817,128818],{},"_b2",[66,128820,128821,128823,128830],{},[69,128822,71],{},[73,128824,128825,128827,128828,128800],{},[76,128826,78],{}," B — It panics at the second ",[39,128829,128343],{},[73,128831,128832,355,128834,128837,128838,128841,128842,128844,128845,128847,128848,128850,128851,128853,128854,128856,128857,128859,128860,128863,128864,128867,128868,128870,128871,128873],{},[76,128833,84],{},[39,128835,128836],{},"_b1"," is a live ",[39,128839,128840],{},"RefMut"," guard that isn't dropped before ",[39,128843,128818],{}," is requested, so ",[39,128846,128683],{}," already has one active mutable borrow when the second ",[39,128849,128343],{}," runs; ",[39,128852,113034],{}," enforces exclusivity at runtime and panics rather than allowing the second borrow. ",[76,128855,16523],{},": the correct fix is to drop ",[39,128858,128836],{}," (e.g., wrap it in its own block, or call ",[39,128861,128862],{},"drop(_b1)",") before taking the next borrow, or to use ",[39,128865,128866],{},"try_borrow_mut()"," and handle the ",[39,128869,116301],{}," case instead of unwrapping blindly. This compiles fine (rules out C) — the whole point of ",[39,128872,113034],{}," is that these checks happen at runtime, not compile time — and there is no silent stale-data behavior (rules out D); the panic is loud and immediate.",[15,128875,128876,128890,128956,128987],{"language":111909},[18,128877,128879,128880,128883,128884,128886,128887,128889],{"id":128878},"q9-this-code-builds-a-parent-child-tree-using-rcrefcellnode-where-each-parent-also-stores-an-rc-back-to-its-child-and-each-child-stores-an-rc-back-to-its-parent-what-is-the-consequence","Q9. This code builds a parent-child tree using ",[39,128881,128882],{},"Rc\u003CRefCell\u003CNode>>"," where each parent also stores an ",[39,128885,128232],{}," back to its child, and each child stores an ",[39,128888,128232],{}," back to its parent. What is the consequence?",[257,128891,128892],{"language":111909},[260,128893,128895],{"className":111918,"code":128894,"language":111909,"meta":264,"style":264},"struct Node {\n    parent: RefCell\u003COption\u003CRc\u003CNode>>>,\n    child: RefCell\u003COption\u003CRc\u003CNode>>>,\n}\n",[39,128896,128897,128905,128929,128952],{"__ignoreMap":264},[268,128898,128899,128901,128903],{"class":270,"line":271},[268,128900,121198],{"class":274},[268,128902,102853],{"class":278},[268,128904,9914],{"class":282},[268,128906,128907,128910,128912,128914,128916,128918,128920,128922,128924,128926],{"class":270,"line":286},[268,128908,128909],{"class":282},"    parent",[268,128911,10728],{"class":274},[268,128913,128713],{"class":278},[268,128915,1076],{"class":282},[268,128917,116852],{"class":278},[268,128919,1076],{"class":282},[268,128921,128232],{"class":278},[268,128923,1076],{"class":282},[268,128925,102926],{"class":278},[268,128927,128928],{"class":282},">>>,\n",[268,128930,128931,128934,128936,128938,128940,128942,128944,128946,128948,128950],{"class":270,"line":296},[268,128932,128933],{"class":282},"    child",[268,128935,10728],{"class":274},[268,128937,128713],{"class":278},[268,128939,1076],{"class":282},[268,128941,116852],{"class":278},[268,128943,1076],{"class":282},[268,128945,128232],{"class":278},[268,128947,1076],{"class":282},[268,128949,102926],{"class":278},[268,128951,128928],{"class":282},[268,128953,128954],{"class":270,"line":311},[268,128955,314],{"class":282},[23,128957,128959,128965,128971,128981],{"className":128958},[26],[28,128960,128962,128964],{"className":128961},[31],[33,128963],{"disabled":35,"type":36}," The program fails to compile because Rust detects the cycle",[28,128966,128968,128970],{"className":128967},[31],[33,128969],{"disabled":35,"type":36}," The program panics at runtime with a stack overflow when dropped",[28,128972,128974,128976,128977,128980],{"className":128973},[31],[33,128975],{"disabled":35,"type":36}," Both nodes leak memory — their strong counts never reach zero, so ",[39,128978,128979],{},"Drop"," never runs, even though nothing is UB",[28,128982,128984,128986],{"className":128983},[31],[33,128985],{"disabled":35,"type":36}," Rust's garbage collector silently reclaims the cycle at the next allocation",[66,128988,128989,128991,128998],{},[69,128990,71],{},[73,128992,128993,128995,128996,128980],{},[76,128994,78],{}," C — Both nodes leak memory — their strong counts never reach zero, so ",[39,128997,128979],{},[73,128999,129000,129002,129003,129005,129006,129008,129009,129011,129012,129014,129015,129018,129019,462],{},[76,129001,84],{}," Parent holds a strong ",[39,129004,128232],{}," to child and child holds a strong ",[39,129007,128232],{}," back to parent, so each keeps the other's strong count above zero forever; once external references go out of scope, both nodes become unreachable garbage that will never be freed. ",[76,129010,17613],{},": this is a memory leak, not undefined behavior — Rust's ownership model guarantees memory safety (no dangling pointers, no double frees) but does not guarantee the absence of leaks, and reference cycles are the classic way to produce one. The compiler has no cycle detector for ",[39,129013,128232],{}," graphs (rules out A), there's no stack overflow or panic involved in the leak itself (rules out B), and Rust has no garbage collector to sweep up cycles (rules out D). The idiomatic fix is to make the parent link a ",[39,129016,129017],{},"Weak\u003CNode>"," instead of a strong ",[39,129020,128232],{},[15,129022,129023,129043,129076],{},[18,129024,55982,129026,129029,129030,129033,129034,5125,129037,129039,129040,129042],{"id":129025},"q10-weakt-is-obtained-via-rcdowngraderc-what-does-calling-upgrade-on-a-weakt-return-once-every-strong-rc-to-the-value-has-been-dropped",[39,129027,129028],{},"Weak\u003CT>"," is obtained via ",[39,129031,129032],{},"Rc::downgrade(&rc)",". What does calling ",[39,129035,129036],{},".upgrade()",[39,129038,129028],{}," return once every strong ",[39,129041,128232],{}," to the value has been dropped?",[23,129044,129046,129054,129062,129068],{"className":129045},[26],[28,129047,129049,355,129051,129053],{"className":129048},[31],[33,129050],{"disabled":35,"type":36},[39,129052,128051],{}," pointing to freed memory (undefined behavior)",[28,129055,129057,355,129059,129061],{"className":129056},[31],[33,129058],{"disabled":35,"type":36},[39,129060,90944],{},", safely indicating the value no longer exists",[28,129063,129065,129067],{"className":129064},[31],[33,129066],{"disabled":35,"type":36}," A panic",[28,129069,129071,129073,129074],{"className":129070},[31],[33,129072],{"disabled":35,"type":36}," A default-constructed ",[39,129075,102486],{},[66,129077,129078,129080,129086],{},[69,129079,71],{},[73,129081,129082,1727,129084,129061],{},[76,129083,78],{},[39,129085,90944],{},[73,129087,129088,355,129090,4912,129093,129096,129097,129100,129101,3990,129103,129106,129107,129109,129110,129113,129114,129116],{},[76,129089,84],{},[39,129091,129092],{},"Weak\u003CT>::upgrade()",[39,129094,129095],{},"Option\u003CRc\u003CT>>",": if the strong count is still above zero it bumps it and returns ",[39,129098,129099],{},"Some(rc)",", and if the value has already been dropped it returns ",[39,129102,90944],{},[39,129104,129105],{},"Weak"," never lets you touch freed memory. This is exactly why ",[39,129108,129105],{}," is the standard tool for breaking parent\u002Fback-references in tree and graph structures without risking a dangling pointer (rules out A, which describes what would be UB in a language like C). There's no panic on upgrade (rules out C) and no requirement that ",[39,129111,129112],{},"T: Default"," (rules out D) — the ",[39,129115,116852],{}," return is the whole safety mechanism.",[15,129118,129119,129126,129161],{},[18,129120,129122,129123,1685],{"id":129121},"q11-on-a-typical-64-bit-target-what-is-stdmemsize_ofrci32","Q11. On a typical 64-bit target, what is ",[39,129124,129125],{},"std::mem::size_of::\u003CRc\u003Ci32>>()",[23,129127,129129,129138,129147,129155],{"className":129128},[26],[28,129130,129132,129134,129135,129137],{"className":129131},[31],[33,129133],{"disabled":35,"type":36}," 8 bytes — ",[39,129136,128051],{}," is just a pointer to a heap block that also holds the strong\u002Fweak counts",[28,129139,129141,129143,129144,129146],{"className":129140},[31],[33,129142],{"disabled":35,"type":36}," 24 bytes — the strong count, weak count, and value are all stored inline in the ",[39,129145,128232],{}," handle",[28,129148,129150,129152,129153],{"className":129149},[31],[33,129151],{"disabled":35,"type":36}," 4 bytes — same as ",[39,129154,113860],{},[28,129156,129158,129160],{"className":129157},[31],[33,129159],{"disabled":35,"type":36}," 16 bytes — one pointer plus one inline count",[66,129162,129163,129165,129172],{},[69,129164,71],{},[73,129166,129167,129169,129170,129137],{},[76,129168,78],{}," A — 8 bytes — ",[39,129171,128051],{},[73,129173,129174,355,129176,129179,129180,129183,129184,129186,129187,129189,129190,3277,129192,129194,129195,129197,129198,129200,129201,129203,129204,129206],{},[76,129175,84],{},[39,129177,129178],{},"Rc::new(v)"," allocates a single heap block containing an ",[39,129181,129182],{},"RcBox"," (strong count, weak count, and the value ",[39,129185,52799],{}," together); the ",[39,129188,128051],{}," handle you hold is just one pointer to that block, so it's a single pointer-sized value like ",[39,129191,127914],{},[76,129193,55328],{},": this is a common gotcha — people assume the counts live \"in the ",[39,129196,128232],{},"\" and inflate its size, but they live on the heap alongside the data, which is also why cloning an ",[39,129199,128232],{}," is cheap (copy one pointer, bump one heap-resident counter) rather than copying counts by value. B describes a design ",[39,129202,128232],{}," doesn't use; C ignores that ",[39,129205,128232],{}," is a pointer, not the value itself; D is a plausible-sounding but incorrect split.",[15,129208,129209,129219,129265],{},[18,129210,129212,129213,186,129216,1685],{"id":129211},"q12-whats-the-difference-between-let-b2-boxnew42-let-b3-b2clone-and-let-r2-rcnew42-let-r3-rccloner2","Q12. What's the difference between ",[39,129214,129215],{},"let b2 = Box::new(42); let b3 = b2.clone();",[39,129217,129218],{},"let r2 = Rc::new(42); let r3 = Rc::clone(&r2);",[23,129220,129222,129228,129246,129254],{"className":129221},[26],[28,129223,129225,129227],{"className":129224},[31],[33,129226],{"disabled":35,"type":36}," No difference — both share the same heap allocation afterward",[28,129229,129231,355,129233,129236,129237,129239,129240,129242,129243,129245],{"className":129230},[31],[33,129232],{"disabled":35,"type":36},[39,129234,129235],{},"Box::clone"," performs a deep clone into a ",[104,129238,2689],{}," heap allocation, while ",[39,129241,128147],{}," shares the ",[104,129244,22779],{}," allocation and just bumps a refcount",[28,129247,129249,355,129251,129253],{"className":129248},[31],[33,129250],{"disabled":35,"type":36},[39,129252,127945],{}," cannot be cloned at all",[28,129255,129257,355,129259,129261,129262,129264],{"className":129256},[31],[33,129258],{"disabled":35,"type":36},[39,129260,128147],{}," performs a deep clone while ",[39,129263,129235],{}," shares the allocation",[66,129266,129267,129269,129281],{},[69,129268,71],{},[73,129270,129271,1727,129273,129236,129275,129239,129277,129242,129279,129245],{},[76,129272,78],{},[39,129274,129235],{},[104,129276,2689],{},[39,129278,128147],{},[104,129280,22779],{},[73,129282,129283,355,129285,129287,129288,129290,129291,129294,129295,186,129298,129301,129302,129304,129305,9057,129307,129309,129310,129312,129313,129315,129316,129318,129319,830,129321,129323,129324,129326],{},[76,129284,84],{},[39,129286,127914],{}," implements single ownership, so its ",[39,129289,122174],{}," impl (when ",[39,129292,129293],{},"T: Clone",") allocates a fresh block and copies the value into it — ",[39,129296,129297],{},"b2",[39,129299,129300],{},"b3"," end up as two independent ",[39,129303,113860],{},"s on the heap. ",[39,129306,128051],{},[39,129308,122174],{}," impl is the opposite: it does not touch the underlying ",[39,129311,102486],{}," at all, it just increments the shared strong count and returns a handle to the ",[104,129314,22779],{}," block. Assuming both behave like ",[39,129317,128232],{}," (A) is the classic trap; ",[39,129320,127914],{},[39,129322,122174],{}," whenever ",[39,129325,129293],{}," (rules out C); D has the two exactly backwards.",[15,129328,129329,129333,129515,129573],{"language":111909},[18,129330,129332],{"id":129331},"q13-what-causes-this-to-panic","Q13. What causes this to panic?",[257,129334,129335],{"language":111909},[260,129336,129338],{"className":111918,"code":129337,"language":111909,"meta":264,"style":264},"use std::cell::RefCell;\n\nfn total(counts: &RefCell\u003CVec\u003Ci32>>) -> i32 {\n    let data = counts.borrow();\n    data.iter().sum()\n}\n\nfn add(counts: &RefCell\u003CVec\u003Ci32>>, n: i32) {\n    let mut data = counts.borrow_mut();\n    data.push(n);\n    println!(\"running total: {}\", total(counts));\n}\n",[39,129339,129340,129356,129360,129392,129410,129428,129432,129436,129467,129485,129495,129511],{"__ignoreMap":264},[268,129341,129342,129344,129346,129348,129350,129352,129354],{"class":270,"line":271},[268,129343,108694],{"class":274},[268,129345,125974],{"class":278},[268,129347,84903],{"class":274},[268,129349,128683],{"class":278},[268,129351,84903],{"class":274},[268,129353,113034],{"class":278},[268,129355,293],{"class":282},[268,129357,129358],{"class":270,"line":286},[268,129359,5033],{"emptyLinePlaceholder":35},[268,129361,129362,129364,129366,129369,129371,129373,129375,129377,129379,129381,129383,129386,129388,129390],{"class":270,"line":296},[268,129363,37837],{"class":274},[268,129365,34590],{"class":278},[268,129367,129368],{"class":282},"(counts",[268,129370,10728],{"class":274},[268,129372,115951],{"class":274},[268,129374,113034],{"class":278},[268,129376,1076],{"class":282},[268,129378,112877],{"class":278},[268,129380,1076],{"class":282},[268,129382,113860],{"class":278},[268,129384,129385],{"class":282},">>) ",[268,129387,113308],{"class":274},[268,129389,113794],{"class":278},[268,129391,9914],{"class":282},[268,129393,129394,129396,129398,129400,129403,129405,129408],{"class":270,"line":311},[268,129395,80826],{"class":274},[268,129397,128410],{"class":282},[268,129399,302],{"class":274},[268,129401,129402],{"class":282}," counts",[268,129404,462],{"class":274},[268,129406,129407],{"class":278},"borrow",[268,129409,794],{"class":282},[268,129411,129412,129415,129417,129420,129422,129424,129426],{"class":270,"line":788},[268,129413,129414],{"class":282},"    data",[268,129416,462],{"class":274},[268,129418,129419],{"class":278},"iter",[268,129421,16952],{"class":282},[268,129423,462],{"class":274},[268,129425,28535],{"class":278},[268,129427,47668],{"class":282},[268,129429,129430],{"class":270,"line":1951},[268,129431,314],{"class":282},[268,129433,129434],{"class":270,"line":8955},[268,129435,5033],{"emptyLinePlaceholder":35},[268,129437,129438,129440,129442,129444,129446,129448,129450,129452,129454,129456,129458,129461,129463,129465],{"class":270,"line":8966},[268,129439,37837],{"class":274},[268,129441,1217],{"class":278},[268,129443,129368],{"class":282},[268,129445,10728],{"class":274},[268,129447,115951],{"class":274},[268,129449,113034],{"class":278},[268,129451,1076],{"class":282},[268,129453,112877],{"class":278},[268,129455,1076],{"class":282},[268,129457,113860],{"class":278},[268,129459,129460],{"class":282},">>, n",[268,129462,10728],{"class":274},[268,129464,113794],{"class":278},[268,129466,1235],{"class":282},[268,129468,129469,129471,129473,129475,129477,129479,129481,129483],{"class":270,"line":8974},[268,129470,80826],{"class":274},[268,129472,113071],{"class":274},[268,129474,128410],{"class":282},[268,129476,302],{"class":274},[268,129478,129402],{"class":282},[268,129480,462],{"class":274},[268,129482,128740],{"class":278},[268,129484,794],{"class":282},[268,129486,129487,129489,129491,129493],{"class":270,"line":8985},[268,129488,129414],{"class":282},[268,129490,462],{"class":274},[268,129492,12499],{"class":278},[268,129494,37888],{"class":282},[268,129496,129497,129499,129501,129504,129506,129508],{"class":270,"line":8990},[268,129498,111958],{"class":278},[268,129500,622],{"class":282},[268,129502,129503],{"class":289},"\"running total: {}\"",[268,129505,42],{"class":282},[268,129507,805],{"class":278},[268,129509,129510],{"class":282},"(counts));\n",[268,129512,129513],{"class":270,"line":8997},[268,129514,314],{"class":282},[23,129516,129518,129529,129552,129562],{"className":129517},[26],[28,129519,129521,129523,129524,186,129526,129528],{"className":129520},[31],[33,129522],{"disabled":35,"type":36}," It never panics — ",[39,129525,805],{},[39,129527,41889],{}," are unrelated functions",[28,129530,129532,355,129534,129536,129537,129539,129540,129542,129543,129545,129546,129548,129549,129551],{"className":129531},[31],[33,129533],{"disabled":35,"type":36},[39,129535,41889],{}," holds a ",[39,129538,128343],{}," guard (",[39,129541,21188],{},") alive while calling ",[39,129544,805],{},", which tries ",[39,129547,128340],{}," on the same still-mutably-borrowed ",[39,129550,113034],{},", panicking with \"already borrowed\"",[28,129553,129555,355,129557,10834,129559,129561],{"className":129554},[31],[33,129556],{"disabled":35,"type":36},[39,129558,12499],{},[39,129560,113034],{}," is not allowed under any circumstances",[28,129563,129565,117747,129567,124638,129570],{"className":129564},[31],[33,129566],{"disabled":35,"type":36},[39,129568,129569],{},"RefCell\u003CVec\u003Ci32>>",[39,129571,129572],{},"Iterator",[66,129574,129575,129577,129593],{},[69,129576,71],{},[73,129578,129579,1727,129581,129536,129583,129539,129585,129542,129587,129545,129589,129548,129591,129551],{},[76,129580,78],{},[39,129582,41889],{},[39,129584,128343],{},[39,129586,21188],{},[39,129588,805],{},[39,129590,128340],{},[39,129592,113034],{},[73,129594,129595,355,129597,2018,129599,358,129601,129603,129604,129607,129608,9057,129610,129613,129614,3277,129617,129619,129620,129622,129623,98691,129626,129629,129630,129632,129633,129635,129636,129638,129639,129641,129642,13450,129645,129647,129648,129651,129652,129654],{},[76,129596,84],{},[39,129598,21188],{},[39,129600,41889],{},[39,129602,128840],{}," that stays alive across the ",[39,129605,129606],{},"total(counts)"," call (it's used again afterward implicitly by scope, and even if it weren't, it hasn't been dropped yet), so ",[39,129609,805],{},[39,129611,129612],{},"counts.borrow()"," runs while a mutable borrow is still outstanding — a runtime ",[39,129615,129616],{},"BorrowError",[76,129618,16523],{},": the fix is to drop or scope ",[39,129621,21188],{}," before calling anything that might re-borrow ",[39,129624,129625],{},"counts",[39,129627,129628],{},"{ let mut data = counts.borrow_mut(); data.push(n); }"," in its own block, then call ",[39,129631,129606],{}," afterward. This absolutely can panic despite the functions looking unrelated (rules out A) — that's exactly the gotcha; nothing bans ",[39,129634,12499],{}," through a ",[39,129637,113034],{}," in general (rules out C); and the code compiles fine since ",[39,129640,805],{}," only calls ",[39,129643,129644],{},".iter().sum()",[39,129646,112877],{}," obtained via ",[39,129649,129650],{},"Deref",", not on the ",[39,129653,113034],{}," itself (rules out D).",[15,129656,129657,129668,129703],{},[18,129658,129660,129661,129664,129665,129667],{"id":129659},"q14-what-is-the-effect-of-calling-droprc_handle-on-one-clone-of-an-rct-that-has-two-other-clones-still-alive-elsewhere","Q14. What is the effect of calling ",[39,129662,129663],{},"drop(rc_handle)"," on one clone of an ",[39,129666,128051],{}," that has two other clones still alive elsewhere?",[23,129669,129671,129677,129686,129695],{"className":129670},[26],[28,129672,129674,129676],{"className":129673},[31],[33,129675],{"disabled":35,"type":36}," It immediately frees the underlying value and invalidates the other clones",[28,129678,129680,129682,129683,129685],{"className":129679},[31],[33,129681],{"disabled":35,"type":36}," It only decrements the strong count by one; the value stays alive because other ",[39,129684,128232],{}," handles still reference it",[28,129687,129689,129691,129692,129694],{"className":129688},[31],[33,129690],{"disabled":35,"type":36}," It's a compile error — ",[39,129693,128051],{}," cannot be manually dropped",[28,129696,129698,129700,129701],{"className":129697},[31],[33,129699],{"disabled":35,"type":36}," It converts the remaining handles into ",[39,129702,129028],{},[66,129704,129705,129707,129714],{},[69,129706,71],{},[73,129708,129709,129711,129712,129685],{},[76,129710,78],{}," B — It only decrements the strong count by one; the value stays alive because other ",[39,129713,128232],{},[73,129715,129716,355,129718,126302,129721,129723,129724,9057,129726,129728,129729,77497,129731,129733,129734,129736,129737,2758,129739,128211],{},[76,129717,84],{},[39,129719,129720],{},"drop",[39,129722,128232],{}," handle runs ",[39,129725,128232],{},[39,129727,128979],{}," impl, which decrements the strong count and only deallocates the inner value when that count reaches zero. With two other live clones, the count merely goes from 3 to 2 and the data is untouched. A is the tempting mistake of treating ",[39,129730,128232],{},[39,129732,127945],{}," (single owner); ",[39,129735,128051],{}," is a completely ordinary value that can be dropped like anything else, no special restriction exists (rules out C); and dropping one strong handle has zero effect on the type of the others — they remain ",[39,129738,128051],{},[39,129740,129028],{},[15,129742,129743,129747,129779],{},[18,129744,129746],{"id":129745},"q15-for-a-struct-field-that-needs-to-be-owned-by-exactly-one-place-but-whose-size-isnt-known-until-runtime-eg-a-boxed-trait-object-or-a-recursive-variant-which-is-the-idiomatic-choice","Q15. For a struct field that needs to be owned by exactly one place but whose size isn't known until runtime (e.g., a boxed trait object or a recursive variant), which is the idiomatic choice?",[23,129748,129750,129757,129764,129771],{"className":129749},[26],[28,129751,129753,355,129755],{"className":129752},[31],[33,129754],{"disabled":35,"type":36},[39,129756,128051],{},[28,129758,129760,355,129762],{"className":129759},[31],[33,129761],{"disabled":35,"type":36},[39,129763,127914],{},[28,129765,129767,355,129769],{"className":129766},[31],[33,129768],{"disabled":35,"type":36},[39,129770,128285],{},[28,129772,129774,355,129776],{"className":129773},[31],[33,129775],{"disabled":35,"type":36},[39,129777,129778],{},"Arc\u003CMutex\u003CT>>",[66,129780,129781,129783,129789],{},[69,129782,71],{},[73,129784,129785,1727,129787],{},[76,129786,78],{},[39,129788,127914],{},[73,129790,129791,355,129793,1783,129795,129797,129798,129800,129801,129803,129804,129806,129807,129809,129810,129812,129813,446,129815,129818,129819,446,129821,129824],{},[76,129792,84],{},[76,129794,17307],{},[39,129796,127914],{}," is the minimal-overhead choice for \"one owner, heap-allocated, unsized-at-compile-time\" — no refcounting overhead, no runtime borrow checks, no atomics. Reaching for ",[39,129799,128051],{}," (A) or ",[39,129802,129778],{}," (D) when you don't actually need shared ownership adds needless refcount\u002Flocking overhead and complexity; reaching for ",[39,129805,128285],{}," (C) solves a mutability problem you don't have here (single ownership already gives you ",[39,129808,114510],{}," access). The rule of thumb: start with ",[39,129811,127945],{},", add ",[39,129814,128232],{},[39,129816,129817],{},"Arc"," only when multiple owners are genuinely required, and add ",[39,129820,113034],{},[39,129822,129823],{},"Mutex"," only when mutation through a shared reference is genuinely required.",[15,129826,129827,129834,129877],{},[18,129828,129830,129831,129833],{"id":129829},"q16-in-a-single-threaded-tree-structure-using-rcrefcellnode-for-parentchild-links-what-is-the-idiomatic-way-to-prevent-the-reference-cycle-leak-described-earlier","Q16. In a single-threaded tree structure using ",[39,129832,128882],{}," for parent\u002Fchild links, what is the idiomatic way to prevent the reference-cycle leak described earlier?",[23,129835,129837,129849,129858,129868],{"className":129836},[26],[28,129838,129840,129842,129843,8574,129846,129848],{"className":129839},[31],[33,129841],{"disabled":35,"type":36}," Wrap the parent link in ",[39,129844,129845],{},"Weak\u003CRefCell\u003CNode>>",[39,129847,128882],{},", since a child shouldn't keep its parent alive",[28,129850,129852,39927,129854,129857],{"className":129851},[31],[33,129853],{"disabled":35,"type":36},[39,129855,129856],{},"std::mem::forget"," on the child before dropping the parent",[28,129859,129861,129863,129864,129867],{"className":129860},[31],[33,129862],{"disabled":35,"type":36}," Manually call ",[39,129865,129866],{},"Rc::strong_count"," and panic if it's above 1",[28,129869,129871,129873,129874],{"className":129870},[31],[33,129872],{"disabled":35,"type":36}," Switch every field to ",[39,129875,129876],{},"Cell\u003CT>",[66,129878,129879,129881,129890],{},[69,129880,71],{},[73,129882,129883,129885,129886,8574,129888,129848],{},[76,129884,78],{}," A — Wrap the parent link in ",[39,129887,129845],{},[39,129889,128882],{},[73,129891,129892,355,129894,129896,129897,129899,129900,129902,129903,129905,129906,3801,129908,129911,129912,129915,129916,129918,129919,129921],{},[76,129893,84],{},[76,129895,17307],{},": the ownership direction should mirror the logical lifetime relationship — a tree's parent owns its children (strong ",[39,129898,128232],{},"), but a child referencing its parent should not keep the parent alive on its own, so that link should be ",[39,129901,129105],{},". This breaks the cycle: when external owners drop the parent, its strong count can reach zero and it's freed even though children still hold ",[39,129904,129105],{}," back-pointers (which safely resolve to ",[39,129907,90944],{},[39,129909,129910],{},"upgrade()"," afterward). ",[39,129913,129914],{},"mem::forget"," (B) leaks deliberately, the opposite of what's wanted; manually auditing strong counts (C) is fragile and not how idiomatic Rust manages this; ",[39,129917,129876],{}," (D) solves a different problem (cheap interior mutability for ",[39,129920,114164],{}," types), not cycles.",[15,129923,129924,129932,129969],{},[18,129925,129927,129928,129931],{"id":129926},"q17-when-is-reaching-for-rcrefcellt-considered-good-practice-versus-a-design-smell","Q17. When is reaching for ",[39,129929,129930],{},"Rc\u003CRefCell\u003CT>>"," considered good practice versus a design smell?",[23,129933,129935,129941,129950,129959],{"className":129934},[26],[28,129936,129938,129940],{"className":129937},[31],[33,129939],{"disabled":35,"type":36}," It should be used everywhere shared state exists, as the default choice",[28,129942,129944,129946,129947,129949],{"className":129943},[31],[33,129945],{"disabled":35,"type":36}," It's appropriate when shared, mutable, single-threaded ownership is a genuine requirement of the domain (e.g., a GUI widget tree); it's a smell when it's used to route around the borrow checker in code that could instead pass ownership or ",[39,129948,114510],{}," explicitly",[28,129951,129953,129955,129956,129958],{"className":129952},[31],[33,129954],{"disabled":35,"type":36}," It should never be used because ",[39,129957,112499],{}," is always faster",[28,129960,129962,129964,129965,129968],{"className":129961},[31],[33,129963],{"disabled":35,"type":36}," It's only valid inside ",[39,129966,129967],{},"#[test]"," modules",[66,129970,129971,129973,129980],{},[69,129972,71],{},[73,129974,129975,129977,129978,129949],{},[76,129976,78],{}," B — It's appropriate when shared, mutable, single-threaded ownership is a genuine requirement of the domain (e.g., a GUI widget tree); it's a smell when it's used to route around the borrow checker in code that could instead pass ownership or ",[39,129979,114510],{},[73,129981,129982,355,129984,1783,129986,129988,129989,129991,129992,129994],{},[76,129983,84],{},[76,129985,17307],{},[39,129987,129930],{}," is a legitimate, commonly used pattern for graphs\u002Ftrees with genuinely shared mutable nodes, but it moves Rust's aliasing guarantees to runtime, so overusing it as a generic escape hatch from ownership\u002Fborrowing errors trades compile-time safety for panics later and is widely considered a code smell. Treating it as an unconditional default (A) throws away the compiler's static guarantees for no reason in code that doesn't need shared mutation. It isn't about ",[39,129990,112499],{}," being faster — ",[39,129993,112499],{}," isn't involved here at all (rules out C) — and it's a general-purpose pattern, not something scoped to tests (rules out D).",[15,129996,129997,130005,130051],{},[18,129998,81397,130000,186,130002,130004],{"id":129999},"q18-cellt-and-refcellt-both-provide-interior-mutability-whats-the-key-practical-difference",[39,130001,129876],{},[39,130003,128285],{}," both provide interior mutability. What's the key practical difference?",[23,130006,130008,130027,130037,130043],{"className":130007},[26],[28,130009,130011,355,130013,71990,130015,130018,130019,446,130021,130023,130024,130026],{"className":130010},[31],[33,130012],{"disabled":35,"type":36},[39,130014,129876],{},[39,130016,130017],{},"T: Copy"," and only exposes ",[39,130020,32437],{},[39,130022,37910],{}," (no borrows, so it can never panic from a borrow conflict); ",[39,130025,128285],{}," hands out borrow guards and can panic if borrow rules are violated",[28,130028,130030,355,130032,130034,130035,2421],{"className":130029},[31],[33,130031],{"disabled":35,"type":36},[39,130033,129876],{}," is thread-safe and ",[39,130036,128285],{},[28,130038,130040,130042],{"className":130039},[31],[33,130041],{"disabled":35,"type":36}," They are interchangeable in every situation",[28,130044,130046,355,130048,130050],{"className":130045},[31],[33,130047],{"disabled":35,"type":36},[39,130049,128285],{}," is faster because it avoids runtime checks entirely",[66,130052,130053,130055,130069],{},[69,130054,71],{},[73,130056,130057,3459,130059,71990,130061,130018,130063,446,130065,130023,130067,130026],{},[76,130058,78],{},[39,130060,129876],{},[39,130062,130017],{},[39,130064,32437],{},[39,130066,37910],{},[39,130068,128285],{},[73,130070,130071,355,130073,130075,130076,446,130078,130080,130081,130083,130084,130086,130087,446,130090,130092,130093,130095,130096,130099,130100,130102,130103,130105],{},[76,130072,84],{},[39,130074,129876],{}," sidesteps the borrow-checking problem entirely by never handing out references to its contents — you copy values in and out via ",[39,130077,32437],{},[39,130079,37910],{},", which is why it's restricted to (effectively) ",[39,130082,114164],{}," types and can never panic at runtime. ",[39,130085,128285],{}," instead hands out ",[39,130088,130089],{},"Ref",[39,130091,128840],{}," guards so it works for non-",[39,130094,114164],{}," types too, but that flexibility is exactly what introduces the possibility of a runtime borrow-rule panic. Neither is thread-safe — both are ",[39,130097,130098],{},"!Sync"," (rules out B); they solve overlapping but distinct problems so they aren't interchangeable (rules out C); and ",[39,130101,113034],{}," does more runtime bookkeeping than ",[39,130104,113037],{},", not less (rules out D).",[15,130107,130108,130112,130224,130268],{"language":111909},[18,130109,130111],{"id":130110},"q19-what-is-the-idiomatic-way-to-safely-attempt-a-borrow-that-might-conflict-without-risking-a-panic","Q19. What is the idiomatic way to safely attempt a borrow that might conflict, without risking a panic?",[257,130113,130114],{"language":111909},[260,130115,130117],{"className":111918,"code":130116,"language":111909,"meta":264,"style":264},"use std::cell::RefCell;\n\nfn maybe_read(cell: &RefCell\u003Ci32>) {\n    match cell.try_borrow() {\n        Ok(guard) => println!(\"value: {}\", *guard),\n        Err(_) => println!(\"currently borrowed elsewhere, skipping\"),\n    }\n}\n",[39,130118,130119,130135,130139,130162,130175,130199,130216,130220],{"__ignoreMap":264},[268,130120,130121,130123,130125,130127,130129,130131,130133],{"class":270,"line":271},[268,130122,108694],{"class":274},[268,130124,125974],{"class":278},[268,130126,84903],{"class":274},[268,130128,128683],{"class":278},[268,130130,84903],{"class":274},[268,130132,113034],{"class":278},[268,130134,293],{"class":282},[268,130136,130137],{"class":270,"line":286},[268,130138,5033],{"emptyLinePlaceholder":35},[268,130140,130141,130143,130146,130149,130151,130153,130155,130157,130159],{"class":270,"line":296},[268,130142,37837],{"class":274},[268,130144,130145],{"class":278}," maybe_read",[268,130147,130148],{"class":282},"(cell",[268,130150,10728],{"class":274},[268,130152,115951],{"class":274},[268,130154,113034],{"class":278},[268,130156,1076],{"class":282},[268,130158,113860],{"class":278},[268,130160,130161],{"class":282},">) {\n",[268,130163,130164,130166,130168,130170,130173],{"class":270,"line":311},[268,130165,120056],{"class":274},[268,130167,128735],{"class":282},[268,130169,462],{"class":274},[268,130171,130172],{"class":278},"try_borrow",[268,130174,283],{"class":282},[268,130176,130177,130179,130182,130184,130187,130189,130192,130194,130196],{"class":270,"line":788},[268,130178,120076],{"class":278},[268,130180,130181],{"class":282},"(guard) ",[268,130183,9414],{"class":274},[268,130185,130186],{"class":278}," println!",[268,130188,622],{"class":282},[268,130190,130191],{"class":289},"\"value: {}\"",[268,130193,42],{"class":282},[268,130195,6134],{"class":274},[268,130197,130198],{"class":282},"guard),\n",[268,130200,130201,130203,130205,130207,130209,130211,130214],{"class":270,"line":1951},[268,130202,120089],{"class":278},[268,130204,120092],{"class":282},[268,130206,9414],{"class":274},[268,130208,130186],{"class":278},[268,130210,622],{"class":282},[268,130212,130213],{"class":289},"\"currently borrowed elsewhere, skipping\"",[268,130215,17159],{"class":282},[268,130217,130218],{"class":270,"line":8955},[268,130219,11972],{"class":282},[268,130221,130222],{"class":270,"line":8966},[268,130223,314],{"class":282},[23,130225,130227,130236,130250,130260],{"className":130226},[26],[28,130228,130230,130232,130233,130235],{"className":130229},[31],[33,130231],{"disabled":35,"type":36}," This is an anti-pattern — always use ",[39,130234,128340],{}," and let it panic",[28,130237,130239,130241,130242,446,130244,10044,130247,130249],{"className":130238},[31],[33,130240],{"disabled":35,"type":36}," This is idiomatic — ",[39,130243,130172],{},[39,130245,130246],{},"try_borrow_mut",[39,130248,110110],{}," so conflicting borrows can be handled gracefully instead of panicking",[28,130251,130253,355,130255,130257,130258],{"className":130252},[31],[33,130254],{"disabled":35,"type":36},[39,130256,130172],{}," doesn't exist on ",[39,130259,113034],{},[28,130261,130263,355,130265,130267],{"className":130262},[31],[33,130264],{"disabled":35,"type":36},[39,130266,130172],{}," still panics, it just delays the panic",[66,130269,130270,130272,130283],{},[69,130271,71],{},[73,130273,130274,130276,130277,446,130279,10044,130281,130249],{},[76,130275,78],{}," B — This is idiomatic — ",[39,130278,130172],{},[39,130280,130246],{},[39,130282,110110],{},[73,130284,130285,355,130287,130289,130290,446,130292,130294,130295,446,130297,130299,130300,446,130302,130304,130305,446,130307,130309,130310,130313,130314,130316,130317,130319],{},[76,130286,84],{},[76,130288,17307],{},": when a borrow conflict is an expected, recoverable possibility (rather than a programming bug you want to fail loudly on), ",[39,130291,130172],{},[39,130293,130246],{}," let you branch on ",[39,130296,120129],{},[39,130298,116301],{}," instead of letting ",[39,130301,129407],{},[39,130303,128740],{}," panic. Reserving the panicking ",[39,130306,128340],{},[39,130308,128343],{}," for cases where a conflict would indicate a genuine logic error (and the fallible ",[39,130311,130312],{},"try_*"," variants for cases where it's a normal runtime condition) is the recommended split — always panicking (A) throws away that flexibility. The method exists and is stable (rules out C), and it returns a ",[39,130315,110110],{}," rather than panicking at all on the ",[39,130318,116301],{}," path (rules out D).",[15,130321,130322,130332,130545,130595],{"language":111909},[18,130323,130325,130326,130328,130329,130331],{"id":130324},"q20-in-this-recursive-tree-printing-function-using-rcrefcellnode-why-is-the-explicit-block-around-borrow-necessary-to-avoid-a-panic","Q20. In this recursive tree-printing function using ",[39,130327,128882],{},", why is the explicit block around ",[39,130330,128340],{}," necessary to avoid a panic?",[257,130333,130334],{"language":111909},[260,130335,130337],{"className":111918,"code":130336,"language":111909,"meta":264,"style":264},"struct Node {\n    value: i32,\n    children: RefCell\u003CVec\u003CRc\u003CRefCell\u003CNode>>>>,\n}\n\nfn print_tree(node: &Rc\u003CRefCell\u003CNode>>, depth: usize) {\n    let children_snapshot = {\n        let n = node.borrow();\n        println!(\"{}{}\", \"  \".repeat(depth), n.value);\n        n.children.borrow().clone()\n    };\n    for child in children_snapshot.iter() {\n        print_tree(child, depth + 1);\n    }\n}\n",[39,130338,130339,130347,130357,130385,130389,130393,130426,130437,130453,130478,130501,130505,130523,130537,130541],{"__ignoreMap":264},[268,130340,130341,130343,130345],{"class":270,"line":271},[268,130342,121198],{"class":274},[268,130344,102853],{"class":278},[268,130346,9914],{"class":282},[268,130348,130349,130351,130353,130355],{"class":270,"line":286},[268,130350,51575],{"class":282},[268,130352,10728],{"class":274},[268,130354,113794],{"class":278},[268,130356,1789],{"class":282},[268,130358,130359,130362,130364,130366,130368,130370,130372,130374,130376,130378,130380,130382],{"class":270,"line":296},[268,130360,130361],{"class":282},"    children",[268,130363,10728],{"class":274},[268,130365,128713],{"class":278},[268,130367,1076],{"class":282},[268,130369,112877],{"class":278},[268,130371,1076],{"class":282},[268,130373,128232],{"class":278},[268,130375,1076],{"class":282},[268,130377,113034],{"class":278},[268,130379,1076],{"class":282},[268,130381,102926],{"class":278},[268,130383,130384],{"class":282},">>>>,\n",[268,130386,130387],{"class":270,"line":311},[268,130388,314],{"class":282},[268,130390,130391],{"class":270,"line":788},[268,130392,5033],{"emptyLinePlaceholder":35},[268,130394,130395,130397,130400,130403,130405,130407,130409,130411,130413,130415,130417,130420,130422,130424],{"class":270,"line":1951},[268,130396,37837],{"class":274},[268,130398,130399],{"class":278}," print_tree",[268,130401,130402],{"class":282},"(node",[268,130404,10728],{"class":274},[268,130406,115951],{"class":274},[268,130408,128232],{"class":278},[268,130410,1076],{"class":282},[268,130412,113034],{"class":278},[268,130414,1076],{"class":282},[268,130416,102926],{"class":278},[268,130418,130419],{"class":282},">>, depth",[268,130421,10728],{"class":274},[268,130423,113286],{"class":278},[268,130425,1235],{"class":282},[268,130427,130428,130430,130433,130435],{"class":270,"line":8955},[268,130429,80826],{"class":274},[268,130431,130432],{"class":282}," children_snapshot ",[268,130434,302],{"class":274},[268,130436,9914],{"class":282},[268,130438,130439,130441,130443,130445,130447,130449,130451],{"class":270,"line":8966},[268,130440,112735],{"class":274},[268,130442,13355],{"class":282},[268,130444,302],{"class":274},[268,130446,68437],{"class":282},[268,130448,462],{"class":274},[268,130450,129407],{"class":278},[268,130452,794],{"class":282},[268,130454,130455,130457,130459,130462,130464,130466,130468,130470,130473,130475],{"class":270,"line":8974},[268,130456,112752],{"class":278},[268,130458,622],{"class":282},[268,130460,130461],{"class":289},"\"{}{}\"",[268,130463,42],{"class":282},[268,130465,6989],{"class":289},[268,130467,462],{"class":274},[268,130469,95916],{"class":278},[268,130471,130472],{"class":282},"(depth), n",[268,130474,462],{"class":274},[268,130476,130477],{"class":282},"value);\n",[268,130479,130480,130483,130485,130488,130490,130492,130494,130496,130499],{"class":270,"line":8985},[268,130481,130482],{"class":282},"        n",[268,130484,462],{"class":274},[268,130486,130487],{"class":282},"children",[268,130489,462],{"class":274},[268,130491,129407],{"class":278},[268,130493,16952],{"class":282},[268,130495,462],{"class":274},[268,130497,130498],{"class":278},"clone",[268,130500,47668],{"class":282},[268,130502,130503],{"class":270,"line":8990},[268,130504,117857],{"class":282},[268,130506,130507,130509,130512,130514,130517,130519,130521],{"class":270,"line":8997},[268,130508,80840],{"class":274},[268,130510,130511],{"class":282}," child ",[268,130513,20749],{"class":274},[268,130515,130516],{"class":282}," children_snapshot",[268,130518,462],{"class":274},[268,130520,129419],{"class":278},[268,130522,283],{"class":282},[268,130524,130525,130528,130531,130533,130535],{"class":270,"line":9002},[268,130526,130527],{"class":278},"        print_tree",[268,130529,130530],{"class":282},"(child, depth ",[268,130532,1246],{"class":274},[268,130534,2199],{"class":305},[268,130536,628],{"class":282},[268,130538,130539],{"class":270,"line":14676},[268,130540,11972],{"class":282},[268,130542,130543],{"class":270,"line":14681},[268,130544,314],{"class":282},[23,130546,130548,130558,130577,130585],{"className":130547},[26],[28,130549,130551,130553,130554,130557],{"className":130550},[31],[33,130552],{"disabled":35,"type":36}," The block is unnecessary style preference; ",[39,130555,130556],{},"node.borrow()"," could stay alive across the recursive calls with no issue",[28,130559,130561,130563,130564,130566,130567,130569,130570,130573,130574,130576],{"className":130560},[31],[33,130562],{"disabled":35,"type":36}," The block ensures the ",[39,130565,130089],{}," guard from ",[39,130568,130556],{}," is dropped before ",[39,130571,130572],{},"print_tree"," recurses, so the recursive call's own ",[39,130575,130556],{}," on a child doesn't conflict with a still-held parent borrow",[28,130578,130580,355,130582,130584],{"className":130579},[31],[33,130581],{"disabled":35,"type":36},[39,130583,113034],{}," borrows are automatically released at the end of every statement, so the block does nothing",[28,130586,130588,130590,130591,130594],{"className":130587},[31],[33,130589],{"disabled":35,"type":36}," The block is required only because ",[39,130592,130593],{},"Vec::clone"," needs exclusive access",[66,130596,130597,130599,130612],{},[69,130598,71],{},[73,130600,130601,130603,130604,130566,130606,130569,130608,130573,130610,130576],{},[76,130602,78],{}," B — The block ensures the ",[39,130605,130089],{},[39,130607,130556],{},[39,130609,130572],{},[39,130611,130556],{},[73,130613,130614,355,130616,358,130618,130620,130621,130624,130625,130627,130628,7625,130631,130634,130635,130637,130638,2472,130641,130643,130644,355,130647,130649,130650,130652,130653,130655,130656,130658,130659,130661],{},[76,130615,84],{},[39,130617,4599],{},[39,130619,130089],{}," guard borrowed from ",[39,130622,130623],{},"node","; ending the block drops ",[39,130626,4599],{}," (and the implicit borrow taken by ",[39,130629,130630],{},"n.children.borrow()",[39,130632,130633],{},"children_snapshot"," is used in the ",[39,130636,6926],{}," loop, so by the time ",[39,130639,130640],{},"print_tree(child, ...)",[39,130642,130623],{},"'s borrow is fully released. Since each recursive call borrows a ",[104,130645,130646],{},"different",[39,130648,128882],{}," (a child, not the same node), this particular example wouldn't panic even without the block — but the pattern of scoping borrows tightly is the general discipline that prevents panics in less trivial call graphs (e.g., a function that re-borrows the ",[104,130651,22779],{}," node it was passed, or mutates while an outer borrow is still live). ",[76,130654,16523],{},": assuming a ",[39,130657,113034],{}," borrow can safely span an arbitrary amount of downstream code (A) is exactly the assumption that causes production panics once the call graph changes; borrows are not scope-magic released at every statement boundary, only when the guard value is actually dropped (rules out C); and ",[39,130660,130593],{}," needs a shared reference to source data, not exclusive access, and has nothing to do with why the block exists (rules out D).",[2107,130663,120639],{},{"title":264,"searchDepth":286,"depth":286,"links":130665},[130666,130668,130670,130672,130674,130676,130677,130679,130680,130682,130684,130686,130688,130689,130691,130692,130694,130696,130698,130699],{"id":127910,"depth":296,"text":130667},"Q1. What problem does Box\u003CT> primarily solve for a type like this?",{"id":128047,"depth":296,"text":130669},"Q2. What is Rc\u003CT> used for?",{"id":128128,"depth":296,"text":130671},"Q3. Given let b = Rc::clone(&a);, what is idiomatic about writing it this way instead of let b = a.clone();?",{"id":128216,"depth":296,"text":130673},"Q4. When does the value inside an Rc\u003CT> actually get dropped?",{"id":128282,"depth":296,"text":130675},"Q5. What does RefCell\u003CT> provide that a plain T behind a shared reference does not?",{"id":128355,"depth":296,"text":128356},{"id":128594,"depth":296,"text":130678},"Q7. What is Box\u003Cdyn Trait> primarily used for?",{"id":128664,"depth":296,"text":128665},{"id":128878,"depth":296,"text":130681},"Q9. This code builds a parent-child tree using Rc\u003CRefCell\u003CNode>> where each parent also stores an Rc back to its child, and each child stores an Rc back to its parent. What is the consequence?",{"id":129025,"depth":296,"text":130683},"Q10. Weak\u003CT> is obtained via Rc::downgrade(&rc). What does calling .upgrade() on a Weak\u003CT> return once every strong Rc to the value has been dropped?",{"id":129121,"depth":296,"text":130685},"Q11. On a typical 64-bit target, what is std::mem::size_of::\u003CRc\u003Ci32>>()?",{"id":129211,"depth":296,"text":130687},"Q12. What's the difference between let b2 = Box::new(42); let b3 = b2.clone(); and let r2 = Rc::new(42); let r3 = Rc::clone(&r2);?",{"id":129331,"depth":296,"text":129332},{"id":129659,"depth":296,"text":130690},"Q14. What is the effect of calling drop(rc_handle) on one clone of an Rc\u003CT> that has two other clones still alive elsewhere?",{"id":129745,"depth":296,"text":129746},{"id":129829,"depth":296,"text":130693},"Q16. In a single-threaded tree structure using Rc\u003CRefCell\u003CNode>> for parent\u002Fchild links, what is the idiomatic way to prevent the reference-cycle leak described earlier?",{"id":129926,"depth":296,"text":130695},"Q17. When is reaching for Rc\u003CRefCell\u003CT>> considered good practice versus a design smell?",{"id":129999,"depth":296,"text":130697},"Q18. Cell\u003CT> and RefCell\u003CT> both provide interior mutability. What's the key practical difference?",{"id":130110,"depth":296,"text":130111},{"id":130324,"depth":296,"text":130700},"Q20. In this recursive tree-printing function using Rc\u003CRefCell\u003CNode>>, why is the explicit block around borrow() necessary to avoid a panic?",{},"\u002Frust\u002F19-smart-pointers",{"title":127900,"description":264},"rust\u002F19-smart-pointers","NfenOegpA9kQTxNlbTXxvvFivOZOzTCFDfkt-Nf1EVI",{"id":130707,"title":130708,"body":130709,"description":264,"extension":2144,"meta":132544,"navigation":35,"path":132545,"seo":132546,"stem":132547,"__hash__":132548},"content\u002Frust\u002F20-modules-and-crates.md","20 — Modules & Crates",{"type":8,"value":130710,"toc":132506},[130711,130714,130776,130830,130902,130996,131090,131196,131281,131353,131453,131531,131611,131728,131834,131937,132009,132073,132162,132261,132342],[11,130712,130708],{"id":130713},"_20-modules-crates",[15,130715,130716,130720,130752],{},[18,130717,130719],{"id":130718},"q1-what-is-the-default-visibility-of-an-item-function-struct-module-declared-inside-a-rust-module-with-no-visibility-modifier","Q1. What is the default visibility of an item (function, struct, module) declared inside a Rust module with no visibility modifier?",[23,130721,130723,130731,130740,130746],{"className":130722},[26],[28,130724,130726,355,130728,130730],{"className":130725},[31],[33,130727],{"disabled":35,"type":36},[39,130729,117577],{}," — visible everywhere, including other crates",[28,130732,130734,355,130736,130739],{"className":130733},[31],[33,130735],{"disabled":35,"type":36},[39,130737,130738],{},"pub(crate)"," — visible anywhere in the current crate",[28,130741,130743,130745],{"className":130742},[31],[33,130744],{"disabled":35,"type":36}," Private — visible only in the defining module and its descendant modules",[28,130747,130749,130751],{"className":130748},[31],[33,130750],{"disabled":35,"type":36}," Private — visible only within the exact same file",[66,130753,130754,130756,130761],{},[69,130755,71],{},[73,130757,130758,130760],{},[76,130759,78],{}," C — Private — visible only in the defining module and its descendant modules",[73,130762,130763,130765,130766,130768,130769,130771,130772,130775],{},[76,130764,84],{}," Rust's default visibility is private, but \"private\" means \"visible within this module and everything nested inside it,\" not \"visible only in this file.\" An item with no modifier is invisible to sibling or parent modules, and completely invisible outside the crate, ruling out A (which describes ",[39,130767,117577],{},") and B (which describes ",[39,130770,130738],{},"). D is the common misconception — file boundaries and module boundaries aren't the same thing, and a child module declared via ",[39,130773,130774],{},"mod"," (even in a separate file) still counts as \"inside\" its parent for privacy purposes.",[15,130777,130778,130784,130811],{},[18,130779,5361,130781,130783],{"id":130780},"q2-what-does-pubcrate-mean-when-applied-to-a-function",[39,130782,130738],{}," mean when applied to a function?",[23,130785,130787,130793,130799,130805],{"className":130786},[26],[28,130788,130790,130792],{"className":130789},[31],[33,130791],{"disabled":35,"type":36}," The function is visible only within the module it's declared in",[28,130794,130796,130798],{"className":130795},[31],[33,130797],{"disabled":35,"type":36}," The function is visible anywhere inside the current crate, but not to external crates that depend on this one",[28,130800,130802,130804],{"className":130801},[31],[33,130803],{"disabled":35,"type":36}," The function is visible to external crates but not within the current crate",[28,130806,130808,130810],{"className":130807},[31],[33,130809],{"disabled":35,"type":36}," The function is exported only when the crate is compiled as a library",[66,130812,130813,130815,130820],{},[69,130814,71],{},[73,130816,130817,130819],{},[76,130818,78],{}," B — The function is visible anywhere inside the current crate, but not to external crates that depend on this one",[73,130821,130822,355,130824,130826,130827,130829],{},[76,130823,84],{},[39,130825,130738],{}," is a restricted-visibility modifier: it opens the item up crate-wide (any module in the same crate can call it) while still hiding it from downstream crates that use this one as a dependency — useful for internal helpers shared across modules without committing them to the public API. A undersells it (that's closer to fully private); C has it backwards; D confuses visibility with crate type (",[39,130828,130738],{}," behaves the same whether the crate is a binary or library, it just controls in-crate reach).",[15,130831,130832,130836,130869],{},[18,130833,130835],{"id":130834},"q3-in-a-typical-binary-crate-which-file-is-the-crate-root-that-the-compiler-starts-building-from","Q3. In a typical binary crate, which file is the crate root that the compiler starts building from?",[23,130837,130839,130847,130855,130862],{"className":130838},[26],[28,130840,130842,355,130844],{"className":130841},[31],[33,130843],{"disabled":35,"type":36},[39,130845,130846],{},"lib.rs",[28,130848,130850,355,130852],{"className":130849},[31],[33,130851],{"disabled":35,"type":36},[39,130853,130854],{},"mod.rs",[28,130856,130858,355,130860],{"className":130857},[31],[33,130859],{"disabled":35,"type":36},[39,130861,109697],{},[28,130863,130865,355,130867],{"className":130864},[31],[33,130866],{"disabled":35,"type":36},[39,130868,108587],{},[66,130870,130871,130873,130879],{},[69,130872,71],{},[73,130874,130875,1004,130877],{},[76,130876,78],{},[39,130878,109697],{},[73,130880,130881,130883,130884,130886,130887,130889,130890,130892,130893,130895,130896,130898,130899,130901],{},[76,130882,84],{}," For a binary crate, ",[39,130885,110279],{}," is the crate root — the module tree is built starting from the ",[39,130888,130774],{}," declarations in that file. ",[39,130891,130846],{}," (A) is the equivalent root for a ",[104,130894,85423],{}," crate (a package can have both, producing both a binary and a library target). ",[39,130897,130854],{}," (B) is a filename convention for a submodule's contents, not a crate root. ",[39,130900,108587],{}," (D) is the package manifest — it configures the build but contains no Rust code or module declarations itself.",[15,130903,130904,130914,130951],{},[18,130905,105620,130907,130909,130910,130913],{"id":130906},"q4-given-srcmainrs-contains-mod-network-which-file-layouts-are-valid-ways-to-provide-that-modules-contents-rust-2018",[39,130908,110279],{}," contains ",[39,130911,130912],{},"mod network;",", which file layouts are valid ways to provide that module's contents (Rust 2018+)?",[23,130915,130917,130925,130933,130943],{"className":130916},[26],[28,130918,130920,50010,130922],{"className":130919},[31],[33,130921],{"disabled":35,"type":36},[39,130923,130924],{},"src\u002Fnetwork.rs",[28,130926,130928,50010,130930],{"className":130927},[31],[33,130929],{"disabled":35,"type":36},[39,130931,130932],{},"src\u002Fnetwork\u002Fmod.rs",[28,130934,130936,66450,130938,383,130940,130942],{"className":130935},[31],[33,130937],{"disabled":35,"type":36},[39,130939,130924],{},[39,130941,130932],{}," — both are recognized, though mixing conventions within one project is discouraged",[28,130944,130946,355,130948],{"className":130945},[31],[33,130947],{"disabled":35,"type":36},[39,130949,130950],{},"src\u002Fmod\u002Fnetwork.rs",[66,130952,130953,130955,130964],{},[69,130954,71],{},[73,130956,130957,130959,130960,383,130962,130942],{},[76,130958,78],{}," C — Either ",[39,130961,130924],{},[39,130963,130932],{},[73,130965,130966,130968,130969,130971,130972,130974,130975,130978,130979,130982,130983,130985,130986,130988,130989,130991,130992,130995],{},[76,130967,84],{}," The compiler accepts two layouts for a module declared with ",[39,130970,130912],{},": the flat ",[39,130973,130924],{}," (the modern, 2018-edition-encouraged style, needed if ",[39,130976,130977],{},"network"," itself has submodules living in a ",[39,130980,130981],{},"src\u002Fnetwork\u002F"," directory), or the older ",[39,130984,130932],{}," style inherited from Rust 2015. A and B are each only half the truth — both forms genuinely work. D is not a recognized layout at all; ",[39,130987,130854],{}," must live ",[104,130990,48842],{}," a directory named after the module, not inside a literal ",[39,130993,130994],{},"mod\u002F"," directory.",[15,130997,130998,131004,131042],{},[18,130999,67628,131001,65680],{"id":131000},"q5-what-does-use-crateutilsparse-do",[39,131002,131003],{},"use crate::utils::parse;",[23,131005,131007,131015,131024,131033],{"className":131006},[26],[28,131008,131010,131012,131013],{"className":131009},[31],[33,131011],{"disabled":35,"type":36}," Declares a new module named ",[39,131014,22274],{},[28,131016,131018,131020,131021,131023],{"className":131017},[31],[33,131019],{"disabled":35,"type":36}," Brings the ",[39,131022,22274],{}," item, referenced by its absolute path from the crate root, into scope under a short local name",[28,131025,131027,131029,131030,131032],{"className":131026},[31],[33,131028],{"disabled":35,"type":36}," Makes ",[39,131031,22274],{}," public to other crates",[28,131034,131036,131038,131039,131041],{"className":131035},[31],[33,131037],{"disabled":35,"type":36}," Re-exports ",[39,131040,22274],{}," so downstream crates can import it via this path",[66,131043,131044,131046,131053],{},[69,131045,71],{},[73,131047,131048,131050,131051,131023],{},[76,131049,78],{}," B — Brings the ",[39,131052,22274],{},[73,131054,131055,355,131057,131059,131060,131063,131064,131066,131067,131069,131070,131072,131073,446,131075,131077,131078,131080,131081,131083,131084,131086,131087,6232],{},[76,131056,84],{},[39,131058,108694],{}," is purely a local scoping\u002Faliasing tool: ",[39,131061,131062],{},"crate::utils::parse"," is an absolute path starting from the crate root, and the ",[39,131065,108694],{}," statement lets the current file refer to that item as just ",[39,131068,22274],{}," instead of writing the full path every time. It does not declare anything new (rules out A — ",[39,131071,130774],{}," does that), does not change any item's visibility (rules out C — visibility is set at the item's definition with ",[39,131074,117577],{},[39,131076,130738],{},"\u002Fetc.), and a plain ",[39,131079,108694],{}," (without ",[39,131082,117577],{},") is not visible to code importing ",[104,131085,950],{}," module, so it does not re-export anything (rules out D — that requires ",[39,131088,131089],{},"pub use",[15,131091,131092,131100,131146],{},[18,131093,131095,131096,131099],{"id":131094},"q6-what-is-the-purpose-of-pub-use-innerthing-written-in-a-parent-module","Q6. What is the purpose of ",[39,131097,131098],{},"pub use inner::Thing;"," written in a parent module?",[23,131101,131103,131115,131128,131138],{"className":131102},[26],[28,131104,131106,131108,131109,22769,131112,131114],{"className":131105},[31],[33,131107],{"disabled":35,"type":36}," It moves ",[39,131110,131111],{},"Thing",[39,131113,15301],{}," into the parent module",[28,131116,131118,131120,131121,131123,131124,131127],{"className":131117},[31],[33,131119],{"disabled":35,"type":36}," It re-exports ",[39,131122,131111],{},", making it accessible via the parent module's path (e.g. ",[39,131125,131126],{},"crate::Thing",") in addition to its original path, without duplicating the definition",[28,131129,131131,131133,131134,76588,131136],{"className":131130},[31],[33,131132],{"disabled":35,"type":36}," It is a syntax error — ",[39,131135,108694],{},[39,131137,117577],{},[28,131139,131141,104514,131143,131145],{"className":131140},[31],[33,131142],{"disabled":35,"type":36},[39,131144,15301],{}," itself public",[66,131147,131148,131150,131159],{},[69,131149,71],{},[73,131151,131152,131154,131155,131123,131157,131127],{},[76,131153,78],{}," B — It re-exports ",[39,131156,131111],{},[39,131158,131126],{},[73,131160,131161,355,131163,131165,131166,131168,131169,131171,131172,8574,131175,10819,131178,131180,131181,131183,131184,131186,131187,131189,131190,131192,131193,131195],{},[76,131162,84],{},[39,131164,131089],{}," is Rust's re-export mechanism: it takes an item visible at this point and makes it visible under a ",[104,131167,2689],{}," public path too, letting library authors flatten a deep internal module tree into a clean public API (e.g. ",[39,131170,131098],{}," at the crate root lets consumers write ",[39,131173,131174],{},"my_crate::Thing",[39,131176,131177],{},"my_crate::inner::Thing",[39,131179,131111],{}," still physically lives in ",[39,131182,15301],{},"; nothing is moved (rules out A) or duplicated. ",[39,131185,131089],{}," is valid, common syntax (rules out C). Re-exporting ",[39,131188,131111],{}," says nothing about ",[39,131191,15301],{},"'s own visibility — ",[39,131194,15301],{}," can remain a private module while one specific item from it is re-exported (rules out D).",[15,131197,131198,131209,131247],{},[18,131199,131201,131202,131205,131206,1685],{"id":131200},"q7-given-pub-struct-config-pub-name-string-version-u32-what-is-true-about-a-caller-outside-the-module-accessing-configversion","Q7. Given ",[39,131203,131204],{},"pub struct Config { pub name: String, version: u32 }",", what is true about a caller outside the module accessing ",[39,131207,131208],{},"config.version",[23,131210,131212,131224,131235,131241],{"className":131211},[26],[28,131213,131215,131217,131218,131220,131221,131223],{"className":131214},[31],[33,131216],{"disabled":35,"type":36}," It compiles — marking the struct ",[39,131219,117577],{}," makes all its fields ",[39,131222,117577],{}," too",[28,131225,131227,117726,131229,131232,131233],{"className":131226},[31],[33,131228],{"disabled":35,"type":36},[39,131230,131231],{},"version"," has no visibility modifier, so it defaults to private even though the struct itself is ",[39,131234,117577],{},[28,131236,131238,131240],{"className":131237},[31],[33,131239],{"disabled":35,"type":36}," It compiles only if the caller is in the same crate",[28,131242,131244,131246],{"className":131243},[31],[33,131245],{"disabled":35,"type":36}," It compiles, but emits a deprecation warning",[66,131248,131249,131251,131260],{},[69,131250,71],{},[73,131252,131253,131255,131256,131232,131258],{},[76,131254,78],{}," B — It fails to compile — ",[39,131257,131231],{},[39,131259,117577],{},[73,131261,131262,131264,131265,131267,131268,131271,131272,131274,131275,131277,131278,131280],{},[76,131263,84],{}," Struct visibility and field visibility are independent in Rust: ",[39,131266,117577],{}," on the struct only controls whether the ",[104,131269,131270],{},"struct type itself"," (and its ",[39,131273,117577],{}," fields\u002Fmethods) can be named from outside the module — each field still needs its own ",[39,131276,117577],{}," to be externally readable\u002Fwritable. This is a common gotcha (assumption A) because many other languages tie member visibility to the containing type's visibility. It's not scoped to same-crate access — ",[39,131279,130738],{}," would be needed for that specific behavior, and plain private means \"this module and descendants\" regardless of crate boundary (rules out C). There's no warning-only leniency here; it's a hard compile error (rules out D).",[15,131282,131283,131294,131324],{},[18,131284,131286,131287,131290,131291,131293],{"id":131285},"q8-what-does-super-mean-in-a-use-path-or-item-path","Q8. What does ",[39,131288,131289],{},"super::"," mean in a ",[39,131292,108694],{}," path or item path?",[23,131295,131297,131306,131312,131318],{"className":131296},[26],[28,131298,131300,131302,131303],{"className":131299},[31],[33,131301],{"disabled":35,"type":36}," It refers to the crate root, equivalent to ",[39,131304,131305],{},"crate::",[28,131307,131309,131311],{"className":131308},[31],[33,131310],{"disabled":35,"type":36}," It refers to the parent of the current module",[28,131313,131315,131317],{"className":131314},[31],[33,131316],{"disabled":35,"type":36}," It refers to a trait's default (super) implementation",[28,131319,131321,131323],{"className":131320},[31],[33,131322],{"disabled":35,"type":36}," It's not valid Rust syntax",[66,131325,131326,131328,131333],{},[69,131327,71],{},[73,131329,131330,131332],{},[76,131331,78],{}," B — It refers to the parent of the current module",[73,131334,131335,355,131337,131339,131340,131343,131344,3277,131347,131349,131350,131352],{},[76,131336,84],{},[39,131338,31153],{}," is a relative-path keyword meaning \"one level up in the module tree\" — useful in a submodule (e.g. ",[39,131341,131342],{},"tests",") that needs to reach items defined in its parent, via ",[39,131345,131346],{},"use super::*;",[39,131348,131305],{}," (confused with A) instead always means \"start from the absolute crate root,\" which is a different starting point unless the current module happens to be a direct child of the root. ",[39,131351,31153],{}," has nothing to do with trait default methods (rules out C), and it is valid, commonly used syntax (rules out D).",[15,131354,131355,131375,131413],{},[18,131356,131358,131359,131361,131362,131365,131366,23506,131369,131371,131372,131374],{"id":131357},"q9-a-private-helper-function-is-defined-in-module-a-module-ab-is-a-child-module-declared-via-mod-b-inside-as-file-can-code-inside-ab-call-that-private-function","Q9. A private helper function is defined in module ",[39,131360,1223],{},". Module ",[39,131363,131364],{},"a::b"," is a child module (declared via ",[39,131367,131368],{},"mod b;",[39,131370,1223],{},"'s file). Can code inside ",[39,131373,131364],{}," call that private function?",[23,131376,131378,131384,131394,131405],{"className":131377},[26],[28,131379,131381,131383],{"className":131380},[31],[33,131382],{"disabled":35,"type":36}," No — private items are never visible outside their exact defining module",[28,131385,131387,131389,131390,131393],{"className":131386},[31],[33,131388],{"disabled":35,"type":36}," Yes — Rust's privacy rule makes a private item visible in its defining module ",[104,131391,131392],{},"and all of that module's descendants",", so child modules can see their ancestors' private items",[28,131395,131397,131399,131400,131402,131403],{"className":131396},[31],[33,131398],{"disabled":35,"type":36}," Only if ",[39,131401,131364],{}," adds ",[39,131404,131346],{},[28,131406,131408,131410,131411],{"className":131407},[31],[33,131409],{"disabled":35,"type":36}," Only if the function is also marked ",[39,131412,130738],{},[66,131414,131415,131417,131424],{},[69,131416,71],{},[73,131418,131419,131421,131422,131393],{},[76,131420,78],{}," B — Yes — Rust's privacy rule makes a private item visible in its defining module ",[104,131423,131392],{},[73,131425,131426,131428,131429,131431,131432,131434,131435,131438,131439,2029,131442,10954,131444,131446,131447,131449,131450,131452],{},[76,131427,84],{}," This is one of Rust's most commonly-missed privacy rules: \"private\" is not \"only this module,\" it's \"this module plus everything nested inside it.\" A child module is considered part of its parent's privacy boundary, so ",[39,131430,131364],{}," can freely call a private (unmarked) item defined in ",[39,131433,1223],{}," by referring to it via a path like ",[39,131436,131437],{},"super::helper()",". A states the opposite of the actual rule. C conflates ",[104,131440,131441],{},"importing a name into scope",[104,131443,62370],{},[39,131445,131346],{}," would bring the name into unqualified scope for convenience, but ",[39,131448,131437],{}," would already compile without it, since visibility (not name resolution) is what was in question. D is unnecessary — no extra ",[39,131451,130738],{}," marker is needed for a descendant to see an ancestor's private item.",[15,131454,131455,131465,131506],{},[18,131456,131458,131459,186,131462,131464],{"id":131457},"q10-what-is-the-difference-between-pubsuper-and-pubcrate-on-an-item","Q10. What is the difference between ",[39,131460,131461],{},"pub(super)",[39,131463,130738],{}," on an item?",[23,131466,131468,131474,131485,131496],{"className":131467},[26],[28,131469,131471,131473],{"className":131470},[31],[33,131472],{"disabled":35,"type":36}," They are identical",[28,131475,131477,355,131479,131481,131482,131484],{"className":131476},[31],[33,131478],{"disabled":35,"type":36},[39,131480,131461],{}," restricts visibility to just the parent module (and, transitively, that parent's descendants), while ",[39,131483,130738],{}," opens it to the entire crate",[28,131486,131488,355,131490,131492,131493,131495],{"className":131487},[31],[33,131489],{"disabled":35,"type":36},[39,131491,131461],{}," is for structs only, ",[39,131494,130738],{}," is for functions only",[28,131497,131499,355,131501,131503,131504,5302],{"className":131498},[31],[33,131500],{"disabled":35,"type":36},[39,131502,131461],{}," makes the item visible to external crates, ",[39,131505,130738],{},[66,131507,131508,131510,131518],{},[69,131509,71],{},[73,131511,131512,1727,131514,131481,131516,131484],{},[76,131513,78],{},[39,131515,131461],{},[39,131517,130738],{},[73,131519,131520,355,131522,131524,131525,131527,131528,131530],{},[76,131521,84],{},[39,131523,131461],{}," is a narrower, path-scoped visibility modifier meaning \"visible to my parent module\" — useful for an item a submodule wants to expose upward without exposing it crate-wide. ",[39,131526,130738],{}," is broader, reaching every module in the crate regardless of position in the tree. They are not interchangeable (rules out A); both modifiers apply to any item kind — functions, structs, enums, modules — not restricted by kind (rules out C); and neither one reaches outside the crate at all — that requires plain ",[39,131529,117577],{}," (rules out D, which also has the external-visibility claim backwards).",[15,131532,131533,131545,131582],{},[18,131534,131536,131537,186,131539,131541,131542,131544],{"id":131535},"q11-what-happens-if-a-project-has-both-srcnetworkrs-and-srcnetworkmodrs-present-at-the-same-time-with-mod-network-declared-in-the-crate-root","Q11. What happens if a project has both ",[39,131538,130924],{},[39,131540,130932],{}," present at the same time, with ",[39,131543,130912],{}," declared in the crate root?",[23,131546,131548,131554,131567,131576],{"className":131547},[26],[28,131549,131551,131553],{"className":131550},[31],[33,131552],{"disabled":35,"type":36}," The compiler merges both files' contents into one module",[28,131555,131557,131559,131560,131563,131564],{"className":131556},[31],[33,131558],{"disabled":35,"type":36}," The compiler picks ",[39,131561,131562],{},"network.rs"," and silently ignores ",[39,131565,131566],{},"network\u002Fmod.rs",[28,131568,131570,131572,131573,131575],{"className":131569},[31],[33,131571],{"disabled":35,"type":36}," It's a compile error — the module ",[39,131574,130977],{}," would be ambiguously defined by two different files",[28,131577,131579,131581],{"className":131578},[31],[33,131580],{"disabled":35,"type":36}," The compiler picks whichever file was modified more recently",[66,131583,131584,131586,131593],{},[69,131585,71],{},[73,131587,131588,131590,131591,131575],{},[76,131589,78],{}," C — It's a compile error — the module ",[39,131592,130977],{},[73,131594,131595,131597,131598,7507,131601,131604,131605,131607,131608,131610],{},[76,131596,84],{}," The two module-file conventions (",[39,131599,131600],{},"name.rs",[39,131602,131603],{},"name\u002Fmod.rs",") are alternatives, not layers that combine — the compiler requires exactly one to exist for a given ",[39,131606,130774],{}," declaration, and finding both is a \"file for module found at two places\" ambiguity error. This trips people up when migrating a codebase from the old ",[39,131609,130854],{}," convention to the new flat-file convention and forgetting to delete the old file. There's no merging (rules out A), no silent precedence (rules out B), and Rust's module resolution has nothing to do with filesystem timestamps (rules out D) — it's a static, deterministic error regardless of file mtimes.",[15,131612,131613,131631,131672],{},[18,131614,131616,131617,2018,131620,131622,131623,89923,131625,131627,131628,1685],{"id":131615},"q12-a-crate-has-pub-mod-net-pub-fn-connect-in-librs-but-nowhere-does-the-crate-write-use-for-connect-can-an-external-crate-that-depends-on-this-one-call-this_cratenetconnect","Q12. A crate has ",[39,131618,131619],{},"pub mod net { pub fn connect() {} }",[39,131621,130846],{},", but nowhere does the crate write ",[39,131624,108694],{},[39,131626,14292],{},". Can an external crate that depends on this one call ",[39,131629,131630],{},"this_crate::net::connect()",[23,131632,131634,131643,131654,131663],{"className":131633},[26],[28,131635,131637,131639,131640,131642],{"className":131636},[31],[33,131638],{"disabled":35,"type":36}," No — without an explicit ",[39,131641,108694],{}," inside the defining crate, nothing is exported",[28,131644,131646,88213,131648,131650,131651,131653],{"className":131645},[31],[33,131647],{"disabled":35,"type":36},[39,131649,117577],{}," on both the module and the function is sufficient; ",[39,131652,108694],{}," is unrelated to whether external crates can reach an item, it only affects local scoping within the defining crate itself",[28,131655,131657,131659,131660,131662],{"className":131656},[31],[33,131658],{"disabled":35,"type":36}," No — only items re-exported with ",[39,131661,131089],{}," at the crate root are ever externally reachable",[28,131664,131666,131668,131669],{"className":131665},[31],[33,131667],{"disabled":35,"type":36}," Yes, but only if the external crate also declares ",[39,131670,131671],{},"mod net;",[66,131673,131674,131676,131684],{},[69,131675,71],{},[73,131677,131678,88240,131680,131650,131682,131653],{},[76,131679,78],{},[39,131681,117577],{},[39,131683,108694],{},[73,131685,131686,131688,131689,131691,131692,56676,131695,131698,131699,131702,131703,131705,131706,131708,131709,131712,131713,446,131715,131717,131718,131720,131721,131724,131725,131727],{},[76,131687,84],{}," External reachability is governed entirely by the chain of ",[39,131690,117577],{}," visibility from the crate root down to the item (",[39,131693,131694],{},"pub mod net",[39,131696,131697],{},"pub fn connect"," means the full path ",[39,131700,131701],{},"this_crate::net::connect"," is public), regardless of whether the defining crate itself ever writes a ",[39,131704,108694],{}," for it internally. ",[39,131707,108694],{}," only affects how ",[104,131710,131711],{},"that crate's own code"," refers to the item by a shorter name — it plays no role in what's exposed externally. A and C both overstate what ",[39,131714,108694],{},[39,131716,131089],{}," are required for: ",[39,131719,131089],{}," is only needed if you want to expose the item under a ",[104,131722,131723],{},"different, shorter"," path than its natural one, not merely to expose it at all. D is not how Rust's module system works — a downstream crate accesses items through the dependency's public path, it doesn't need to mirror the internal module structure with its own ",[39,131726,130774],{}," declaration.",[15,131729,131730,131752,131790],{},[18,131731,45860,131733,131736,131737,131740,131741,131743,131744,131747,131748,131751],{"id":131732},"q13-mod-shapes-privately-defines-pub-fn-circle_arear-f64-f64-and-a-private-non-pub-helper-fn-validater-f64-bool-elsewhere-code-does-use-shapes-what-becomes-available-at-the-call-site",[39,131734,131735],{},"mod shapes"," privately defines ",[39,131738,131739],{},"pub fn circle_area(r: f64) -> f64 {...}"," and a private (non-",[39,131742,117577],{},") helper ",[39,131745,131746],{},"fn validate(r: f64) -> bool {...}",". Elsewhere, code does ",[39,131749,131750],{},"use shapes::*;",". What becomes available at the call site?",[23,131753,131755,131766,131776,131782],{"className":131754},[26],[28,131756,131758,2247,131760,186,131763,131765],{"className":131757},[31],[33,131759],{"disabled":35,"type":36},[39,131761,131762],{},"circle_area",[39,131764,39376],{},", since glob imports bring in everything regardless of visibility",[28,131767,131769,50010,131771,131773,131774],{"className":131768},[31],[33,131770],{"disabled":35,"type":36},[39,131772,131762],{}," — glob imports still respect normal privacy rules, so private items are never pulled in even by ",[39,131775,6134],{},[28,131777,131779,131781],{"className":131778},[31],[33,131780],{"disabled":35,"type":36}," Neither — glob imports only work for enums, not modules",[28,131783,131785,50010,131787,131789],{"className":131784},[31],[33,131786],{"disabled":35,"type":36},[39,131788,39376],{},", since glob imports prioritize private items",[66,131791,131792,131794,131802],{},[69,131793,71],{},[73,131795,131796,79831,131798,131773,131800],{},[76,131797,78],{},[39,131799,131762],{},[39,131801,6134],{},[73,131803,131804,355,131806,131809,131810,131813,131814,131816,131817,21182,131819,9530,131821,131823,131824,131827,131828,131830,131831,131833],{},[76,131805,84],{},[39,131807,131808],{},"use path::*;"," is sugar for \"bring every ",[104,131811,131812],{},"visible-from-here"," item at ",[39,131815,58872],{}," into scope\" — it is not a privacy bypass. Since ",[39,131818,39376],{},[39,131820,117577],{},[39,131822,108694],{}," site is outside ",[39,131825,131826],{},"shapes"," and its descendants, ",[39,131829,39376],{}," was never visible there to begin with, glob or not. Assuming ",[39,131832,6134],{}," reaches into private internals (A) is the tempting mistake; glob imports work for any module's contents, not just enum variants (rules out C, which describes a much narrower legitimate use of glob imports); and there's no such \"private items take priority\" behavior (rules out D).",[15,131835,131836,131862,131904],{},[18,131837,131839,131840,131842,131843,7501,131846,131848,131849,137,131851,131853,131854,355,131856,131858,131859,131861],{"id":131838},"q14-mainrs-contains-in-this-order-mod-b-mod-a-where-as-code-calls-a-function-defined-in-b-and-bs-code-declared-textually-after-a-in-the-file-calls-a-function-defined-in-a-does-this-compile","Q14. ",[39,131841,109697],{}," contains, in this order: ",[39,131844,131845],{},"mod b; mod a;",[39,131847,1223],{},"'s code calls a function defined in ",[39,131850,1232],{},[39,131852,1232],{},"'s code (declared textually ",[104,131855,1747],{},[39,131857,1223],{}," in the file) calls a function defined in ",[39,131860,1223],{},". Does this compile?",[23,131863,131865,131881,131890,131896],{"className":131864},[26],[28,131866,131868,88201,131870,131872,131873,1179,131875,131877,131878,131880],{"className":131867},[31],[33,131869],{"disabled":35,"type":36},[39,131871,1232],{}," is declared before ",[39,131874,1223],{},[39,131876,1223],{},"'s items don't exist yet when ",[39,131879,1232],{}," is compiled",[28,131882,131884,131886,131887,131889],{"className":131883},[31],[33,131885],{"disabled":35,"type":36}," Yes — Rust resolves the whole module graph before checking cross-references, so declaration order of ",[39,131888,130774],{}," statements doesn't matter, unlike top-to-bottom execution order in scripting languages",[28,131891,131893,131895],{"className":131892},[31],[33,131894],{"disabled":35,"type":36}," No — mutual references between sibling modules are always a compile error",[28,131897,131899,131901,131902],{"className":131898},[31],[33,131900],{"disabled":35,"type":36}," Yes, but only if both modules are also marked ",[39,131903,117577],{},[66,131905,131906,131908,131915],{},[69,131907,71],{},[73,131909,131910,131912,131913,131889],{},[76,131911,78],{}," B — Yes — Rust resolves the whole module graph before checking cross-references, so declaration order of ",[39,131914,130774],{},[73,131916,131917,131919,131920,131922,131923,131925,131926,131928,131929,186,131931,131933,131934,131936],{},[76,131918,84],{}," Unlike C's single-pass, order-sensitive translation units, Rust builds a full module tree from all ",[39,131921,130774],{}," declarations in the crate before resolving any paths, so two sibling modules can freely call into each other regardless of which ",[39,131924,130774],{}," line appears first — there's no \"not declared yet\" state at the module-graph level. A projects familiar top-down\u002Fdeclaration-order thinking from other languages onto Rust, which is exactly the gotcha. Mutual references between modules are completely ordinary and common (rules out C) — Rust isn't a header-file\u002Fforward-declaration language. Visibility markers control whether ",[104,131927,33735],{}," modules outside this pair can see the items, not whether ",[39,131930,1223],{},[39,131932,1232],{}," can see each other as siblings in the same crate (rules out D, and here both functions only need to be visible to sibling modules, which private-by-default already permits per the ancestor\u002Fdescendant privacy rule, not ",[39,131935,117577],{}," specifically).",[15,131938,131939,131943,131983],{},[18,131940,131942],{"id":131941},"q15-when-designing-a-librarys-public-api-which-is-the-more-idiomatic-structure","Q15. When designing a library's public API, which is the more idiomatic structure?",[23,131944,131946,131955,131968,131977],{"className":131945},[26],[28,131947,131949,131951,131952],{"className":131948},[31],[33,131950],{"disabled":35,"type":36}," Require consumers to import everything via deep paths like ",[39,131953,131954],{},"my_crate::internal::storage::backend::Client",[28,131956,131958,131960,131961,131963,131964,131967],{"className":131957},[31],[33,131959],{"disabled":35,"type":36}," Keep implementation details in whatever module nesting makes sense internally, then use ",[39,131962,131089],{}," at the crate root (or a curated ",[39,131965,131966],{},"prelude"," module) to re-export the small set of types consumers actually need under short, stable paths",[28,131969,131971,131973,131974,131976],{"className":131970},[31],[33,131972],{"disabled":35,"type":36}," Make every module and item ",[39,131975,117577],{}," so nothing is ever hidden",[28,131978,131980,131982],{"className":131979},[31],[33,131981],{"disabled":35,"type":36}," Avoid modules entirely and put all code in a single file to eliminate path issues",[66,131984,131985,131987,131996],{},[69,131986,71],{},[73,131988,131989,131991,131992,131963,131994,131967],{},[76,131990,78],{}," B — Keep implementation details in whatever module nesting makes sense internally, then use ",[39,131993,131089],{},[39,131995,131966],{},[73,131997,131998,355,132000,132002,132003,132005,132006,132008],{},[76,131999,84],{},[76,132001,17307],{},": separating internal organization (which can change freely) from the public API surface (exposed via a small number of ",[39,132004,131089],{}," re-exports) is standard practice in well-designed Rust crates — it lets internals be refactored without breaking downstream code, since only the re-exported paths are a semver commitment. Forcing consumers through deep internal paths (A) leaks implementation structure into your API contract, making future refactors breaking changes. Making everything ",[39,132007,117577],{}," (C) is the opposite problem — it maximizes the semver-committed surface area, including things you'll want to change later. Avoiding modules altogether (D) doesn't scale and throws away the organizational and privacy benefits modules provide.",[15,132010,132011,132015,132048],{},[18,132012,132014],{"id":132013},"q16-for-a-helper-function-used-by-multiple-internal-modules-but-never-meant-to-be-called-by-downstream-crates-which-visibility-is-generally-the-better-default","Q16. For a helper function used by multiple internal modules but never meant to be called by downstream crates, which visibility is generally the better default?",[23,132016,132018,132026,132034,132040],{"className":132017},[26],[28,132019,132021,355,132023,132025],{"className":132020},[31],[33,132022],{"disabled":35,"type":36},[39,132024,117577],{},", in case a downstream crate wants it someday",[28,132027,132029,355,132031,132033],{"className":132028},[31],[33,132030],{"disabled":35,"type":36},[39,132032,130738],{}," — visible to every module inside this crate, but excluded from the crate's public API and semver contract",[28,132035,132037,132039],{"className":132036},[31],[33,132038],{"disabled":35,"type":36}," Leave it fully private and duplicate the function in every module that needs it",[28,132041,132043,355,132045,132047],{"className":132042},[31],[33,132044],{"disabled":35,"type":36},[39,132046,131461],{},", regardless of whether the callers are actually siblings or unrelated modules",[66,132049,132050,132052,132058],{},[69,132051,71],{},[73,132053,132054,1727,132056,132033],{},[76,132055,78],{},[39,132057,130738],{},[73,132059,132060,355,132062,1783,132064,132066,132067,132069,132070,132072],{},[76,132061,84],{},[76,132063,17307],{},[39,132065,130738],{}," is the standard choice for \"shared internally, not part of the public contract\" — it gives every module in the crate access while keeping the item free to change or remove later without a semver-breaking release, since it was never externally reachable. Defaulting to ",[39,132068,117577],{}," \"just in case\" (A) is a common anti-pattern that needlessly locks the signature into your public API forever. Duplicating the function per module (C) creates maintenance drift and defeats the purpose of having a module system. ",[39,132071,131461],{}," (D) only works when every caller happens to be the direct parent module — reaching for it regardless of the actual caller locations is fragile and will break the moment a caller lives elsewhere in the tree.",[15,132074,132075,132082,132122],{},[18,132076,132078,132079,132081],{"id":132077},"q17-in-a-large-project-migrating-from-the-rust-2015-style-modrs-layout-to-the-modern-flat-file-layout-what-is-the-practical-motivation-the-community-usually-cites","Q17. In a large project migrating from the Rust 2015-style ",[39,132080,130854],{}," layout to the modern flat-file layout, what is the practical motivation the community usually cites?",[23,132083,132085,132093,132105,132113],{"className":132084},[26],[28,132086,132088,355,132090,132092],{"className":132087},[31],[33,132089],{"disabled":35,"type":36},[39,132091,130854],{}," files are compiled slower than flat files",[28,132094,132096,132098,132099,132101,132102,132104],{"className":132095},[31],[33,132097],{"disabled":35,"type":36}," Having many files all literally named ",[39,132100,130854],{}," is hard to distinguish in editor tabs and file pickers, whereas ",[39,132103,131562],{}," immediately identifies itself",[28,132106,132108,355,132110,132112],{"className":132107},[31],[33,132109],{"disabled":35,"type":36},[39,132111,130854],{}," is deprecated and will be a hard compile error in a future edition",[28,132114,132116,132118,132119,132121],{"className":132115},[31],[33,132117],{"disabled":35,"type":36}," Only the flat-file style supports ",[39,132120,131089],{}," re-exports",[66,132123,132124,132126,132135],{},[69,132125,71],{},[73,132127,132128,132130,132131,132101,132133,132104],{},[76,132129,78],{}," B — Having many files all literally named ",[39,132132,130854],{},[39,132134,131562],{},[73,132136,132137,355,132139,132141,132142,7728,132144,132146,132147,132149,132150,42,132152,132155,132156,132158,132159,132161],{},[76,132138,84],{},[76,132140,17307],{},": both layouts compile to the identical module structure and have no performance difference, so the widely cited reason for preferring ",[39,132143,131600],{},[39,132145,131603],{}," is purely ergonomic — a dozen open ",[39,132148,130854],{}," tabs are indistinguishable at a glance, while ",[39,132151,131562],{},[39,132153,132154],{},"parser.rs",", etc. are self-identifying. There's no compile-speed difference (rules out A), ",[39,132157,130854],{}," remains fully supported and not deprecated in current editions (rules out C), and ",[39,132160,131089],{}," re-exporting works identically regardless of which file-layout convention defines the module (rules out D).",[15,132163,132164,132174,132217],{},[18,132165,132167,132168,132170,132171,132173],{"id":132166},"q18-per-common-rust-formatting-convention-and-rustfmtclippy-defaults-how-should-use-statements-typically-be-grouped-at-the-top-of-a-file","Q18. Per common Rust formatting convention (and ",[39,132169,108632],{},"\u002Fclippy defaults), how should ",[39,132172,108694],{}," statements typically be grouped at the top of a file?",[23,132175,132177,132183,132205,132211],{"className":132176},[26],[28,132178,132180,132182],{"className":132179},[31],[33,132181],{"disabled":35,"type":36}," In reverse-alphabetical order with no grouping",[28,132184,132186,132188,132189,446,132191,446,132193,132196,132197,446,132199,446,132202,132204],{"className":132185},[31],[33,132187],{"disabled":35,"type":36}," Grouped into standard library (",[39,132190,109737],{},[39,132192,110615],{},[39,132194,132195],{},"alloc","), external crate, and local crate (",[39,132198,131305],{},[39,132200,132201],{},"self::",[39,132203,131289],{},") blocks, each internally sorted",[28,132206,132208,132210],{"className":132207},[31],[33,132209],{"disabled":35,"type":36}," All on a single line separated by semicolons for compactness",[28,132212,132214,132216],{"className":132213},[31],[33,132215],{"disabled":35,"type":36}," Inline within each function right before first use, never at the top of the file",[66,132218,132219,132221,132238],{},[69,132220,71],{},[73,132222,132223,132225,132226,446,132228,446,132230,132196,132232,446,132234,446,132236,132204],{},[76,132224,78],{}," B — Grouped into standard library (",[39,132227,109737],{},[39,132229,110615],{},[39,132231,132195],{},[39,132233,131305],{},[39,132235,132201],{},[39,132237,131289],{},[73,132239,132240,355,132242,132244,132245,132247,132248,132250,132251,132254,132255,132257,132258,132260],{},[76,132241,84],{},[76,132243,17307],{},": separating ",[39,132246,108694],{}," declarations into std \u002F external-crate \u002F local-crate groups (a convention ",[39,132249,108632],{}," can enforce with ",[39,132252,132253],{},"group_imports",", and that ",[39,132256,110057],{},"\u002Fcommunity style guides converge on) makes it easy to scan a file's dependencies at a glance — what's from the standard library, what's a third-party crate, and what's local to this project. Reverse-alphabetical-only (A) ignores the semantic grouping that makes imports scannable. Cramming everything onto one line (C) is valid syntax but actively fights readability and diffing. Scattering ",[39,132259,108694],{}," statements inline per-function (D) is unconventional in Rust — the idiom is top-of-file imports, unlike languages that favor fully local imports.",[15,132262,132263,132271,132306],{},[18,132264,132266,132267,132270],{"id":132265},"q19-why-is-a-blanket-pub-use-inner_module-at-a-crate-root-generally-discouraged-compared-to-explicitly-naming-re-exports","Q19. Why is a blanket ",[39,132268,132269],{},"pub use inner_module::*;"," at a crate root generally discouraged compared to explicitly naming re-exports?",[23,132272,132274,132280,132290,132296],{"className":132273},[26],[28,132275,132277,132279],{"className":132276},[31],[33,132278],{"disabled":35,"type":36}," It is a syntax error in current Rust editions",[28,132281,132283,132285,132286,132289],{"className":132282},[31],[33,132284],{"disabled":35,"type":36}," It obscures exactly what's part of the public API (making intentional vs. accidental exposure hard to audit) and risks silent re-export naming conflicts as ",[39,132287,132288],{},"inner_module"," evolves",[28,132291,132293,132295],{"className":132292},[31],[33,132294],{"disabled":35,"type":36}," Glob re-exports are always slower at runtime than named re-exports",[28,132297,132299,355,132301,2029,132303,132305],{"className":132298},[31],[33,132300],{"disabled":35,"type":36},[39,132302,131089],{},[39,132304,6134],{}," only works for enums",[66,132307,132308,132310,132317],{},[69,132309,71],{},[73,132311,132312,132314,132315,132289],{},[76,132313,78],{}," B — It obscures exactly what's part of the public API (making intentional vs. accidental exposure hard to audit) and risks silent re-export naming conflicts as ",[39,132316,132288],{},[73,132318,132319,355,132321,132323,132324,132326,132327,132330,132331,132333,132334,132336,132337,446,132339,132341],{},[76,132320,84],{},[76,132322,17307],{},": a glob ",[39,132325,131089],{}," re-exports ",[104,132328,132329],{},"everything"," currently visible in ",[39,132332,132288],{},", including items added later that the author may not have intended to commit to the public API — every new item silently becomes part of the semver contract, and two glob-reexported modules that later both add an item of the same name produce a re-export collision far from where the actual conflict originates. Explicit, named ",[39,132335,131089],{}," statements make the public surface auditable at a glance and immune to that drift. It's valid, working syntax, not an error (rules out A); there is no runtime cost difference — ",[39,132338,108694],{},[39,132340,131089],{}," are purely a compile-time path\u002Fname resolution mechanism with zero runtime representation (rules out C); and glob re-exports work for any module's public contents, not just enums (rules out D).",[15,132343,132344,132378,132441],{},[18,132345,132347,132348,42,132350,7255,132353,132356,132357,186,132360,132363,132364,132367,132368,132370,132371,132373,132374,132377],{"id":132346},"q20-a-crate-is-organized-as-srclibrs-srcnetmodrs-or-srcnetrs-declaring-pubcrate-mod-client-and-srcnetclientrs-defining-pub-struct-client-with-mostly-pubcrate-helper-functions-alongside-it-librs-also-contains-pub-use-netclientclient-what-is-the-effect-of-this-structure-for-a-downstream-crate","Q20. A crate is organized as ",[39,132349,110291],{},[39,132351,132352],{},"src\u002Fnet\u002Fmod.rs",[39,132354,132355],{},"src\u002Fnet.rs",") declaring ",[39,132358,132359],{},"pub(crate) mod client;",[39,132361,132362],{},"src\u002Fnet\u002Fclient.rs"," defining ",[39,132365,132366],{},"pub struct Client { ... }"," with mostly ",[39,132369,130738],{}," helper functions alongside it. ",[39,132372,130846],{}," also contains ",[39,132375,132376],{},"pub use net::client::Client;",". What is the effect of this structure for a downstream crate?",[23,132379,132381,132397,132409,132430],{"className":132380},[26],[28,132382,132384,132386,132387,132390,132391,132394,132395],{"className":132383},[31],[33,132385],{"disabled":35,"type":36}," It cannot see ",[39,132388,132389],{},"Client"," at all, since ",[39,132392,132393],{},"net"," itself is only ",[39,132396,130738],{},[28,132398,132400,132402,132403,132405,132406],{"className":132399},[31],[33,132401],{"disabled":35,"type":36}," It can reach ",[39,132404,132389],{}," only via the full path ",[39,132407,132408],{},"this_crate::net::client::Client",[28,132410,132412,132402,132414,132416,132417,132420,132421,446,132423,132426,132427,132429],{"className":132411},[31],[33,132413],{"disabled":35,"type":36},[39,132415,132389],{}," via the short, stable path ",[39,132418,132419],{},"this_crate::Client",", while the ",[39,132422,132393],{},[39,132424,132425],{},"client"," module layout and any ",[39,132428,130738],{}," helpers stay fully internal and free to refactor",[28,132431,132433,132435,132436,132438,132439,105377],{"className":132432},[31],[33,132434],{"disabled":35,"type":36}," It gets a compile error because ",[39,132437,131089],{}," cannot re-export an item from a ",[39,132440,130738],{},[66,132442,132443,132445,132460],{},[69,132444,71],{},[73,132446,132447,132449,132450,132416,132452,132420,132454,446,132456,132426,132458,132429],{},[76,132448,78],{}," C — It can reach ",[39,132451,132389],{},[39,132453,132419],{},[39,132455,132393],{},[39,132457,132425],{},[39,132459,130738],{},[73,132461,132462,132464,132465,132467,132468,132470,132471,132473,132474,132476,132477,132479,132480,132482,132483,132485,132486,132488,132489,132491,132492,132494,132495,2182,132498,132500,132501,830,132503,132505],{},[76,132463,84],{}," This is the idiomatic re-export pattern in practice: ",[39,132466,132393],{}," being merely ",[39,132469,130738],{}," would normally block external access to anything nested inside it, but the ",[39,132472,132376],{}," at the crate root creates an independent, fully ",[39,132475,117577],{}," path directly to ",[39,132478,132389],{}," that does not depend on ",[39,132481,132393],{},"'s own visibility — re-export visibility is evaluated at the ",[39,132484,131089],{}," site, not inherited from the source module's visibility. A is the tempting mistake of assuming a ",[39,132487,131089],{}," inherits its source module's restricted visibility rather than establishing its own. B undersells the re-export — the whole point of ",[39,132490,131089],{}," is to avoid forcing consumers through the internal path. D is wrong: re-exporting an item out of a less-visible module into a more-visible path is exactly what ",[39,132493,131089],{}," is for and is a completely standard, compiling pattern, as long as the ",[104,132496,132497],{},"item itself",[39,132499,132389],{},") is at least as visible as the path you're re-exporting it to (",[39,132502,132389],{},[39,132504,117577],{},", so this works).",{"title":264,"searchDepth":286,"depth":286,"links":132507},[132508,132509,132511,132512,132514,132516,132518,132520,132522,132524,132526,132528,132530,132532,132534,132535,132536,132538,132540,132542],{"id":130718,"depth":296,"text":130719},{"id":130780,"depth":296,"text":132510},"Q2. What does pub(crate) mean when applied to a function?",{"id":130834,"depth":296,"text":130835},{"id":130906,"depth":296,"text":132513},"Q4. Given src\u002Fmain.rs contains mod network;, which file layouts are valid ways to provide that module's contents (Rust 2018+)?",{"id":131000,"depth":296,"text":132515},"Q5. What does use crate::utils::parse; do?",{"id":131094,"depth":296,"text":132517},"Q6. What is the purpose of pub use inner::Thing; written in a parent module?",{"id":131200,"depth":296,"text":132519},"Q7. Given pub struct Config { pub name: String, version: u32 }, what is true about a caller outside the module accessing config.version?",{"id":131285,"depth":296,"text":132521},"Q8. What does super:: mean in a use path or item path?",{"id":131357,"depth":296,"text":132523},"Q9. A private helper function is defined in module a. Module a::b is a child module (declared via mod b; inside a's file). Can code inside a::b call that private function?",{"id":131457,"depth":296,"text":132525},"Q10. What is the difference between pub(super) and pub(crate) on an item?",{"id":131535,"depth":296,"text":132527},"Q11. What happens if a project has both src\u002Fnetwork.rs and src\u002Fnetwork\u002Fmod.rs present at the same time, with mod network; declared in the crate root?",{"id":131615,"depth":296,"text":132529},"Q12. A crate has pub mod net { pub fn connect() {} } in lib.rs, but nowhere does the crate write use for connect. Can an external crate that depends on this one call this_crate::net::connect()?",{"id":131732,"depth":296,"text":132531},"Q13. mod shapes privately defines pub fn circle_area(r: f64) -> f64 {...} and a private (non-pub) helper fn validate(r: f64) -> bool {...}. Elsewhere, code does use shapes::*;. What becomes available at the call site?",{"id":131838,"depth":296,"text":132533},"Q14. main.rs contains, in this order: mod b; mod a; where a's code calls a function defined in b, and b's code (declared textually after a in the file) calls a function defined in a. Does this compile?",{"id":131941,"depth":296,"text":131942},{"id":132013,"depth":296,"text":132014},{"id":132077,"depth":296,"text":132537},"Q17. In a large project migrating from the Rust 2015-style mod.rs layout to the modern flat-file layout, what is the practical motivation the community usually cites?",{"id":132166,"depth":296,"text":132539},"Q18. Per common Rust formatting convention (and rustfmt\u002Fclippy defaults), how should use statements typically be grouped at the top of a file?",{"id":132265,"depth":296,"text":132541},"Q19. Why is a blanket pub use inner_module::*; at a crate root generally discouraged compared to explicitly naming re-exports?",{"id":132346,"depth":296,"text":132543},"Q20. A crate is organized as src\u002Flib.rs, src\u002Fnet\u002Fmod.rs (or src\u002Fnet.rs) declaring pub(crate) mod client; and src\u002Fnet\u002Fclient.rs defining pub struct Client { ... } with mostly pub(crate) helper functions alongside it. lib.rs also contains pub use net::client::Client;. What is the effect of this structure for a downstream crate?",{},"\u002Frust\u002F20-modules-and-crates",{"title":130708,"description":264},"rust\u002F20-modules-and-crates","Bq-AXdlvi7Hid41CD5OrLkQWuUC01aoMx3YASVgjh1k",{"id":132550,"title":132551,"body":132552,"description":264,"extension":2144,"meta":134517,"navigation":35,"path":134518,"seo":134519,"stem":134520,"__hash__":134521},"content\u002Frust\u002F21-testing.md","21 — Testing",{"type":8,"value":132553,"toc":134478},[132554,132557,132692,132780,132870,133033,133108,133173,133313,133408,133495,133577,133689,133761,133854,133962,134037,134127,134197,134311,134385,134475],[11,132555,132551],{"id":132556},"_21-testing",[15,132558,132559,132566,132610,132643],{"language":111909},[18,132560,132562,132563,132565],{"id":132561},"q1-what-does-the-test-attribute-do","Q1. What does the ",[39,132564,129967],{}," attribute do?",[257,132567,132568],{"language":111909},[260,132569,132571],{"className":111918,"code":132570,"language":111909,"meta":264,"style":264},"#[test]\nfn adds_two() {\n    assert_eq!(2 + 2, 4);\n}\n",[39,132572,132573,132578,132587,132606],{"__ignoreMap":264},[268,132574,132575],{"class":270,"line":271},[268,132576,132577],{"class":282},"#[test]\n",[268,132579,132580,132582,132585],{"class":270,"line":286},[268,132581,37837],{"class":274},[268,132583,132584],{"class":278}," adds_two",[268,132586,283],{"class":282},[268,132588,132589,132592,132594,132596,132598,132600,132602,132604],{"class":270,"line":296},[268,132590,132591],{"class":278},"    assert_eq!",[268,132593,622],{"class":282},[268,132595,2258],{"class":305},[268,132597,3350],{"class":274},[268,132599,2214],{"class":305},[268,132601,42],{"class":282},[268,132603,15049],{"class":305},[268,132605,628],{"class":282},[268,132607,132608],{"class":270,"line":311},[268,132609,314],{"class":282},[23,132611,132613,132621,132631,132637],{"className":132612},[26],[28,132614,132616,132618,132619],{"className":132615},[31],[33,132617],{"disabled":35,"type":36}," It marks the function to run automatically before ",[39,132620,111207],{},[28,132622,132624,132626,132627,132630],{"className":132623},[31],[33,132625],{"disabled":35,"type":36}," It marks the function as a test case that ",[39,132628,132629],{},"cargo test"," discovers and runs as its own isolated execution",[28,132632,132634,132636],{"className":132633},[31],[33,132635],{"disabled":35,"type":36}," It disables the function in release builds only",[28,132638,132640,132642],{"className":132639},[31],[33,132641],{"disabled":35,"type":36}," It generates documentation from the function's body",[66,132644,132645,132647,132654],{},[69,132646,71],{},[73,132648,132649,132651,132652,132630],{},[76,132650,78],{}," B — It marks the function as a test case that ",[39,132653,132629],{},[73,132655,132656,355,132658,132660,132661,132663,132664,132666,132667,132669,132670,132672,132673,132675,132676,132678,132679,132682,132683,132685,132686,132689,132690,128211],{},[76,132657,84],{},[39,132659,129967],{}," registers a function with the built-in test harness; ",[39,132662,132629],{}," compiles a special test binary that runs every ",[39,132665,129967],{},"-annotated function, each in its own thread by default, reporting pass\u002Ffail per test. It has nothing to do with ",[39,132668,111207],{}," startup order (rules out A) — test binaries don't even have the crate's normal ",[39,132671,111207],{},". It's excluded from ",[104,132674,119080],{}," (non-test) builds entirely, not just release builds specifically (rules out C, ",[39,132677,129967],{}," code is compiled out unless ",[39,132680,132681],{},"cfg(test)"," is active, which happens for ",[39,132684,132629],{}," regardless of debug\u002Frelease). Doc generation is ",[39,132687,132688],{},"\u002F\u002F\u002F"," doc comments, unrelated to ",[39,132691,129967],{},[15,132693,132694,132706,132736],{},[18,132695,132697,132698,132701,132702,132705],{"id":132696},"q2-why-is-cfgtest-commonly-placed-on-a-mod-tests-block-containing-unit-tests","Q2. Why is ",[39,132699,132700],{},"#[cfg(test)]"," commonly placed on a ",[39,132703,132704],{},"mod tests { ... }"," block containing unit tests?",[23,132707,132709,132715,132721,132730],{"className":132708},[26],[28,132710,132712,132714],{"className":132711},[31],[33,132713],{"disabled":35,"type":36}," It makes the tests run in parallel instead of sequentially",[28,132716,132718,132720],{"className":132717},[31],[33,132719],{"disabled":35,"type":36}," It ensures the test module (and everything inside it, including test-only imports) is compiled only when building for testing, not in normal builds",[28,132722,132724,132726,132727],{"className":132723},[31],[33,132725],{"disabled":35,"type":36}," It is required syntax for any function using ",[39,132728,132729],{},"assert_eq!",[28,132731,132733,132735],{"className":132732},[31],[33,132734],{"disabled":35,"type":36}," It hides the test results from the terminal output",[66,132737,132738,132740,132745],{},[69,132739,71],{},[73,132741,132742,132744],{},[76,132743,78],{}," B — It ensures the test module (and everything inside it, including test-only imports) is compiled only when building for testing, not in normal builds",[73,132746,132747,355,132749,132751,132752,132754,132755,132757,132758,132761,132762,132764,132765,132767,132768,132770,132771,132773,132774,132777,132778,128211],{},[76,132748,84],{},[39,132750,132700],{}," is conditional compilation: the annotated item only exists in builds where the ",[39,132753,57434],{}," cfg flag is set, which ",[39,132756,132629],{}," sets automatically. Wrapping unit tests in a ",[39,132759,132760],{},"#[cfg(test)] mod tests { use super::*; ... }"," block means test code, test-only dependencies, and test helper functions never bloat or ship in the production binary. It's unrelated to test parallelism, which is a ",[39,132763,132629],{}," runtime behavior controlled separately (rules out A, see also the test-isolation question later in this file). ",[39,132766,132729],{}," works in any function regardless of ",[39,132769,80368],{}," (rules out C). Output visibility is controlled by ",[39,132772,132629],{}," flags like ",[39,132775,132776],{},"--nocapture",", not by ",[39,132779,132681],{},[15,132781,132782,132788,132835],{},[18,132783,132785,132786,1685],{"id":132784},"q3-where-do-rust-integration-tests-live-and-how-do-they-differ-from-unit-tests-in-src","Q3. Where do Rust integration tests live, and how do they differ from unit tests in ",[39,132787,109701],{},[23,132789,132791,132801,132817,132823],{"className":132790},[26],[28,132792,132794,132796,132797,132800],{"className":132793},[31],[33,132795],{"disabled":35,"type":36}," In ",[39,132798,132799],{},"src\u002Ftests\u002F",", and they have access to private items just like unit tests",[28,132802,132804,132806,132807,132810,132811,132813,132814,132816],{"className":132803},[31],[33,132805],{"disabled":35,"type":36}," In a top-level ",[39,132808,132809],{},"tests\u002F"," directory (sibling to ",[39,132812,109701],{},"); each file there is compiled as its own separate crate that can only call the library's ",[39,132815,117577],{}," API, not its private internals",[28,132818,132820,132822],{"className":132819},[31],[33,132821],{"disabled":35,"type":36}," Integration tests and unit tests are the same thing in Rust — there's no distinction",[28,132824,132826,132796,132828,132830,132831,132834],{"className":132825},[31],[33,132827],{"disabled":35,"type":36},[39,132829,108587],{},", as declarative ",[39,132832,132833],{},"[[test]]"," blocks with no Rust code",[66,132836,132837,132839,132850],{},[69,132838,71],{},[73,132840,132841,132843,132844,132810,132846,132813,132848,132816],{},[76,132842,78],{}," B — In a top-level ",[39,132845,132809],{},[39,132847,109701],{},[39,132849,117577],{},[73,132851,132852,132854,132855,132857,132858,132860,132861,132863,132864,132866,132867,132869],{},[76,132853,84],{}," Cargo automatically treats every ",[39,132856,109654],{}," file directly inside ",[39,132859,132809],{}," as an independent test crate that depends on and links against your library crate exactly like an external consumer would — meaning it exercises only the public API, which is valuable for catching \"this only works because a test reaches into internals\" bugs. A is wrong about location and about access — putting a file in ",[39,132862,132799],{}," doesn't grant it the \"separate crate, public-API-only\" property that defines integration tests; that's purely a ",[39,132865,132809],{},"-directory behavior. C conflates two genuinely different testing layers Rust distinguishes on purpose. D misunderstands the mechanism — no manifest declaration is needed; Cargo's ",[39,132868,132809],{}," convention is filesystem-based and automatic.",[15,132871,132872,132879,132950,132988],{"language":111909},[18,132873,132875,132876,132878],{"id":132874},"q4-do-doctests-code-examples-in-documentation-comments-actually-get-executed","Q4. Do doctests (code examples in ",[39,132877,132688],{}," documentation comments) actually get executed?",[257,132880,132881],{"language":111909},[260,132882,132884],{"className":111918,"code":132883,"language":111909,"meta":264,"style":264},"\u002F\u002F\u002F Adds one to the given number.\n\u002F\u002F\u002F\n\u002F\u002F\u002F ```\n\u002F\u002F\u002F let x = my_crate::add_one(2);\n\u002F\u002F\u002F assert_eq!(x, 3);\n\u002F\u002F\u002F ```\npub fn add_one(x: i32) -> i32 {\n    x + 1\n}\n",[39,132885,132886,132891,132896,132901,132906,132911,132915,132938,132946],{"__ignoreMap":264},[268,132887,132888],{"class":270,"line":271},[268,132889,132890],{"class":29390},"\u002F\u002F\u002F Adds one to the given number.\n",[268,132892,132893],{"class":270,"line":286},[268,132894,132895],{"class":29390},"\u002F\u002F\u002F\n",[268,132897,132898],{"class":270,"line":296},[268,132899,132900],{"class":29390},"\u002F\u002F\u002F ```\n",[268,132902,132903],{"class":270,"line":311},[268,132904,132905],{"class":29390},"\u002F\u002F\u002F let x = my_crate::add_one(2);\n",[268,132907,132908],{"class":270,"line":788},[268,132909,132910],{"class":29390},"\u002F\u002F\u002F assert_eq!(x, 3);\n",[268,132912,132913],{"class":270,"line":1951},[268,132914,132900],{"class":29390},[268,132916,132917,132919,132921,132924,132926,132928,132930,132932,132934,132936],{"class":270,"line":8955},[268,132918,117577],{"class":274},[268,132920,37900],{"class":274},[268,132922,132923],{"class":278}," add_one",[268,132925,117178],{"class":282},[268,132927,10728],{"class":274},[268,132929,113794],{"class":278},[268,132931,6131],{"class":282},[268,132933,113308],{"class":274},[268,132935,113794],{"class":278},[268,132937,9914],{"class":282},[268,132939,132940,132942,132944],{"class":270,"line":8966},[268,132941,111947],{"class":282},[268,132943,1246],{"class":274},[268,132945,84787],{"class":305},[268,132947,132948],{"class":270,"line":8974},[268,132949,314],{"class":282},[23,132951,132953,132959,132970,132976],{"className":132952},[26],[28,132954,132956,132958],{"className":132955},[31],[33,132957],{"disabled":35,"type":36}," No — they're purely illustrative text, never compiled or run",[28,132960,132962,88213,132964,132966,132967,2690],{"className":132961},[31],[33,132963],{"disabled":35,"type":36},[39,132965,132629],{}," compiles and runs every fenced code block in a doc comment as its own test, unless the block is explicitly marked otherwise (e.g. ",[39,132968,132969],{},"```ignore",[28,132971,132973,132975],{"className":132972},[31],[33,132974],{"disabled":35,"type":36}," They're only checked for correct Markdown syntax, not compiled",[28,132977,132979,132981,132982,132985,132986],{"className":132978},[31],[33,132980],{"disabled":35,"type":36}," They run only when ",[39,132983,132984],{},"cargo doc"," is invoked, never during ",[39,132987,132629],{},[66,132989,132990,132992,133000],{},[69,132991,71],{},[73,132993,132994,88240,132996,132966,132998,2690],{},[76,132995,78],{},[39,132997,132629],{},[39,132999,132969],{},[73,133001,133002,133004,133005,133007,133008,133011,133012,133014,133015,133017,133018,133020,133021,99,133023,133026,133027,133029,133030,133032],{},[76,133003,84],{}," Doctests are real, executable tests: ",[39,133006,132629],{}," extracts each ",[39,133009,133010],{},"```"," fenced block from doc comments, wraps it in an implicit ",[39,133013,111197],{}," if needed, compiles it as its own tiny binary linked against the crate's public API, and runs it — an ",[39,133016,132729],{}," failure or panic inside one fails the test suite just like a ",[39,133019,129967],{}," function would. This is a genuine gotcha for newcomers who assume doc examples are \"just comments\" (option A) and are surprised when a stale example breaks CI. Fences can opt out with annotations like ",[39,133022,132969],{},[39,133024,133025],{},"```text"," (rules out the idea that all blocks always run unconditionally, though the default is that they do). It's not merely a syntax\u002Flint check (rules out C), and doctests run under ",[39,133028,132629],{},", independent of whether ",[39,133031,132984],{}," is ever invoked (rules out D).",[15,133034,133035,133044,133073],{},[18,133036,67628,133038,125910,133041,133043],{"id":133037},"q5-what-does-should_panic-do-when-applied-to-a-test-function",[39,133039,133040],{},"#[should_panic]",[39,133042,129967],{}," function?",[23,133045,133047,133053,133059,133065],{"className":133046},[26],[28,133048,133050,133052],{"className":133049},[31],[33,133051],{"disabled":35,"type":36}," It suppresses panic output so the test suite doesn't print a stack trace",[28,133054,133056,133058],{"className":133055},[31],[33,133057],{"disabled":35,"type":36}," It asserts the test function must panic for the test to be considered passing; if the function returns normally, the test fails",[28,133060,133062,133064],{"className":133061},[31],[33,133063],{"disabled":35,"type":36}," It marks the test as expected to fail and skips it",[28,133066,133068,133070,133071],{"className":133067},[31],[33,133069],{"disabled":35,"type":36}," It catches the panic and converts it into a ",[39,133072,115920],{},[66,133074,133075,133077,133082],{},[69,133076,71],{},[73,133078,133079,133081],{},[76,133080,78],{}," B — It asserts the test function must panic for the test to be considered passing; if the function returns normally, the test fails",[73,133083,133084,355,133086,133088,133089,133092,133093,133096,133097,133100,133101,133103,133104,133107],{},[76,133085,84],{},[39,133087,133040],{}," inverts the usual pass condition: the test harness runs the function expecting a panic, marks the test as passed if one occurs, and — importantly — marks it as ",[104,133090,133091],{},"failed"," if the function completes without panicking. It's commonly paired with ",[39,133094,133095],{},"expected = \"substring\""," to also verify the panic message matches, catching the case where the function panics for the wrong reason. It doesn't just silence output (rules out A) — panic details still print by default so you can see what happened. It's not the same as ",[39,133098,133099],{},"#[ignore]",", which actually skips a test rather than expecting a panic (rules out C). And it doesn't convert anything into ",[39,133102,110110],{}," — that's a different, non-panicking test convention (",[39,133105,133106],{},"fn test() -> Result\u003C(), String>",") entirely (rules out D).",[15,133109,133110,133116,133143],{},[18,133111,112464,133113,133115],{"id":133112},"q6-how-does-cargo-test-run-multiple-test-functions-by-default",[39,133114,132629],{}," run multiple test functions by default?",[23,133117,133119,133125,133131,133137],{"className":133118},[26],[28,133120,133122,133124],{"className":133121},[31],[33,133123],{"disabled":35,"type":36}," Sequentially, one at a time, in the order they appear in the source file",[28,133126,133128,133130],{"className":133127},[31],[33,133129],{"disabled":35,"type":36}," In parallel across multiple threads, so tests should not assume exclusive access to shared external state (files, env vars, ports) unless they coordinate",[28,133132,133134,133136],{"className":133133},[31],[33,133135],{"disabled":35,"type":36}," In a random, single-threaded order",[28,133138,133140,133142],{"className":133139},[31],[33,133141],{"disabled":35,"type":36}," All tests run in one shared thread but interleaved via async cooperative scheduling",[66,133144,133145,133147,133152],{},[69,133146,71],{},[73,133148,133149,133151],{},[76,133150,78],{}," B — In parallel across multiple threads, so tests should not assume exclusive access to shared external state (files, env vars, ports) unless they coordinate",[73,133153,133154,105011,133156,133158,133159,133161,133162,133165,133166,133169,133170,133172],{},[76,133155,84],{},[39,133157,132629],{}," spins up a thread pool and runs test functions concurrently for speed, which is exactly why tests that mutate shared global state (a file on disk, a process-wide environment variable, a fixed network port, a ",[39,133160,31581],{}," with interior mutability) can flake or corrupt each other unless they're made independent or explicitly serialized (e.g. ",[39,133163,133164],{},"--test-threads=1",", or a crate like ",[39,133167,133168],{},"serial_test","). This surprises people coming from test runners that default to sequential execution (option A). It's not randomized-but-single-threaded (rules out C), and it's plain OS-thread parallelism, not async scheduling (rules out D) — ",[39,133171,132629],{},"'s default harness has no async runtime involved.",[15,133174,133175,133181,133236,133272],{"language":111909},[18,133176,133178,133179,1685],{"id":133177},"q7-what-is-the-simplest-way-to-check-that-a-function-returns-the-expected-value-in-a-test","Q7. What is the simplest way to check that a function returns the expected value in a ",[39,133180,129967],{},[257,133182,133183],{"language":111909},[260,133184,133186],{"className":111918,"code":133185,"language":111909,"meta":264,"style":264},"#[test]\nfn parses_valid_input() {\n    let result = parse(\"42\");\n    assert_eq!(result, Ok(42));\n}\n",[39,133187,133188,133192,133201,133217,133232],{"__ignoreMap":264},[268,133189,133190],{"class":270,"line":271},[268,133191,132577],{"class":282},[268,133193,133194,133196,133199],{"class":270,"line":286},[268,133195,37837],{"class":274},[268,133197,133198],{"class":278}," parses_valid_input",[268,133200,283],{"class":282},[268,133202,133203,133205,133207,133209,133211,133213,133215],{"class":270,"line":296},[268,133204,80826],{"class":274},[268,133206,10881],{"class":282},[268,133208,302],{"class":274},[268,133210,118179],{"class":278},[268,133212,622],{"class":282},[268,133214,6960],{"class":289},[268,133216,628],{"class":282},[268,133218,133219,133221,133224,133226,133228,133230],{"class":270,"line":311},[268,133220,132591],{"class":278},[268,133222,133223],{"class":282},"(result, ",[268,133225,120129],{"class":278},[268,133227,622],{"class":282},[268,133229,4659],{"class":305},[268,133231,4818],{"class":282},[268,133233,133234],{"class":270,"line":788},[268,133235,314],{"class":282},[23,133237,133239,133247,133255,133264],{"className":133238},[26],[28,133240,133242,355,133244,133246],{"className":133241},[31],[33,133243],{"disabled":35,"type":36},[39,133245,132729],{},", which panics (failing the test) with a diff of the left and right values if they aren't equal",[28,133248,133250,355,133252,133254],{"className":133249},[31],[33,133251],{"disabled":35,"type":36},[39,133253,118575],{},", since printed output alone fails the test if incorrect",[28,133256,133258,355,133260,133263],{"className":133257},[31],[33,133259],{"disabled":35,"type":36},[39,133261,133262],{},"if result != Ok(42) { return; }",", which cargo interprets as a failure",[28,133265,133267,355,133269,133271],{"className":133266},[31],[33,133268],{"disabled":35,"type":36},[39,133270,129967],{}," functions cannot assert on return values, only on side effects",[66,133273,133274,133276,133282],{},[69,133275,71],{},[73,133277,133278,3459,133280,133246],{},[76,133279,78],{},[39,133281,132729],{},[73,133283,133284,133286,133287,133289,133290,5789,133292,446,133294,446,133297,133300,133301,133303,133304,133306,133307,133309,133310,133312],{},[76,133285,84],{}," The test harness considers a test failed if the function panics (or, for the ",[39,133288,110110],{},"-returning test convention, if it returns ",[39,133291,116301],{},[39,133293,132729],{},[39,133295,133296],{},"assert_ne!",[39,133298,133299],{},"assert!"," are macros that panic with a helpful message (showing both compared values for ",[39,133302,132729],{},") when the condition doesn't hold, which is exactly what drives pass\u002Ffail. ",[39,133305,118575],{}," output alone is inert — the harness doesn't parse printed text to decide pass\u002Ffail, it only reacts to a panic or early ",[39,133308,116301],{}," (rules out B). Silently ",[39,133311,9151],{},"-ing early does not signal failure to the harness at all — the test would report as passed (rules out C), which is itself a subtle pitfall to watch for in hand-rolled test logic. Return-value assertions are the most common thing tests do; nothing prevents it (rules out D).",[15,133314,133315,133321,133341,133383],{"language":111909},[18,133316,10249,133318,133320],{"id":133317},"q8-what-happens-when-a-test-function-is-empty-no-assertions-no-panics-just-an-empty-body",[39,133319,129967],{}," function is empty (no assertions, no panics, just an empty body)?",[257,133322,133323],{"language":111909},[260,133324,133326],{"className":111918,"code":133325,"language":111909,"meta":264,"style":264},"#[test]\nfn todo_write_this_test() {}\n",[39,133327,133328,133332],{"__ignoreMap":264},[268,133329,133330],{"class":270,"line":271},[268,133331,132577],{"class":282},[268,133333,133334,133336,133339],{"class":270,"line":286},[268,133335,37837],{"class":274},[268,133337,133338],{"class":278}," todo_write_this_test",[268,133340,3682],{"class":282},[23,133342,133344,133352,133361,133371],{"className":133343},[26],[28,133345,133347,355,133349,133351],{"className":133346},[31],[33,133348],{"disabled":35,"type":36},[39,133350,132629],{}," fails it, requiring at least one assertion",[28,133353,133355,133357,133358,133360],{"className":133354},[31],[33,133356],{"disabled":35,"type":36}," It reports as passing — an empty function neither panics nor returns ",[39,133359,116301],{},", so the harness has no reason to consider it failed, even though it verifies nothing",[28,133362,133364,129691,133366,133368,133369],{"className":133363},[31],[33,133365],{"disabled":35,"type":36},[39,133367,129967],{}," functions must contain at least one ",[39,133370,133299],{},[28,133372,133374,355,133376,133378,133379,133382],{"className":133373},[31],[33,133375],{"disabled":35,"type":36},[39,133377,132629],{}," marks it ",[39,133380,133381],{},"ignored"," automatically since it does nothing",[66,133384,133385,133387,133394],{},[69,133386,71],{},[73,133388,133389,133391,133392,133360],{},[76,133390,78],{}," B — It reports as passing — an empty function neither panics nor returns ",[39,133393,116301],{},[73,133395,133396,133398,133399,133401,133402,133404,133405,133407],{},[76,133397,84],{}," The test harness's pass criterion is purely \"did this function panic or return ",[39,133400,116301],{},"\" — it has no concept of \"did this test actually check anything.\" A stub test left behind as a TODO will happily report green forever, which is a genuine production trap: a passing test suite can hide untested code paths behind empty or assertion-less test functions. Nothing in the language or ",[39,133403,132629],{}," enforces a minimum number of assertions (rules out A and C — there's no such compile-time requirement). ",[39,133406,133099],{}," is an explicit, separate opt-out attribute a developer must add themselves; it is never inferred from an empty body (rules out D).",[15,133409,133410,133421,133452],{},[18,133411,133413,133414,133417,133418,133420],{"id":133412},"q9-two-tests-both-write-to-the-same-hardcoded-file-path-tmpoutputtxt-then-assert-on-its-contents-running-cargo-test-default-parallel-execution-shows-intermittent-non-deterministic-failures-why","Q9. Two tests both write to the same hardcoded file path, ",[39,133415,133416],{},"\u002Ftmp\u002Foutput.txt",", then assert on its contents. Running ",[39,133419,132629],{}," (default parallel execution) shows intermittent, non-deterministic failures. Why?",[23,133422,133424,133432,133438,133444],{"className":133423},[26],[28,133425,133427,355,133429,133431],{"className":133426},[31],[33,133428],{"disabled":35,"type":36},[39,133430,132629],{}," corrupts the filesystem when run in parallel",[28,133433,133435,133437],{"className":133434},[31],[33,133436],{"disabled":35,"type":36}," The two tests race on the shared file — running concurrently on different threads, one test's write can interleave with or overwrite the other's before its own assertion reads the file back",[28,133439,133441,133443],{"className":133440},[31],[33,133442],{"disabled":35,"type":36}," Rust's file I\u002FO is not thread-safe at the language level, causing undefined behavior",[28,133445,133447,355,133449,133451],{"className":133446},[31],[33,133448],{"disabled":35,"type":36},[39,133450,132729],{}," is not reentrant across threads",[66,133453,133454,133456,133461],{},[69,133455,71],{},[73,133457,133458,133460],{},[76,133459,78],{}," B — The two tests race on the shared file — running concurrently on different threads, one test's write can interleave with or overwrite the other's before its own assertion reads the file back",[73,133462,133463,133465,133466,133468,133469,133471,133472,133475,133476,99,133478,20968,133481,133483,133484,133487,133488,133491,133492,133494],{},[76,133464,84],{}," This is the canonical test-isolation pitfall: tests are expected to be independent, but a hardcoded shared resource (a fixed file path, a fixed port, a shared env var, a ",[39,133467,31581],{}," counter) breaks that independence, and default parallel test execution turns the resulting race into a flaky, order-dependent failure that's hard to reproduce. ",[76,133470,16523],{},": fixes include giving each test a unique temp path (e.g. via ",[39,133473,133474],{},"tempfile"," or a name derived from the test), serializing the offending tests (",[39,133477,133164],{},[39,133479,133480],{},"#[serial]",[39,133482,133168],{},"), or restructuring the test to avoid shared mutable external state entirely. Filesystem operations themselves aren't corrupted by concurrency at the OS level (rules out A); this isn't a language-level data race or UB — ",[39,133485,133486],{},"std::fs"," calls are ordinary syscalls, safe to call from multiple threads, they just aren't automatically ",[104,133489,133490],{},"coordinated"," for you (rules out C); and ",[39,133493,132729],{}," is a plain macro with no reentrancy concept — the race is entirely in the shared file, not in the assertion (rules out D).",[15,133496,133497,133503,133542],{},[18,133498,103121,133500,133502],{"id":133499},"q10-what-does-ignore-do-on-a-test-function-and-how-do-you-run-ignored-tests",[39,133501,133099],{}," do on a test function, and how do you run ignored tests?",[23,133504,133506,133514,133526,133534],{"className":133505},[26],[28,133507,133509,133511,133512],{"className":133508},[31],[33,133510],{"disabled":35,"type":36}," It permanently disables the test; there is no way to run it via ",[39,133513,132629],{},[28,133515,133517,133519,133520,133522,133523],{"className":133516},[31],[33,133518],{"disabled":35,"type":36}," It excludes the test from the default ",[39,133521,132629],{}," run, but it can still be run explicitly with ",[39,133524,133525],{},"cargo test -- --ignored",[28,133527,133529,133531,133532,35800],{"className":133528},[31],[33,133530],{"disabled":35,"type":36}," It's identical to deleting the ",[39,133533,129967],{},[28,133535,133537,133539,133540],{"className":133536},[31],[33,133538],{"disabled":35,"type":36}," It marks the test as expected to fail, similar to ",[39,133541,133040],{},[66,133543,133544,133546,133555],{},[69,133545,71],{},[73,133547,133548,133550,133551,133522,133553],{},[76,133549,78],{}," B — It excludes the test from the default ",[39,133552,132629],{},[39,133554,133525],{},[73,133556,133557,355,133559,133561,133562,133564,133565,7255,133567,133570,133571,133573,133574,133576],{},[76,133558,84],{},[39,133560,133099],{}," is meant for tests that are valid but too slow, environment-dependent, or otherwise unsuitable to run on every default ",[39,133563,132629],{}," invocation (e.g. tests that hit a real network service); they're skipped by default but remain runnable on demand via ",[39,133566,133525],{},[39,133568,133569],{},"--include-ignored"," to run everything). It's not a permanent disable (rules out A) and not equivalent to removing ",[39,133572,129967],{}," entirely, since the function is still recognized and reported as \"ignored\" rather than simply not existing as a test (rules out C). It has nothing to do with expecting a panic — that's ",[39,133575,133040],{},"'s job, and the two attributes address unrelated concerns (rules out D).",[15,133578,133579,133589,133642],{},[18,133580,133582,133583,112022,133586,133588],{"id":133581},"q11-a-test-function-is-written-as-fn-returns_config-result-string-without-should_panic-what-determines-whether-this-test-passes","Q11. A test function is written as ",[39,133584,133585],{},"fn returns_config() -> Result\u003C(), String> { ... }",[39,133587,133040],{},". What determines whether this test passes?",[23,133590,133592,133603,133624,133633],{"className":133591},[26],[28,133593,133595,133597,133598,133600,133601],{"className":133594},[31],[33,133596],{"disabled":35,"type":36}," It never passes, because ",[39,133599,129967],{}," functions must return ",[39,133602,16952],{},[28,133604,133606,133608,133609,133612,133613,133616,133617,133619,133620,133623],{"className":133605},[31],[33,133607],{"disabled":35,"type":36}," The harness treats ",[39,133610,133611],{},"Ok(())"," as pass and ",[39,133614,133615],{},"Err(_)"," as fail, letting the test use ",[39,133618,1685],{}," to propagate errors instead of ",[39,133621,133622],{},"unwrap()","-triggered panics",[28,133625,133627,133629,133630,133632],{"className":133626},[31],[33,133628],{"disabled":35,"type":36}," Only the presence of the ",[39,133631,129967],{}," attribute matters; the return type is ignored",[28,133634,133636,133638,133639,133641],{"className":133635},[31],[33,133637],{"disabled":35,"type":36}," It always fails at compile time because ",[39,133640,110110],{}," cannot appear in test signatures",[66,133643,133644,133646,133659],{},[69,133645,71],{},[73,133647,133648,133650,133651,133612,133653,133616,133655,133619,133657,133623],{},[76,133649,78],{}," B — The harness treats ",[39,133652,133611],{},[39,133654,133615],{},[39,133656,1685],{},[39,133658,133622],{},[73,133660,133661,133663,133664,133666,133667,133670,133671,7501,133674,133677,133678,133680,133681,133683,133684,3277,133686,133688],{},[76,133662,84],{}," Since Rust 2018, ",[39,133665,129967],{}," functions may return any type implementing ",[39,133668,133669],{},"std::process::Termination",", most commonly ",[39,133672,133673],{},"Result\u003C(), E>",[39,133675,133676],{},"E: Debug"," — this lets test bodies use ",[39,133679,1685],{}," on fallible operations and get a clean ",[39,133682,116301],{}," printout on failure instead of a panic from ",[39,133685,110107],{},[39,133687,16952],{},"-returning tests are still the common case, but they aren't the only option (rules out A and D, both of which describe restrictions that don't exist). The return type is very much inspected by the harness to decide pass\u002Ffail — it isn't ignored (rules out C).",[15,133690,133691,133698,133732],{},[18,133692,133694,133695,133697],{"id":133693},"q12-what-happens-to-output-from-println-inside-a-passing-test-by-default","Q12. What happens to output from ",[39,133696,118575],{}," inside a passing test, by default?",[23,133699,133701,133707,133715,133721],{"className":133700},[26],[28,133702,133704,133706],{"className":133703},[31],[33,133705],{"disabled":35,"type":36}," It always prints immediately to the terminal",[28,133708,133710,133712,133713,109209],{"className":133709},[31],[33,133711],{"disabled":35,"type":36}," The test harness captures (suppresses) stdout for passing tests by default; it's only shown for tests that fail, unless ",[39,133714,132776],{},[28,133716,133718,133720],{"className":133717},[31],[33,133719],{"disabled":35,"type":36}," It's written to a log file instead of the terminal",[28,133722,133724,355,133726,133728,133729,133731],{"className":133723},[31],[33,133725],{"disabled":35,"type":36},[39,133727,118575],{}," cannot be used inside ",[39,133730,129967],{}," functions at all",[66,133733,133734,133736,133743],{},[69,133735,71],{},[73,133737,133738,133740,133741,109209],{},[76,133739,78],{}," B — The test harness captures (suppresses) stdout for passing tests by default; it's only shown for tests that fail, unless ",[39,133742,132776],{},[73,133744,133745,133747,133748,133750,133751,133753,133754,133757,133758,133760],{},[76,133746,84],{}," By default ",[39,133749,132629],{}," captures each test's stdout\u002Fstderr and only surfaces it for tests that fail, keeping a clean summary for a large, mostly-passing suite; debugging with stray ",[39,133752,118575],{},"s that never appear is a common early confusion (assumption A). Passing ",[39,133755,133756],{},"cargo test -- --nocapture"," disables this capturing so all output streams live regardless of pass\u002Ffail. There's no log-file redirection involved (rules out C), and ",[39,133759,118575],{}," works perfectly fine inside tests — it's simply capture behavior, not a restriction on the macro itself (rules out D).",[15,133762,133763,133773,133813],{},[18,133764,133766,133767,133769,133770,133772],{"id":133765},"q13-a-unit-test-module-does-use-super-to-access-the-parent-modules-private-items-why-does-this-work-even-though-those-items-have-no-pub-modifier","Q13. A unit test module does ",[39,133768,131346],{}," to access the parent module's private items. Why does this work even though those items have no ",[39,133771,117577],{}," modifier?",[23,133774,133776,133786,133797,133805],{"className":133775},[26],[28,133777,133779,355,133781,133783,133784],{"className":133778},[31],[33,133780],{"disabled":35,"type":36},[39,133782,132700],{}," implicitly makes every item in the crate ",[39,133785,117577],{},[28,133787,133789,4396,133791,133793,133794,133796],{"className":133788},[31],[33,133790],{"disabled":35,"type":36},[39,133792,131342],{}," submodule is a ",[104,133795,66161],{}," of the module it's testing, and Rust's privacy rule makes a module's private items visible to all of its descendants — the test module included",[28,133798,133800,355,133802,133804],{"className":133799},[31],[33,133801],{"disabled":35,"type":36},[39,133803,131346],{}," bypasses privacy checks as a special case for testing",[28,133806,133808,133810,133811],{"className":133807},[31],[33,133809],{"disabled":35,"type":36}," It only works if every tested item is additionally marked ",[39,133812,130738],{},[66,133814,133815,133817,133825],{},[69,133816,71],{},[73,133818,133819,57091,133821,133793,133823,133796],{},[76,133820,78],{},[39,133822,131342],{},[104,133824,66161],{},[73,133826,133827,133829,133830,133832,133833,133835,133836,355,133839,133841,133842,133844,133845,133847,133848,133850,133851,133853],{},[76,133828,84],{}," This is the same general privacy rule covered for modules generally: a private item is visible in its defining module and every module nested inside it, and ",[39,133831,132704],{}," declared inside the module under test is exactly such a descendant — so ",[39,133834,131346],{}," can name and call private functions without any special-case testing behavior. This is precisely why unit tests conventionally live in a ",[39,133837,133838],{},"#[cfg(test)] mod tests",[104,133840,48842],{}," the same file as the code, while integration tests in ",[39,133843,132809],{}," (a separate crate) deliberately cannot see private items — different levels of the module tree, different visibility outcomes. ",[39,133846,132700],{}," only controls conditional compilation, not privacy (rules out A). There's no special glob-import privacy bypass (rules out C); ",[39,133849,108694],{}," never overrides visibility, it can only bring already-visible items into scope. And no extra ",[39,133852,130738],{}," is required — plain private is already sufficient for a descendant module (rules out D).",[15,133855,133856,133875,133920],{},[18,133857,133859,133860,133862,133863,133866,133867,358,133870,46957,133872,133874],{"id":133858},"q14-in-an-integration-test-file-under-tests-why-does-use-my_crateinternal_helper-fail-to-compile-if-internal_helper-is-a-pubcrate-not-pub-function-in-the-library","Q14. In an integration test file under ",[39,133861,132809],{},", why does ",[39,133864,133865],{},"use my_crate::internal_helper;"," fail to compile if ",[39,133868,133869],{},"internal_helper",[39,133871,130738],{},[39,133873,117577],{},") function in the library?",[23,133876,133878,133889,133901,133909],{"className":133877},[26],[28,133879,133881,355,133883,133885,133886,133888],{"className":133880},[31],[33,133882],{"disabled":35,"type":36},[39,133884,132809],{}," files cannot use ",[39,133887,108694],{}," statements at all",[28,133890,133892,133894,133895,133897,133898,133900],{"className":133891},[31],[33,133893],{"disabled":35,"type":36}," Each file in ",[39,133896,132809],{}," is compiled as an entirely separate crate consuming the library through its public API only; ",[39,133899,130738],{}," explicitly excludes visibility outside the defining crate, and the integration test is, from the compiler's perspective, a different crate",[28,133902,133904,355,133906,133908],{"className":133903},[31],[33,133905],{"disabled":35,"type":36},[39,133907,130738],{}," items are visible to integration tests but not unit tests",[28,133910,133912,133914,133915,186,133917,133919],{"className":133911},[31],[33,133913],{"disabled":35,"type":36}," It's a typo-only issue; ",[39,133916,130738],{},[39,133918,117577],{}," are otherwise identical",[66,133921,133922,133924,133933],{},[69,133923,71],{},[73,133925,133926,133928,133929,133897,133931,133900],{},[76,133927,78],{}," B — Each file in ",[39,133930,132809],{},[39,133932,130738],{},[73,133934,133935,133937,133938,133940,133941,133943,133944,133946,133947,133949,133950,133952,133953,133956,133957,186,133959,133961],{},[76,133936,84],{}," This directly follows from how ",[39,133939,132809],{}," is set up (Q3): each file there is its own crate linked against the library the way any external consumer would be, so it is bound by the same rules any other downstream crate faces — ",[39,133942,130738],{}," items are, by definition, invisible past the crate boundary. This is actually a ",[104,133945,70681],{},": it forces integration tests to exercise the same API surface real users get, catching \"only works via internals\" bugs. ",[39,133948,108694],{}," is completely normal and necessary in ",[39,133951,132809],{}," files (rules out A). Visibility rules aren't different for integration vs. unit tests as a special case — it's a direct consequence of crate boundaries, and it's the reverse of C (integration tests see ",[104,133954,133955],{},"less",", not more, than unit tests). ",[39,133958,130738],{},[39,133960,117577],{}," differ precisely in this cross-crate reachability, which is the whole point, not a typo (rules out D).",[15,133963,133964,133968,134005],{},[18,133965,133967],{"id":133966},"q15-whats-the-idiomatic-way-to-organize-tests-that-need-expensive-shared-setup-eg-spinning-up-an-in-memory-database-without-letting-one-tests-mutations-leak-into-anothers-results","Q15. What's the idiomatic way to organize tests that need expensive shared setup (e.g., spinning up an in-memory database) without letting one test's mutations leak into another's results?",[23,133969,133971,133980,133986,133995],{"className":133970},[26],[28,133972,133974,133976,133977,133979],{"className":133973},[31],[33,133975],{"disabled":35,"type":36}," Use a single ",[39,133978,112559],{}," database instance shared by all tests for efficiency",[28,133981,133983,133985],{"className":133982},[31],[33,133984],{"disabled":35,"type":36}," Have each test construct its own fresh, independent instance of the resource (or reset state at the start of each test), so tests remain independent even when run in parallel",[28,133987,133989,133991,133992,133994],{"className":133988},[31],[33,133990],{"disabled":35,"type":36}," Force all tests to run with ",[39,133993,133164],{}," permanently as the default workaround",[28,133996,133998,134000,134001,134004],{"className":133997},[31],[33,133999],{"disabled":35,"type":36}," Put all setup logic in ",[39,134002,134003],{},"#[test] fn setup()"," and rely on test execution order to run it first",[66,134006,134007,134009,134014],{},[69,134008,71],{},[73,134010,134011,134013],{},[76,134012,78],{}," B — Have each test construct its own fresh, independent instance of the resource (or reset state at the start of each test), so tests remain independent even when run in parallel",[73,134015,134016,355,134018,134020,134021,134023,134024,134026,134027,134029,134030,134032,134033,134036],{},[76,134017,84],{},[76,134019,17307],{},": the healthiest fix for shared-state flakiness is to make each test self-contained (its own in-memory DB instance, its own temp directory, its own fixture) rather than fighting the test runner's default concurrency — this keeps the suite fast and each test's failure meaningful in isolation. ",[39,134022,112559],{}," (A) is both a legacy ",[39,134025,112499],{},"-only construct and reintroduces exactly the shared-mutable-state race this question is about — it is not a fix. Forcing single-threaded execution everywhere (C) sacrifices the speed benefit of parallel tests project-wide just to paper over a design issue in a few tests. Relying on a test literally named\u002Fordered to run \"first\" (D) doesn't work — ",[39,134028,132629],{},"'s execution order isn't guaranteed or controllable that way, and treating a ",[39,134031,129967],{}," function as a setup hook is not a supported pattern (use a helper function called from each test, or a ",[39,134034,134035],{},"OnceLock","\u002Ffixture pattern instead).",[15,134038,134039,134043,134081],{},[18,134040,134042],{"id":134041},"q16-which-is-the-more-idiomatic-assertion-style-for-a-test-that-must-produce-a-clear-failure-message-when-comparing-two-computed-values","Q16. Which is the more idiomatic assertion style for a test that must produce a clear failure message when comparing two computed values?",[23,134044,134046,134054,134063,134071],{"className":134045},[26],[28,134047,134049,355,134051],{"className":134048},[31],[33,134050],{"disabled":35,"type":36},[39,134052,134053],{},"if a != b { panic!(\"failed\"); }",[28,134055,134057,355,134059,134062],{"className":134056},[31],[33,134058],{"disabled":35,"type":36},[39,134060,134061],{},"assert_eq!(a, b, \"computed value did not match expected for input {:?}\", input);"," — using the built-in comparison macro with an optional custom context message",[28,134064,134066,355,134068],{"className":134065},[31],[33,134067],{"disabled":35,"type":36},[39,134069,134070],{},"assert!(format!(\"{:?}\", a) == format!(\"{:?}\", b));",[28,134072,134074,134076,134077,134080],{"className":134073},[31],[33,134075],{"disabled":35,"type":36}," Silently allowing the test to continue if ",[39,134078,134079],{},"a != b",", and checking a log file afterward",[66,134082,134083,134085,134091],{},[69,134084,71],{},[73,134086,134087,1727,134089,134062],{},[76,134088,78],{},[39,134090,134061],{},[73,134092,134093,355,134095,1783,134097,446,134099,134101,134102,446,134104,134106,134107,134110,134111,134114,134115,186,134118,134120,134121,134123,134124,134126],{},[76,134094,84],{},[76,134096,17307],{},[39,134098,132729],{},[39,134100,133296],{}," are preferred over a hand-rolled ",[39,134103,2179],{},[39,134105,119025],{}," because they automatically print both compared values in a readable diff on failure, and they accept an optional trailing format string for extra context — combining both gives the clearest failure output with the least code. A hand-rolled ",[39,134108,134109],{},"panic!(\"failed\")"," (A) throws away the actual values that mismatched, making debugging a failure much harder. Comparing via ",[39,134112,134113],{},"format!(\"{:?}\", ...)"," string equality (C) is a needless workaround — it obscures the real values behind their debug-formatted strings and loses type-level comparison semantics (e.g. it would consider ",[39,134116,134117],{},"-0.0",[39,134119,124403],{}," different if their ",[39,134122,16523],{}," output differs, or ",[39,134125,3040],{}," cases mismatch bizarrely). Silently continuing on a mismatch (D) defeats the entire purpose of a test.",[15,134128,134129,134133,134167],{},[18,134130,134132],{"id":134131},"q17-why-is-it-generally-considered-best-practice-for-unit-tests-to-avoid-depending-on-wall-clock-time-or-real-network-calls","Q17. Why is it generally considered best practice for unit tests to avoid depending on wall-clock time or real network calls?",[23,134134,134136,134144,134150,134161],{"className":134135},[26],[28,134137,134139,134141,134142],{"className":134138},[31],[33,134140],{"disabled":35,"type":36}," Rust's test harness physically disallows network access during ",[39,134143,132629],{},[28,134145,134147,134149],{"className":134146},[31],[33,134148],{"disabled":35,"type":36}," Such dependencies make tests slow, flaky (affected by network conditions, clock skew, timing races), and non-reproducible across environments and CI runs — prefer injecting a fake clock\u002Fmock service or testing pure logic separately from I\u002FO",[28,134151,134153,355,134155,134157,134158,8705],{"className":134152},[31],[33,134154],{"disabled":35,"type":36},[39,134156,132729],{}," cannot compare ",[39,134159,134160],{},"std::time::Instant",[28,134162,134164,134166],{"className":134163},[31],[33,134165],{"disabled":35,"type":36}," Only integration tests are allowed to perform I\u002FO; unit tests are compiled without network access",[66,134168,134169,134171,134176],{},[69,134170,71],{},[73,134172,134173,134175],{},[76,134174,78],{}," B — Such dependencies make tests slow, flaky (affected by network conditions, clock skew, timing races), and non-reproducible across environments and CI runs — prefer injecting a fake clock\u002Fmock service or testing pure logic separately from I\u002FO",[73,134177,134178,355,134180,134182,134183,134185,134186,134188,134189,134192,134193,134196],{},[76,134179,84],{},[76,134181,17307],{},": tests that reach out over the real network or depend on precise timing are a leading cause of CI flakiness — a temporary DNS blip, a slow CI runner, or a shared clock jitter can fail a test that has nothing wrong with the code under test. The standard fix is dependency injection (pass in a trait object or fake clock\u002Fservice implementation for tests) so the logic under test is deterministic, with any real I\u002FO covered separately by a smaller number of integration tests that explicitly accept that cost. There is no language- or harness-level network block during ",[39,134184,132629],{}," (rules out A and D — nothing stops a test from making a real HTTP call, which is exactly the problem). ",[39,134187,132729],{}," works on any ",[39,134190,134191],{},"PartialEq + Debug"," type including ",[39,134194,134195],{},"Instant"," (rules out C) — the issue isn't comparability, it's non-determinism.",[15,134198,134199,134214,134265],{},[18,134200,134202,134203,134205,134206,134208,134209,446,134211,134213],{"id":134201},"q18-what-is-a-common-pitfall-of-writing-test-functions-that-call-unwrap-liberally-on-resultoption-values-from-the-code-under-test","Q18. What is a common pitfall of writing ",[39,134204,129967],{}," functions that call ",[39,134207,110107],{}," liberally on ",[39,134210,110110],{},[39,134212,116852],{}," values from the code under test?",[23,134215,134217,134228,134251,134259],{"className":134216},[26],[28,134218,134220,355,134222,134224,134225,134227],{"className":134219},[31],[33,134221],{"disabled":35,"type":36},[39,134223,110107],{}," is banned inside ",[39,134226,129967],{}," functions by the compiler",[28,134229,134231,134233,134234,446,134236,134238,134239,106496,134242,134244,134245,134247,134248,134250],{"className":134230},[31],[33,134232],{"disabled":35,"type":36}," It works fine for surfacing failures as panics, but the failure message on an ",[39,134235,116301],{},[39,134237,90944],{}," can be uninformative compared to ",[39,134240,134241],{},"expect(\"context\")",[39,134243,110110],{},"-returning test with ",[39,134246,1685],{},", making it harder to diagnose ",[104,134249,127251],{}," a test failed from CI logs alone",[28,134252,134254,355,134256,134258],{"className":134253},[31],[33,134255],{"disabled":35,"type":36},[39,134257,110107],{}," silently converts errors into passing tests",[28,134260,134262,134264],{"className":134261},[31],[33,134263],{"disabled":35,"type":36}," It causes tests to run in a different thread than normal",[66,134266,134267,134269,134286],{},[69,134268,71],{},[73,134270,134271,134273,134274,446,134276,134238,134278,106496,134280,134244,134282,134247,134284,134250],{},[76,134272,78],{}," B — It works fine for surfacing failures as panics, but the failure message on an ",[39,134275,116301],{},[39,134277,90944],{},[39,134279,134241],{},[39,134281,110110],{},[39,134283,1685],{},[104,134285,127251],{},[73,134287,134288,355,134290,1783,134292,134294,134295,19286,134298,134301,134302,2029,134305,134307,134308,134310],{},[76,134289,84],{},[76,134291,17307],{},[39,134293,110107],{}," does correctly fail the test (any panic fails it), but its default panic message is generic (",[39,134296,134297],{},"called Result::unwrap() on an Err value: ...",[39,134299,134300],{},".expect(\"parsing config from valid TOML should not fail\")"," or restructuring the test as ",[39,134303,134304],{},"fn test() -> Result\u003C(), Error> { ...; Ok(()) }",[39,134306,1685],{}," gives future-you (or a teammate reading a CI log at 2am) immediate context about which operation failed and why, without needing to reproduce locally. ",[39,134309,110107],{}," is not disallowed anywhere in tests (rules out A), it does not swallow errors into a false pass — quite the opposite, it panics loudly (rules out C) — and it has no effect on which thread a test runs on (rules out D).",[15,134312,134313,134326,134358],{},[18,134314,134316,134317,134319,134320,134322,134323,134325],{"id":134315},"q19-why-do-many-real-world-rust-projects-prefer-to-keep-expensive-environment-dependent-integration-tests-separate-from-fast-unit-tests-eg-via-ignore-feature-flags-or-separate-tests-binaries-rather-than-mixing-everything-into-one-cargo-test-run","Q19. Why do many real-world Rust projects prefer to keep expensive, environment-dependent integration tests separate from fast unit tests (e.g., via ",[39,134318,133099],{},", feature flags, or separate ",[39,134321,132809],{}," binaries), rather than mixing everything into one ",[39,134324,132629],{}," run?",[23,134327,134329,134335,134344,134352],{"className":134328},[26],[28,134330,134332,134334],{"className":134331},[31],[33,134333],{"disabled":35,"type":36}," cargo physically cannot compile more than one kind of test in the same crate",[28,134336,134338,134340,134341,134343],{"className":134337},[31],[33,134339],{"disabled":35,"type":36}," Keeping the default ",[39,134342,132629],{}," run fast and hermetic encourages developers to actually run it constantly (tight feedback loop), while slower\u002Fenvironment-dependent tests are opted into explicitly (e.g., in a scheduled CI job) rather than punishing every local test run",[28,134345,134347,355,134349,134351],{"className":134346},[31],[33,134348],{"disabled":35,"type":36},[39,134350,133099],{}," is required by the compiler for any test that takes longer than one second",[28,134353,134355,134357],{"className":134354},[31],[33,134356],{"disabled":35,"type":36}," Mixing test types causes silent data corruption in the test binary",[66,134359,134360,134362,134369],{},[69,134361,71],{},[73,134363,134364,134366,134367,134343],{},[76,134365,78],{}," B — Keeping the default ",[39,134368,132629],{},[73,134370,134371,355,134373,134375,134376,134378,134379,134381,134382,134384],{},[76,134372,84],{},[76,134374,17307],{},": a test suite that takes 30 seconds because of a handful of slow, flaky, or environment-coupled tests trains developers to stop running it locally, which defeats the entire purpose of fast feedback — separating \"always run this\" from \"run this in CI or on demand\" (via ",[39,134377,133099],{},", a Cargo feature flag, or a distinct ",[39,134380,132809],{}," binary invoked separately) keeps the fast path fast without deleting valuable slower coverage. This is a process\u002Fworkflow best practice, not a compiler limitation — nothing stops you from mixing test kinds in one crate (rules out A and D, neither of which describes any real constraint), and there's no enforced timing threshold that mandates ",[39,134383,133099],{}," — it's a judgment call developers make deliberately (rules out C).",[15,134386,134387,134394,134433],{},[18,134388,134390,134391,134393],{"id":134389},"q20-a-test-suite-has-one-slow-test-that-takes-45-seconds-due-to-a-large-fixture-buried-among-hundreds-of-millisecond-scale-unit-tests-and-it-isnt-marked-ignore-whats-the-idiomatic-fix-and-why-not-just-delete-the-slow-test","Q20. A test suite has one slow test that takes 45 seconds due to a large fixture, buried among hundreds of millisecond-scale unit tests, and it isn't marked ",[39,134392,133099],{},". What's the idiomatic fix, and why not just delete the slow test?",[23,134395,134397,134403,134415,134424],{"className":134396},[26],[28,134398,134400,134402],{"className":134399},[31],[33,134401],{"disabled":35,"type":36}," Delete it — a slow test is never worth keeping",[28,134404,134406,134408,134409,134411,134412,134414],{"className":134405},[31],[33,134407],{"disabled":35,"type":36}," Mark it ",[39,134410,133099],{}," (with a comment explaining why), or move it to a ",[39,134413,132809],{}," integration binary run separately in CI, so the fast default suite stays quick while the valuable coverage isn't lost — deleting it would remove real regression protection just to fix a workflow annoyance",[28,134416,134418,134420,134421,134423],{"className":134417},[31],[33,134419],{"disabled":35,"type":36}," Wrap its body in ",[39,134422,133040],{}," so it fails fast instead of running to completion",[28,134425,134427,134429,134430,134432],{"className":134426},[31],[33,134428],{"disabled":35,"type":36}," Rename the function so ",[39,134431,132629],{}," alphabetically runs it last",[66,134434,134435,134437,134446],{},[69,134436,71],{},[73,134438,134439,134441,134442,134411,134444,134414],{},[76,134440,78],{}," B — Mark it ",[39,134443,133099],{},[39,134445,132809],{},[73,134447,134448,355,134450,134452,134453,134456,134457,134459,134460,134462,134463,134465,134466,134468,134469,134471,134472,134474],{},[76,134449,84],{},[76,134451,17307],{},": the test itself may well be catching real bugs (large-input behavior, performance regressions, resource-heavy edge cases) — the actual problem is the ",[104,134454,134455],{},"default local workflow"," getting slower, not that the test lacks value. ",[39,134458,133099],{}," (paired with ",[39,134461,133525],{}," in a dedicated CI job or nightly run) or relocating it to its own ",[39,134464,132809],{}," binary that CI invokes on a different cadence both preserve the coverage while keeping the everyday ",[39,134467,132629],{}," loop fast. Deleting it outright (A) throws away a real regression check to solve what's really a scheduling\u002Fworkflow problem. ",[39,134470,133040],{}," (C) changes the test's pass condition to \"must panic,\" which is unrelated to speed and would be actively wrong if the test isn't supposed to panic. ",[39,134473,132629],{},"'s execution order isn't reliably alphabetical or otherwise developer-controlled, and even if it were, running last doesn't make a 45-second test any faster or less disruptive to the overall run time (rules out D).",[2107,134476,134477],{},"html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}",{"title":264,"searchDepth":286,"depth":286,"links":134479},[134480,134482,134484,134486,134488,134490,134492,134494,134496,134498,134500,134502,134504,134506,134508,134509,134510,134511,134513,134515],{"id":132561,"depth":296,"text":134481},"Q1. What does the #[test] attribute do?",{"id":132696,"depth":296,"text":134483},"Q2. Why is #[cfg(test)] commonly placed on a mod tests { ... } block containing unit tests?",{"id":132784,"depth":296,"text":134485},"Q3. Where do Rust integration tests live, and how do they differ from unit tests in src\u002F?",{"id":132874,"depth":296,"text":134487},"Q4. Do doctests (code examples in \u002F\u002F\u002F documentation comments) actually get executed?",{"id":133037,"depth":296,"text":134489},"Q5. What does #[should_panic] do when applied to a #[test] function?",{"id":133112,"depth":296,"text":134491},"Q6. How does cargo test run multiple test functions by default?",{"id":133177,"depth":296,"text":134493},"Q7. What is the simplest way to check that a function returns the expected value in a #[test]?",{"id":133317,"depth":296,"text":134495},"Q8. What happens when a #[test] function is empty (no assertions, no panics, just an empty body)?",{"id":133412,"depth":296,"text":134497},"Q9. Two tests both write to the same hardcoded file path, \u002Ftmp\u002Foutput.txt, then assert on its contents. Running cargo test (default parallel execution) shows intermittent, non-deterministic failures. Why?",{"id":133499,"depth":296,"text":134499},"Q10. What does #[ignore] do on a test function, and how do you run ignored tests?",{"id":133581,"depth":296,"text":134501},"Q11. A test function is written as fn returns_config() -> Result\u003C(), String> { ... } without #[should_panic]. What determines whether this test passes?",{"id":133693,"depth":296,"text":134503},"Q12. What happens to output from println! inside a passing test, by default?",{"id":133765,"depth":296,"text":134505},"Q13. A unit test module does use super::*; to access the parent module's private items. Why does this work even though those items have no pub modifier?",{"id":133858,"depth":296,"text":134507},"Q14. In an integration test file under tests\u002F, why does use my_crate::internal_helper; fail to compile if internal_helper is a pub(crate) (not pub) function in the library?",{"id":133966,"depth":296,"text":133967},{"id":134041,"depth":296,"text":134042},{"id":134131,"depth":296,"text":134132},{"id":134201,"depth":296,"text":134512},"Q18. What is a common pitfall of writing #[test] functions that call .unwrap() liberally on Result\u002FOption values from the code under test?",{"id":134315,"depth":296,"text":134514},"Q19. Why do many real-world Rust projects prefer to keep expensive, environment-dependent integration tests separate from fast unit tests (e.g., via #[ignore], feature flags, or separate tests\u002F binaries), rather than mixing everything into one cargo test run?",{"id":134389,"depth":296,"text":134516},"Q20. A test suite has one slow test that takes 45 seconds due to a large fixture, buried among hundreds of millisecond-scale unit tests, and it isn't marked #[ignore]. What's the idiomatic fix, and why not just delete the slow test?",{},"\u002Frust\u002F21-testing",{"title":132551,"description":264},"rust\u002F21-testing","HkvTJwK8shLAN5pqm9b-RjVxlNTESB7NxOHinBwDqug",{"id":134523,"title":134524,"body":134525,"description":264,"extension":2144,"meta":136619,"navigation":35,"path":136620,"seo":136621,"stem":136622,"__hash__":136623},"content\u002Frust\u002F28-cargo-features.md","28 — Cargo Features",{"type":8,"value":134526,"toc":136578},[134527,134530,134662,134755,134838,134977,135071,135216,135333,135401,135485,135581,135661,135768,135848,135964,136121,136183,136313,136402,136494,136575],[11,134528,134524],{"id":134529},"_28-cargo-features",[15,134531,134533,134543,134574,134622],{"language":134532},"toml",[18,134534,134536,134537,134540,134541,1685],{"id":134535},"q1-what-is-the-correct-way-to-declare-a-feature-named-logging-that-has-no-dependencies-of-its-own-in-cargotoml","Q1. What is the correct way to declare a feature named ",[39,134538,134539],{},"logging"," that has no dependencies of its own in ",[39,134542,108587],{},[257,134544,134545],{"language":134532},[260,134546,134549],{"className":134547,"code":134548,"language":134532,"meta":264,"style":264},"language-toml shiki shiki-themes github-light github-dark","[dependencies]\ntracing = { version = \"0.1\", optional = true }\n",[39,134550,134551,134559],{"__ignoreMap":264},[268,134552,134553,134555,134557],{"class":270,"line":271},[268,134554,15175],{"class":282},[268,134556,82698],{"class":278},[268,134558,89183],{"class":282},[268,134560,134561,134564,134567,134570,134572],{"class":270,"line":286},[268,134562,134563],{"class":282},"tracing = { version = ",[268,134565,134566],{"class":289},"\"0.1\"",[268,134568,134569],{"class":282},", optional = ",[268,134571,2185],{"class":305},[268,134573,29394],{"class":282},[23,134575,134577,134589,134600,134611],{"className":134576},[26],[28,134578,134580,355,134582,134585,134586],{"className":134579},[31],[33,134581],{"disabled":35,"type":36},[39,134583,134584],{},"[features]"," section with ",[39,134587,134588],{},"logging = []",[28,134590,134592,355,134594,2029,134597],{"className":134591},[31],[33,134593],{"disabled":35,"type":36},[39,134595,134596],{},"[dependencies.logging]",[39,134598,134599],{},"optional = true",[28,134601,134603,355,134605,134608,134609],{"className":134602},[31],[33,134604],{"disabled":35,"type":36},[39,134606,134607],{},"logging = true"," at the top level of ",[39,134610,108587],{},[28,134612,134614,355,134616,2029,134619],{"className":134613},[31],[33,134615],{"disabled":35,"type":36},[39,134617,134618],{},"[profile.logging]",[39,134620,134621],{},"enabled = true",[66,134623,134624,134626,134634],{},[69,134625,71],{},[73,134627,134628,3459,134630,134585,134632],{},[76,134629,78],{},[39,134631,134584],{},[39,134633,134588],{},[73,134635,134636,134638,134639,134641,134642,134645,134646,134649,134650,134652,134653,134655,134656,134659,134660,462],{},[76,134637,84],{}," Features are declared under a ",[39,134640,134584],{}," table as ",[39,134643,134644],{},"name = [list-of-other-features-or-optional-deps-to-enable]","; an empty list is valid for a \"marker\" feature used only in ",[39,134647,134648],{},"#[cfg(feature = \"logging\")]"," checks. ",[39,134651,134596],{}," is wrong because features aren't dependencies unless tied to an optional crate. ",[39,134654,134607],{}," at the top level isn't valid TOML for Cargo's schema. ",[39,134657,134658],{},"[profile.*]"," tables configure compilation profiles (opt-level, debug info), not feature flags — a common mix-up for newcomers scanning ",[39,134661,108587],{},[15,134663,134664,134674,134718],{},[18,134665,134667,134668,36284,134671,134673],{"id":134666},"q2-a-crate-declares-serde-version-1-optional-true-under-dependencies-what-happens-by-default","Q2. A crate declares ",[39,134669,134670],{},"serde = { version = \"1\", optional = true }",[39,134672,110765],{},". What happens by default?",[23,134675,134677,134686,134697,134709],{"className":134676},[26],[28,134678,134680,134682,134683,134685],{"className":134679},[31],[33,134681],{"disabled":35,"type":36}," Cargo implicitly creates a feature named ",[39,134684,110818],{}," that enables the dependency",[28,134687,134689,134691,134692,77794,134695],{"className":134688},[31],[33,134690],{"disabled":35,"type":36}," The dependency is compiled in unconditionally, ",[39,134693,134694],{},"optional",[39,134696,132984],{},[28,134698,134700,134702,134703,134705,134706,134708],{"className":134699},[31],[33,134701],{"disabled":35,"type":36}," The build fails until a matching ",[39,134704,134584],{}," entry named ",[39,134707,110818],{}," is added manually",[28,134710,134712,134714,134715,131223],{"className":134711},[31],[33,134713],{"disabled":35,"type":36}," The dependency is never compiled unless explicitly named in ",[39,134716,134717],{},"[build-dependencies]",[66,134719,134720,134722,134729],{},[69,134721,71],{},[73,134723,134724,134726,134727,134685],{},[76,134725,78],{}," A — Cargo implicitly creates a feature named ",[39,134728,110818],{},[73,134730,134731,134733,134734,134736,134737,134739,134740,134743,134744,134747,134748,134751,134752,134754],{},[76,134732,84],{}," Marking a dependency ",[39,134735,134599],{}," automatically creates an implicit feature of the same name; enabling that feature pulls in the crate. No manual ",[39,134738,134584],{}," entry is required (though on the 2021 edition you can opt into requiring the explicit ",[39,134741,134742],{},"dep:serde"," syntax to ",[104,134745,134746],{},"suppress"," that implicit feature — see the ",[39,134749,134750],{},"dep:"," question later in this quiz). It doesn't compile unconditionally, and it has nothing to do with ",[39,134753,134717],{},", which is a separate dependency graph for build scripts.",[15,134756,134757,134764,134799],{},[18,134758,134760,134761,134763],{"id":134759},"q3-which-flag-builds-a-crate-with-its-default-feature-set-disabled","Q3. Which flag builds a crate with its ",[39,134762,9046],{}," feature set disabled?",[23,134765,134767,134775,134783,134791],{"className":134766},[26],[28,134768,134770,355,134772],{"className":134769},[31],[33,134771],{"disabled":35,"type":36},[39,134773,134774],{},"cargo build --no-default-features",[28,134776,134778,355,134780],{"className":134777},[31],[33,134779],{"disabled":35,"type":36},[39,134781,134782],{},"cargo build --features=none",[28,134784,134786,355,134788],{"className":134785},[31],[33,134787],{"disabled":35,"type":36},[39,134789,134790],{},"cargo build --default-features=false",[28,134792,134794,355,134796],{"className":134793},[31],[33,134795],{"disabled":35,"type":36},[39,134797,134798],{},"cargo build --minimal",[66,134800,134801,134803,134809],{},[69,134802,71],{},[73,134804,134805,3459,134807],{},[76,134806,78],{},[39,134808,134774],{},[73,134810,134811,355,134813,134816,134817,134820,134821,3277,134824,134827,134828,134831,134832,137,134834,134837],{},[76,134812,84],{},[39,134814,134815],{},"--no-default-features"," opts out of whatever ",[39,134818,134819],{},"[features] default = [...]"," lists; you then opt back in to specific features with ",[39,134822,134823],{},"--features",[39,134825,134826],{},"--default-features=false"," is invalid CLI syntax (that phrasing only exists as a Cargo.toml dependency table key, not a top-level flag), ",[39,134829,134830],{},"--features=none"," just tries to enable a feature literally named ",[39,134833,50400],{},[39,134835,134836],{},"--minimal"," isn't a real Cargo flag.",[15,134839,134840,134846,134891,134941],{"language":134532},[18,134841,97054,134843,134845],{"id":134842},"q4-in-cargotoml-what-does-this-dependency-declaration-mean",[39,134844,108587],{},", what does this dependency declaration mean?",[257,134847,134848],{"language":134532},[260,134849,134851],{"className":134547,"code":134850,"language":134532,"meta":264,"style":264},"[dependencies.reqwest]\nversion = \"0.11\"\ndefault-features = false\nfeatures = [\"json\"]\n",[39,134852,134853,134866,134874,134881],{"__ignoreMap":264},[268,134854,134855,134857,134859,134861,134864],{"class":270,"line":271},[268,134856,15175],{"class":282},[268,134858,82698],{"class":278},[268,134860,462],{"class":282},[268,134862,134863],{"class":278},"reqwest",[268,134865,89183],{"class":282},[268,134867,134868,134871],{"class":270,"line":286},[268,134869,134870],{"class":282},"version = ",[268,134872,134873],{"class":289},"\"0.11\"\n",[268,134875,134876,134879],{"class":270,"line":296},[268,134877,134878],{"class":282},"default-features = ",[268,134880,82172],{"class":305},[268,134882,134883,134886,134889],{"class":270,"line":311},[268,134884,134885],{"class":282},"features = [",[268,134887,134888],{"class":289},"\"json\"",[268,134890,89183],{"class":282},[23,134892,134894,134906,134917,134928],{"className":134893},[26],[28,134895,134897,134899,134900,134902,134903,134905],{"className":134896},[31],[33,134898],{"disabled":35,"type":36}," Depend on ",[39,134901,134863],{}," with its own defaults disabled, enabling only the ",[39,134904,1751],{}," feature",[28,134907,134909,134899,134911,134913,134914,134916],{"className":134908},[31],[33,134910],{"disabled":35,"type":36},[39,134912,134863],{}," with all features enabled, then filter down to ",[39,134915,1751],{}," at link time",[28,134918,134920,355,134922,134925,134926],{"className":134919},[31],[33,134921],{"disabled":35,"type":36},[39,134923,134924],{},"default-features = false"," disables features for the whole workspace, not just ",[39,134927,134863],{},[28,134929,134931,134933,134934,186,134937,134940],{"className":134930},[31],[33,134932],{"disabled":35,"type":36}," This is a syntax error; ",[39,134935,134936],{},"features",[39,134938,134939],{},"default-features"," cannot appear together",[66,134942,134943,134945,134954],{},[69,134944,71],{},[73,134946,134947,134949,134950,134902,134952,134905],{},[76,134948,78],{}," A — Depend on ",[39,134951,134863],{},[39,134953,1751],{},[73,134955,134956,355,134958,5125,134960,134963,134964,134966,134967,355,134970,134972,134973,134976],{},[76,134957,84],{},[39,134959,134924],{},[104,134961,134962],{},"specific dependency entry"," opts that dependency out of its own ",[39,134965,9046],{}," feature set (defined in ",[104,134968,134969],{},"its",[39,134971,108587],{},"), scoped only to that dependency — it has no effect on the current crate's own features or the workspace. ",[39,134974,134975],{},"features = [\"json\"]"," then explicitly turns on just that one. The two keys commonly appear together and are not mutually exclusive; there's nothing resembling \"filtering at link time.\"",[15,134978,134979,135003,135038],{},[18,134980,134982,134983,111257,134985,2029,134988,134991,134992,134994,134995,2029,134997,134999,135000,135002],{"id":134981},"q5-crate-a-depends-on-net-lib-with-features-tls-crate-b-a-sibling-dependency-in-the-same-build-depends-on-net-lib-with-default-features-false-and-no-extra-features-both-end-up-in-the-same-final-binary-what-features-does-net-lib-actually-get-compiled-with","Q5. Crate ",[39,134984,47783],{},[39,134986,134987],{},"net-lib",[39,134989,134990],{},"features = [\"tls\"]",". Crate ",[39,134993,47807],{}," (a sibling dependency in the same build) depends on ",[39,134996,134987],{},[39,134998,134924],{}," and no extra features. Both end up in the same final binary. What features does ",[39,135001,134987],{}," actually get compiled with?",[23,135004,135006,135015,135024,135032],{"className":135005},[26],[28,135007,135009,50010,135011,135014],{"className":135008},[31],[33,135010],{"disabled":35,"type":36},[39,135012,135013],{},"tls"," — Cargo unifies to the union of all requested features across the graph",[28,135016,135018,135020,135021,135023],{"className":135017},[31],[33,135019],{"disabled":35,"type":36}," Neither — ",[39,135022,134924],{}," from B overrides A's request",[28,135025,135027,355,135029,135031],{"className":135026},[31],[33,135028],{"disabled":35,"type":36},[39,135030,134987],{}," is compiled twice, once per requested feature set",[28,135033,135035,135037],{"className":135034},[31],[33,135036],{"disabled":35,"type":36}," The build fails with a \"conflicting feature requirements\" error",[66,135039,135040,135042,135049],{},[69,135041,71],{},[73,135043,135044,135046,135047,135014],{},[76,135045,78],{}," A — Only ",[39,135048,135013],{},[73,135050,135051,355,135053,135056,135057,135060,135061,135063,135064,135066,135067,135070],{},[76,135052,84],{},[76,135054,135055],{},"Safety\u002FIdiom:"," Cargo compiles each version of a dependency exactly once per build graph, so it must reconcile every requester's feature request into a single set — it takes the ",[104,135058,135059],{},"union",". B's ",[39,135062,134924],{}," only says \"don't turn on ",[39,135065,134987],{},"'s own defaults ",[104,135068,135069],{},"for my request","\"; it can't retract a feature that A separately asked for. This is the classic \"feature unification\" footgun: you cannot rely on disabling defaults to shrink a dependency if any other crate in the graph re-enables them. There's no per-requester recompilation and no conflict error — features are required to be purely additive for exactly this reason.",[15,135072,135073,135084,135134,135176],{"language":134532},[18,135074,135076,135077,135080,135081,135083],{"id":135075},"q6-a-library-crate-wants-an-optional-dependency-regex-available-for-internal-use-but-does-not-want-a-public-feature-named-regex-to-appear-in-its-feature-list-to-avoid-it-being-confused-with-a-user-facing-toggle-which-mechanism-achieves-this","Q6. A library crate wants an optional dependency ",[39,135078,135079],{},"regex"," available for internal use, but does NOT want a public feature named ",[39,135082,135079],{}," to appear in its feature list (to avoid it being confused with a user-facing toggle). Which mechanism achieves this?",[257,135085,135086],{"language":134532},[260,135087,135089],{"className":134547,"code":135088,"language":134532,"meta":264,"style":264},"[dependencies]\nregex = { version = \"1\", optional = true }\n\n[features]\nsearch = [\"dep:regex\"]\n",[39,135090,135091,135099,135112,135116,135124],{"__ignoreMap":264},[268,135092,135093,135095,135097],{"class":270,"line":271},[268,135094,15175],{"class":282},[268,135096,82698],{"class":278},[268,135098,89183],{"class":282},[268,135100,135101,135104,135106,135108,135110],{"class":270,"line":286},[268,135102,135103],{"class":282},"regex = { version = ",[268,135105,3387],{"class":289},[268,135107,134569],{"class":282},[268,135109,2185],{"class":305},[268,135111,29394],{"class":282},[268,135113,135114],{"class":270,"line":296},[268,135115,5033],{"emptyLinePlaceholder":35},[268,135117,135118,135120,135122],{"class":270,"line":311},[268,135119,15175],{"class":282},[268,135121,134936],{"class":278},[268,135123,89183],{"class":282},[268,135125,135126,135129,135132],{"class":270,"line":788},[268,135127,135128],{"class":282},"search = [",[268,135130,135131],{"class":289},"\"dep:regex\"",[268,135133,89183],{"class":282},[23,135135,135137,135151,135161,135170],{"className":135136},[26],[28,135138,135140,4396,135142,135145,135146,135148,135149,134905],{"className":135139},[31],[33,135141],{"disabled":35,"type":36},[39,135143,135144],{},"dep:regex"," syntax in ",[39,135147,134584],{},", which suppresses the automatic implicit ",[39,135150,135079],{},[28,135152,135154,135156,135157,135160],{"className":135153},[31],[33,135155],{"disabled":35,"type":36}," Renaming the crate import with ",[39,135158,135159],{},"package = \"regex\""," under a different key",[28,135162,135164,135166,135167],{"className":135163},[31],[33,135165],{"disabled":35,"type":36}," Marking the dependency ",[39,135168,135169],{},"optional = true, hidden = true",[28,135171,135173,135175],{"className":135172},[31],[33,135174],{"disabled":35,"type":36}," There is no way to do this; every optional dependency always gets a public feature",[66,135177,135178,135180,135190],{},[69,135179,71],{},[73,135181,135182,43363,135184,135145,135186,135148,135188,134905],{},[76,135183,78],{},[39,135185,135144],{},[39,135187,134584],{},[39,135189,135079],{},[73,135191,135192,135194,135195,135197,135198,135200,135201,135204,135205,135208,135209,135212,135213,135215],{},[76,135193,84],{}," Since the 2021 edition's feature resolver, referencing an optional dependency as ",[39,135196,135144],{}," inside any ",[39,135199,134584],{}," entry suppresses the automatic implicit feature of the same name, letting you expose only ",[39,135202,135203],{},"search"," publicly while still gating the dependency internally. ",[39,135206,135207],{},"hidden = true"," isn't a real Cargo.toml key. Renaming via ",[39,135210,135211],{},"package ="," changes which crate is pulled in under a local name, it doesn't touch feature visibility. Before this mechanism existed, optional deps unavoidably created a same-named public feature — that's exactly the gap ",[39,135214,134750],{}," was added to close.",[15,135217,135218,135226,135286],{},[18,135219,135221,135222,135225],{"id":135220},"q7-what-is-the-idiomatic-way-to-express-this-crate-is-no_std-unless-a-feature-is-enabled","Q7. What is the idiomatic way to express \"this crate is ",[39,135223,135224],{},"no_std"," unless a feature is enabled\"?",[23,135227,135229,135251,135263,135277],{"className":135228},[26],[28,135230,135232,135234,135235,135237,135238,135240,135241,135244,135245,135247,135248],{"className":135231},[31],[33,135233],{"disabled":35,"type":36}," Add a feature (e.g. ",[39,135236,109737],{},") that, when enabled, brings in ",[39,135239,109737],{},"; keep the crate ",[39,135242,135243],{},"#![no_std]"," by default and gate ",[39,135246,109737],{},"-only code behind ",[39,135249,135250],{},"#[cfg(feature = \"std\")]",[28,135252,135254,135256,135257,135259,135260,135262],{"className":135253},[31],[33,135255],{"disabled":35,"type":36}," Add a feature named ",[39,135258,135224],{}," that disables ",[39,135261,109737],{}," when enabled",[28,135264,135266,4353,135268,135270,135271,135274,135275],{"className":135265},[31],[33,135267],{"disabled":35,"type":36},[39,135269,134924],{}," in the crate's own ",[39,135272,135273],{},"[package]"," section to disable ",[39,135276,109737],{},[28,135278,135280,135282,135283,135285],{"className":135279},[31],[33,135281],{"disabled":35,"type":36}," It cannot be done — ",[39,135284,135224],{}," must be a fixed, unconditional attribute",[66,135287,135288,135290,135303],{},[69,135289,71],{},[73,135291,135292,135294,135295,135297,135298,135300,135301],{},[76,135293,78],{}," A — Add a positive ",[39,135296,109737],{}," feature; stay ",[39,135299,135243],{}," by default and gate on ",[39,135302,135250],{},[73,135304,135305,355,135307,135309,135310,135312,135313,355,135316,135318,135319,135321,135322,135324,135325,135327,135328,2018,135330,135332],{},[76,135306,84],{},[76,135308,930],{}," Cargo features must be additive\u002Funification-safe — enabling a feature can only ever add capability, never remove it, because unification takes the union across the whole graph. A ",[39,135311,135224],{}," feature that ",[104,135314,135315],{},"removes",[39,135317,109737],{}," support when turned on would break the instant two crates in the graph disagree (one wants ",[39,135320,109737],{},", one wants \"not std\" — unification would nonsensically enable both). The idiomatic pattern flips the polarity: the crate is minimal (",[39,135323,135224],{},") by default, and an additive ",[39,135326,109737],{}," feature unlocks more. ",[39,135329,134924],{},[39,135331,135273],{}," isn't a valid key — that phrasing only applies to dependency entries.",[15,135334,135335,135348,135378],{},[18,135336,65427,135338,135340,135341,186,135344,135347],{"id":135337},"q8-a-features-table-defines-backend-a-and-backend-b-and-the-crates-code-assumes-exactly-one-is-active-panicking-or-producing-nonsensical-output-if-both-are-compiled-in-at-once-a-downstream-users-dependency-graph-ends-up-unifying-both-features-on-what-is-the-actual-build-time-outcome",[39,135339,134584],{}," table defines ",[39,135342,135343],{},"backend-a = []",[39,135345,135346],{},"backend-b = []",", and the crate's code assumes exactly one is active, panicking or producing nonsensical output if both are compiled in at once. A downstream user's dependency graph ends up unifying both features on. What is the actual build-time outcome?",[23,135349,135351,135357,135366,135372],{"className":135350},[26],[28,135352,135354,135356],{"className":135353},[31],[33,135355],{"disabled":35,"type":36}," Cargo compiles successfully with both features enabled — Cargo has no built-in concept of mutually exclusive features",[28,135358,135360,135362,135363,135365],{"className":135359},[31],[33,135361],{"disabled":35,"type":36}," Cargo automatically detects the conflict from the ",[39,135364,134584],{}," table shape and refuses to build",[28,135367,135369,135371],{"className":135368},[31],[33,135370],{"disabled":35,"type":36}," Cargo picks whichever feature was requested first in the dependency graph and silently ignores the other",[28,135373,135375,135377],{"className":135374},[31],[33,135376],{"disabled":35,"type":36}," Cargo emits a warning but disables both features to avoid ambiguity",[66,135379,135380,135382,135387],{},[69,135381,71],{},[73,135383,135384,135386],{},[76,135385,78],{}," A — Cargo compiles successfully; it has no built-in concept of mutually exclusive features",[73,135388,135389,355,135391,135393,135394,10834,135397,135400],{},[76,135390,84],{},[76,135392,582],{}," Cargo's feature system was designed to be purely additive so unification always has a well-defined answer (the union); it has no syntax for declaring two features as mutually exclusive, and it will happily enable both if any two crates in the graph disagree. If the crate author needs a hard failure, the idiom is to add ",[39,135395,135396],{},"compile_error!(\"backend-a and backend-b are mutually exclusive\")",[39,135398,135399],{},"#[cfg(all(feature = \"backend-a\", feature = \"backend-b\"))]"," block so misuse fails loudly at compile time instead of silently misbehaving at runtime. Cargo does not pick a winner or auto-disable — that would violate the additive guarantee other tooling relies on.",[15,135402,135403,135423,135457],{},[18,135404,135406,135407,2029,135410,135412,135413,135416,135417,135419,135420,135422],{"id":135405},"q9-a-binary-crate-depends-on-image-with-default-features-false-in-hopes-of-dropping-the-heavy-png-default-codec-another-dependency-deeper-in-the-graph-pulls-in-image-with-its-regular-defaults-after-unification-is-png-support-present-in-the-final-binary","Q9. A binary crate depends on ",[39,135408,135409],{},"image",[39,135411,134924],{}," in hopes of dropping the (heavy) ",[39,135414,135415],{},"png"," default codec. Another dependency deeper in the graph pulls in ",[39,135418,135409],{}," with its regular defaults. After unification, is ",[39,135421,135415],{}," support present in the final binary?",[23,135424,135426,135435,135443,135451],{"className":135425},[26],[28,135427,135429,135431,135432,135434],{"className":135428},[31],[33,135430],{"disabled":35,"type":36}," Yes — because the other dependency's request for defaults wins the union, ",[39,135433,134924],{}," cannot retract it",[28,135436,135438,88201,135440,135442],{"className":135437},[31],[33,135439],{"disabled":35,"type":36},[39,135441,134924],{}," anywhere in the graph always wins and strips defaults for everyone",[28,135444,135446,135448,135449],{"className":135445},[31],[33,135447],{"disabled":35,"type":36}," It depends on declaration order in ",[39,135450,108587],{},[28,135452,135454,135456],{"className":135453},[31],[33,135455],{"disabled":35,"type":36}," No — Cargo deduplicates by intersecting feature requests, not unioning them",[66,135458,135459,135461,135466],{},[69,135460,71],{},[73,135462,135463,135465],{},[76,135464,78],{}," A — Yes; the other dependency's request for defaults wins the union",[73,135467,135468,355,135470,135472,135473,135475,135476,135478,135479,135481,135482,135484],{},[76,135469,84],{},[76,135471,438],{}," This is a widely-hit real-world footgun: ",[39,135474,134924],{}," is a per-requester opt-out, not a graph-wide veto. Because unification takes the union of every requester's features, as soon as ",[104,135477,21375],{}," crate in the graph asks for ",[39,135480,135409],{},"'s defaults, they're included in the single shared compilation — your own ",[39,135483,134924],{}," only means \"I personally don't require them,\" not \"disable them globally.\" The only reliable fix is to get the other dependency changed (or patched\u002Fforked) to also opt out, or to avoid depending on the offending crate. There is no declaration-order tiebreak and no intersection semantics — it's always a union.",[15,135486,135487,135506,135541],{},[18,135488,135490,135491,135494,135495,135498,135499,186,135502,135505],{"id":135489},"q10-a-crate-has-features-full-net-db-compress-if-a-user-builds-with-cargo-build-features-net-which-of-db-and-compress-get-enabled","Q10. A crate has ",[39,135492,135493],{},"[features] full = [\"net\", \"db\", \"compress\"]",". If a user builds with ",[39,135496,135497],{},"cargo build --features net",", which of ",[39,135500,135501],{},"db",[39,135503,135504],{},"compress"," get enabled?",[23,135507,135509,135518,135527,135535],{"className":135508},[26],[28,135510,135512,135020,135514,135517],{"className":135511},[31],[33,135513],{"disabled":35,"type":36},[39,135515,135516],{},"full"," is just an alias that itself must be explicitly requested to pull in its members",[28,135519,135521,135523,135524,135526],{"className":135520},[31],[33,135522],{"disabled":35,"type":36}," Both — enabling any member of ",[39,135525,135516],{}," retroactively enables the whole group",[28,135528,135530,50010,135532,135534],{"className":135529},[31],[33,135531],{"disabled":35,"type":36},[39,135533,135501],{},", because it's listed second",[28,135536,135538,135540],{"className":135537},[31],[33,135539],{"disabled":35,"type":36}," It's a compile error to request a partial subset of a feature group",[66,135542,135543,135545,135553],{},[69,135544,71],{},[73,135546,135547,135549,135550,135552],{},[76,135548,78],{}," A — Neither; ",[39,135551,135516],{}," is just an alias and must itself be requested",[73,135554,135555,135557,135558,135561,135562,355,135564,135567,135568,135570,135571,42,135573,383,135575,135577,135578,135580],{},[76,135556,84],{}," A feature entry like ",[39,135559,135560],{},"full = [\"net\", \"db\", \"compress\"]"," defines a one-directional relationship: turning ",[39,135563,135516],{},[104,135565,135566],{},"on"," turns those three on. It says nothing about the reverse — enabling ",[39,135569,132393],{}," alone has no effect on ",[39,135572,135516],{},[39,135574,135501],{},[39,135576,135504],{},". This trips people up because they expect feature \"groups\" to behave symmetrically; in reality ",[39,135579,135516],{}," is nothing more than syntactic sugar for \"enable these three together,\" requested independently like any other feature.",[15,135582,135583,135603,135630],{},[18,135584,135586,135587,135590,135591,135593,135594,135596,135597,135600,135601,1685],{"id":135585},"q11-a-crate-lists-criterion-05-only-under-dev-dependencies-not-under-dependencies-can-library-code-non-test-non-bench-reference-criterion-when-the-crate-is-built-normally-with-cargo-build","Q11. A crate lists ",[39,135588,135589],{},"criterion = \"0.5\""," only under ",[39,135592,110825],{},", not under ",[39,135595,110765],{},". Can library code (non-test, non-bench) reference ",[39,135598,135599],{},"criterion"," when the crate is built normally with ",[39,135602,108649],{},[23,135604,135606,135612,135618,135624],{"className":135605},[26],[28,135607,135609,135611],{"className":135608},[31],[33,135610],{"disabled":35,"type":36}," No — dev-dependencies are only available to tests, examples, and benchmarks, not the library target during a normal build",[28,135613,135615,135617],{"className":135614},[31],[33,135616],{"disabled":35,"type":36}," Yes — dev-dependencies are merged into the normal dependency graph automatically",[28,135619,135621,135623],{"className":135620},[31],[33,135622],{"disabled":35,"type":36}," Only if a matching feature flag with the same name is also enabled",[28,135625,135627,135629],{"className":135626},[31],[33,135628],{"disabled":35,"type":36}," Only in debug builds; release builds strip dev-dependencies but still link them in debug",[66,135631,135632,135634,135639],{},[69,135633,71],{},[73,135635,135636,135638],{},[76,135637,78],{}," A — No; dev-dependencies are only available to tests, examples, and benchmarks",[73,135640,135641,355,135643,135645,135646,42,135648,42,135651,135654,135655,135657,135658,135660],{},[76,135642,84],{},[39,135644,110825],{}," populate a separate graph used only when building test\u002Fbench\u002Fexample targets (",[39,135647,132629],{},[39,135649,135650],{},"cargo bench",[39,135652,135653],{},"cargo run --example","); they are not linked into the library or binary artifact produced by a plain ",[39,135656,108649],{},", and downstream consumers of your published crate never see them at all. This is why crates.io rejects a ",[39,135659,108587],{}," where library source references a dev-only dependency — it simply won't resolve outside test builds. There's no feature-flag coupling and no debug\u002Frelease distinction here; the separation is by target kind, not build profile.",[15,135662,135663,135674,135718],{},[18,135664,135666,135667,135670,135671,135673],{"id":135665},"q12-inside-a-buildrs-script-what-is-the-correct-way-to-check-whether-the-feature-json-is-enabled-for-the-crate-being-built","Q12. Inside a ",[39,135668,135669],{},"build.rs"," script, what is the correct way to check whether the feature ",[39,135672,1751],{}," is enabled for the crate being built?",[23,135675,135677,135687,135698,135709],{"className":135676},[26],[28,135678,135680,135682,135683,135686],{"className":135679},[31],[33,135681],{"disabled":35,"type":36}," Read the ",[39,135684,135685],{},"CARGO_FEATURE_JSON"," environment variable",[28,135688,135690,4353,135692,135695,135696],{"className":135689},[31],[33,135691],{"disabled":35,"type":36},[39,135693,135694],{},"#[cfg(feature = \"json\")]"," directly inside ",[39,135697,135669],{},[28,135699,135701,39927,135703,28179,135706,135708],{"className":135700},[31],[33,135702],{"disabled":35,"type":36},[39,135704,135705],{},"cargo::features::is_enabled(\"json\")",[39,135707,108615],{}," crate",[28,135710,135712,135714,135715,135717],{"className":135711},[31],[33,135713],{"disabled":35,"type":36}," Parse ",[39,135716,108587],{}," manually since features aren't otherwise visible to build scripts",[66,135719,135720,135722,135729],{},[69,135721,71],{},[73,135723,135724,135726,135727,135686],{},[76,135725,78],{}," A — Read the ",[39,135728,135685],{},[73,135730,135731,355,135733,135735,135736,135738,135739,135742,135743,4977,135745,135747,135748,135750,135751,135754,135755,135757,135758,135761,135762,135764,135765,135767],{},[76,135732,84],{},[76,135734,365],{}," Cargo exposes each enabled feature to ",[39,135737,135669],{}," as an environment variable named ",[39,135740,135741],{},"CARGO_FEATURE_\u003CFEATURE_NAME_UPPERCASE_WITH_UNDERSCORES>"," (e.g. ",[39,135744,1751],{},[39,135746,135685],{},"), set to ",[39,135749,2255],{}," when enabled and absent otherwise. ",[39,135752,135753],{},"#[cfg(feature = ...)]"," doesn't apply here because ",[39,135756,135669],{}," is compiled and run as a ",[104,135759,135760],{},"separate"," program before the crate itself, under a different cfg context — a mistake newcomers make constantly. There's no such ",[39,135763,108615],{}," crate API for this, and manually parsing ",[39,135766,108587],{}," is unnecessary and fragile since Cargo already does the resolution and hands you the answer via env vars.",[15,135769,135770,135777,135811],{},[18,135771,135773,135774,135776],{"id":135772},"q13-running-plain-cargo-doc-no-extra-flags-on-a-crate-with-several-feature-gated-public-items-what-shows-up-in-the-generated-documentation-for-those-items","Q13. Running plain ",[39,135775,132984],{}," (no extra flags) on a crate with several feature-gated public items — what shows up in the generated documentation for those items?",[23,135778,135780,135786,135795,135805],{"className":135779},[26],[28,135781,135783,135785],{"className":135782},[31],[33,135784],{"disabled":35,"type":36}," Only items reachable under the crate's default feature set; feature-gated items behind non-default features are omitted",[28,135787,135789,135791,135792,135794],{"className":135788},[31],[33,135790],{"disabled":35,"type":36}," All items regardless of feature gating — ",[39,135793,132984],{}," always compiles with every feature enabled",[28,135796,135798,52864,135800,71990,135802,135804],{"className":135797},[31],[33,135799],{"disabled":35,"type":36},[39,135801,132984],{},[39,135803,109522],{}," to produce any output at all",[28,135806,135808,135810],{"className":135807},[31],[33,135809],{"disabled":35,"type":36}," Feature-gated items appear but are rendered with strikethrough text automatically",[66,135812,135813,135815,135820],{},[69,135814,71],{},[73,135816,135817,135819],{},[76,135818,78],{}," A — Only items reachable under the crate's default feature set",[73,135821,135822,355,135824,135826,135827,135829,135830,135832,135833,135836,135837,135840,135841,135844,135845,135847],{},[76,135823,84],{},[39,135825,132984],{}," builds documentation the same way ",[39,135828,108649],{}," compiles code: using whatever feature set is active for the invocation, which defaults to the ",[39,135831,9046],{}," feature list. Items behind non-default ",[39,135834,135835],{},"#[cfg(feature = \"...\")]"," gates simply don't exist in that compilation and so never reach the doc generator. To document everything, maintainers run ",[39,135838,135839],{},"cargo doc --all-features"," (or docs.rs's ",[39,135842,135843],{},"[package.metadata.docs.rs] all-features = true"," config). Plain ",[39,135846,132984],{}," does not fail on zero features, and there's no automatic strikethrough rendering for gated items.",[15,135849,135850,135889,135937],{},[18,135851,135853,135854,186,135857,135860,135861,3277,135863,9057,135865,135867,135868,135870,135871,135873,135874,135876,135877,135880,135881,135883,135884,9057,135886,135888],{"id":135852},"q14-a-workspace-has-two-member-crates-app-and-lib-both-depending-on-serde-apps-cargotoml-requests-serde-with-the-derive-feature-libs-does-not-when-building-the-whole-workspace-with-cargo-build-workspace-does-libs-compilation-unit-get-serdes-derive-feature","Q14. A workspace has two member crates, ",[39,135855,135856],{},"app",[39,135858,135859],{},"lib",", both depending on ",[39,135862,110818],{},[39,135864,135856],{},[39,135866,108587],{}," requests ",[39,135869,110818],{}," with the ",[39,135872,124545],{}," feature; ",[39,135875,135859],{},"'s does not. When building the whole workspace with ",[39,135878,135879],{},"cargo build --workspace",", does ",[39,135882,135859],{},"'s compilation unit get ",[39,135885,110818],{},[39,135887,124545],{}," feature?",[23,135890,135892,135905,135911,135925],{"className":135891},[26],[28,135893,135895,135897,135898,135901,135902,135904],{"className":135894},[31],[33,135896],{"disabled":35,"type":36}," Yes — feature unification happens across the whole workspace build by default, so ",[39,135899,135900],{},"serde\u002Fderive"," is active everywhere ",[39,135903,110818],{}," is used in that build",[28,135906,135908,135910],{"className":135907},[31],[33,135909],{"disabled":35,"type":36}," No — each workspace member is compiled with only the features it explicitly lists",[28,135912,135914,131399,135916,101278,135918,135920,135921,135924],{"className":135913},[31],[33,135915],{"disabled":35,"type":36},[39,135917,135859],{},[39,135919,135856],{}," in the workspace ",[39,135922,135923],{},"[members]"," array",[28,135926,135928,135930,135931,99,135934,135936],{"className":135927},[31],[33,135929],{"disabled":35,"type":36}," It depends on whether ",[39,135932,135933],{},"resolver = \"1\"",[39,135935,9269],{}," is set, but resolver 2 disables unification entirely",[66,135938,135939,135941,135946],{},[69,135940,71],{},[73,135942,135943,135945],{},[76,135944,78],{}," A — Yes, feature unification applies across the whole workspace build by default",[73,135947,135948,135950,135951,135953,135954,6131,135957,135960,135961,135963],{},[76,135949,84],{}," When multiple workspace members share a dependency and are built together in one ",[39,135952,135879],{}," invocation, Cargo still compiles that shared dependency once, unified across every member being built in that command — exactly like unification across a single crate's transitive graph. This surprises people who expect workspace members to be isolated. The 2021 \"feature resolver v2\" (",[39,135955,135956],{},"resolver = \"2\"",[104,135958,135959],{},"narrows"," unification (notably separating host\u002Ftarget and dev-dependency feature sets) but does not eliminate cross-member unification for normal dependencies built together; it does not disable unification outright. Member order in ",[39,135962,135923],{}," has no bearing on this.",[15,135965,135966,135976,136033,136079],{"language":134532},[18,135967,135969,135970,135972,135973,135975],{"id":135968},"q15-a-published-library-crate-wants-to-offer-an-async-api-built-on-tokio-but-also-be-usable-by-consumers-who-dont-want-tokio-pulled-in-at-all-what-is-the-idiomatic-cargotoml-structure","Q15. A published library crate wants to offer an async API built on ",[39,135971,110821],{}," but also be usable by consumers who don't want ",[39,135974,110821],{}," pulled in at all. What is the idiomatic Cargo.toml structure?",[257,135977,135978],{"language":134532},[260,135979,135981],{"className":134547,"code":135980,"language":134532,"meta":264,"style":264},"[dependencies]\ntokio = { version = \"1\", optional = true, features = [\"rt\"] }\n\n[features]\nasync = [\"dep:tokio\"]\n",[39,135982,135983,135991,136011,136015,136023],{"__ignoreMap":264},[268,135984,135985,135987,135989],{"class":270,"line":271},[268,135986,15175],{"class":282},[268,135988,82698],{"class":278},[268,135990,89183],{"class":282},[268,135992,135993,135996,135998,136000,136002,136005,136008],{"class":270,"line":286},[268,135994,135995],{"class":282},"tokio = { version = ",[268,135997,3387],{"class":289},[268,135999,134569],{"class":282},[268,136001,2185],{"class":305},[268,136003,136004],{"class":282},", features = [",[268,136006,136007],{"class":289},"\"rt\"",[268,136009,136010],{"class":282},"] }\n",[268,136012,136013],{"class":270,"line":296},[268,136014,5033],{"emptyLinePlaceholder":35},[268,136016,136017,136019,136021],{"class":270,"line":311},[268,136018,15175],{"class":282},[268,136020,134936],{"class":278},[268,136022,89183],{"class":282},[268,136024,136025,136028,136031],{"class":270,"line":788},[268,136026,136027],{"class":282},"async = [",[268,136029,136030],{"class":289},"\"dep:tokio\"",[268,136032,89183],{"class":282},[23,136034,136036,136050,136061,136070],{"className":136035},[26],[28,136037,136039,136041,136042,136044,136045,136047,136048],{"className":136038},[31],[33,136040],{"disabled":35,"type":36}," Make ",[39,136043,110821],{}," an optional dependency gated behind an additive ",[39,136046,379],{}," feature that is NOT in ",[39,136049,9046],{},[28,136051,136053,134899,136055,136057,136058,136060],{"className":136052},[31],[33,136054],{"disabled":35,"type":36},[39,136056,110821],{}," unconditionally; consumers who don't want it can use ",[39,136059,134815],{}," on their own crate",[28,136062,136064,136066,136067,136069],{"className":136063},[31],[33,136065],{"disabled":35,"type":36}," Vendor a minimal subset of ",[39,136068,110821],{},"'s API directly into the crate to avoid the dependency entirely",[28,136071,136073,136075,136076,136078],{"className":136072},[31],[33,136074],{"disabled":35,"type":36}," Use two entirely separate published crates with identical code, one with ",[39,136077,110821],{}," and one without",[66,136080,136081,136083,136093],{},[69,136082,71],{},[73,136084,136085,136087,136088,136090,136091,134905],{},[76,136086,78],{}," A — Make ",[39,136089,110821],{}," optional, gated behind a non-default ",[39,136092,379],{},[73,136094,136095,355,136097,136099,136100,42,136102,136105,136106,136108,136109,136111,136112,136114,136115,13450,136117,136120],{},[76,136096,84],{},[76,136098,930],{}," This is the standard pattern seen across the ecosystem (e.g. ",[39,136101,134863],{},[39,136103,136104],{},"sqlx","): mark the runtime dependency ",[39,136107,134599],{}," and expose it through an additive feature that consumers opt into, leaving it off of ",[39,136110,9046],{}," so sync-only consumers pay zero cost. Depending on ",[39,136113,110821],{}," unconditionally forces every consumer to compile and link it even if they never touch the async API — ",[39,136116,134815],{},[104,136118,136119],{},"consumer's own crate"," does nothing to strip a dependency the library itself declared unconditionally. Vendoring or forking into duplicate crates massively increases maintenance burden for no benefit when Cargo already solves this cleanly.",[15,136122,136123,136131,136161],{},[18,136124,136126,136127,136130],{"id":136125},"q16-which-of-these-is-the-best-practice-for-a-feature-that-changes-the-behavior-of-existing-default-functionality-eg-switching-a-hash-function-to-a-faster-non-cryptographic-one-rather-than-adding-new-opt-in-api-surface","Q16. Which of these is the best practice for a feature that changes the ",[104,136128,136129],{},"behavior"," of existing default functionality (e.g. switching a hash function to a faster non-cryptographic one), rather than adding new opt-in API surface?",[23,136132,136134,136140,136146,136155],{"className":136133},[26],[28,136135,136137,136139],{"className":136136},[31],[33,136138],{"disabled":35,"type":36}," Avoid it if at all possible — behavior-changing features violate the \"features are additive\" convention and can silently produce different results depending on unrelated crates in the dependency graph",[28,136141,136143,136145],{"className":136142},[31],[33,136144],{"disabled":35,"type":36}," It's fine as long as the feature is well documented in the crate's README",[28,136147,136149,136151,136152,136154],{"className":136148},[31],[33,136150],{"disabled":35,"type":36}," Always make such features part of ",[39,136153,9046],{}," so behavior is consistent",[28,136156,136158,136160],{"className":136157},[31],[33,136159],{"disabled":35,"type":36}," Use a build-time environment variable instead of a Cargo feature, since env vars are more explicit",[66,136162,136163,136165,136170],{},[69,136164,71],{},[73,136166,136167,136169],{},[76,136168,78],{}," A — Avoid it; behavior-changing features break the additive convention",[73,136171,136172,355,136174,136176,136177,136179,136180,136182],{},[76,136173,84],{},[76,136175,582],{}," Because feature unification means \"if anything in the dependency graph enables this feature, it's on for everyone,\" a feature that changes semantics (not just adds capability) can silently alter your crate's behavior based on an unrelated dependency three levels away enabling it for its own reasons — a notoriously hard bug to trace. The Cargo team's own guidance is that features should be strictly additive; behavior toggles are better expressed as separate crates, runtime configuration, or distinct type-level APIs. Documentation doesn't fix the unification hazard, making it ",[39,136178,9046],{}," doesn't solve the underlying issue, and environment variables introduce their own non-reproducibility problems for library code (they're invisible to ",[39,136181,108726],{}," and to downstream consumers reasoning about a crate's compiled behavior).",[15,136184,136185,136192,136217,136259],{"language":134532},[18,136186,136188,136189,136191],{"id":136187},"q17-a-crate-wants-to-enable-a-specific-feature-of-an-optional-dependency-serdederive-only-when-its-own-dependent-turns-that-dependency-on-elsewhere-in-the-graph-without-itself-forcing-the-optional-dependency-to-be-pulled-in-which-syntax-expresses-this-weak-feature-dependency","Q17. A crate wants to enable a specific feature of an optional dependency (",[39,136190,135900],{},") only when its own dependent turns that dependency on elsewhere in the graph, without itself forcing the optional dependency to be pulled in. Which syntax expresses this \"weak\" feature dependency?",[257,136193,136194],{"language":134532},[260,136195,136197],{"className":134547,"code":136196,"language":134532,"meta":264,"style":264},"[features]\nderive-support = [\"serde?\u002Fderive\"]\n",[39,136198,136199,136207],{"__ignoreMap":264},[268,136200,136201,136203,136205],{"class":270,"line":271},[268,136202,15175],{"class":282},[268,136204,134936],{"class":278},[268,136206,89183],{"class":282},[268,136208,136209,136212,136215],{"class":270,"line":286},[268,136210,136211],{"class":282},"derive-support = [",[268,136213,136214],{"class":289},"\"serde?\u002Fderive\"",[268,136216,89183],{"class":282},[23,136218,136220,136232,136243,136253],{"className":136219},[26],[28,136221,136223,4396,136225,136228,136229,2690],{"className":136222},[31],[33,136224],{"disabled":35,"type":36},[39,136226,136227],{},"dep_name?\u002Ffeature_name"," syntax (e.g. ",[39,136230,136231],{},"serde?\u002Fderive",[28,136233,136235,4396,136237,136240,136241],{"className":136234},[31],[33,136236],{"disabled":35,"type":36},[39,136238,136239],{},"dep_name\u002Ffeature_name"," syntax without a ",[39,136242,1685],{},[28,136244,136246,355,136248,36284,136251],{"className":136245},[31],[33,136247],{"disabled":35,"type":36},[39,136249,136250],{},"optional-features = [\"serde\u002Fderive\"]",[39,136252,135273],{},[28,136254,136256,136258],{"className":136255},[31],[33,136257],{"disabled":35,"type":36}," There is no such mechanism; enabling a sub-feature always forces the base dependency on",[66,136260,136261,136263,136270],{},[69,136262,71],{},[73,136264,136265,43363,136267,136269],{},[76,136266,78],{},[39,136268,136227],{}," weak-dependency-feature syntax",[73,136271,136272,355,136274,355,136276,136278,136279,136281,136282,136284,136285,136288,136289,136291,136292,136294,136295,136297,136298,136300,136301,136303,136304,136306,136307,21182,136309,136312],{},[76,136273,84],{},[76,136275,930],{},[39,136277,136231],{}," (the ",[39,136280,1685],{}," marks it \"weak\") means \"if ",[39,136283,110818],{}," ends up enabled by ",[104,136286,136287],{},"someone"," in the graph, also turn on its ",[39,136290,124545],{}," feature — but don't turn ",[39,136293,110818],{}," on by yourself.\" This is exactly for the case in the question: contributing a feature to a dependency without forcing that dependency to exist. The non-",[39,136296,1685],{}," form ",[39,136299,135900],{}," is the older, \"strong\" syntax that ",[104,136302,10043],{}," implicitly enable ",[39,136305,110818],{}," as a side effect, which is the opposite of what's wanted here. ",[39,136308,135273],{},[39,136310,136311],{},"optional-features"," key.",[15,136314,136315,136323,136362],{},[18,136316,136318,136319,136322],{"id":136317},"q18-why-do-many-cratesio-libraries-deliberately-keep-features-default-empty-rather-than-defaulting-to-their-most-common-configuration","Q18. Why do many crates.io libraries deliberately keep ",[39,136320,136321],{},"[features] default = []"," (empty) rather than defaulting to their most common configuration?",[23,136324,136326,136332,136341,136349],{"className":136325},[26],[28,136327,136329,136331],{"className":136328},[31],[33,136330],{"disabled":35,"type":36}," To let downstream consumers opt into exactly what they need without unwanted transitive dependencies or unification surprises leaking through unless explicitly requested",[28,136333,136335,136337,136338,136340],{"className":136334},[31],[33,136336],{"disabled":35,"type":36}," Because Cargo requires ",[39,136339,9046],{}," to be empty for crates published to crates.io",[28,136342,136344,136346,136347],{"className":136343},[31],[33,136345],{"disabled":35,"type":36}," Because non-empty defaults are silently ignored by ",[39,136348,108886],{},[28,136350,136352,136354,136355,136358,136359,136361],{"className":136351},[31],[33,136353],{"disabled":35,"type":36}," It has no practical effect; ",[39,136356,136357],{},"default = []"," and omitting ",[39,136360,134584],{}," entirely behave identically in every situation",[66,136363,136364,136366,136371],{},[69,136365,71],{},[73,136367,136368,136370],{},[76,136369,78],{}," A — To let consumers opt in explicitly and avoid unwanted transitive weight or unification surprises",[73,136372,136373,355,136375,136377,136378,136380,136381,136383,136384,136386,136387,136389,136390,136392,136393,136395,136396,136398,136399,136401],{},[76,136374,84],{},[76,136376,930],{}," Keeping ",[39,136379,9046],{}," minimal (or empty) is a deliberate ecosystem convention for foundational crates so that consumers pay only for what they ask for, and so that unification doesn't quietly drag in heavy optional dependencies just because ",[104,136382,37205],{}," crate in the graph forgot to pass ",[39,136385,134924],{},". This is purely a design choice, not a crates.io requirement — Cargo places no restriction on ",[39,136388,9046],{}," content for publishing. ",[39,136391,108886],{}," respects defaults normally. And the last option is wrong in a subtle way: omitting ",[39,136394,134584],{}," entirely means the crate has zero features at all (nothing to enable), whereas an explicit ",[39,136397,136357],{}," still allows ",[104,136400,33735],{},", non-default features to exist and be turned on individually — they're not identical when the crate defines additional optional features.",[15,136403,136404,136408,136446],{},[18,136405,136407],{"id":136406},"q19-what-is-the-most-reliable-way-to-verify-that-a-crate-compiles-correctly-under-every-individual-feature-combination-not-just-all-features-on-or-default-only-before-publishing","Q19. What is the most reliable way to verify that a crate compiles correctly under every individual feature combination, not just \"all features on\" or \"default only,\" before publishing?",[23,136409,136411,136421,136432,136440],{"className":136410},[26],[28,136412,136414,136416,136417,136420],{"className":136413},[31],[33,136415],{"disabled":35,"type":36}," Use a tool like ",[39,136418,136419],{},"cargo hack --feature-powerset --no-dev-deps check"," in CI to compile every combination of feature flags",[28,136422,136424,88738,136426,136428,136429,136431],{"className":136423},[31],[33,136425],{"disabled":35,"type":36},[39,136427,110360],{}," once with ",[39,136430,109522],{},"; if that passes, every subset is guaranteed to also compile",[28,136433,136435,88738,136437,136439],{"className":136434},[31],[33,136436],{"disabled":35,"type":36},[39,136438,132629],{}," once; test failures would reveal any feature-combination compile errors",[28,136441,136443,136445],{"className":136442},[31],[33,136444],{"disabled":35,"type":36}," It's unnecessary — Cargo's unification guarantees every subset compiles if the full set does",[66,136447,136448,136450,136458],{},[69,136449,71],{},[73,136451,136452,3459,136454,136457],{},[76,136453,78],{},[39,136455,136456],{},"cargo hack --feature-powerset"," (or similar) to check every combination",[73,136459,136460,355,136462,355,136465,136467,136468,136470,136471,136474,136475,136477,136478,136480,136481,136483,136484,9057,136487,136490,136491,136493],{},[76,136461,84],{},[76,136463,136464],{},"Idiom\u002FDebug:",[39,136466,109522],{}," on is a ",[104,136469,130646],{}," compilation than any individual subset — a crate can easily compile fine with everything on (where conflicting ",[39,136472,136473],{},"#[cfg]"," branches never both trigger issues) yet fail to compile with only feature ",[39,136476,2403],{}," on and not ",[39,136479,2909],{},", especially with mutually-referential ",[39,136482,135753],{}," code. ",[39,136485,136486],{},"cargo-hack",[39,136488,136489],{},"--feature-powerset"," mode compiles every combination in turn and is the standard CI safeguard used by mature crates for exactly this reason. ",[39,136492,132629],{}," only runs whatever single feature set was active for that invocation, so it can't surface combination-specific breakage on its own, and there is no guarantee that \"all features compiles\" implies \"every subset compiles\" — the additive-features convention is a social contract enforced by testing, not something the compiler verifies for you.",[15,136495,136496,136504,136548],{},[18,136497,136499,136500,136503],{"id":136498},"q20-a-crate-has-a-feature-unstable-that-exposes-experimental-semver-unstable-apis-what-is-the-recommended-convention-for-how-this-feature-interacts-with-semantic-versioning-guarantees","Q20. A crate has a feature ",[39,136501,136502],{},"unstable"," that exposes experimental, semver-unstable APIs. What is the recommended convention for how this feature interacts with semantic versioning guarantees?",[23,136505,136507,136516,136525,136535],{"className":136506},[26],[28,136508,136510,136512,136513,136515],{"className":136509},[31],[33,136511],{"disabled":35,"type":36}," Document explicitly that APIs behind ",[39,136514,136502],{}," are exempt from semver guarantees and may break even in patch releases",[28,136517,136519,136521,136522,136524],{"className":136518},[31],[33,136520],{"disabled":35,"type":36}," Treat ",[39,136523,136502],{}," like any other feature — once published, its APIs are covered by normal semver like everything else",[28,136526,136528,136530,136531,136534],{"className":136527},[31],[33,136529],{"disabled":35,"type":36}," Cargo automatically excludes ",[39,136532,136533],{},"#[cfg(feature = \"unstable\")]"," items from semver compatibility checks with no documentation needed",[28,136536,136538,136540,136541,136543,136544,136547],{"className":136537},[31],[33,136539],{"disabled":35,"type":36}," Publish ",[39,136542,136502],{},"-gated code only to a separate ",[39,136545,136546],{},"-unstable"," suffixed crate name, never mixed into the main crate",[66,136549,136550,136552,136560],{},[69,136551,71],{},[73,136553,136554,136556,136557,136559],{},[76,136555,78],{}," A — Explicitly document that ",[39,136558,136502],{},"-gated APIs are exempt from normal semver guarantees",[73,136561,136562,355,136564,136566,136567,136569,136570,42,136572,136574],{},[76,136563,84],{},[76,136565,930],{}," Since Cargo has no built-in notion of \"this feature's APIs don't count toward semver\" (there is no automatic exemption — that part of option C is fabricated), crates that ship experimental surface behind a feature like ",[39,136568,136502],{}," rely entirely on clear documentation (README, feature doc comment, changelog policy) stating that breaking changes there can land in any release, including patches. This is a widely used convention (e.g. in ",[39,136571,110821],{},[39,136573,110907],{},") precisely because publishing genuinely separate crates for every experimental API would fragment the ecosystem and versioning unnecessarily. Treating it like normal semver-bound code would freeze experimentation prematurely.",[2107,136576,136577],{},"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 pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}",{"title":264,"searchDepth":286,"depth":286,"links":136579},[136580,136582,136584,136586,136588,136590,136592,136594,136596,136598,136600,136602,136604,136606,136608,136610,136612,136614,136616,136617],{"id":134535,"depth":296,"text":136581},"Q1. What is the correct way to declare a feature named logging that has no dependencies of its own in Cargo.toml?",{"id":134666,"depth":296,"text":136583},"Q2. A crate declares serde = { version = \"1\", optional = true } under [dependencies]. What happens by default?",{"id":134759,"depth":296,"text":136585},"Q3. Which flag builds a crate with its default feature set disabled?",{"id":134842,"depth":296,"text":136587},"Q4. In Cargo.toml, what does this dependency declaration mean?",{"id":134981,"depth":296,"text":136589},"Q5. Crate A depends on net-lib with features = [\"tls\"]. Crate B (a sibling dependency in the same build) depends on net-lib with default-features = false and no extra features. Both end up in the same final binary. What features does net-lib actually get compiled with?",{"id":135075,"depth":296,"text":136591},"Q6. A library crate wants an optional dependency regex available for internal use, but does NOT want a public feature named regex to appear in its feature list (to avoid it being confused with a user-facing toggle). Which mechanism achieves this?",{"id":135220,"depth":296,"text":136593},"Q7. What is the idiomatic way to express \"this crate is no_std unless a feature is enabled\"?",{"id":135337,"depth":296,"text":136595},"Q8. A [features] table defines backend-a = [] and backend-b = [], and the crate's code assumes exactly one is active, panicking or producing nonsensical output if both are compiled in at once. A downstream user's dependency graph ends up unifying both features on. What is the actual build-time outcome?",{"id":135405,"depth":296,"text":136597},"Q9. A binary crate depends on image with default-features = false in hopes of dropping the (heavy) png default codec. Another dependency deeper in the graph pulls in image with its regular defaults. After unification, is png support present in the final binary?",{"id":135489,"depth":296,"text":136599},"Q10. A crate has [features] full = [\"net\", \"db\", \"compress\"]. If a user builds with cargo build --features net, which of db and compress get enabled?",{"id":135585,"depth":296,"text":136601},"Q11. A crate lists criterion = \"0.5\" only under [dev-dependencies], not under [dependencies]. Can library code (non-test, non-bench) reference criterion when the crate is built normally with cargo build?",{"id":135665,"depth":296,"text":136603},"Q12. Inside a build.rs script, what is the correct way to check whether the feature json is enabled for the crate being built?",{"id":135772,"depth":296,"text":136605},"Q13. Running plain cargo doc (no extra flags) on a crate with several feature-gated public items — what shows up in the generated documentation for those items?",{"id":135852,"depth":296,"text":136607},"Q14. A workspace has two member crates, app and lib, both depending on serde. app's Cargo.toml requests serde with the derive feature; lib's does not. When building the whole workspace with cargo build --workspace, does lib's compilation unit get serde's derive feature?",{"id":135968,"depth":296,"text":136609},"Q15. A published library crate wants to offer an async API built on tokio but also be usable by consumers who don't want tokio pulled in at all. What is the idiomatic Cargo.toml structure?",{"id":136125,"depth":296,"text":136611},"Q16. Which of these is the best practice for a feature that changes the behavior of existing default functionality (e.g. switching a hash function to a faster non-cryptographic one), rather than adding new opt-in API surface?",{"id":136187,"depth":296,"text":136613},"Q17. A crate wants to enable a specific feature of an optional dependency (serde\u002Fderive) only when its own dependent turns that dependency on elsewhere in the graph, without itself forcing the optional dependency to be pulled in. Which syntax expresses this \"weak\" feature dependency?",{"id":136317,"depth":296,"text":136615},"Q18. Why do many crates.io libraries deliberately keep [features] default = [] (empty) rather than defaulting to their most common configuration?",{"id":136406,"depth":296,"text":136407},{"id":136498,"depth":296,"text":136618},"Q20. A crate has a feature unstable that exposes experimental, semver-unstable APIs. What is the recommended convention for how this feature interacts with semantic versioning guarantees?",{},"\u002Frust\u002F28-cargo-features",{"title":134524,"description":264},"rust\u002F28-cargo-features","t80IBEFn6jwXXJdhB4bBO6HCqKKiyG1EvUfQFffs2y8",{"id":136625,"title":136626,"body":136627,"description":264,"extension":2144,"meta":139492,"navigation":35,"path":139493,"seo":139494,"stem":139495,"__hash__":139496},"content\u002Frust\u002F29-advanced-type-system.md","29 — Advanced Type System",{"type":8,"value":136628,"toc":139453},[136629,136632,136826,136896,137075,137161,137304,137388,137498,137680,137857,137949,138106,138273,138511,138687,138777,138899,138997,139146,139266,139450],[11,136630,136626],{"id":136631},"_29-advanced-type-system",[15,136633,136634,136638,136752,136779],{"language":111909},[18,136635,136637],{"id":136636},"q1-what-is-the-key-difference-between-an-associated-type-and-a-generic-type-parameter-on-a-trait","Q1. What is the key difference between an associated type and a generic type parameter on a trait?",[257,136639,136640],{"language":111909},[260,136641,136643],{"className":111918,"code":136642,"language":111909,"meta":264,"style":264},"trait IteratorLike {\n    type Item;\n    fn next(&mut self) -> Option\u003CSelf::Item>;\n}\n\ntrait Container\u003CT> {\n    fn get(&self, i: usize) -> Option\u003C&T>;\n}\n",[39,136644,136645,136655,136665,136694,136698,136702,136715,136748],{"__ignoreMap":264},[268,136646,136647,136650,136653],{"class":270,"line":271},[268,136648,136649],{"class":274},"trait",[268,136651,136652],{"class":278}," IteratorLike",[268,136654,9914],{"class":282},[268,136656,136657,136660,136663],{"class":270,"line":286},[268,136658,136659],{"class":274},"    type",[268,136661,136662],{"class":278}," Item",[268,136664,293],{"class":282},[268,136666,136667,136669,136671,136673,136675,136677,136679,136681,136683,136685,136687,136689,136691],{"class":270,"line":296},[268,136668,120364],{"class":274},[268,136670,16907],{"class":278},[268,136672,622],{"class":282},[268,136674,114510],{"class":274},[268,136676,96472],{"class":305},[268,136678,6131],{"class":282},[268,136680,113308],{"class":274},[268,136682,126457],{"class":278},[268,136684,1076],{"class":282},[268,136686,124895],{"class":305},[268,136688,84903],{"class":274},[268,136690,125123],{"class":278},[268,136692,136693],{"class":282},">;\n",[268,136695,136696],{"class":270,"line":311},[268,136697,314],{"class":282},[268,136699,136700],{"class":270,"line":788},[268,136701,5033],{"emptyLinePlaceholder":35},[268,136703,136704,136706,136709,136711,136713],{"class":270,"line":1951},[268,136705,136649],{"class":274},[268,136707,136708],{"class":278}," Container",[268,136710,1076],{"class":282},[268,136712,102486],{"class":278},[268,136714,121209],{"class":282},[268,136716,136717,136719,136721,136723,136725,136727,136730,136732,136734,136736,136738,136740,136742,136744,136746],{"class":270,"line":8955},[268,136718,120364],{"class":274},[268,136720,104867],{"class":278},[268,136722,622],{"class":282},[268,136724,85350],{"class":274},[268,136726,87099],{"class":305},[268,136728,136729],{"class":282},", i",[268,136731,10728],{"class":274},[268,136733,113286],{"class":278},[268,136735,6131],{"class":282},[268,136737,113308],{"class":274},[268,136739,126457],{"class":278},[268,136741,1076],{"class":282},[268,136743,85350],{"class":274},[268,136745,102486],{"class":278},[268,136747,136693],{"class":282},[268,136749,136750],{"class":270,"line":8966},[268,136751,314],{"class":282},[23,136753,136755,136761,136767,136773],{"className":136754},[26],[28,136756,136758,136760],{"className":136757},[31],[33,136759],{"disabled":35,"type":36}," A type implementing a trait with an associated type may only provide ONE concrete type for it, while a generic trait parameter allows multiple impls for different types on the same type",[28,136762,136764,136766],{"className":136763},[31],[33,136765],{"disabled":35,"type":36}," Associated types are resolved at runtime; generic parameters are resolved at compile time",[28,136768,136770,136772],{"className":136769},[31],[33,136771],{"disabled":35,"type":36}," Associated types can only be primitive types; generics can be any type",[28,136774,136776,136778],{"className":136775},[31],[33,136777],{"disabled":35,"type":36}," There is no functional difference — they are two syntaxes for the same feature",[66,136780,136781,136783,136788],{},[69,136782,71],{},[73,136784,136785,136787],{},[76,136786,78],{}," A — a type may implement a trait with an associated type only once, but can implement a generic-parameter trait many times for different type arguments",[73,136789,136790,355,136792,136795,136796,135742,136798,186,136801,136804,136805,136807,136808,136811,136812,136815,136816,136818,136819,136821,136822,136825],{},[76,136791,84],{},[39,136793,136794],{},"impl\u003CT> Container\u003CT> for MyType"," can be written once per distinct ",[39,136797,102486],{},[39,136799,136800],{},"Container\u003Ci32> for MyType",[39,136802,136803],{},"Container\u003CString> for MyType"," can coexist), because ",[39,136806,102486],{}," is part of the trait signature being implemented. But ",[39,136809,136810],{},"impl IteratorLike for MyType"," can only exist once total, with ",[39,136813,136814],{},"Self::Item"," fixed to a single concrete type — the associated type is an output determined by the impl, not an input you can vary across multiple impls. Both are fully resolved at compile time (Rust has no runtime generics), and associated types can be any type, not just primitives — this is why real-world ",[39,136817,129572],{}," uses an associated ",[39,136820,125123],{}," (one element type per iterator) while traits like ",[39,136823,136824],{},"From\u003CT>"," use a generic parameter (many conversions per type).",[15,136827,136828,136832,136862],{},[18,136829,136831],{"id":136830},"q2-what-does-gat-stand-for-and-what-capability-does-it-add-over-a-plain-associated-type","Q2. What does GAT stand for, and what capability does it add over a plain associated type?",[23,136833,136835,136844,136850,136856],{"className":136834},[26],[28,136836,136838,136840,136841],{"className":136837},[31],[33,136839],{"disabled":35,"type":36}," Generic Associated Type — an associated type that can itself be generic over a lifetime or type parameter, e.g. ",[39,136842,136843],{},"type Item\u003C'a>",[28,136845,136847,136849],{"className":136846},[31],[33,136848],{"disabled":35,"type":36}," Global Application Trait — a trait implemented automatically for every type in the crate",[28,136851,136853,136855],{"className":136852},[31],[33,136854],{"disabled":35,"type":36}," Guaranteed Allocation Type — a marker trait indicating heap-allocated storage",[28,136857,136859,136861],{"className":136858},[31],[33,136860],{"disabled":35,"type":36}," Generic Abstract Trait — a trait with no default method implementations",[66,136863,136864,136866,136871],{},[69,136865,71],{},[73,136867,136868,136870],{},[76,136869,78],{}," A — Generic Associated Type: an associated type parameterized by a lifetime or type",[73,136872,136873,136875,136876,136879,136880,99,136883,136886,136887,136889,136890,136892,136893,136895],{},[76,136874,84],{}," A plain associated type (",[39,136877,136878],{},"type Item;",") is a single fixed type per impl. A GAT (",[39,136881,136882],{},"type Item\u003C'a>;",[39,136884,136885],{},"type Container\u003CT>;",") lets that associated type itself depend on a lifetime or type parameter supplied at the point of use, which is what makes \"lending iterators\" (an iterator whose ",[39,136888,17034],{}," borrows from ",[39,136891,87099],{}," for the duration of the call) expressible — something impossible with the older associated-type system because ",[39,136894,125123],{}," couldn't vary per call. The other three options describe nothing that exists in Rust's type system.",[15,136897,136898,136905,136979,137020],{"language":111909},[18,136899,136901,136902,114665],{"id":136900},"q3-what-is-phantomdatat-primarily-used-for","Q3. What is ",[39,136903,136904],{},"PhantomData\u003CT>",[257,136906,136907],{"language":111909},[260,136908,136910],{"className":111918,"code":136909,"language":111909,"meta":264,"style":264},"use std::marker::PhantomData;\n\nstruct TypedId\u003CT> {\n    id: u64,\n    _marker: PhantomData\u003CT>,\n}\n",[39,136911,136912,136930,136934,136947,136958,136975],{"__ignoreMap":264},[268,136913,136914,136916,136918,136920,136923,136925,136928],{"class":270,"line":271},[268,136915,108694],{"class":274},[268,136917,125974],{"class":278},[268,136919,84903],{"class":274},[268,136921,136922],{"class":278},"marker",[268,136924,84903],{"class":274},[268,136926,136927],{"class":278},"PhantomData",[268,136929,293],{"class":282},[268,136931,136932],{"class":270,"line":286},[268,136933,5033],{"emptyLinePlaceholder":35},[268,136935,136936,136938,136941,136943,136945],{"class":270,"line":296},[268,136937,121198],{"class":274},[268,136939,136940],{"class":278}," TypedId",[268,136942,1076],{"class":282},[268,136944,102486],{"class":278},[268,136946,121209],{"class":282},[268,136948,136949,136952,136954,136956],{"class":270,"line":311},[268,136950,136951],{"class":282},"    id",[268,136953,10728],{"class":274},[268,136955,117989],{"class":278},[268,136957,1789],{"class":282},[268,136959,136960,136963,136965,136968,136970,136972],{"class":270,"line":788},[268,136961,136962],{"class":282},"    _marker",[268,136964,10728],{"class":274},[268,136966,136967],{"class":278}," PhantomData",[268,136969,1076],{"class":282},[268,136971,102486],{"class":278},[268,136973,136974],{"class":282},">,\n",[268,136976,136977],{"class":270,"line":1951},[268,136978,314],{"class":282},[23,136980,136982,136993,137002,137008],{"className":136981},[26],[28,136983,136985,136987,136988,136990,136991],{"className":136984},[31],[33,136986],{"disabled":35,"type":36}," Telling the compiler a struct \"acts as if\" it owns\u002Fuses a ",[39,136989,102486],{}," for variance, drop-check, and auto-trait purposes, even though no field actually stores a ",[39,136992,102486],{},[28,136994,136996,136998,136999,137001],{"className":136995},[31],[33,136997],{"disabled":35,"type":36}," Allocating a placeholder value of type ",[39,137000,102486],{}," lazily on first access",[28,137003,137005,137007],{"className":137004},[31],[33,137006],{"disabled":35,"type":36}," Making a struct's fields optional at compile time",[28,137009,137011,137013,137014,137016,137017,137019],{"className":137010},[31],[33,137012],{"disabled":35,"type":36}," Forcing ",[39,137015,102486],{}," to implement ",[39,137018,124579],{}," so a zero value can be materialized",[66,137021,137022,137024,137032],{},[69,137023,71],{},[73,137025,137026,137028,137029,137031],{},[76,137027,78],{}," A — signals the compiler to treat the struct as if it owns\u002Fuses a ",[39,137030,102486],{},", for variance, drop-check, and auto-trait purposes",[73,137033,137034,355,137036,137038,137039,137042,137043,137045,137046,137049,137050,137052,137053,137055,137056,446,137058,137060,137061,137063,137064,3990,137066,137068,137069,137071,137072,137074],{},[76,137035,84],{},[39,137037,136904],{}," occupies zero space at runtime but participates in the type system: it affects variance (does ",[39,137040,137041],{},"TypedId\u003C&'a str>"," behave covariantly in ",[39,137044,120753],{},"?), the drop-checker (does dropping ",[39,137047,137048],{},"TypedId\u003CT>"," count as potentially dropping a ",[39,137051,102486],{},", affecting borrow-checking around ",[39,137054,102486],{},"'s lifetime?), and auto-trait inference (",[39,137057,128111],{},[39,137059,128114],{},") exactly as if a real ",[39,137062,102486],{}," field were present. It's commonly used for phantom-typed IDs, unit-of-measure wrappers, or marking unsafe code's intended ownership. It doesn't allocate anything, doesn't affect field optionality, and doesn't require ",[39,137065,129112],{},[39,137067,136904],{}," is constructible via ",[39,137070,136927],{}," regardless of what traits ",[39,137073,102486],{}," implements.",[15,137076,137077,137084,137117],{},[18,137078,137080,137081,137083],{"id":137079},"q4-which-of-the-following-best-describes-object-safety-for-a-trait-ie-what-determines-whether-dyn-trait-is-a-valid-type","Q4. Which of the following best describes \"object safety\" for a trait — i.e. what determines whether ",[39,137082,122543],{}," is a valid type?",[23,137085,137087,137096,137105,137111],{"className":137086},[26],[28,137088,137090,137092,137093,137095],{"className":137089},[31],[33,137091],{"disabled":35,"type":36}," A trait is object-safe roughly when none of its methods return ",[39,137094,124895],{}," by value or take generic type parameters, and it has no associated consts (with some further refinements)",[28,137097,137099,137101,137102,137104],{"className":137098},[31],[33,137100],{"disabled":35,"type":36}," Every trait in Rust is automatically object-safe; ",[39,137103,122543],{}," always compiles for any trait",[28,137106,137108,137110],{"className":137107},[31],[33,137109],{"disabled":35,"type":36}," A trait is object-safe only if it has exactly one method",[28,137112,137114,137116],{"className":137113},[31],[33,137115],{"disabled":35,"type":36}," Object safety is a runtime property checked when the trait object is constructed, not a compile-time one",[66,137118,137119,137121,137129],{},[69,137120,71],{},[73,137122,137123,137125,137126,137128],{},[76,137124,78],{}," A — roughly: no methods returning ",[39,137127,124895],{}," by value, no generic methods, no associated consts (plus a few more refinements)",[73,137130,137131,355,137133,137135,137136,137138,137139,137141,137142,137144,137145,137148,137149,137151,137152,137154,137155,4912,137158,137160],{},[76,137132,84],{},[39,137134,122543],{}," erases the concrete type behind a vtable, so any method whose signature depends on knowing the concrete ",[39,137137,124895],{}," size or identity at compile time (returning ",[39,137140,124895],{}," by value, taking ",[39,137143,124895],{}," by value as a non-receiver parameter, or having generic type parameters that would require monomorphizing per call site) can't be represented in a single vtable entry, making the trait not object-safe as-is (methods can individually opt out via ",[39,137146,137147],{},"where Self: Sized","). This is checked entirely at compile time — attempting ",[39,137150,121396],{}," for a non-object-safe trait is a compile error, never a runtime failure. Not every trait qualifies (e.g. ",[39,137153,122174],{}," is famously not object-safe because ",[39,137156,137157],{},"fn clone(&self) -> Self",[39,137159,124895],{}," by value), and method count is irrelevant to object safety.",[15,137162,137163,137172,137214,137257],{"language":111909},[18,137164,69815,137166,137168,137169,1685],{"id":137165},"q5-why-is-clone-not-object-safe-ie-why-cant-you-write-boxdyn-clone",[39,137167,122174],{}," not object-safe, i.e. why can't you write ",[39,137170,137171],{},"Box\u003Cdyn Clone>",[257,137173,137174],{"language":111909},[260,137175,137177],{"className":111918,"code":137176,"language":111909,"meta":264,"style":264},"trait Clone {\n    fn clone(&self) -> Self;\n}\n",[39,137178,137179,137188,137210],{"__ignoreMap":264},[268,137180,137181,137183,137186],{"class":270,"line":271},[268,137182,136649],{"class":274},[268,137184,137185],{"class":278}," Clone",[268,137187,9914],{"class":282},[268,137189,137190,137192,137195,137197,137199,137201,137203,137205,137208],{"class":270,"line":286},[268,137191,120364],{"class":274},[268,137193,137194],{"class":278}," clone",[268,137196,622],{"class":282},[268,137198,85350],{"class":274},[268,137200,87099],{"class":305},[268,137202,6131],{"class":282},[268,137204,113308],{"class":274},[268,137206,137207],{"class":305}," Self",[268,137209,293],{"class":282},[268,137211,137212],{"class":270,"line":296},[268,137213,314],{"class":282},[23,137215,137217,137228,137238,137246],{"className":137216},[26],[28,137218,137220,355,137222,4912,137225,137227],{"className":137219},[31],[33,137221],{"disabled":35,"type":36},[39,137223,137224],{},"clone(&self) -> Self",[39,137226,124895],{}," by value, and the vtable has no way to know the size of the concrete type to return, since that information is erased",[28,137229,137231,355,137233,71990,137235,137237],{"className":137230},[31],[33,137232],{"disabled":35,"type":36},[39,137234,122174],{},[39,137236,112499],{}," internally, which trait objects forbid",[28,137239,137241,355,137243,137245],{"className":137240},[31],[33,137242],{"disabled":35,"type":36},[39,137244,122174],{}," has too many blanket implementations for the compiler to resolve a vtable",[28,137247,137249,355,137251,137253,137254],{"className":137248},[31],[33,137250],{"disabled":35,"type":36},[39,137252,137171],{}," actually does compile; the restriction only applies to ",[39,137255,137256],{},"&dyn Clone",[66,137258,137259,137261,137271],{},[69,137260,71],{},[73,137262,137263,137265,137266,137268,137269],{},[76,137264,78],{}," A — returning ",[39,137267,124895],{}," by value requires knowing the concrete type's size, which is erased by ",[39,137270,128648],{},[73,137272,137273,812,137275,137278,137279,137282,137283,137285,137286,137288,137289,137291,137292,137294,137295,137297,137298,137300,137301,137303],{},[76,137274,84],{},[39,137276,137277],{},"dyn Clone"," trait object has erased its concrete type down to a ",[39,137280,137281],{},"(data pointer, vtable pointer)"," pair; the caller of ",[39,137284,128102],{}," on it has no compile-time knowledge of how large the returned ",[39,137287,124895],{}," is or how to place it on the stack, since different underlying types implementing ",[39,137290,122174],{}," have different sizes. This makes ",[39,137293,137157],{}," impossible to call through a vtable in a type-erased way, so the trait fails object safety. Neither ",[39,137296,112499],{}," nor blanket impls have anything to do with it, and ",[39,137299,137171],{}," fails to compile identically to ",[39,137302,137256],{}," — boxing doesn't change the object-safety requirement, since the vtable problem exists regardless of the pointer wrapper.",[15,137305,137306,137320,137355],{},[18,137307,137309,137310,64118,137313,64118,137316,137319],{"id":137308},"q6-given-fn-foot-traitx-t-versus-fn-foox-impl-trait-versus-fn-foox-boxdyn-trait-which-statement-is-correct","Q6. Given ",[39,137311,137312],{},"fn foo\u003CT: Trait>(x: T)",[39,137314,137315],{},"fn foo(x: impl Trait)",[39,137317,137318],{},"fn foo(x: Box\u003Cdyn Trait>)",", which statement is correct?",[23,137321,137323,137329,137335,137347],{"className":137322},[26],[28,137324,137326,137328],{"className":137325},[31],[33,137327],{"disabled":35,"type":36}," The first two are static dispatch (monomorphized per concrete type at compile time); the third is dynamic dispatch through a vtable at runtime",[28,137330,137332,137334],{"className":137331},[31],[33,137333],{"disabled":35,"type":36}," All three compile to identical machine code; the syntax differences are purely stylistic",[28,137336,137338,355,137340,137343,137344],{"className":137337},[31],[33,137339],{"disabled":35,"type":36},[39,137341,137342],{},"impl Trait"," in argument position uses dynamic dispatch, unlike ",[39,137345,137346],{},"\u003CT: Trait>",[28,137348,137350,355,137352,137354],{"className":137349},[31],[33,137351],{"disabled":35,"type":36},[39,137353,121396],{}," is resolved at compile time via monomorphization just like generics",[66,137356,137357,137359,137364],{},[69,137358,71],{},[73,137360,137361,137363],{},[76,137362,78],{}," A — the first two are static dispatch via monomorphization; the third is dynamic dispatch via a vtable",[73,137365,137366,355,137368,355,137370,186,137372,137374,137375,137378,137379,137381,137382,137384,137385,137387],{},[76,137367,84],{},[76,137369,438],{},[39,137371,137312],{},[39,137373,137315],{}," are exactly equivalent sugar for each other — both cause the compiler to generate a separate specialized copy of ",[39,137376,137377],{},"foo"," for every concrete type used at call sites (monomorphization), enabling inlining and eliminating indirect calls, at the cost of larger binary size (\"code bloat\") if used with many types. ",[39,137380,121396],{}," instead compiles ",[39,137383,137377],{}," once, taking a fat pointer, and dispatches each method call through the vtable at runtime — smaller binary, one indirect call per invocation, no inlining across the call boundary. They are not machine-code-identical, and ",[39,137386,137342],{}," in argument position is definitively static, not dynamic, dispatch.",[15,137389,137390,137398,137450],{},[18,137391,137393,137394,137397],{"id":137392},"q7-what-does-it-mean-for-a-generic-type-to-be-covariant-in-a-lifetime-parameter-using-a-t-as-the-canonical-example","Q7. What does it mean for a generic type to be \"covariant\" in a lifetime parameter, using ",[39,137395,137396],{},"&'a T"," as the canonical example?",[23,137399,137401,137426,137438,137444],{"className":137400},[26],[28,137402,137404,137406,137407,137410,137411,137414,137415,3299,137418,137421,137422,137425],{"className":137403},[31],[33,137405],{"disabled":35,"type":36}," If ",[39,137408,137409],{},"'long: 'short"," (i.e. ",[39,137412,137413],{},"'long"," outlives ",[39,137416,137417],{},"'short",[39,137419,137420],{},"&'long T"," can be used wherever ",[39,137423,137424],{},"&'short T"," is expected — the subtyping relationship on the lifetime carries over to the reference type",[28,137427,137429,137431,137432,46500,137434,137437],{"className":137428},[31],[33,137430],{"disabled":35,"type":36}," Covariance means the compiler automatically converts ",[39,137433,137396],{},[39,137435,137436],{},"&'a mut T"," when needed",[28,137439,137441,137443],{"className":137440},[31],[33,137442],{"disabled":35,"type":36}," Covariance means the type can be mutated through an immutable reference",[28,137445,137447,137449],{"className":137446},[31],[33,137448],{"disabled":35,"type":36}," Covariance only applies to trait objects, never to plain reference types",[66,137451,137452,137454,137459],{},[69,137453,71],{},[73,137455,137456,137458],{},[76,137457,78],{}," A — a longer-lived reference can be used where a shorter-lived one is expected, mirroring the lifetime subtyping relationship",[73,137460,137461,355,137463,137465,137466,137468,137469,137471,137472,137474,137475,137478,137479,137481,137482,137484,137485,137487,137488,446,137490,137492,137493,137465,137495,137497],{},[76,137462,84],{},[39,137464,137396],{}," is covariant in ",[39,137467,120753],{},": because a longer lifetime is considered a \"subtype\" of a shorter one (anything valid for longer is trivially valid for a shorter window), ",[39,137470,137420],{}," can be passed anywhere ",[39,137473,137424],{}," is needed automatically — this is what lets you pass a ",[39,137476,137477],{},"&'static str"," to a function expecting ",[39,137480,122395],{}," for any ",[39,137483,120753],{},". It has nothing to do with converting immutable to mutable references (that's an entirely separate, forbidden operation) or mutating through ",[39,137486,120804],{}," (that's interior mutability via ",[39,137489,113037],{},[39,137491,113034],{},", unrelated to variance). Variance applies broadly to any generic type over lifetimes or type parameters, not only trait objects — ",[39,137494,116767],{},[39,137496,102486],{},", for instance.",[15,137499,137500,137524,137562,137605],{"language":111909},[18,137501,55624,137503,186,137505,137507,137508,5804,137510,186,137512,137514,137515,137517,137518,137520,137521,137523],{"id":137502},"q8-cellt-and-refcellt-are-invariant-in-t-while-t-and-vect-are-covariant-in-t-why-does-refcellt-need-to-be-invariant-even-though-t-is-covariant",[39,137504,129876],{},[39,137506,128285],{}," are invariant in ",[39,137509,102486],{},[39,137511,120804],{},[39,137513,116767],{}," are covariant in ",[39,137516,102486],{},". Why does ",[39,137519,128285],{}," need to be invariant even though ",[39,137522,120804],{}," is covariant?",[257,137525,137526],{"language":111909},[260,137527,137529],{"className":111918,"code":137528,"language":111909,"meta":264,"style":264},"struct RefCell\u003CT> {\n    value: UnsafeCell\u003CT>,\n}\n",[39,137530,137531,137543,137558],{"__ignoreMap":264},[268,137532,137533,137535,137537,137539,137541],{"class":270,"line":271},[268,137534,121198],{"class":274},[268,137536,128713],{"class":278},[268,137538,1076],{"class":282},[268,137540,102486],{"class":278},[268,137542,121209],{"class":282},[268,137544,137545,137547,137549,137552,137554,137556],{"class":270,"line":286},[268,137546,51575],{"class":282},[268,137548,10728],{"class":274},[268,137550,137551],{"class":278}," UnsafeCell",[268,137553,1076],{"class":282},[268,137555,102486],{"class":278},[268,137557,136974],{"class":282},[268,137559,137560],{"class":270,"line":296},[268,137561,314],{"class":282},[23,137563,137565,137573,137579,137590],{"className":137564},[26],[28,137566,137568,12848,137570,137572],{"className":137567},[31],[33,137569],{"disabled":35,"type":36},[39,137571,113034],{}," allows mutation through a shared reference (interior mutability); if it were covariant, you could smuggle a shorter-lived value in through a longer-lived alias and later read it back out as the longer lifetime, unsoundly extending it",[28,137574,137576,137578],{"className":137575},[31],[33,137577],{"disabled":35,"type":36}," Invariance is just a conservative default the compiler applies to any struct with more than one field",[28,137580,137582,355,137584,137586,137587,137589],{"className":137581},[31],[33,137583],{"disabled":35,"type":36},[39,137585,128285],{}," is actually covariant; only ",[39,137588,129876],{}," is invariant",[28,137591,137593,137595,137596,137598,137599,137601,137602,137604],{"className":137592},[31],[33,137594],{"disabled":35,"type":36}," Invariance only matters for ",[39,137597,112499],{}," code; ",[39,137600,113034],{}," doesn't use ",[39,137603,112499],{}," internally so this is moot",[66,137606,137607,137609,137614],{},[69,137608,71],{},[73,137610,137611,137613],{},[76,137612,78],{}," A — covariance plus interior mutability would let a shorter-lived value be written in and later smuggled out under a longer lifetime, unsoundly extending it",[73,137615,137616,355,137618,137406,137620,137623,137624,137627,137628,137630,137631,137633,137634,137636,137637,137640,137641,137643,137644,137646,137647,3801,137649,137652,137653,137655,137656,137658,137659,137662,137663,446,137665,137668,137669,137671,137672,137674,137675,2182,137677,137679],{},[76,137617,84],{},[76,137619,582],{},[39,137621,137622],{},"RefCell\u003C&'short U>"," could coerce to ",[39,137625,137626],{},"RefCell\u003C&'long U>"," (covariance), code holding the ",[39,137629,137626],{}," handle could ",[39,137632,18333],{}," in a value borrowed for only ",[39,137635,137417],{},", then later ",[39,137638,137639],{},".borrow()"," it back out believing it's valid for ",[39,137642,137413],{}," — a lifetime-extension unsoundness bug. Because ",[39,137645,113034],{}," exposes mutation through ",[39,137648,112964],{},[39,137650,137651],{},"UnsafeCell",", the type system must be conservative and treat ",[39,137654,102486],{}," as invariant (",[39,137657,128285],{}," is neither a subtype nor supertype of ",[39,137660,137661],{},"RefCell\u003CU>"," even if ",[39,137664,102486],{},[39,137666,137667],{},"U"," are related), closing that hole. This isn't a generic \"more than one field\" rule — variance is derived structurally from how ",[39,137670,102486],{}," is actually used inside the type, and ",[39,137673,113034],{}," genuinely does rely on ",[39,137676,112499],{},[39,137678,137651],{},") internally precisely because interior mutability requires it; that's exactly why its variance can't be left permissive.",[15,137681,137682,137690,137780,137817],{"language":111909},[18,137683,137685,137686,137689],{"id":137684},"q9-what-happens-if-you-attempt-to-define-a-gat-style-associated-type-where-the-type-parameter-needs-a-where-self-a-bound-but-you-omit-it","Q9. What happens if you attempt to define a GAT-style associated type where the type parameter needs a ",[39,137687,137688],{},"where Self: 'a"," bound but you omit it?",[257,137691,137692],{"language":111909},[260,137693,137695],{"className":111918,"code":137694,"language":111909,"meta":264,"style":264},"trait LendingIterator {\n    type Item\u003C'a> where Self: 'a;\n    fn next\u003C'a>(&'a mut self) -> Option\u003CSelf::Item\u003C'a>>;\n}\n",[39,137696,137697,137706,137732,137776],{"__ignoreMap":264},[268,137698,137699,137701,137704],{"class":270,"line":271},[268,137700,136649],{"class":274},[268,137702,137703],{"class":278}," LendingIterator",[268,137705,9914],{"class":282},[268,137707,137708,137710,137712,137714,137716,137718,137721,137723,137725,137728,137730],{"class":270,"line":286},[268,137709,136659],{"class":274},[268,137711,136662],{"class":278},[268,137713,121204],{"class":282},[268,137715,1223],{"class":278},[268,137717,127009],{"class":282},[268,137719,137720],{"class":274},"where",[268,137722,137207],{"class":305},[268,137724,10728],{"class":274},[268,137726,137727],{"class":282}," '",[268,137729,1223],{"class":278},[268,137731,293],{"class":282},[268,137733,137734,137736,137738,137740,137742,137745,137747,137749,137751,137753,137755,137757,137759,137761,137763,137765,137767,137769,137771,137773],{"class":270,"line":296},[268,137735,120364],{"class":274},[268,137737,16907],{"class":278},[268,137739,121204],{"class":282},[268,137741,1223],{"class":278},[268,137743,137744],{"class":282},">(",[268,137746,85350],{"class":274},[268,137748,52434],{"class":282},[268,137750,1223],{"class":278},[268,137752,113071],{"class":274},[268,137754,96472],{"class":305},[268,137756,6131],{"class":282},[268,137758,113308],{"class":274},[268,137760,126457],{"class":278},[268,137762,1076],{"class":282},[268,137764,124895],{"class":305},[268,137766,84903],{"class":274},[268,137768,125123],{"class":278},[268,137770,121204],{"class":282},[268,137772,1223],{"class":278},[268,137774,137775],{"class":282},">>;\n",[268,137777,137778],{"class":270,"line":311},[268,137779,314],{"class":282},[23,137781,137783,137794,137802,137808],{"className":137782},[26],[28,137784,137786,137788,137789,137791,137792],{"className":137785},[31],[33,137787],{"disabled":35,"type":36}," Omitting a required ",[39,137790,137688],{}," clause on a GAT typically produces a compile error demanding the bound, because without it the compiler cannot prove the associated type's lifetime is compatible with borrows of ",[39,137793,124895],{},[28,137795,137797,137799,137800],{"className":137796},[31],[33,137798],{"disabled":35,"type":36}," The bound is optional stylistic sugar; omitting it silently defaults to ",[39,137801,112492],{},[28,137803,137805,137807],{"className":137804},[31],[33,137806],{"disabled":35,"type":36}," Omitting it causes a runtime panic the first time the associated type is instantiated",[28,137809,137811,137813,137814,137816],{"className":137810},[31],[33,137812],{"disabled":35,"type":36}," It compiles identically either way; ",[39,137815,137688],{}," has no semantic effect on GATs",[66,137818,137819,137821,137829],{},[69,137820,71],{},[73,137822,137823,137825,137826,137828],{},[76,137824,78],{}," A — omitting a required ",[39,137827,137688],{}," clause is a compile error demanding the bound",[73,137830,137831,137833,137834,137836,137837,137840,137841,137843,137844,137846,137847,137849,137850,137853,137854,137856],{},[76,137832,84],{}," GATs that borrow from ",[39,137835,124895],{}," (like a lending iterator's ",[39,137838,137839],{},"Item\u003C'a>",") generally need a ",[39,137842,137688],{}," clause so the compiler can verify, for every concrete lifetime ",[39,137845,120753],{}," the associated type gets instantiated with, that ",[39,137848,124895],{}," itself lives at least that long — without it, downstream code manipulating ",[39,137851,137852],{},"Self::Item\u003C'a>"," couldn't safely assume this relationship and the compiler rejects the trait definition (or usages of it) with a lifetime-bound error. It's not sugar and not optional when the implementation actually needs it, there's no ",[39,137855,112492],{}," default, and this is caught entirely at compile time — GATs, like all Rust generics, have no runtime instantiation step to panic during.",[15,137858,137859,137867,137914],{},[18,137860,137862,137863,137866],{"id":137861},"q10-a-trait-method-has-this-signature-fn-processt-sendself-val-t-can-this-trait-still-be-object-safe-overall-assuming-this-is-its-only-method","Q10. A trait method has this signature: ",[39,137864,137865],{},"fn process\u003CT: Send>(&self, val: T);",". Can this trait still be object-safe overall (assuming this is its only method)?",[23,137868,137870,137882,137890,137902],{"className":137869},[26],[28,137871,137873,137875,137876,137878,137879,137881],{"className":137872},[31],[33,137874],{"disabled":35,"type":36}," No — a generic method (one with its own type parameters beyond ",[39,137877,124895],{},") makes the trait not object-safe, because the vtable would need a separate entry per possible ",[39,137880,102486],{},", which is unbounded",[28,137883,137885,88213,137887,137889],{"className":137884},[31],[33,137886],{"disabled":35,"type":36},[39,137888,128111],{}," bounds have no effect on object safety, only lifetime bounds do",[28,137891,137893,137895,137896,24764,137899,137901],{"className":137892},[31],[33,137894],{"disabled":35,"type":36}," Yes — as long as ",[39,137897,137898],{},"T: Send",[39,137900,121292],{},", generic methods are exempted from the object-safety rule",[28,137903,137905,137907,137908,137910,137911,137913],{"className":137904},[31],[33,137906],{"disabled":35,"type":36}," No — but only because ",[39,137909,112964],{}," should be ",[39,137912,113013],{}," for the method to be considered",[66,137915,137916,137918,137923],{},[69,137917,71],{},[73,137919,137920,137922],{},[76,137921,78],{}," A — a generic method makes the trait not object-safe, since the vtable can't have unboundedly many entries",[73,137924,137925,137927,137928,137931,137932,137934,137935,137937,137938,137940,137941,137943,137944,7507,137946,137948],{},[76,137926,84],{}," A vtable is a fixed, finite table of function pointers built once per concrete implementing type; a generic method like ",[39,137929,137930],{},"process\u003CT>"," would need a distinct function pointer per possible ",[39,137933,102486],{}," used at any call site anywhere in the program, which is open-ended and unknowable at the point the vtable is built. This makes any trait with a generic method (regardless of what bound, ",[39,137936,128111],{}," or otherwise, is on that generic parameter) non-object-safe for that method — though the trait can still be used as ",[39,137939,137342],{}," or with static dispatch, or the method can be excluded from the vtable via ",[39,137942,137147],{}," on just that method. The receiver being ",[39,137945,112964],{},[39,137947,113013],{}," is unrelated to this particular restriction.",[15,137950,137951,137964,138032,138073],{"language":111909},[18,137952,137954,137955,137957,137958,186,137960,137963],{"id":137953},"q11-what-is-the-compile-time-behavior-of-this-code-given-that-iterator-has-one-associated-type-item-and-dyn-iterator-no-type-argument-is-written-without-specifying-it","Q11. What is the compile-time behavior of this code, given that ",[39,137956,129572],{}," has one associated type ",[39,137959,125123],{},[39,137961,137962],{},"dyn Iterator"," (no type argument) is written without specifying it?",[257,137965,137966],{"language":111909},[260,137967,137969],{"className":111918,"code":137968,"language":111909,"meta":264,"style":264},"fn make_iter() -> Box\u003Cdyn Iterator> {\n    Box::new(vec![1, 2, 3].into_iter())\n}\n",[39,137970,137971,137994,138028],{"__ignoreMap":264},[268,137972,137973,137975,137978,137980,137982,137985,137987,137989,137992],{"class":270,"line":271},[268,137974,37837],{"class":274},[268,137976,137977],{"class":278}," make_iter",[268,137979,16182],{"class":282},[268,137981,113308],{"class":274},[268,137983,137984],{"class":278}," Box",[268,137986,1076],{"class":282},[268,137988,128648],{"class":274},[268,137990,137991],{"class":278}," Iterator",[268,137993,121209],{"class":282},[268,137995,137996,137999,138001,138003,138005,138007,138009,138011,138013,138015,138017,138019,138021,138023,138026],{"class":270,"line":286},[268,137997,137998],{"class":278},"    Box",[268,138000,84903],{"class":274},[268,138002,2689],{"class":278},[268,138004,622],{"class":282},[268,138006,128424],{"class":278},[268,138008,15175],{"class":282},[268,138010,2255],{"class":305},[268,138012,42],{"class":282},[268,138014,2258],{"class":305},[268,138016,42],{"class":282},[268,138018,3423],{"class":305},[268,138020,17149],{"class":282},[268,138022,462],{"class":274},[268,138024,138025],{"class":278},"into_iter",[268,138027,53907],{"class":282},[268,138029,138030],{"class":270,"line":296},[268,138031,314],{"class":282},[23,138033,138035,138044,138056,138067],{"className":138034},[26],[28,138036,138038,138040,138041],{"className":138037},[31],[33,138039],{"disabled":35,"type":36}," Compile error — a trait object over a trait with an associated type must specify that associated type, e.g. ",[39,138042,138043],{},"dyn Iterator\u003CItem = i32>",[28,138045,138047,138049,138050,28179,138052,138055],{"className":138046},[31],[33,138048],{"disabled":35,"type":36}," Compiles fine; the compiler infers ",[39,138051,125123],{},[39,138053,138054],{},"Box::new"," argument automatically",[28,138057,138059,138061,138062,4001,138064,138066],{"className":138058},[31],[33,138060],{"disabled":35,"type":36}," Compiles fine; ",[39,138063,125123],{},[39,138065,16952],{}," when omitted from a trait object",[28,138068,138070,138072],{"className":138069},[31],[33,138071],{"disabled":35,"type":36}," Compiles fine; associated types are erased entirely for trait objects and don't need specifying",[66,138074,138075,138077,138084],{},[69,138076,71],{},[73,138078,138079,138081,138082],{},[76,138080,78],{}," A — compile error; trait objects must specify associated types explicitly, e.g. ",[39,138083,138043],{},[73,138085,138086,355,138088,138090,138091,138093,138094,138096,138097,138099,138100,138102,138103,138105],{},[76,138087,84],{},[76,138089,365],{}," Unlike a generic type parameter, an associated type is part of the trait's contract that must be pinned down to form a concrete, well-defined vtable — ",[39,138092,137962],{}," alone is ambiguous about what ",[39,138095,17034],{}," returns, so Rust requires ",[39,138098,138043],{}," (or whatever concrete item type) to be written explicitly. This differs from ordinary type inference elsewhere in the language; there's no defaulting to ",[39,138101,16952],{},", no erasure of associated types (the vtable's ",[39,138104,16949],{}," method needs a known return layout), and no automatic inference from the constructor argument in the return-type position — the function signature itself must be unambiguous independent of the body.",[15,138107,138108,138117,138191,138222],{"language":111909},[18,138109,106957,138111,138113,138114,138116],{"id":138110},"q12-what-is-the-effect-of-non_exhaustive-combined-with-a-private-field-pattern-versus-using-phantomdata-purely-for-sealing-a-trait-so-external-crates-cannot-implement-it-which-correctly-implements-the-sealed-trait-pattern",[39,138112,125151],{}," combined with a private field pattern versus using ",[39,138115,136927],{}," purely for sealing a trait so external crates cannot implement it — which correctly implements the \"sealed trait\" pattern?",[257,138118,138119],{"language":111909},[260,138120,138122],{"className":111918,"code":138121,"language":111909,"meta":264,"style":264},"mod sealed {\n    pub trait Sealed {}\n}\n\npub trait MyTrait: sealed::Sealed {\n    fn method(&self);\n}\n",[39,138123,138124,138133,138145,138149,138153,138173,138187],{"__ignoreMap":264},[268,138125,138126,138128,138131],{"class":270,"line":271},[268,138127,130774],{"class":274},[268,138129,138130],{"class":278}," sealed",[268,138132,9914],{"class":282},[268,138134,138135,138138,138140,138143],{"class":270,"line":286},[268,138136,138137],{"class":274},"    pub",[268,138139,122242],{"class":274},[268,138141,138142],{"class":278}," Sealed",[268,138144,30486],{"class":282},[268,138146,138147],{"class":270,"line":296},[268,138148,314],{"class":282},[268,138150,138151],{"class":270,"line":311},[268,138152,5033],{"emptyLinePlaceholder":35},[268,138154,138155,138157,138159,138162,138164,138166,138168,138171],{"class":270,"line":788},[268,138156,117577],{"class":274},[268,138158,122242],{"class":274},[268,138160,138161],{"class":278}," MyTrait",[268,138163,10728],{"class":274},[268,138165,138130],{"class":278},[268,138167,84903],{"class":274},[268,138169,138170],{"class":278},"Sealed",[268,138172,9914],{"class":282},[268,138174,138175,138177,138179,138181,138183,138185],{"class":270,"line":1951},[268,138176,120364],{"class":274},[268,138178,100975],{"class":278},[268,138180,622],{"class":282},[268,138182,85350],{"class":274},[268,138184,87099],{"class":305},[268,138186,628],{"class":282},[268,138188,138189],{"class":270,"line":8955},[268,138190,314],{"class":282},[23,138192,138194,138200,138208,138216],{"className":138193},[26],[28,138195,138197,138199],{"className":138196},[31],[33,138198],{"disabled":35,"type":36}," Making the public trait require a supertrait defined in a private module that external crates cannot name or implement, so they cannot satisfy the supertrait bound and thus cannot implement the public trait",[28,138201,138203,28423,138205,138207],{"className":138202},[31],[33,138204],{"disabled":35,"type":36},[39,138206,125151],{}," to the trait definition itself prevents external implementations",[28,138209,138211,97641,138213,138215],{"className":138210},[31],[33,138212],{"disabled":35,"type":36},[39,138214,136927],{}," as an associated type prevents external crates from implementing the trait",[28,138217,138219,138221],{"className":138218},[31],[33,138220],{"disabled":35,"type":36}," There is no way to prevent external crates from implementing a public trait; visibility only affects structs and enums",[66,138223,138224,138226,138231],{},[69,138225,71],{},[73,138227,138228,138230],{},[76,138229,78],{}," A — require a supertrait from a private module that outside crates can't name or implement",[73,138232,138233,355,138235,138237,138238,138241,138242,4948,138245,138248,138249,138251,138252,138254,138255,138257,138258,138260,138261,138263,138264,138266,138267,138269,138270,138272],{},[76,138234,84],{},[76,138236,930],{}," The \"sealed trait\" pattern exploits the fact that implementing ",[39,138239,138240],{},"MyTrait"," requires also implementing ",[39,138243,138244],{},"sealed::Sealed",[39,138246,138247],{},"sealed"," is a private module — external crates can ",[104,138250,63196],{}," and use ",[39,138253,138240],{}," (it's ",[39,138256,117577],{},") but cannot name ",[39,138259,138244],{}," to provide an impl of it, so they're structurally barred from ever implementing ",[39,138262,138240],{},", while code within the defining crate can implement both freely. ",[39,138265,125151],{}," only affects exhaustive matching\u002Fconstruction of structs, enums, and variants — it has no effect on trait implementability. ",[39,138268,136927],{}," is a marker for variance\u002Fdrop-check, unrelated to sealing. This pattern is exactly why sealing traits ",[104,138271,4447],{}," possible, contrary to the last option.",[15,138274,138275,138289,138411,138456],{"language":111909},[18,138276,138278,138279,138282,138283,138285,138286,1685],{"id":138277},"q13-whats-wrong-with-this-attempt-to-implement-a-trait-generically-for-a-type-parameter-assuming-wrappert-is-a-local-struct-and-display-is-from-stdfmt","Q13. What's wrong with this attempt to implement a trait generically for a type parameter, assuming ",[39,138280,138281],{},"Wrapper\u003CT>"," is a local struct and ",[39,138284,127368],{}," is from ",[39,138287,138288],{},"std::fmt",[257,138290,138291],{"language":111909},[260,138292,138294],{"className":111918,"code":138293,"language":111909,"meta":264,"style":264},"struct Wrapper\u003CT>(T);\n\nimpl\u003CT> std::fmt::Display for T {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        write!(f, \"generic\")\n    }\n}\n",[39,138295,138296,138312,138316,138343,138390,138403,138407],{"__ignoreMap":264},[268,138297,138298,138300,138302,138304,138306,138308,138310],{"class":270,"line":271},[268,138299,121198],{"class":274},[268,138301,123568],{"class":278},[268,138303,1076],{"class":282},[268,138305,102486],{"class":278},[268,138307,137744],{"class":282},[268,138309,102486],{"class":278},[268,138311,628],{"class":282},[268,138313,138314],{"class":270,"line":286},[268,138315,5033],{"emptyLinePlaceholder":35},[268,138317,138318,138320,138322,138324,138326,138328,138330,138333,138335,138337,138339,138341],{"class":270,"line":296},[268,138319,123290],{"class":274},[268,138321,1076],{"class":282},[268,138323,102486],{"class":278},[268,138325,127009],{"class":282},[268,138327,109737],{"class":278},[268,138329,84903],{"class":274},[268,138331,138332],{"class":278},"fmt",[268,138334,84903],{"class":274},[268,138336,127368],{"class":278},[268,138338,85712],{"class":274},[268,138340,119649],{"class":278},[268,138342,9914],{"class":282},[268,138344,138345,138347,138350,138352,138354,138356,138359,138361,138363,138365,138367,138369,138371,138374,138376,138378,138380,138382,138384,138386,138388],{"class":270,"line":311},[268,138346,120364],{"class":274},[268,138348,138349],{"class":278}," fmt",[268,138351,622],{"class":282},[268,138353,85350],{"class":274},[268,138355,87099],{"class":305},[268,138357,138358],{"class":282},", f",[268,138360,10728],{"class":274},[268,138362,126710],{"class":274},[268,138364,125974],{"class":278},[268,138366,84903],{"class":274},[268,138368,138332],{"class":278},[268,138370,84903],{"class":274},[268,138372,138373],{"class":278},"Formatter",[268,138375,6131],{"class":282},[268,138377,113308],{"class":274},[268,138379,125974],{"class":278},[268,138381,84903],{"class":274},[268,138383,138332],{"class":278},[268,138385,84903],{"class":274},[268,138387,110110],{"class":278},[268,138389,9914],{"class":282},[268,138391,138392,138395,138398,138401],{"class":270,"line":788},[268,138393,138394],{"class":278},"        write!",[268,138396,138397],{"class":282},"(f, ",[268,138399,138400],{"class":289},"\"generic\"",[268,138402,20702],{"class":282},[268,138404,138405],{"class":270,"line":1951},[268,138406,11972],{"class":282},[268,138408,138409],{"class":270,"line":8955},[268,138410,314],{"class":282},[23,138412,138414,138429,138435,138447],{"className":138413},[26],[28,138415,138417,138419,138420,138422,138423,138425,138426,138428],{"className":138416},[31],[33,138418],{"disabled":35,"type":36}," This violates the orphan rule: you cannot implement a foreign trait (",[39,138421,127368],{},", from ",[39,138424,109737],{},") for a fully generic, unconstrained type ",[39,138427,102486],{}," that isn't local to this crate — it must be a local type or the trait must be local",[28,138430,138432,138434],{"className":138431},[31],[33,138433],{"disabled":35,"type":36}," This is valid but only compiles in edition 2021 and later",[28,138436,138438,138440,138441,138443,138444,138446],{"className":138437},[31],[33,138439],{"disabled":35,"type":36}," The error is that ",[39,138442,138281],{}," should have been used instead of ",[39,138445,102486],{},", but otherwise the pattern is fine",[28,138448,138450,138452,138453,138455],{"className":138449},[31],[33,138451],{"disabled":35,"type":36}," This is legal Rust; the orphan rule only restricts ",[39,138454,123290],{}," blocks for concrete foreign types, not generic ones",[66,138457,138458,138460,138468],{},[69,138459,71],{},[73,138461,138462,138464,138465,138467],{},[76,138463,78],{}," A — this violates the orphan rule; both the trait and the blanket-implemented type must have some local connection, and a bare unconstrained ",[39,138466,102486],{}," has none",[73,138469,138470,355,138472,138474,138475,138478,138479,99,138482,138485,138486,138488,138489,138491,138492,138494,138495,138497,138498,138500,138501,138504,138505,138507,138508,138510],{},[76,138471,84],{},[76,138473,582],{}," The orphan rule requires that for ",[39,138476,138477],{},"impl Trait for Type",", either ",[39,138480,138481],{},"Trait",[39,138483,138484],{},"Type"," be local to the current crate (with generic parameters needing to appear \"covered\" by a local type when the trait is foreign). Here ",[39,138487,127368],{}," is foreign (from ",[39,138490,109737],{},") and ",[39,138493,102486],{}," is a fully generic, uncovered type parameter — not ",[39,138496,138281],{},", which ",[104,138499,13519],{}," be local and legal (",[39,138502,138503],{},"impl\u003CT: Display> Display for Wrapper\u003CT>"," compiles fine). Allowing a blanket foreign-trait-for-any-",[39,138506,102486],{}," impl would let any crate globally claim ",[39,138509,127368],{}," for every type in the ecosystem, causing unresolvable conflicts if two crates both tried it — exactly the coherence violation the orphan rule exists to prevent. This is not edition-gated; the rule is a fundamental, long-standing part of trait coherence.",[15,138512,138513,138520,138595,138628],{"language":111909},[18,138514,7516,138516,138519],{"id":138515},"q14-what-does-self-sized-mean-when-added-as-a-bound-to-an-individual-trait-method-and-why-would-you-add-it",[39,138517,138518],{},"Self: Sized"," mean when added as a bound to an individual trait method, and why would you add it?",[257,138521,138522],{"language":111909},[260,138523,138525],{"className":111918,"code":138524,"language":111909,"meta":264,"style":264},"trait Shape {\n    fn area(&self) -> f64;\n    fn scaled(self, factor: f64) -> Self where Self: Sized;\n}\n",[39,138526,138527,138535,138556,138591],{"__ignoreMap":264},[268,138528,138529,138531,138533],{"class":270,"line":271},[268,138530,136649],{"class":274},[268,138532,32866],{"class":278},[268,138534,9914],{"class":282},[268,138536,138537,138539,138541,138543,138545,138547,138549,138551,138554],{"class":270,"line":286},[268,138538,120364],{"class":274},[268,138540,32275],{"class":278},[268,138542,622],{"class":282},[268,138544,85350],{"class":274},[268,138546,87099],{"class":305},[268,138548,6131],{"class":282},[268,138550,113308],{"class":274},[268,138552,138553],{"class":278}," f64",[268,138555,293],{"class":282},[268,138557,138558,138560,138562,138564,138566,138569,138571,138573,138575,138577,138579,138582,138584,138586,138589],{"class":270,"line":296},[268,138559,120364],{"class":274},[268,138561,37094],{"class":278},[268,138563,622],{"class":282},[268,138565,87099],{"class":305},[268,138567,138568],{"class":282},", factor",[268,138570,10728],{"class":274},[268,138572,138553],{"class":278},[268,138574,6131],{"class":282},[268,138576,113308],{"class":274},[268,138578,137207],{"class":305},[268,138580,138581],{"class":274}," where",[268,138583,137207],{"class":305},[268,138585,10728],{"class":274},[268,138587,138588],{"class":278}," Sized",[268,138590,293],{"class":282},[268,138592,138593],{"class":270,"line":311},[268,138594,314],{"class":282},[23,138596,138598,138610,138616,138622],{"className":138597},[26],[28,138599,138601,138603,138604,138606,138607],{"className":138600},[31],[33,138602],{"disabled":35,"type":36}," It opts that specific method out of being included in the trait's vtable, allowing the rest of the trait to remain object-safe even though this one method (which takes\u002Freturns ",[39,138605,124895],{}," by value) could not itself be called through ",[39,138608,138609],{},"dyn Shape",[28,138611,138613,138615],{"className":138612},[31],[33,138614],{"disabled":35,"type":36}," It forces every implementor of the trait to be a fixed, statically known size at compile time, which all Rust types already are by default anyway so the bound is meaningless",[28,138617,138619,138621],{"className":138618},[31],[33,138620],{"disabled":35,"type":36}," It's required on every trait method as boilerplate and has no functional effect",[28,138623,138625,138627],{"className":138624},[31],[33,138626],{"disabled":35,"type":36}," It disables monomorphization for that method, forcing dynamic dispatch even when called via a generic",[66,138629,138630,138632,138639],{},[69,138631,71],{},[73,138633,138634,138636,138637],{},[76,138635,78],{}," A — it excludes that method from the vtable, letting the rest of the trait stay object-safe despite this method being incompatible with ",[39,138638,128648],{},[73,138640,138641,355,138643,138645,138646,138648,138649,138652,138653,138655,138656,138659,138660,138662,138663,138665,138666,138668,138669,138672,138673,138675,138676,138679,138680,138682,138683,138686],{},[76,138642,84],{},[76,138644,930],{}," Methods that take or return ",[39,138647,124895],{}," by value (like ",[39,138650,138651],{},"scaled",", which consumes and returns ",[39,138654,124895],{},") are individually incompatible with dynamic dispatch for the same reason ",[39,138657,138658],{},"Clone::clone"," is — the vtable can't represent an unsized-context by-value ",[39,138661,124895],{},". Adding ",[39,138664,137147],{}," to just that method tells the compiler \"this method is unavailable when called through ",[39,138667,138609],{},",\" which excludes it from the vtable while leaving the rest of the trait (like ",[39,138670,138671],{},"area(&self)",") usable through ",[39,138674,138609],{}," — a common technique to make otherwise-inconvenient traits partially object-safe. It's not boilerplate (most methods don't need it), it doesn't relate to monomorphization\u002Fdispatch selection for other calls, and while most types genuinely are ",[39,138677,138678],{},"Sized"," by default, trait objects (",[39,138681,122543],{},") and slices (",[39,138684,138685],{},"[T]",") are the important unsized exceptions this bound is specifically excluding.",[15,138688,138689,138693,138726],{},[18,138690,138692],{"id":138691},"q15-when-designing-a-trait-when-should-you-prefer-an-associated-type-over-a-generic-type-parameter-as-a-matter-of-api-design-idiom","Q15. When designing a trait, when should you prefer an associated type over a generic type parameter as a matter of API design idiom?",[23,138694,138696,138708,138714,138720],{"className":138695},[26],[28,138697,138699,138701,138702,138704,138705,138707],{"className":138698},[31],[33,138700],{"disabled":35,"type":36}," When there is logically only one sensible output type per implementation (e.g. one ",[39,138703,125123],{}," type per iterator, one ",[39,138706,48601],{}," type per parser) — use an associated type; when a type can meaningfully implement the trait multiple times for different type arguments, use a generic parameter",[28,138709,138711,138713],{"className":138710},[31],[33,138712],{"disabled":35,"type":36}," Always prefer generic type parameters; associated types are a legacy feature kept only for backward compatibility",[28,138715,138717,138719],{"className":138716},[31],[33,138718],{"disabled":35,"type":36}," Associated types should be used whenever performance matters, since they avoid monomorphization",[28,138721,138723,138725],{"className":138722},[31],[33,138724],{"disabled":35,"type":36}," It's purely a stylistic choice with no design implications either way",[66,138727,138728,138730,138735],{},[69,138729,71],{},[73,138731,138732,138734],{},[76,138733,78],{}," A — use an associated type when there's one canonical output per impl; use a generic when a type can implement the trait multiple ways",[73,138736,138737,355,138739,138741,138742,42,138745,137,138748,138751,138752,138754,138755,138757,138758,138760,138761,446,138763,138766,138767,42,138770,138773,138774,138776],{},[76,138738,84],{},[76,138740,930],{}," This is the standard Rust API-design heuristic: ",[39,138743,138744],{},"Iterator::Item",[39,138746,138747],{},"Add::Output",[39,138749,138750],{},"Deref::Target"," are associated types because a given type has exactly one sensible answer (a ",[39,138753,128512],{},"'s iterator only ever yields ",[39,138756,113860],{},"), which also gives callers cleaner type inference (no need to annotate ",[39,138759,125123],{}," at every call site). ",[39,138762,136824],{},[39,138764,138765],{},"Into\u003CT>"," are generic-parameterized because a single type genuinely can convert from many different source types (",[39,138768,138769],{},"String: From\u003C&str>",[39,138771,138772],{},"String: From\u003Cchar>",", etc.), which associated types couldn't express since each impl would collide. Neither choice affects monomorphization or dispatch strategy by itself — that's a function of ",[39,138775,128648],{}," vs static generics, orthogonal to associated-type-vs-generic-parameter. This is a real, consequential API design decision, not a stylistic wash.",[15,138778,138779,138791,138841],{},[18,138780,138782,138783,138786,138787,138790],{"id":138781},"q16-a-crate-defines-trait-repositoryt-fn-saveself-item-t-and-separately-has-three-concrete-repository-structs-a-reviewer-suggests-switching-to-trait-repository-type-item-fn-saveself-item-selfitem-instead-when-is-this-refactor-the-better-idiomatic-choice","Q16. A crate defines ",[39,138784,138785],{},"trait Repository\u003CT> { fn save(&self, item: T); }"," and separately has three concrete repository structs. A reviewer suggests switching to ",[39,138788,138789],{},"trait Repository { type Item; fn save(&self, item: Self::Item); }"," instead. When is this refactor the better idiomatic choice?",[23,138792,138794,138814,138820,138832],{"className":138793},[26],[28,138795,138797,138799,138800,186,138803,138806,138807,138810,138811,138813],{"className":138796},[31],[33,138798],{"disabled":35,"type":36}," When each concrete repository type is only ever meant to store one specific item type — the associated-type version prevents accidentally implementing ",[39,138801,138802],{},"Repository\u003CFoo>",[39,138804,138805],{},"Repository\u003CBar>"," on the same struct and simplifies generic code that's writing against ",[39,138808,138809],{},"impl Repository"," without specifying ",[39,138812,102486],{}," everywhere",[28,138815,138817,138819],{"className":138816},[31],[33,138818],{"disabled":35,"type":36}," Never — generic parameters are strictly more powerful and associated types should be avoided whenever a generic would also work",[28,138821,138823,67576,138825,138827,138828,99,138830],{"className":138822},[31],[33,138824],{"disabled":35,"type":36},[39,138826,102486],{}," is a primitive type like ",[39,138829,113860],{},[39,138831,89412],{},[28,138833,138835,131399,138837,138840],{"className":138834},[31],[33,138836],{"disabled":35,"type":36},[39,138838,138839],{},"Repository"," needs to be object-safe, since generic-parameter traits are always automatically object-safe",[66,138842,138843,138845,138850],{},[69,138844,71],{},[73,138846,138847,138849],{},[76,138848,78],{}," A — when each repository is meant to store exactly one item type, associated types prevent accidental multi-impl and simplify generic call sites",[73,138851,138852,355,138854,137406,138856,138858,138859,138861,138862,138865,138866,138869,138870,138873,138874,138877,138878,138880,138881,138884,138885,138888,138889,138891,138892,138895,138896,138898],{},[76,138853,84],{},[76,138855,930],{},[39,138857,77274],{}," should only ever save ",[39,138860,123025],{},"s, the generic version ",[39,138863,138864],{},"Repository\u003CT>"," technically permits also implementing ",[39,138867,138868],{},"Repository\u003COtherType>"," on the same struct by accident (nothing stops it), while ",[39,138871,138872],{},"Repository { type Item; }"," makes \"one item type per repository\" a structural guarantee. It also means code generic over ",[39,138875,138876],{},"fn process\u003CR: Repository>(repo: R)"," doesn't need an extra ",[39,138879,102486],{}," parameter threaded through — ",[39,138882,138883],{},"R::Item"," is derivable. This is a real trade-off, not a strict-dominance situation — generics remain correct when multiple simultaneous implementations genuinely make sense (as in Q1's ",[39,138886,138887],{},"Container\u003CT>","). Object safety is unrelated: a generic-parameter trait like ",[39,138890,138864],{}," is not automatically object-safe either — ",[39,138893,138894],{},"dyn Repository\u003CT>"," still needs a concrete ",[39,138897,102486],{}," picked, same as an associated type needing to be pinned down; generic methods within an impl are what break object safety, not the presence of a type parameter on the trait itself.",[15,138900,138901,138911,138950],{},[18,138902,138904,138905,138907,138908,1685],{"id":138903},"q17-in-idiomatic-rust-when-should-a-public-api-function-accept-impl-trait-in-argument-position-versus-dyn-trait","Q17. In idiomatic Rust, when should a public API function accept ",[39,138906,137342],{}," in argument position versus ",[39,138909,138910],{},"&dyn Trait",[23,138912,138914,138926,138936,138942],{"className":138913},[26],[28,138915,138917,138919,138920,138922,138923,138925],{"className":138916},[31],[33,138918],{"disabled":35,"type":36}," Prefer ",[39,138921,137342],{}," (or a generic bound) by default for performance-sensitive or small-surface-area APIs since it enables inlining and avoids vtable indirection; reach for ",[39,138924,138910],{}," when you need to store heterogeneous trait objects in a collection, reduce compile times\u002Fbinary size from excessive monomorphization, or avoid generic code bloat across many call sites",[28,138927,138929,4207,138931,2272,138933,138935],{"className":138928},[31],[33,138930],{"disabled":35,"type":36},[39,138932,138910],{},[39,138934,137342],{}," in argument position is deprecated",[28,138937,138939,138941],{"className":138938},[31],[33,138940],{"disabled":35,"type":36}," They are interchangeable in every context including trait method signatures used as trait objects",[28,138943,138945,138919,138947,138949],{"className":138944},[31],[33,138946],{"disabled":35,"type":36},[39,138948,137342],{}," only for return types, never for arguments — using it for arguments is a syntax error",[66,138951,138952,138954,138965],{},[69,138953,71],{},[73,138955,138956,138958,138959,138961,138962,138964],{},[76,138957,78],{}," A — default to ",[39,138960,137342],{},"\u002Fgenerics for performance; use ",[39,138963,138910],{}," for heterogeneous collections or to curb monomorphization bloat",[73,138966,138967,355,138969,138972,138973,138975,138976,138979,138980,138982,138983,138985,138986,10819,138988,138990,138991,138993,138994,138996],{},[76,138968,84],{},[76,138970,138971],{},"Performance\u002FIdiom:"," This mirrors the static-vs-dynamic dispatch trade-off from Q6: ",[39,138974,137342],{}," arguments get monomorphized per call site, which is usually the right default for hot paths since it allows inlining, but if a function is called with many different concrete types across a large codebase, or if you need a ",[39,138977,138978],{},"Vec\u003CBox\u003Cdyn Trait>>"," of mixed concrete types, ",[39,138981,122543],{}," avoids both the code-size explosion and enables true runtime heterogeneity that generics fundamentally cannot express (a ",[39,138984,116767],{}," can only hold one ",[39,138987,102486],{},[39,138989,137342],{}," in argument position is valid, current, non-deprecated syntax and works in both positions (though the two behave differently in the two positions regarding caller vs. callee choosing the type) — this option is fabricated. And ",[39,138992,137342],{}," cannot be used directly in a trait method signature that also needs to be object-safe\u002Fused as ",[39,138995,128648],{},", since that would itself introduce a hidden generic parameter, colliding with object-safety rules from Q10.",[15,138998,138999,139006,139085,139112],{"language":111909},[18,139000,139002,139003,139005],{"id":139001},"q18-what-is-the-idiomatic-reason-to-reach-for-a-gat-instead-of-just-returning-owned-data-cloning-from-a-trait-method-that-would-otherwise-need-to-borrow-from-mut-self-per-call","Q18. What is the idiomatic reason to reach for a GAT instead of just returning owned data (cloning) from a trait method that would otherwise need to borrow from ",[39,139004,113013],{}," per call?",[257,139007,139008],{"language":111909},[260,139009,139011],{"className":111918,"code":139010,"language":111909,"meta":264,"style":264},"trait WindowIterator {\n    type Window\u003C'a> where Self: 'a;\n    fn next_window(&mut self) -> Option\u003CSelf::Window\u003C'_>>;\n}\n",[39,139012,139013,139022,139047,139081],{"__ignoreMap":264},[268,139014,139015,139017,139020],{"class":270,"line":271},[268,139016,136649],{"class":274},[268,139018,139019],{"class":278}," WindowIterator",[268,139021,9914],{"class":282},[268,139023,139024,139026,139029,139031,139033,139035,139037,139039,139041,139043,139045],{"class":270,"line":286},[268,139025,136659],{"class":274},[268,139027,139028],{"class":278}," Window",[268,139030,121204],{"class":282},[268,139032,1223],{"class":278},[268,139034,127009],{"class":282},[268,139036,137720],{"class":274},[268,139038,137207],{"class":305},[268,139040,10728],{"class":274},[268,139042,137727],{"class":282},[268,139044,1223],{"class":278},[268,139046,293],{"class":282},[268,139048,139049,139051,139054,139056,139058,139060,139062,139064,139066,139068,139070,139072,139075,139077,139079],{"class":270,"line":296},[268,139050,120364],{"class":274},[268,139052,139053],{"class":278}," next_window",[268,139055,622],{"class":282},[268,139057,114510],{"class":274},[268,139059,96472],{"class":305},[268,139061,6131],{"class":282},[268,139063,113308],{"class":274},[268,139065,126457],{"class":278},[268,139067,1076],{"class":282},[268,139069,124895],{"class":305},[268,139071,84903],{"class":274},[268,139073,139074],{"class":278},"Window",[268,139076,121204],{"class":282},[268,139078,52315],{"class":278},[268,139080,137775],{"class":282},[268,139082,139083],{"class":270,"line":311},[268,139084,314],{"class":282},[23,139086,139088,139094,139100,139106],{"className":139087},[26],[28,139089,139091,139093],{"className":139090},[31],[33,139092],{"disabled":35,"type":36}," To avoid the allocation\u002Fclone cost of materializing owned data on every call when the underlying data can instead be borrowed directly, which matters in hot loops over large buffers",[28,139095,139097,139099],{"className":139096},[31],[33,139098],{"disabled":35,"type":36}," GATs are purely a compile-time convenience with no runtime performance implication either way",[28,139101,139103,139105],{"className":139102},[31],[33,139104],{"disabled":35,"type":36}," Cloning is always faster than borrowing in Rust, so GATs are used for API ergonomics only, never performance",[28,139107,139109,139111],{"className":139108},[31],[33,139110],{"disabled":35,"type":36}," GATs eliminate the need for lifetimes entirely in the method signature",[66,139113,139114,139116,139121],{},[69,139115,71],{},[73,139117,139118,139120],{},[76,139119,78],{}," A — to avoid allocation\u002Fclone overhead by borrowing directly instead of materializing owned copies each call",[73,139122,139123,355,139125,139127,139128,139130,139131,139134,139135,139137,139138,139141,139142,139145],{},[76,139124,84],{},[76,139126,438],{}," Before GATs, a trait method wanting to return \"a view into ",[39,139129,87099],{},"\" per call had no way to express a per-call lifetime in an associated type, so implementors were forced to either return owned\u002Fcloned data (extra allocation and copying on every iteration) or use awkward external-iteration workarounds. GATs let ",[39,139132,139133],{},"Window\u003C'a>"," borrow from ",[39,139136,87099],{}," for exactly the call's lifetime, which is why \"lending iterators\" over large in-memory buffers (audio samples, matrix rows, parser tokens) benefit — no per-item allocation. It's very much a runtime-performance-relevant feature, not merely compile-time sugar, cloning is not \"always faster\" (it's essentially always slower or equal, since it does strictly more work than a borrow), and lifetimes remain very much present in GAT signatures (",[39,139139,139140],{},"Self::Window\u003C'_>",") — GATs add lifetime ",[104,139143,139144],{},"parameters"," to associated types, they don't remove lifetimes from the picture.",[15,139147,139148,139159,139200],{},[18,139149,139151,139152,139155,139156,139158],{"id":139150},"q19-why-does-the-standard-library-not-define-iteratornextmut-self-optionselfitem_-ie-why-is-the-standard-iteratoritem-not-a-gat-even-though-a-lending-iterator-would-seem-more-general","Q19. Why does the standard library NOT define ",[39,139153,139154],{},"Iterator::next(&mut self) -> Option\u003CSelf::Item\u003C'_>>"," (i.e. why is the standard ",[39,139157,138744],{}," not a GAT), even though a \"lending iterator\" would seem more general?",[23,139160,139162,139177,139183,139192],{"className":139161},[26],[28,139163,139165,139167,139168,139170,139171,139173,139174,139176],{"className":139164},[31],[33,139166],{"disabled":35,"type":36}," Making ",[39,139169,125123],{}," a GAT would break an enormous amount of existing code that relies on being able to hold multiple yielded items simultaneously (e.g. collecting into a ",[39,139172,112877],{},"), since a lending iterator's items are tied to the borrow of ",[39,139175,87099],{}," and can't outlive the next call",[28,139178,139180,139182],{"className":139179},[31],[33,139181],{"disabled":35,"type":36}," The standard library simply hasn't gotten around to it yet and it's a planned future breaking change",[28,139184,139186,139188,139189,139191],{"className":139185},[31],[33,139187],{"disabled":35,"type":36}," GATs didn't exist when ",[39,139190,129572],{}," was designed, and Rust never changes existing trait definitions for any reason",[28,139193,139195,355,139197,139199],{"className":139194},[31],[33,139196],{"disabled":35,"type":36},[39,139198,138744],{}," actually is a GAT already; this question's premise is false",[66,139201,139202,139204,139218],{},[69,139203,71],{},[73,139205,139206,139208,139209,139211,139212,139214,139215,2690],{},[76,139207,78],{}," A — a GAT-based ",[39,139210,125123],{}," would tie each yielded item to the borrow of ",[39,139213,87099],{},", breaking the enormous amount of code that holds multiple items at once (e.g. ",[39,139216,139217],{},"collect()",[73,139219,139220,355,139222,355,139224,9057,139226,139228,139229,139232,139233,139235,139236,139239,139240,122789,139242,139245,139246,139248,139249,139252,139253,139255,139256,139258,139259,139262,139263,139265],{},[76,139221,84],{},[76,139223,135055],{},[39,139225,129572],{},[39,139227,125123],{}," is deliberately a plain (non-GAT) associated type precisely so that ",[39,139230,139231],{},"iter.next()"," returns something with no borrow-tie to ",[39,139234,87099],{},", letting you do ",[39,139237,139238],{},"v.iter().cloned().collect::\u003CVec\u003C_>>()"," or hold many yielded items alive at once — a lending-iterator ",[39,139241,137839],{},[39,139243,139244],{},"&'a mut self"," would forbid exactly this pattern, since each item would have to be dropped or copied before calling ",[39,139247,17034],{}," again. This is a genuine, permanent API-design decision (there's ongoing separate work on a distinct ",[39,139250,139251],{},"LendingIterator","-style trait, but it is not, and won't be, a change to ",[39,139254,129572],{}," itself) — not a stopgap due to GATs being unavailable at design time (GATs postdate ",[39,139257,129572],{}," by years, correct, but that's not why the design stands: it stands because it's the ",[104,139260,139261],{},"right"," design for the vast majority of iteration use cases). ",[39,139264,138744],{}," in std remains a plain associated type today.",[15,139267,139268,139280,139344,139397],{"language":111909},[18,139269,139271,139272,139275,139276,139279],{"id":139270},"q20-a-team-is-designing-a-plugin-trait-meant-to-be-stored-as-vecboxdyn-plugin-and-called-uniformly-one-team-member-proposes-adding-fn-configurec-configmut-self-cfg-c-to-the-trait-whats-the-best-practice-critique","Q20. A team is designing a plugin trait meant to be stored as ",[39,139273,139274],{},"Vec\u003CBox\u003Cdyn Plugin>>"," and called uniformly. One team member proposes adding ",[39,139277,139278],{},"fn configure\u003CC: Config>(&mut self, cfg: C)"," to the trait. What's the best-practice critique?",[257,139281,139282],{"language":111909},[260,139283,139285],{"className":111918,"code":139284,"language":111909,"meta":264,"style":264},"trait Plugin {\n    fn run(&mut self);\n    fn configure\u003CC: Config>(&mut self, cfg: C);\n}\n",[39,139286,139287,139296,139310,139340],{"__ignoreMap":264},[268,139288,139289,139291,139294],{"class":270,"line":271},[268,139290,136649],{"class":274},[268,139292,139293],{"class":278}," Plugin",[268,139295,9914],{"class":282},[268,139297,139298,139300,139302,139304,139306,139308],{"class":270,"line":286},[268,139299,120364],{"class":274},[268,139301,13549],{"class":278},[268,139303,622],{"class":282},[268,139305,114510],{"class":274},[268,139307,96472],{"class":305},[268,139309,628],{"class":282},[268,139311,139312,139314,139317,139319,139321,139323,139325,139327,139329,139331,139334,139336,139338],{"class":270,"line":296},[268,139313,120364],{"class":274},[268,139315,139316],{"class":278}," configure",[268,139318,1076],{"class":282},[268,139320,47793],{"class":278},[268,139322,10728],{"class":274},[268,139324,97944],{"class":278},[268,139326,137744],{"class":282},[268,139328,114510],{"class":274},[268,139330,96472],{"class":305},[268,139332,139333],{"class":282},", cfg",[268,139335,10728],{"class":274},[268,139337,99960],{"class":278},[268,139339,628],{"class":282},[268,139341,139342],{"class":270,"line":311},[268,139343,314],{"class":282},[23,139345,139347,139361,139371,139385],{"className":139346},[26],[28,139348,139350,139352,139353,139356,139357,139360],{"className":139349},[31],[33,139351],{"disabled":35,"type":36}," The generic method makes ",[39,139354,139355],{},"Plugin"," not object-safe, which directly conflicts with the stated goal of storing plugins as ",[39,139358,139359],{},"Box\u003Cdyn Plugin>","; it should instead take a concrete or enum-based config type, or be moved to a separate non-object-safe extension trait",[28,139362,139364,139366,139367,139370],{"className":139363},[31],[33,139365],{"disabled":35,"type":36}," There's no issue; generic methods work fine on trait objects as long as ",[39,139368,139369],{},"C: Config"," is a marker trait with no methods",[28,139372,139374,139376,139377,5425,139379,139381,139382],{"className":139373},[31],[33,139375],{"disabled":35,"type":36}," The fix is to add ",[39,139378,137147],{},[39,139380,13701],{}," instead of touching ",[39,139383,139384],{},"configure",[28,139386,139388,355,139390,139392,139393,139396],{"className":139387},[31],[33,139389],{"disabled":35,"type":36},[39,139391,139359],{}," would still compile, but calling ",[39,139394,139395],{},".configure()"," through it would panic at runtime instead of failing to compile",[66,139398,139399,139401,139409],{},[69,139400,71],{},[73,139402,139403,139405,139406,139408],{},[76,139404,78],{}," A — a generic method breaks object safety, conflicting with the ",[39,139407,139359],{}," requirement; use a concrete\u002Fenum config type or split it into a separate trait",[73,139410,139411,355,139413,139415,139416,139418,139419,139421,139422,139424,139425,139428,139429,139432,139433,139435,139436,139438,139439,5425,139441,139443,139444,139446,139447,139449],{},[76,139412,84],{},[76,139414,136464],{}," As established in Q10, any generic method (regardless of what the bound ",[39,139417,139369],{}," requires) makes a trait non-object-safe because the vtable can't have unbounded entries — this isn't about whether ",[39,139420,98075],{}," has methods, it's structural. Given the explicit design goal of ",[39,139423,139274],{},", the fix must remove the genericity from the object-safe surface: accept a concrete type (",[39,139426,139427],{},"&dyn Config"," or a specific ",[39,139430,139431],{},"PluginConfig"," struct\u002Fenum) instead of ",[39,139434,139369],{},", or split ",[39,139437,139384],{}," off into a separate, non-object-safe trait that's used only where static dispatch is acceptable. Adding ",[39,139440,137147],{},[39,139442,13701],{}," (an unrelated, already-object-safe method) does nothing to fix ",[39,139445,139384],{},". And critically, this is a compile-time rejection — ",[39,139448,139359],{}," with a generic method present simply fails to compile at the trait-object-construction or vtable-formation point; there is no runtime panic path here, since Rust never allows constructing a value of a type it can't statically verify.",[2107,139451,139452],{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}",{"title":264,"searchDepth":286,"depth":286,"links":139454},[139455,139456,139457,139459,139461,139463,139465,139467,139469,139471,139473,139475,139477,139479,139481,139482,139484,139486,139488,139490],{"id":136636,"depth":296,"text":136637},{"id":136830,"depth":296,"text":136831},{"id":136900,"depth":296,"text":139458},"Q3. What is PhantomData\u003CT> primarily used for?",{"id":137079,"depth":296,"text":139460},"Q4. Which of the following best describes \"object safety\" for a trait — i.e. what determines whether dyn Trait is a valid type?",{"id":137165,"depth":296,"text":139462},"Q5. Why is Clone not object-safe, i.e. why can't you write Box\u003Cdyn Clone>?",{"id":137308,"depth":296,"text":139464},"Q6. Given fn foo\u003CT: Trait>(x: T) versus fn foo(x: impl Trait) versus fn foo(x: Box\u003Cdyn Trait>), which statement is correct?",{"id":137392,"depth":296,"text":139466},"Q7. What does it mean for a generic type to be \"covariant\" in a lifetime parameter, using &'a T as the canonical example?",{"id":137502,"depth":296,"text":139468},"Q8. Cell\u003CT> and RefCell\u003CT> are invariant in T, while &T and Vec\u003CT> are covariant in T. Why does RefCell\u003CT> need to be invariant even though &T is covariant?",{"id":137684,"depth":296,"text":139470},"Q9. What happens if you attempt to define a GAT-style associated type where the type parameter needs a where Self: 'a bound but you omit it?",{"id":137861,"depth":296,"text":139472},"Q10. A trait method has this signature: fn process\u003CT: Send>(&self, val: T);. Can this trait still be object-safe overall (assuming this is its only method)?",{"id":137953,"depth":296,"text":139474},"Q11. What is the compile-time behavior of this code, given that Iterator has one associated type Item and dyn Iterator (no type argument) is written without specifying it?",{"id":138110,"depth":296,"text":139476},"Q12. What is the effect of #[non_exhaustive] combined with a private field pattern versus using PhantomData purely for sealing a trait so external crates cannot implement it — which correctly implements the \"sealed trait\" pattern?",{"id":138277,"depth":296,"text":139478},"Q13. What's wrong with this attempt to implement a trait generically for a type parameter, assuming Wrapper\u003CT> is a local struct and Display is from std::fmt?",{"id":138515,"depth":296,"text":139480},"Q14. What does Self: Sized mean when added as a bound to an individual trait method, and why would you add it?",{"id":138691,"depth":296,"text":138692},{"id":138781,"depth":296,"text":139483},"Q16. A crate defines trait Repository\u003CT> { fn save(&self, item: T); } and separately has three concrete repository structs. A reviewer suggests switching to trait Repository { type Item; fn save(&self, item: Self::Item); } instead. When is this refactor the better idiomatic choice?",{"id":138903,"depth":296,"text":139485},"Q17. In idiomatic Rust, when should a public API function accept impl Trait in argument position versus &dyn Trait?",{"id":139001,"depth":296,"text":139487},"Q18. What is the idiomatic reason to reach for a GAT instead of just returning owned data (cloning) from a trait method that would otherwise need to borrow from &mut self per call?",{"id":139150,"depth":296,"text":139489},"Q19. Why does the standard library NOT define Iterator::next(&mut self) -> Option\u003CSelf::Item\u003C'_>> (i.e. why is the standard Iterator::Item not a GAT), even though a \"lending iterator\" would seem more general?",{"id":139270,"depth":296,"text":139491},"Q20. A team is designing a plugin trait meant to be stored as Vec\u003CBox\u003Cdyn Plugin>> and called uniformly. One team member proposes adding fn configure\u003CC: Config>(&mut self, cfg: C) to the trait. What's the best-practice critique?",{},"\u002Frust\u002F29-advanced-type-system",{"title":136626,"description":264},"rust\u002F29-advanced-type-system","uxrEWVGSVL1eibsy7f8a1pa_iC3bfIMXf8m0zT_ZFfY",{"id":139498,"title":139499,"body":139500,"description":264,"extension":2144,"meta":143060,"navigation":35,"path":143061,"seo":143062,"stem":143063,"__hash__":143064},"content\u002Frust\u002F30-design-patterns.md","30 — Design Patterns",{"type":8,"value":139501,"toc":143030},[139502,139505,139667,139817,140033,140334,140535,140820,140933,141181,141369,141512,141735,141888,142071,142244,142363,142568,143027],[11,139503,139499],{"id":139504},"_30-design-patterns",[15,139506,139507,139511,139597,139635],{"language":111909},[18,139508,139510],{"id":139509},"q1-what-is-the-defining-structural-feature-of-the-builder-pattern-as-commonly-written-in-rust","Q1. What is the defining structural feature of the builder pattern as commonly written in Rust?",[257,139512,139513],{"language":111909},[260,139514,139516],{"className":111918,"code":139515,"language":111909,"meta":264,"style":264},"let req = RequestBuilder::new(\"https:\u002F\u002Fapi.example.com\")\n    .method(\"POST\")\n    .header(\"Content-Type\", \"application\u002Fjson\")\n    .timeout_secs(30)\n    .build()?;\n",[39,139517,139518,139541,139553,139572,139585],{"__ignoreMap":264},[268,139519,139520,139522,139525,139527,139530,139532,139534,139536,139539],{"class":270,"line":271},[268,139521,240],{"class":274},[268,139523,139524],{"class":282}," req ",[268,139526,302],{"class":274},[268,139528,139529],{"class":278}," RequestBuilder",[268,139531,84903],{"class":274},[268,139533,2689],{"class":278},[268,139535,622],{"class":282},[268,139537,139538],{"class":289},"\"https:\u002F\u002Fapi.example.com\"",[268,139540,20702],{"class":282},[268,139542,139543,139545,139547,139549,139551],{"class":270,"line":286},[268,139544,53891],{"class":274},[268,139546,15529],{"class":278},[268,139548,622],{"class":282},[268,139550,127663],{"class":289},[268,139552,20702],{"class":282},[268,139554,139555,139557,139560,139562,139565,139567,139570],{"class":270,"line":296},[268,139556,53891],{"class":274},[268,139558,139559],{"class":278},"header",[268,139561,622],{"class":282},[268,139563,139564],{"class":289},"\"Content-Type\"",[268,139566,42],{"class":282},[268,139568,139569],{"class":289},"\"application\u002Fjson\"",[268,139571,20702],{"class":282},[268,139573,139574,139576,139579,139581,139583],{"class":270,"line":311},[268,139575,53891],{"class":274},[268,139577,139578],{"class":278},"timeout_secs",[268,139580,622],{"class":282},[268,139582,24274],{"class":305},[268,139584,20702],{"class":282},[268,139586,139587,139589,139591,139593,139595],{"class":270,"line":788},[268,139588,53891],{"class":274},[268,139590,14155],{"class":278},[268,139592,16952],{"class":282},[268,139594,1685],{"class":274},[268,139596,293],{"class":282},[23,139598,139600,139614,139623,139629],{"className":139599},[26],[28,139601,139603,139605,139606,7255,139608,139610,139611,139613],{"className":139602},[31],[33,139604],{"disabled":35,"type":36}," A separate builder struct accumulates configuration through chained methods that each consume and return ",[39,139607,87099],{},[39,139609,113013],{},"), with a final ",[39,139612,125109],{}," that validates and produces the target type",[28,139615,139617,139619,139620,139622],{"className":139616},[31],[33,139618],{"disabled":35,"type":36}," A struct that implements ",[39,139621,124579],{}," and is mutated directly via public fields",[28,139624,139626,139628],{"className":139625},[31],[33,139627],{"disabled":35,"type":36}," A macro that generates a constructor accepting every field as a positional argument",[28,139630,139632,139634],{"className":139631},[31],[33,139633],{"disabled":35,"type":36}," A trait that all configurable types must implement, with no separate builder struct involved",[66,139636,139637,139639,139646],{},[69,139638,71],{},[73,139640,139641,139643,139644],{},[76,139642,78],{}," A — a separate builder struct with chained methods and a final validating ",[39,139645,125109],{},[73,139647,139648,139650,139651,139654,139655,139657,139658,139660,139661,42,139664,6232],{},[76,139649,84],{}," The builder pattern exists in Rust largely because the language has no named\u002Fdefault function arguments — chained ",[39,139652,139653],{},".method(...)"," calls on a dedicated builder struct simulate that ergonomics while letting each step be independently optional, and ",[39,139656,125109],{}," gives a single place to validate combinations and return ",[39,139659,110110],{}," for invalid configurations. Direct public-field mutation skips validation and locks in field names\u002Ftypes as public API forever. A positional-argument macro reintroduces the exact problem builders solve (unreadable call sites, fragile argument order). A trait-only approach without a separate accumulating struct doesn't match how the pattern is idiomatically structured in the ecosystem (e.g. ",[39,139662,139663],{},"reqwest::RequestBuilder",[39,139665,139666],{},"std::process::Command",[15,139668,139669,139677,139736,139775],{"language":111909},[18,139670,139672,139673,139676],{"id":139671},"q2-what-core-problem-does-the-newtype-pattern-struct-metersf64-solve","Q2. What core problem does the newtype pattern (",[39,139674,139675],{},"struct Meters(f64);",") solve?",[257,139678,139679],{"language":111909},[260,139680,139682],{"className":111918,"code":139681,"language":111909,"meta":264,"style":264},"struct Meters(f64);\nstruct Feet(f64);\n\nfn distance_traveled(m: Meters) -> Meters { m }\n",[39,139683,139684,139696,139709,139713],{"__ignoreMap":264},[268,139685,139686,139688,139690,139692,139694],{"class":270,"line":271},[268,139687,121198],{"class":274},[268,139689,123218],{"class":278},[268,139691,622],{"class":282},[268,139693,115196],{"class":278},[268,139695,628],{"class":282},[268,139697,139698,139700,139703,139705,139707],{"class":270,"line":286},[268,139699,121198],{"class":274},[268,139701,139702],{"class":278}," Feet",[268,139704,622],{"class":282},[268,139706,115196],{"class":278},[268,139708,628],{"class":282},[268,139710,139711],{"class":270,"line":296},[268,139712,5033],{"emptyLinePlaceholder":35},[268,139714,139715,139717,139720,139723,139725,139727,139729,139731,139733],{"class":270,"line":311},[268,139716,37837],{"class":274},[268,139718,139719],{"class":278}," distance_traveled",[268,139721,139722],{"class":282},"(m",[268,139724,10728],{"class":274},[268,139726,123218],{"class":278},[268,139728,6131],{"class":282},[268,139730,113308],{"class":274},[268,139732,123218],{"class":278},[268,139734,139735],{"class":282}," { m }\n",[23,139737,139739,139748,139757,139763],{"className":139738},[26],[28,139740,139742,139744,139745,139747],{"className":139741},[31],[33,139743],{"disabled":35,"type":36}," It creates a distinct type at compile time so values with the same underlying representation (e.g. two ",[39,139746,115196],{},"s meaning different units) cannot be accidentally interchanged",[28,139749,139751,139753,139754,139756],{"className":139750},[31],[33,139752],{"disabled":35,"type":36}," It reduces the runtime memory footprint of ",[39,139755,115196],{}," by removing unused precision bits",[28,139758,139760,139762],{"className":139759},[31],[33,139761],{"disabled":35,"type":36}," It's required by the compiler any time a struct has exactly one field",[28,139764,139766,139768,139769,186,139771,139774],{"className":139765},[31],[33,139767],{"disabled":35,"type":36}," It automatically implements ",[39,139770,117737],{},[39,139772,139773],{},"Sub"," for the wrapped type",[66,139776,139777,139779,139784],{},[69,139778,71],{},[73,139780,139781,139783],{},[76,139782,78],{}," A — creates a distinct compile-time type so same-representation values with different meanings can't be mixed up accidentally",[73,139785,139786,355,139788,355,139790,186,139793,139796,139797,139799,139800,139803,139804,139806,139807,7501,139809,139811,139812,446,139814,139816],{},[76,139787,84],{},[76,139789,582],{},[39,139791,139792],{},"Meters(f64)",[39,139794,139795],{},"Feet(f64)"," share an identical runtime layout (a single ",[39,139798,115196],{},", and with ",[39,139801,139802],{},"#[repr(transparent)]"," even guaranteed ABI-identical to ",[39,139805,115196],{},") but are different types to the compiler — passing a ",[39,139808,124389],{},[39,139810,124386],{}," is expected is a compile error, catching unit-confusion bugs (the kind that famously destroyed the Mars Climate Orbiter) at compile time instead of production. It has zero effect on runtime memory representation\u002Fprecision — the wrapper is typically free at runtime (a compile-time-only distinction). It's a voluntary pattern, not a compiler requirement for single-field structs (plenty of single-field structs aren't newtypes in this sense). And trait impls like ",[39,139813,117737],{},[39,139815,139773],{}," are never automatic — they must be explicitly implemented (or derived, where applicable) for the new type; wrapping a value implements nothing by itself.",[15,139818,139819,139823,139953,139994],{"language":111909},[18,139820,139822],{"id":139821},"q3-the-newtype-pattern-is-also-used-to-work-around-rusts-orphan-rule-which-scenario-is-a-correct-use-of-newtype-for-this-purpose","Q3. The newtype pattern is also used to work around Rust's orphan rule. Which scenario is a correct use of newtype for this purpose?",[257,139824,139825],{"language":111909},[260,139826,139828],{"className":111918,"code":139827,"language":111909,"meta":264,"style":264},"use std::fmt;\n\nstruct Wrapper(Vec\u003CString>);\n\nimpl fmt::Display for Wrapper {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"[{}]\", self.0.join(\", \"))\n    }\n}\n",[39,139829,139830,139841,139845,139862,139866,139882,139918,139945,139949],{"__ignoreMap":264},[268,139831,139832,139834,139836,139838],{"class":270,"line":271},[268,139833,108694],{"class":274},[268,139835,125974],{"class":278},[268,139837,84903],{"class":274},[268,139839,139840],{"class":282},"fmt;\n",[268,139842,139843],{"class":270,"line":286},[268,139844,5033],{"emptyLinePlaceholder":35},[268,139846,139847,139849,139851,139853,139855,139857,139859],{"class":270,"line":296},[268,139848,121198],{"class":274},[268,139850,123568],{"class":278},[268,139852,622],{"class":282},[268,139854,112877],{"class":278},[268,139856,1076],{"class":282},[268,139858,16721],{"class":278},[268,139860,139861],{"class":282},">);\n",[268,139863,139864],{"class":270,"line":311},[268,139865,5033],{"emptyLinePlaceholder":35},[268,139867,139868,139870,139872,139874,139876,139878,139880],{"class":270,"line":788},[268,139869,123290],{"class":274},[268,139871,138349],{"class":278},[268,139873,84903],{"class":274},[268,139875,127368],{"class":278},[268,139877,85712],{"class":274},[268,139879,123568],{"class":278},[268,139881,9914],{"class":282},[268,139883,139884,139886,139888,139890,139892,139894,139896,139898,139900,139902,139904,139906,139908,139910,139912,139914,139916],{"class":270,"line":1951},[268,139885,120364],{"class":274},[268,139887,138349],{"class":278},[268,139889,622],{"class":282},[268,139891,85350],{"class":274},[268,139893,87099],{"class":305},[268,139895,138358],{"class":282},[268,139897,10728],{"class":274},[268,139899,126710],{"class":274},[268,139901,138349],{"class":278},[268,139903,84903],{"class":274},[268,139905,138373],{"class":278},[268,139907,6131],{"class":282},[268,139909,113308],{"class":274},[268,139911,138349],{"class":278},[268,139913,84903],{"class":274},[268,139915,110110],{"class":278},[268,139917,9914],{"class":282},[268,139919,139920,139922,139924,139927,139929,139931,139933,139936,139938,139940,139943],{"class":270,"line":8955},[268,139921,138394],{"class":278},[268,139923,138397],{"class":282},[268,139925,139926],{"class":289},"\"[{}]\"",[268,139928,42],{"class":282},[268,139930,87099],{"class":305},[268,139932,462],{"class":274},[268,139934,139935],{"class":305},"0.",[268,139937,18112],{"class":278},[268,139939,622],{"class":282},[268,139941,139942],{"class":289},"\", \"",[268,139944,47690],{"class":282},[268,139946,139947],{"class":270,"line":8966},[268,139948,11972],{"class":282},[268,139950,139951],{"class":270,"line":8974},[268,139952,314],{"class":282},[23,139954,139956,139973,139979,139985],{"className":139955},[26],[28,139957,139959,139961,139962,138422,139964,139966,139967,139969,139970,139972],{"className":139958},[31],[33,139960],{"disabled":35,"type":36}," Wrapping a foreign type (",[39,139963,127753],{},[39,139965,109737],{},") in a local tuple struct so you can implement a foreign trait (",[39,139968,127368],{},", also from ",[39,139971,109737],{},") on the local wrapper, since neither the trait nor the raw type is local",[28,139974,139976,139978],{"className":139975},[31],[33,139977],{"disabled":35,"type":36}," Wrapping a local struct so you can implement a local trait on it, which would otherwise be impossible",[28,139980,139982,139984],{"className":139981},[31],[33,139983],{"disabled":35,"type":36}," Using newtype to bypass the borrow checker's mutable-aliasing rules",[28,139986,139988,139990,139991,139993],{"className":139987},[31],[33,139989],{"disabled":35,"type":36}," The orphan rule doesn't apply to ",[39,139992,127368],{},", so no wrapper is needed here at all",[66,139995,139996,139998,140003],{},[69,139997,71],{},[73,139999,140000,140002],{},[76,140001,78],{}," A — wrap the foreign type locally so the impl target (the wrapper) is local, satisfying the orphan rule for the foreign trait",[73,140004,140005,355,140007,140009,140010,140013,140014,5893,140016,140018,140019,140021,140022,140024,140025,446,140027,140029,140030,140032],{},[76,140006,84],{},[76,140008,930],{}," The orphan rule blocks ",[39,140011,140012],{},"impl Display for Vec\u003CString>"," directly because neither ",[39,140015,127368],{},[39,140017,112877],{}," is defined in your crate — both are foreign. Wrapping ",[39,140020,127753],{}," in a local tuple struct ",[39,140023,123699],{}," makes the impl target local, satisfying \"at least one of trait or type must be local,\" even though the trait itself remains foreign. Implementing a local trait on a local type was never blocked by the orphan rule in the first place (that's always allowed), so option B describes a non-problem. Newtype has nothing to do with borrow-checker aliasing rules — those are governed by ",[39,140026,85350],{},[39,140028,114510],{}," reference rules, unrelated to type wrapping. And ",[39,140031,127368],{}," is subject to the orphan rule exactly like any other foreign trait; there's no special exemption.",[15,140034,140035,140039,140241,140286],{"language":111909},[18,140036,140038],{"id":140037},"q4-what-does-the-typestate-pattern-encode-and-how-does-it-typically-prevent-misuse-at-compile-time","Q4. What does the typestate pattern encode, and how does it typically prevent misuse at compile time?",[257,140040,140041],{"language":111909},[260,140042,140044],{"className":111918,"code":140043,"language":111909,"meta":264,"style":264},"struct Locked;\nstruct Unlocked;\n\nstruct Door\u003CState> {\n    _state: std::marker::PhantomData\u003CState>,\n}\n\nimpl Door\u003CLocked> {\n    fn unlock(self, _key: &str) -> Door\u003CUnlocked> { Door { _state: std::marker::PhantomData } }\n}\n\nimpl Door\u003CUnlocked> {\n    fn open(self) -> Door\u003CUnlocked> { println!(\"opened\"); self }\n}\n",[39,140045,140046,140055,140064,140068,140082,140105,140109,140113,140126,140181,140185,140189,140201,140237],{"__ignoreMap":264},[268,140047,140048,140050,140053],{"class":270,"line":271},[268,140049,121198],{"class":274},[268,140051,140052],{"class":278}," Locked",[268,140054,293],{"class":282},[268,140056,140057,140059,140062],{"class":270,"line":286},[268,140058,121198],{"class":274},[268,140060,140061],{"class":278}," Unlocked",[268,140063,293],{"class":282},[268,140065,140066],{"class":270,"line":296},[268,140067,5033],{"emptyLinePlaceholder":35},[268,140069,140070,140072,140075,140077,140080],{"class":270,"line":311},[268,140071,121198],{"class":274},[268,140073,140074],{"class":278}," Door",[268,140076,1076],{"class":282},[268,140078,140079],{"class":278},"State",[268,140081,121209],{"class":282},[268,140083,140084,140087,140089,140091,140093,140095,140097,140099,140101,140103],{"class":270,"line":788},[268,140085,140086],{"class":282},"    _state",[268,140088,10728],{"class":274},[268,140090,125974],{"class":278},[268,140092,84903],{"class":274},[268,140094,136922],{"class":278},[268,140096,84903],{"class":274},[268,140098,136927],{"class":278},[268,140100,1076],{"class":282},[268,140102,140079],{"class":278},[268,140104,136974],{"class":282},[268,140106,140107],{"class":270,"line":1951},[268,140108,314],{"class":282},[268,140110,140111],{"class":270,"line":8955},[268,140112,5033],{"emptyLinePlaceholder":35},[268,140114,140115,140117,140119,140121,140124],{"class":270,"line":8966},[268,140116,123290],{"class":274},[268,140118,140074],{"class":278},[268,140120,1076],{"class":282},[268,140122,140123],{"class":278},"Locked",[268,140125,121209],{"class":282},[268,140127,140128,140130,140133,140135,140137,140140,140142,140144,140146,140148,140150,140152,140154,140157,140160,140163,140166,140168,140170,140172,140174,140176,140178],{"class":270,"line":8974},[268,140129,120364],{"class":274},[268,140131,140132],{"class":278}," unlock",[268,140134,622],{"class":282},[268,140136,87099],{"class":305},[268,140138,140139],{"class":282},", _key",[268,140141,10728],{"class":274},[268,140143,115951],{"class":274},[268,140145,17109],{"class":278},[268,140147,6131],{"class":282},[268,140149,113308],{"class":274},[268,140151,140074],{"class":278},[268,140153,1076],{"class":282},[268,140155,140156],{"class":278},"Unlocked",[268,140158,140159],{"class":282},"> { ",[268,140161,140162],{"class":278},"Door",[268,140164,140165],{"class":282}," { _state",[268,140167,10728],{"class":274},[268,140169,125974],{"class":278},[268,140171,84903],{"class":274},[268,140173,136922],{"class":278},[268,140175,84903],{"class":274},[268,140177,136927],{"class":278},[268,140179,140180],{"class":282}," } }\n",[268,140182,140183],{"class":270,"line":8985},[268,140184,314],{"class":282},[268,140186,140187],{"class":270,"line":8990},[268,140188,5033],{"emptyLinePlaceholder":35},[268,140190,140191,140193,140195,140197,140199],{"class":270,"line":8997},[268,140192,123290],{"class":274},[268,140194,140074],{"class":278},[268,140196,1076],{"class":282},[268,140198,140156],{"class":278},[268,140200,121209],{"class":282},[268,140202,140203,140205,140208,140210,140212,140214,140216,140218,140220,140222,140224,140226,140228,140231,140233,140235],{"class":270,"line":9002},[268,140204,120364],{"class":274},[268,140206,140207],{"class":278}," open",[268,140209,622],{"class":282},[268,140211,87099],{"class":305},[268,140213,6131],{"class":282},[268,140215,113308],{"class":274},[268,140217,140074],{"class":278},[268,140219,1076],{"class":282},[268,140221,140156],{"class":278},[268,140223,140159],{"class":282},[268,140225,118575],{"class":278},[268,140227,622],{"class":282},[268,140229,140230],{"class":289},"\"opened\"",[268,140232,5789],{"class":282},[268,140234,87099],{"class":305},[268,140236,29394],{"class":282},[268,140238,140239],{"class":270,"line":14676},[268,140240,314],{"class":282},[23,140242,140244,140257,140266,140277],{"className":140243},[26],[28,140245,140247,140249,140250,5125,140253,140256],{"className":140246},[31],[33,140248],{"disabled":35,"type":36}," It encodes an object's runtime state as distinct types (often via a generic parameter), so methods only valid in a given state are only defined on that state's type — calling ",[39,140251,140252],{},"open()",[39,140254,140255],{},"Door\u003CLocked>"," is a compile error, not a runtime check",[28,140258,140260,140262,140263,140265],{"className":140259},[31],[33,140261],{"disabled":35,"type":36}," It stores the current state as an enum field and uses a ",[39,140264,116378],{}," inside every method to check validity at runtime",[28,140267,140269,140271,140272,446,140274,140276],{"className":140268},[31],[33,140270],{"disabled":35,"type":36}," It's a synonym for the state machine pattern implemented purely with ",[39,140273,2179],{},[39,140275,9884],{}," branches",[28,140278,140280,140282,140283,140285],{"className":140279},[31],[33,140281],{"disabled":35,"type":36}," It requires ",[39,140284,112499],{}," to transition between states since ownership must be forcibly reinterpreted",[66,140287,140288,140290,140295],{},[69,140289,71],{},[73,140291,140292,140294],{},[76,140293,78],{}," A — states become distinct types, so only valid-for-that-state methods exist, and invalid transitions fail to compile",[73,140296,140297,355,140299,140301,140302,186,140304,140307,140308,140311,140312,42,140314,140317,140318,140320,140321,140324,140325,140327,140328,140330,140331,140333],{},[76,140298,84],{},[76,140300,582],{}," In the typestate pattern, ",[39,140303,140255],{},[39,140305,140306],{},"Door\u003CUnlocked>"," are different types with non-overlapping method sets (",[39,140309,140310],{},"unlock"," only exists on ",[39,140313,140255],{},[39,140315,140316],{},"open"," only on ",[39,140319,140306],{},"), so attempting ",[39,140322,140323],{},"Door\u003CLocked>::open()"," is a \"no method named ",[39,140326,140316],{}," found\" compile error — the illegal transition is caught before the program ever runs, unlike the described enum-plus-runtime-",[39,140329,116378],{}," approach (option B), which is a valid but strictly weaker pattern (it moves the same check to runtime, where a forgotten branch panics or misbehaves in production instead of failing the build). It's related to but distinct from a general state machine (which typestate implements specifically via the type system, not just any state-tracking technique), and it requires no ",[39,140332,112499],{}," — transitions are ordinary by-value moves consuming the old-state value and returning a new-state value.",[15,140335,140336,140343,140434,140484],{"language":111909},[18,140337,140339,140340,140342],{"id":140338},"q5-what-guarantee-does-raii-resource-acquisition-is-initialization-via-drop-provide-in-rust","Q5. What guarantee does RAII (Resource Acquisition Is Initialization) via ",[39,140341,128979],{}," provide in Rust?",[257,140344,140345],{"language":111909},[260,140346,140348],{"className":111918,"code":140347,"language":111909,"meta":264,"style":264},"struct FileGuard {\n    file: std::fs::File,\n}\n\nimpl Drop for FileGuard {\n    fn drop(&mut self) {\n        println!(\"closing file\");\n    }\n}\n",[39,140349,140350,140359,140379,140383,140387,140400,140415,140426,140430],{"__ignoreMap":264},[268,140351,140352,140354,140357],{"class":270,"line":271},[268,140353,121198],{"class":274},[268,140355,140356],{"class":278}," FileGuard",[268,140358,9914],{"class":282},[268,140360,140361,140364,140366,140368,140370,140372,140374,140377],{"class":270,"line":286},[268,140362,140363],{"class":282},"    file",[268,140365,10728],{"class":274},[268,140367,125974],{"class":278},[268,140369,84903],{"class":274},[268,140371,41],{"class":278},[268,140373,84903],{"class":274},[268,140375,140376],{"class":278},"File",[268,140378,1789],{"class":282},[268,140380,140381],{"class":270,"line":296},[268,140382,314],{"class":282},[268,140384,140385],{"class":270,"line":311},[268,140386,5033],{"emptyLinePlaceholder":35},[268,140388,140389,140391,140394,140396,140398],{"class":270,"line":788},[268,140390,123290],{"class":274},[268,140392,140393],{"class":278}," Drop",[268,140395,85712],{"class":274},[268,140397,140356],{"class":278},[268,140399,9914],{"class":282},[268,140401,140402,140404,140407,140409,140411,140413],{"class":270,"line":1951},[268,140403,120364],{"class":274},[268,140405,140406],{"class":278}," drop",[268,140408,622],{"class":282},[268,140410,114510],{"class":274},[268,140412,96472],{"class":305},[268,140414,1235],{"class":282},[268,140416,140417,140419,140421,140424],{"class":270,"line":8955},[268,140418,112752],{"class":278},[268,140420,622],{"class":282},[268,140422,140423],{"class":289},"\"closing file\"",[268,140425,628],{"class":282},[268,140427,140428],{"class":270,"line":8966},[268,140429,11972],{"class":282},[268,140431,140432],{"class":270,"line":8974},[268,140433,314],{"class":282},[23,140435,140437,140453,140465,140473],{"className":140436},[26],[28,140438,140440,140442,140443,140446,140447,140449,140450,140452],{"className":140439},[31],[33,140441],{"disabled":35,"type":36}," Cleanup code in ",[39,140444,140445],{},"drop()"," runs automatically when the value goes out of scope, whether via normal control flow, an early ",[39,140448,9151],{},", or an unwinding panic (barring ",[39,140451,129856],{}," or a process abort)",[28,140454,140456,355,140458,140460,140461,124716,140463],{"className":140455},[31],[33,140457],{"disabled":35,"type":36},[39,140459,140445],{}," only runs if the program exits normally via ",[39,140462,111207],{},[39,140464,133611],{},[28,140466,140468,355,140470,140472],{"className":140467},[31],[33,140469],{"disabled":35,"type":36},[39,140471,140445],{}," must be called manually by the programmer; Rust does not call it automatically",[28,140474,140476,355,140478,140480,140481],{"className":140475},[31],[33,140477],{"disabled":35,"type":36},[39,140479,140445],{}," runs at a nondeterministic time chosen by the garbage collector, similar to Java's ",[39,140482,140483],{},"finalize()",[66,140485,140486,140488,140498],{},[69,140487,71],{},[73,140489,140490,3459,140492,140494,140495,140497],{},[76,140491,78],{},[39,140493,140445],{}," runs automatically at scope exit through normal flow, early return, or unwinding, with only ",[39,140496,129914],{},"\u002Fabort as exceptions",[73,140499,140500,355,140502,140504,140505,140507,140508,140511,140512,140514,140515,140518,140519,124716,140521,140523,140524,140527,140528,140531,140532,140534],{},[76,140501,84],{},[76,140503,582],{}," Rust has deterministic, scope-based destruction (no garbage collector) — the compiler inserts a call to ",[39,140506,140445],{}," at every point a value's owning scope ends, including early returns and (during unwinding, not ",[39,140509,140510],{},"panic = \"abort\""," builds) stack unwinding from a panic, which is what makes RAII reliable for releasing locks, closing files, and flushing buffers even in error paths. The two real escape hatches are ",[39,140513,129856],{}," (explicitly suppresses the drop) and process abort\u002F",[39,140516,140517],{},"SIGKILL"," (no unwinding happens at all). It is not tied to ",[39,140520,111207],{},[39,140522,120129],{},", is very much automatic (that's the entire point of RAII — no explicit ",[39,140525,140526],{},".close()"," call needed, unlike C's manual ",[39,140529,140530],{},"fclose","), and has nothing to do with garbage collection or Java's notoriously non-deterministic, sometimes-never-called ",[39,140533,140483],{}," — Rust's timing is fully deterministic and scope-derived.",[15,140536,140537,140541,140730,140774],{"language":111909},[18,140538,140540],{"id":140539},"q6-in-the-visitor-pattern-implemented-via-a-rust-enum-rather-than-the-classic-oop-double-dispatch-visitor-how-is-visiting-different-node-types-typically-expressed","Q6. In the visitor pattern implemented via a Rust enum (rather than the classic OOP double-dispatch visitor), how is \"visiting different node types\" typically expressed?",[257,140542,140543],{"language":111909},[260,140544,140546],{"className":111918,"code":140545,"language":111909,"meta":264,"style":264},"enum Expr {\n    Num(f64),\n    Add(Box\u003CExpr>, Box\u003CExpr>),\n    Mul(Box\u003CExpr>, Box\u003CExpr>),\n}\n\nfn eval(e: &Expr) -> f64 {\n    match e {\n        Expr::Num(n) => *n,\n        Expr::Add(l, r) => eval(l) + eval(r),\n        Expr::Mul(l, r) => eval(l) * eval(r),\n    }\n}\n",[39,140547,140548,140557,140568,140593,140616,140620,140624,140648,140655,140674,140699,140722,140726],{"__ignoreMap":264},[268,140549,140550,140552,140555],{"class":270,"line":271},[268,140551,125449],{"class":274},[268,140553,140554],{"class":278}," Expr",[268,140556,9914],{"class":282},[268,140558,140559,140562,140564,140566],{"class":270,"line":286},[268,140560,140561],{"class":278},"    Num",[268,140563,622],{"class":282},[268,140565,115196],{"class":278},[268,140567,17159],{"class":282},[268,140569,140570,140573,140575,140577,140579,140582,140585,140587,140589,140591],{"class":270,"line":296},[268,140571,140572],{"class":278},"    Add",[268,140574,622],{"class":282},[268,140576,127945],{"class":278},[268,140578,1076],{"class":282},[268,140580,140581],{"class":278},"Expr",[268,140583,140584],{"class":282},">, ",[268,140586,127945],{"class":278},[268,140588,1076],{"class":282},[268,140590,140581],{"class":278},[268,140592,127953],{"class":282},[268,140594,140595,140598,140600,140602,140604,140606,140608,140610,140612,140614],{"class":270,"line":311},[268,140596,140597],{"class":278},"    Mul",[268,140599,622],{"class":282},[268,140601,127945],{"class":278},[268,140603,1076],{"class":282},[268,140605,140581],{"class":278},[268,140607,140584],{"class":282},[268,140609,127945],{"class":278},[268,140611,1076],{"class":282},[268,140613,140581],{"class":278},[268,140615,127953],{"class":282},[268,140617,140618],{"class":270,"line":788},[268,140619,314],{"class":282},[268,140621,140622],{"class":270,"line":1951},[268,140623,5033],{"emptyLinePlaceholder":35},[268,140625,140626,140628,140631,140634,140636,140638,140640,140642,140644,140646],{"class":270,"line":8955},[268,140627,37837],{"class":274},[268,140629,140630],{"class":278}," eval",[268,140632,140633],{"class":282},"(e",[268,140635,10728],{"class":274},[268,140637,115951],{"class":274},[268,140639,140581],{"class":278},[268,140641,6131],{"class":282},[268,140643,113308],{"class":274},[268,140645,138553],{"class":278},[268,140647,9914],{"class":282},[268,140649,140650,140652],{"class":270,"line":8966},[268,140651,120056],{"class":274},[268,140653,140654],{"class":282}," e {\n",[268,140656,140657,140660,140662,140665,140667,140669,140671],{"class":270,"line":8974},[268,140658,140659],{"class":278},"        Expr",[268,140661,84903],{"class":274},[268,140663,140664],{"class":278},"Num",[268,140666,120079],{"class":282},[268,140668,9414],{"class":274},[268,140670,6108],{"class":274},[268,140672,140673],{"class":282},"n,\n",[268,140675,140676,140678,140680,140682,140685,140687,140689,140692,140694,140696],{"class":270,"line":8985},[268,140677,140659],{"class":278},[268,140679,84903],{"class":274},[268,140681,117737],{"class":278},[268,140683,140684],{"class":282},"(l, r) ",[268,140686,9414],{"class":274},[268,140688,140630],{"class":278},[268,140690,140691],{"class":282},"(l) ",[268,140693,1246],{"class":274},[268,140695,140630],{"class":278},[268,140697,140698],{"class":282},"(r),\n",[268,140700,140701,140703,140705,140708,140710,140712,140714,140716,140718,140720],{"class":270,"line":8990},[268,140702,140659],{"class":278},[268,140704,84903],{"class":274},[268,140706,140707],{"class":278},"Mul",[268,140709,140684],{"class":282},[268,140711,9414],{"class":274},[268,140713,140630],{"class":278},[268,140715,140691],{"class":282},[268,140717,6134],{"class":274},[268,140719,140630],{"class":278},[268,140721,140698],{"class":282},[268,140723,140724],{"class":270,"line":8997},[268,140725,11972],{"class":282},[268,140727,140728],{"class":270,"line":9002},[268,140729,314],{"class":282},[23,140731,140733,140745,140755,140768],{"className":140732},[26],[28,140734,140736,140738,140739,140741,140742,140744],{"className":140735},[31],[33,140737],{"disabled":35,"type":36}," An exhaustive ",[39,140740,116378],{}," over the enum's variants, where the compiler enforces that every variant is handled — new variants force every existing ",[39,140743,116378],{}," to be updated or fail to compile",[28,140746,140748,140750,140751,140754],{"className":140747},[31],[33,140749],{"disabled":35,"type":36}," A separate ",[39,140752,140753],{},"Visitor"," trait with one method per variant is mandatory; enums cannot be visited without it",[28,140756,140758,140760,140761,140764,140765],{"className":140757},[31],[33,140759],{"disabled":35,"type":36}," Dynamic dispatch through ",[39,140762,140763],{},"Box\u003Cdyn Any>"," and runtime type-checking via ",[39,140766,140767],{},"downcast_ref",[28,140769,140771,140773],{"className":140770},[31],[33,140772],{"disabled":35,"type":36}," Enums cannot express the visitor pattern in Rust; only trait objects can",[66,140775,140776,140778,140786],{},[69,140777,71],{},[73,140779,140780,140782,140783,140785],{},[76,140781,78],{}," A — an exhaustive ",[39,140784,116378],{},", with the compiler enforcing every variant is handled",[73,140787,140788,355,140790,140792,140793,140795,140796,140798,140799,140801,140802,140805,140806,140808,140809,140811,140812,140815,140816,140819],{},[76,140789,84],{},[76,140791,930],{}," Rust's enums plus exhaustive ",[39,140794,116378],{}," give you the visitor pattern's core benefit (dispatch based on concrete node kind) without needing the classic double-dispatch machinery OOP languages use to work around lacking sum types — and critically, adding a new ",[39,140797,140581],{}," variant makes every non-wildcard ",[39,140800,116378],{}," across the codebase a compile error until updated, which is a ",[104,140803,140804],{},"stronger"," guarantee than the classic visitor pattern's ",[39,140807,140753],{}," trait (where forgetting to implement a new visit method for a new node type is usually just a silent no-op or an easy-to-miss default). A separate ",[39,140810,140753],{}," trait is a valid ",[104,140813,140814],{},"alternative"," implementation style (useful when the set of \"visitors\"\u002Foperations grows faster than the set of node types), not a requirement — enums alone are sufficient and commonly used exactly this way (e.g. rustc's own AST handling). ",[39,140817,140818],{},"dyn Any"," downcasting throws away compile-time exhaustiveness checking entirely and is not idiomatic here.",[15,140821,140822,140836,140881],{},[18,140823,140825,140826,140828,140829,140832,140833,140835],{"id":140824},"q7-why-might-a-codebase-choose-the-classic-trait-based-visitor-pattern-a-visitor-trait-with-a-visit_-method-per-node-type-over-a-plain-match-based-enum-approach-for-an-ast","Q7. Why might a codebase choose the classic trait-based visitor pattern (a ",[39,140827,140753],{}," trait with a ",[39,140830,140831],{},"visit_*"," method per node type) over a plain ",[39,140834,116378],{},"-based enum approach for an AST?",[23,140837,140839,140855,140864,140872],{"className":140838},[26],[28,140840,140842,140844,140845,140848,140849,140852,140853],{"className":140841},[31],[33,140843],{"disabled":35,"type":36}," When new ",[104,140846,140847],{},"operations"," over the AST are added frequently but the set of node ",[104,140850,140851],{},"types"," is stable — the trait-based visitor makes adding an operation a matter of writing one new impl, rather than editing every existing ",[39,140854,116378],{},[28,140856,140858,140860,140861,140863],{"className":140857},[31],[33,140859],{"disabled":35,"type":36}," The trait-based visitor is strictly faster at runtime in all cases due to avoiding ",[39,140862,116378],{}," branch prediction misses",[28,140865,140867,355,140869,140871],{"className":140866},[31],[33,140868],{"disabled":35,"type":36},[39,140870,116378],{},"-based enums cannot support recursive tree structures at all",[28,140873,140875,140877,140878,140880],{"className":140874},[31],[33,140876],{"disabled":35,"type":36}," There's no reason to ever prefer it — ",[39,140879,116378],{},"-based enums are strictly superior in every scenario",[66,140882,140883,140885,140892],{},[69,140884,71],{},[73,140886,140887,140889,140890],{},[76,140888,78],{}," A — when operations grow faster than node types, trait-based visitors avoid editing every existing ",[39,140891,116378],{},[73,140893,140894,355,140896,140898,140899,140901,140902,140905,140906,140909,140910,140913,140914,140916,140917,140919,140920,81504,140922,140924,140925,446,140927,140929,140930,140932],{},[76,140895,84],{},[76,140897,930],{}," This is the classic \"expression problem\" trade-off: enum + ",[39,140900,116378],{}," makes adding a new ",[104,140903,140904],{},"node type"," force-update every match site (good when types are the axis of change, as in Q6), while trait-based visitor makes adding a new ",[104,140907,140908],{},"operation"," (a new ",[39,140911,140912],{},"impl Visitor",") require zero changes to existing code, at the cost of adding a new ",[104,140915,140904],{}," now requiring updates across every existing ",[39,140918,140753],{}," implementor. Neither is \"strictly superior\" — the right choice depends on which axis (types vs. operations) changes more often in that codebase. There's no inherent, universal runtime performance advantage to virtual dispatch over a ",[39,140921,116378],{},[39,140923,116378],{}," on a fieldless discriminant is typically a fast jump table, often faster than a vtable call), and enums recurse over trees perfectly well via ",[39,140926,127945],{},[39,140928,128232],{}," indirection, as shown in Q6's ",[39,140931,140581],{}," — recursion is not a limitation of the enum approach.",[15,140934,140935,140948,141096,141140],{"language":111909},[18,140936,65427,140938,140940,140941,140943,140944,140947],{"id":140937},"q8-a-config-struct-has-8-optional-fields-most-with-sensible-defaults-what-happens-if-a-builders-build-method-is-called-before-any-required-fields-say-api_key-are-set",[39,140939,98075],{}," struct has 8 optional fields, most with sensible defaults. What happens if a builder's ",[39,140942,125109],{}," method is called before any required fields (say, ",[39,140945,140946],{},"api_key",") are set?",[257,140949,140950],{"language":111909},[260,140951,140953],{"className":111918,"code":140952,"language":111909,"meta":264,"style":264},"struct ConfigBuilder {\n    api_key: Option\u003CString>,\n    timeout: u64,\n}\n\nimpl ConfigBuilder {\n    fn build(self) -> Result\u003CConfig, BuildError> {\n        let api_key = self.api_key.ok_or(BuildError::MissingApiKey)?;\n        Ok(Config { api_key, timeout: self.timeout })\n    }\n}\n",[39,140954,140955,140964,140979,140990,140994,140998,141006,141033,141068,141088,141092],{"__ignoreMap":264},[268,140956,140957,140959,140962],{"class":270,"line":271},[268,140958,121198],{"class":274},[268,140960,140961],{"class":278}," ConfigBuilder",[268,140963,9914],{"class":282},[268,140965,140966,140969,140971,140973,140975,140977],{"class":270,"line":286},[268,140967,140968],{"class":282},"    api_key",[268,140970,10728],{"class":274},[268,140972,126457],{"class":278},[268,140974,1076],{"class":282},[268,140976,16721],{"class":278},[268,140978,136974],{"class":282},[268,140980,140981,140984,140986,140988],{"class":270,"line":296},[268,140982,140983],{"class":282},"    timeout",[268,140985,10728],{"class":274},[268,140987,117989],{"class":278},[268,140989,1789],{"class":282},[268,140991,140992],{"class":270,"line":311},[268,140993,314],{"class":282},[268,140995,140996],{"class":270,"line":788},[268,140997,5033],{"emptyLinePlaceholder":35},[268,140999,141000,141002,141004],{"class":270,"line":1951},[268,141001,123290],{"class":274},[268,141003,140961],{"class":278},[268,141005,9914],{"class":282},[268,141007,141008,141010,141012,141014,141016,141018,141020,141022,141024,141026,141028,141031],{"class":270,"line":8955},[268,141009,120364],{"class":274},[268,141011,14104],{"class":278},[268,141013,622],{"class":282},[268,141015,87099],{"class":305},[268,141017,6131],{"class":282},[268,141019,113308],{"class":274},[268,141021,116239],{"class":278},[268,141023,1076],{"class":282},[268,141025,98075],{"class":278},[268,141027,42],{"class":282},[268,141029,141030],{"class":278},"BuildError",[268,141032,121209],{"class":282},[268,141034,141035,141037,141040,141042,141044,141046,141048,141050,141053,141055,141057,141059,141062,141064,141066],{"class":270,"line":8966},[268,141036,112735],{"class":274},[268,141038,141039],{"class":282}," api_key ",[268,141041,302],{"class":274},[268,141043,96472],{"class":305},[268,141045,462],{"class":274},[268,141047,140946],{"class":282},[268,141049,462],{"class":274},[268,141051,141052],{"class":278},"ok_or",[268,141054,622],{"class":282},[268,141056,141030],{"class":278},[268,141058,84903],{"class":274},[268,141060,141061],{"class":278},"MissingApiKey",[268,141063,2690],{"class":282},[268,141065,1685],{"class":274},[268,141067,293],{"class":282},[268,141069,141070,141072,141074,141076,141079,141081,141083,141085],{"class":270,"line":8974},[268,141071,120076],{"class":278},[268,141073,622],{"class":282},[268,141075,98075],{"class":278},[268,141077,141078],{"class":282}," { api_key, timeout",[268,141080,10728],{"class":274},[268,141082,96472],{"class":305},[268,141084,462],{"class":274},[268,141086,141087],{"class":282},"timeout })\n",[268,141089,141090],{"class":270,"line":8985},[268,141091,11972],{"class":282},[268,141093,141094],{"class":270,"line":8990},[268,141095,314],{"class":282},[23,141097,141099,141110,141118,141130],{"className":141098},[26],[28,141100,141102,355,141104,4912,141106,141109],{"className":141101},[31],[33,141103],{"disabled":35,"type":36},[39,141105,125109],{},[39,141107,141108],{},"Err(BuildError::MissingApiKey)",", since the required field was validated and found absent — this is the idiomatic way to surface missing-required-field errors without a panic",[28,141111,141113,355,141115,141117],{"className":141112},[31],[33,141114],{"disabled":35,"type":36},[39,141116,125109],{}," panics immediately with an \"unwrap on None\" message",[28,141119,141121,355,141123,141125,141126,17040,141128],{"className":141120},[31],[33,141122],{"disabled":35,"type":36},[39,141124,125109],{}," silently substitutes an empty string for ",[39,141127,140946],{},[39,141129,120129],{},[28,141131,141133,141135,141136,141139],{"className":141132},[31],[33,141134],{"disabled":35,"type":36}," This code fails to compile because ",[39,141137,141138],{},"Option\u003CString>"," can't be used inside a builder struct",[66,141141,141142,141144,141153],{},[69,141143,71],{},[73,141145,141146,3459,141148,4912,141150,141152],{},[76,141147,78],{},[39,141149,125109],{},[39,141151,141108],{},", the idiomatic way to surface a missing required field",[73,141154,141155,97641,141157,141160,141161,62857,141163,141165,141166,141168,141169,8574,141172,141174,141175,141177,141178,141180],{},[76,141156,84],{},[39,141158,141159],{},".ok_or(...)?"," converts the ",[39,141162,141138],{},[39,141164,110110],{},", propagating a descriptive error rather than panicking — this is exactly why ",[39,141167,125109],{}," idiomatically returns ",[39,141170,141171],{},"Result\u003CConfig, BuildError>",[39,141173,98075],{}," directly, letting callers handle missing-configuration errors gracefully (e.g. surfacing a helpful message) instead of crashing. It does not panic (there's no ",[39,141176,110107],{}," anywhere in this path), does not silently default a security-sensitive field like an API key to empty string (that would be a dangerous silent failure mode, not idiomatic error handling), and ",[39,141179,141138],{}," inside a plain struct is completely ordinary, valid Rust with no compile issue.",[15,141182,141183,141187,141266,141313],{"language":111909},[18,141184,141186],{"id":141185},"q9-what-happens-when-a-typestate-encoded-value-is-used-after-a-state-transitioning-method-has-consumed-it","Q9. What happens when a typestate-encoded value is used after a state-transitioning method has consumed it?",[257,141188,141189],{"language":111909},[260,141190,141192],{"className":111918,"code":141191,"language":111909,"meta":264,"style":264},"let door = Door::\u003CLocked> { _state: std::marker::PhantomData };\nlet unlocked = door.unlock(\"1234\");\ndoor.unlock(\"1234\");\n",[39,141193,141194,141228,141251],{"__ignoreMap":264},[268,141195,141196,141198,141201,141203,141205,141207,141209,141211,141214,141216,141218,141220,141222,141224,141226],{"class":270,"line":271},[268,141197,240],{"class":274},[268,141199,141200],{"class":282}," door ",[268,141202,302],{"class":274},[268,141204,140074],{"class":278},[268,141206,84903],{"class":274},[268,141208,1076],{"class":282},[268,141210,140123],{"class":278},[268,141212,141213],{"class":282},"> { _state",[268,141215,10728],{"class":274},[268,141217,125974],{"class":278},[268,141219,84903],{"class":274},[268,141221,136922],{"class":278},[268,141223,84903],{"class":274},[268,141225,136927],{"class":278},[268,141227,2790],{"class":282},[268,141229,141230,141232,141235,141237,141240,141242,141244,141246,141249],{"class":270,"line":286},[268,141231,240],{"class":274},[268,141233,141234],{"class":282}," unlocked ",[268,141236,302],{"class":274},[268,141238,141239],{"class":282}," door",[268,141241,462],{"class":274},[268,141243,140310],{"class":278},[268,141245,622],{"class":282},[268,141247,141248],{"class":289},"\"1234\"",[268,141250,628],{"class":282},[268,141252,141253,141256,141258,141260,141262,141264],{"class":270,"line":296},[268,141254,141255],{"class":282},"door",[268,141257,462],{"class":274},[268,141259,140310],{"class":278},[268,141261,622],{"class":282},[268,141263,141248],{"class":289},[268,141265,628],{"class":282},[23,141267,141269,141286,141295,141301],{"className":141268},[26],[28,141270,141272,119243,141274,26924,141276,141278,141279,141281,141282,141285],{"className":141271},[31],[33,141273],{"disabled":35,"type":36},[39,141275,140310],{},[39,141277,87099],{}," by value, so ",[39,141280,141255],{}," is moved into the first call; the second ",[39,141283,141284],{},"door.unlock(...)"," is a use-after-move error",[28,141287,141289,141291,141292,141294],{"className":141288},[31],[33,141290],{"disabled":35,"type":36}," Both calls succeed; ",[39,141293,141255],{}," is implicitly cloned since it's a zero-sized type",[28,141296,141298,141300],{"className":141297},[31],[33,141299],{"disabled":35,"type":36}," The second call panics at runtime with \"use of moved value\"",[28,141302,141304,355,141306,141308,141309,114284,141311,126892],{"className":141303},[31],[33,141305],{"disabled":35,"type":36},[39,141307,141255],{}," is automatically re-locked and re-usable since ",[39,141310,140162],{},[39,141312,114164],{},[66,141314,141315,141317,141329],{},[69,141316,71],{},[73,141318,141319,141321,141322,141325,141326,141328],{},[76,141320,78],{}," A — compile error; ",[39,141323,141324],{},"unlock(self)"," moves ",[39,141327,141255],{},", so the second call is a use-after-move",[73,141330,141331,355,141333,141335,141336,141338,141339,446,141341,141343,141344,141346,141347,141350,141351,141353,141354,141356,141357,141359,141360,141362,141363,112022,141365,141368],{},[76,141332,84],{},[76,141334,582],{}," This is precisely why typestate methods take ",[39,141337,87099],{}," by value rather than ",[39,141340,112964],{},[39,141342,113013],{}," — consuming ",[39,141345,87099],{}," guarantees the ",[104,141348,141349],{},"old","-state value cannot be reused after transitioning, which is what makes a state transition genuinely one-way and irreversible at compile time (you can't accidentally \"unlock an already-consumed door twice\"). The borrow checker rejects the second ",[39,141352,141284],{}," at compile time with a \"use of moved value\" error — this is a compile-time diagnostic, never a runtime panic, since move-checking has no runtime component. Structs are never implicitly ",[39,141355,114164],{}," by default in Rust (it must be explicitly derived and is only valid when every field is ",[39,141358,114164],{},"), and even a zero-sized ",[39,141361,136927],{},"-only struct doesn't get free ",[39,141364,114164],{},[39,141366,141367],{},"#[derive(Copy, Clone)]"," explicitly opting in.",[15,141370,141371,141381,141443,141478],{"language":111909},[18,141372,141374,141375,141377,141378,141380],{"id":141373},"q10-in-a-drop-implementation-what-happens-if-drop-itself-panics-while-the-program-is-already-unwinding-from-a-prior-panic-ie-a-double-panic","Q10. In a ",[39,141376,128979],{}," implementation, what happens if ",[39,141379,140445],{}," itself panics while the program is already unwinding from a prior panic (i.e. a \"double panic\")?",[257,141382,141383],{"language":111909},[260,141384,141386],{"className":111918,"code":141385,"language":111909,"meta":264,"style":264},"struct Noisy;\nimpl Drop for Noisy {\n    fn drop(&mut self) {\n        panic!(\"dropped during unwind\");\n    }\n}\n",[39,141387,141388,141397,141409,141423,141435,141439],{"__ignoreMap":264},[268,141389,141390,141392,141395],{"class":270,"line":271},[268,141391,121198],{"class":274},[268,141393,141394],{"class":278}," Noisy",[268,141396,293],{"class":282},[268,141398,141399,141401,141403,141405,141407],{"class":270,"line":286},[268,141400,123290],{"class":274},[268,141402,140393],{"class":278},[268,141404,85712],{"class":274},[268,141406,141394],{"class":278},[268,141408,9914],{"class":282},[268,141410,141411,141413,141415,141417,141419,141421],{"class":270,"line":296},[268,141412,120364],{"class":274},[268,141414,140406],{"class":278},[268,141416,622],{"class":282},[268,141418,114510],{"class":274},[268,141420,96472],{"class":305},[268,141422,1235],{"class":282},[268,141424,141425,141428,141430,141433],{"class":270,"line":311},[268,141426,141427],{"class":278},"        panic!",[268,141429,622],{"class":282},[268,141431,141432],{"class":289},"\"dropped during unwind\"",[268,141434,628],{"class":282},[268,141436,141437],{"class":270,"line":788},[268,141438,11972],{"class":282},[268,141440,141441],{"class":270,"line":1951},[268,141442,314],{"class":282},[23,141444,141446,141452,141458,141464],{"className":141445},[26],[28,141447,141449,141451],{"className":141448},[31],[33,141450],{"disabled":35,"type":36}," The process aborts immediately — Rust cannot unwind through two simultaneous panics, so this becomes a hard abort instead of a normal panic-and-recover",[28,141453,141455,141457],{"className":141454},[31],[33,141456],{"disabled":35,"type":36}," The second panic is silently swallowed and unwinding continues normally",[28,141459,141461,141463],{"className":141460},[31],[33,141462],{"disabled":35,"type":36}," The second panic simply replaces the first, and the program continues as if only one panic occurred",[28,141465,141467,355,141469,141472,141473,141475,141476],{"className":141466},[31],[33,141468],{"disabled":35,"type":36},[39,141470,141471],{},"Drop::drop"," cannot panic; the compiler rejects any ",[39,141474,140445],{}," body containing ",[39,141477,119025],{},[66,141479,141480,141482,141487],{},[69,141481,71],{},[73,141483,141484,141486],{},[76,141485,78],{}," A — the process aborts immediately; Rust cannot unwind through two simultaneous panics",[73,141488,141489,355,141491,141494,141495,141497,141498,141500,141501,141503,141504,141506,141507,23506,141509,141511],{},[76,141490,84],{},[76,141492,141493],{},"Safety\u002FDebug:"," If a ",[39,141496,140445],{}," runs as part of unwinding from an earlier panic and itself panics, Rust has no defined way to unwind two panics at once through the same stack, so the runtime immediately calls ",[39,141499,40012],{}," — no further cleanup, no graceful shutdown, process terminates hard. This is a production-relevant gotcha: ",[39,141502,128979],{}," implementations should avoid any code that can panic (avoid ",[39,141505,110107],{},", indexing, arithmetic that can overflow in debug mode, etc.), preferring to log-and-continue or use fallible alternatives, precisely because a panicking destructor during unwinding is one of the few ways to lose the ability to gracefully report an error at all. The compiler does not reject ",[39,141508,119025],{},[39,141510,140445],{}," — it's syntactically and semantically legal, just dangerous in this specific double-unwind scenario; the double-panic-aborts behavior is a hard runtime rule, not something silently absorbed or overwritten.",[15,141513,141514,141521,141629,141685],{"language":111909},[18,141515,141517,141518,141520],{"id":141516},"q11-a-struct-wraps-a-vecu8-as-a-newtype-to-represent-a-validated-non-empty-buffer-what-is-the-most-common-mistake-that-defeats-the-purpose-of-this-newtype","Q11. A struct wraps a ",[39,141519,121381],{}," as a newtype to represent a validated, non-empty buffer. What is the most common mistake that defeats the purpose of this newtype?",[257,141522,141523],{"language":111909},[260,141524,141526],{"className":111918,"code":141525,"language":111909,"meta":264,"style":264},"pub struct NonEmptyBuffer(Vec\u003Cu8>);\n\nimpl NonEmptyBuffer {\n    pub fn new(data: Vec\u003Cu8>) -> Option\u003CSelf> {\n        if data.is_empty() { None } else { Some(Self(data)) }\n    }\n}\n",[39,141527,141528,141548,141552,141560,141591,141621,141625],{"__ignoreMap":264},[268,141529,141530,141532,141535,141538,141540,141542,141544,141546],{"class":270,"line":271},[268,141531,117577],{"class":274},[268,141533,141534],{"class":274}," struct",[268,141536,141537],{"class":278}," NonEmptyBuffer",[268,141539,622],{"class":282},[268,141541,112877],{"class":278},[268,141543,1076],{"class":282},[268,141545,114808],{"class":278},[268,141547,139861],{"class":282},[268,141549,141550],{"class":270,"line":286},[268,141551,5033],{"emptyLinePlaceholder":35},[268,141553,141554,141556,141558],{"class":270,"line":296},[268,141555,123290],{"class":274},[268,141557,141537],{"class":278},[268,141559,9914],{"class":282},[268,141561,141562,141564,141566,141568,141571,141573,141575,141577,141579,141581,141583,141585,141587,141589],{"class":270,"line":311},[268,141563,138137],{"class":274},[268,141565,37900],{"class":274},[268,141567,11370],{"class":278},[268,141569,141570],{"class":282},"(data",[268,141572,10728],{"class":274},[268,141574,124747],{"class":278},[268,141576,1076],{"class":282},[268,141578,114808],{"class":278},[268,141580,126464],{"class":282},[268,141582,113308],{"class":274},[268,141584,126457],{"class":278},[268,141586,1076],{"class":282},[268,141588,124895],{"class":305},[268,141590,121209],{"class":282},[268,141592,141593,141595,141597,141599,141602,141604,141606,141608,141610,141612,141614,141616,141618],{"class":270,"line":788},[268,141594,119688],{"class":274},[268,141596,68593],{"class":282},[268,141598,462],{"class":274},[268,141600,141601],{"class":278},"is_empty",[268,141603,34756],{"class":282},[268,141605,90944],{"class":278},[268,141607,7908],{"class":282},[268,141609,9884],{"class":274},[268,141611,20200],{"class":282},[268,141613,125816],{"class":278},[268,141615,622],{"class":282},[268,141617,124895],{"class":305},[268,141619,141620],{"class":282},"(data)) }\n",[268,141622,141623],{"class":270,"line":1951},[268,141624,11972],{"class":282},[268,141626,141627],{"class":270,"line":8955},[268,141628,314],{"class":282},[23,141630,141632,141653,141665,141674],{"className":141631},[26],[28,141633,141635,141637,141638,141640,141641,141644,141645,141648,141649,141652],{"className":141634},[31],[33,141636],{"disabled":35,"type":36}," Leaving the tuple field ",[39,141639,121381],{}," public (",[39,141642,141643],{},"pub Vec\u003Cu8>"," instead of a private field), which lets any caller construct ",[39,141646,141647],{},"NonEmptyBuffer(vec![])"," directly, bypassing the validating ",[39,141650,141651],{},"new()"," and violating the non-empty invariant",[28,141654,141656,97641,141658,8574,141661,141664],{"className":141655},[31],[33,141657],{"disabled":35,"type":36},[39,141659,141660],{},"Option\u003CSelf>",[39,141662,141663],{},"Result\u003CSelf, Error>"," in the constructor, which is always wrong",[28,141666,141668,141670,141671,141673],{"className":141667},[31],[33,141669],{"disabled":35,"type":36}," Deriving ",[39,141672,122174],{}," on the struct, which would allow duplicating the buffer",[28,141675,141677,141679,141680,8574,141682],{"className":141676},[31],[33,141678],{"disabled":35,"type":36}," Naming the constructor ",[39,141681,141651],{},[39,141683,141684],{},"from_vec()",[66,141686,141687,141689,141694],{},[69,141688,71],{},[73,141690,141691,141693],{},[76,141692,78],{}," A — leaving the inner field public lets callers construct the newtype directly, bypassing validation",[73,141695,141696,355,141698,141700,141701,141703,141704,141706,141707,141709,141710,6033,141712,141714,141715,21599,141717,141719,141720,7507,141722,141724,141725,141727,141728,141730,141731,141734],{},[76,141697,84],{},[76,141699,582],{}," The entire value of a \"validated newtype\" (non-empty buffer, positive integer, normalized email, etc.) depends on there being no way to construct one except through the checked constructor — if the tuple field is ",[39,141702,117577],{},", anyone can write ",[39,141705,141647],{}," directly from outside the module, completely bypassing ",[39,141708,141651],{},"'s emptiness check and silently reintroducing the exact bug the type was created to prevent. Keeping the field private (as shown, no ",[39,141711,117577],{},[39,141713,121381],{},") is what makes ",[39,141716,141651],{},[104,141718,3117],{}," construction path. ",[39,141721,116852],{},[39,141723,110110],{}," in the constructor is a legitimate, context-dependent API choice (not \"always wrong\" — ",[39,141726,116852],{}," is fine when there's only one failure reason and no extra context to convey). Deriving ",[39,141729,122174],{}," is harmless here — cloning a valid ",[39,141732,141733],{},"NonEmptyBuffer"," produces another valid one, since the invariant (non-empty) is preserved by copying the same data. Constructor naming is a style preference with no soundness implication.",[15,141736,141737,141748,141812,141846],{"language":111909},[18,141738,141740,141741,141743,141744,141747],{"id":141739},"q12-a-builders-build-method-is-called-twice-on-the-same-builder-instance-given-standard-consuming-builder-design-fn-buildself-t-what-happens-on-the-second-call","Q12. A builder's ",[39,141742,125109],{}," method is called twice on the same builder instance. Given standard consuming-builder design (",[39,141745,141746],{},"fn build(self) -> T","), what happens on the second call?",[257,141749,141750],{"language":111909},[260,141751,141753],{"className":111918,"code":141752,"language":111909,"meta":264,"style":264},"let builder = RequestBuilder::new(\"url\");\nlet req1 = builder.build();\nlet req2 = builder.build();\n",[39,141754,141755,141777,141795],{"__ignoreMap":264},[268,141756,141757,141759,141762,141764,141766,141768,141770,141772,141775],{"class":270,"line":271},[268,141758,240],{"class":274},[268,141760,141761],{"class":282}," builder ",[268,141763,302],{"class":274},[268,141765,139529],{"class":278},[268,141767,84903],{"class":274},[268,141769,2689],{"class":278},[268,141771,622],{"class":282},[268,141773,141774],{"class":289},"\"url\"",[268,141776,628],{"class":282},[268,141778,141779,141781,141784,141786,141789,141791,141793],{"class":270,"line":286},[268,141780,240],{"class":274},[268,141782,141783],{"class":282}," req1 ",[268,141785,302],{"class":274},[268,141787,141788],{"class":282}," builder",[268,141790,462],{"class":274},[268,141792,14155],{"class":278},[268,141794,794],{"class":282},[268,141796,141797,141799,141802,141804,141806,141808,141810],{"class":270,"line":296},[268,141798,240],{"class":274},[268,141800,141801],{"class":282}," req2 ",[268,141803,302],{"class":274},[268,141805,141788],{"class":282},[268,141807,462],{"class":274},[268,141809,14155],{"class":278},[268,141811,794],{"class":282},[23,141813,141815,141828,141834,141840],{"className":141814},[26],[28,141816,141818,119243,141820,141823,141824,141827],{"className":141817},[31],[33,141819],{"disabled":35,"type":36},[39,141821,141822],{},"build(self)"," consumes the builder by value on the first call, making ",[39,141825,141826],{},"builder"," unavailable for the second call (use-after-move)",[28,141829,141831,141833],{"className":141830},[31],[33,141832],{"disabled":35,"type":36}," Both calls succeed and produce two independent, identically-configured requests",[28,141835,141837,141839],{"className":141836},[31],[33,141838],{"disabled":35,"type":36}," The second call returns a default-constructed, empty request instead of erroring",[28,141841,141843,141845],{"className":141842},[31],[33,141844],{"disabled":35,"type":36}," It compiles, but the second call panics at runtime with \"builder already consumed\"",[66,141847,141848,141850,141857],{},[69,141849,71],{},[73,141851,141852,141321,141854,141856],{},[76,141853,78],{},[39,141855,141822],{}," moves the builder, so calling it twice is a use-after-move caught at compile time",[73,141858,141859,355,141861,124316,141863,141865,141866,141868,141869,141871,141872,141874,141875,141877,141878,141880,141881,141883,141884,141887],{},[76,141860,84],{},[76,141862,930],{},[39,141864,87099],{}," by value in ",[39,141867,125109],{}," is a deliberate design choice (not an accident) — it statically enforces \"a builder can only be finalized once,\" turning a whole class of \"did I already call ",[39,141870,120262],{},"?\" bugs into compile errors rather than needing runtime tracking. This is why many builder APIs use ",[39,141873,87099],{}," (consuming) rather than ",[39,141876,113013],{}," for chained methods that lead into ",[39,141879,125109],{},": it composes with move semantics to make double-finalization structurally impossible, exactly analogous to the typestate consumption in Q9. There's no runtime panic path here — the compiler rejects the second call before the program can ever run, and there's no default-empty fallback or implicit duplication; if a caller genuinely needs to build multiple times, the builder type would need to implement ",[39,141882,122174],{}," explicitly, or expose ",[39,141885,141886],{},"build(&self)"," instead (a valid alternative design with its own trade-offs, but not what's shown here).",[15,141889,141890,141899,141974,142024],{"language":111909},[18,141891,141893,141894,141896,141897,1685],{"id":141892},"q13-what-happens-if-a-drop-impl-is-written-for-a-type-that-also-derives-copy","Q13. What happens if a ",[39,141895,128979],{}," impl is written for a type that also derives ",[39,141898,114164],{},[257,141900,141901],{"language":111909},[260,141902,141904],{"className":111918,"code":141903,"language":111909,"meta":264,"style":264},"#[derive(Clone, Copy)]\nstruct Point { x: i32, y: i32 }\n\nimpl Drop for Point {\n    fn drop(&mut self) {}\n}\n",[39,141905,141906,141919,141939,141943,141955,141970],{"__ignoreMap":264},[268,141907,141908,141911,141913,141915,141917],{"class":270,"line":271},[268,141909,141910],{"class":282},"#[derive(",[268,141912,122174],{"class":278},[268,141914,42],{"class":282},[268,141916,114164],{"class":278},[268,141918,105523],{"class":282},[268,141920,141921,141923,141925,141927,141929,141931,141933,141935,141937],{"class":270,"line":286},[268,141922,121198],{"class":274},[268,141924,30134],{"class":278},[268,141926,125469],{"class":282},[268,141928,10728],{"class":274},[268,141930,113794],{"class":278},[268,141932,121628],{"class":282},[268,141934,10728],{"class":274},[268,141936,113794],{"class":278},[268,141938,29394],{"class":282},[268,141940,141941],{"class":270,"line":296},[268,141942,5033],{"emptyLinePlaceholder":35},[268,141944,141945,141947,141949,141951,141953],{"class":270,"line":311},[268,141946,123290],{"class":274},[268,141948,140393],{"class":278},[268,141950,85712],{"class":274},[268,141952,30134],{"class":278},[268,141954,9914],{"class":282},[268,141956,141957,141959,141961,141963,141965,141967],{"class":270,"line":788},[268,141958,120364],{"class":274},[268,141960,140406],{"class":278},[268,141962,622],{"class":282},[268,141964,114510],{"class":274},[268,141966,96472],{"class":305},[268,141968,141969],{"class":282},") {}\n",[268,141971,141972],{"class":270,"line":1951},[268,141973,314],{"class":282},[23,141975,141977,141994,142003,142015],{"className":141976},[26],[28,141978,141980,141982,141983,186,141985,141987,141988,141990,141991,141993],{"className":141979},[31],[33,141981],{"disabled":35,"type":36}," This is a compile error — ",[39,141984,114164],{},[39,141986,128979],{}," are mutually exclusive on the same type, because ",[39,141989,114164],{}," implies bitwise duplication with no notion of \"the original is now gone,\" which conflicts with ",[39,141992,128979],{},"'s single-owner cleanup guarantee",[28,141995,141997,141999,142000,142002],{"className":141996},[31],[33,141998],{"disabled":35,"type":36}," This compiles fine; ",[39,142001,140445],{}," simply runs once per each bitwise copy independently",[28,142004,142006,142008,142009,142011,142012,142014],{"className":142005},[31],[33,142007],{"disabled":35,"type":36}," This compiles, but ",[39,142010,114164],{}," is silently ignored and the type behaves as ",[39,142013,122174],{},"-only",[28,142016,142018,142020,142021,142023],{"className":142017},[31],[33,142019],{"disabled":35,"type":36}," This compiles only if ",[39,142022,141471],{}," is an empty function body, as shown",[66,142025,142026,142028,142037],{},[69,142027,71],{},[73,142029,142030,141321,142032,186,142034,142036],{},[76,142031,78],{},[39,142033,114164],{},[39,142035,128979],{}," are mutually exclusive by design",[73,142038,142039,355,142041,355,142043,142045,142046,142048,142049,126945,142052,142055,142056,142059,142060,142062,142063,142065,142066,446,142068,142070],{},[76,142040,84],{},[76,142042,582],{},[39,142044,114164],{}," means assignment\u002Fpassing duplicates the bits with no move semantics — both the \"original\" and the \"copy\" remain simultaneously valid and usable. ",[39,142047,128979],{}," is built entirely around Rust's ownership guarantee that a value has exactly one owner responsible for cleanup at scope end. If a type were both, you'd get either a double-free (both bitwise copies' destructors trying to free\u002Frelease the same resource) or an ill-defined \"which copy actually owns the resource\" question — so the compiler flatly rejects ",[39,142050,142051],{},"#[derive(Copy)]",[39,142053,142054],{},"impl Copy",") on any type that also ",[39,142057,142058],{},"impl Drop",", regardless of whether the ",[39,142061,140445],{}," body is empty (option D is a red herring: the restriction is structural\u002Ftype-level, not based on the body's contents). This isn't silently downgraded to ",[39,142064,122174],{},"-only either — it's a hard compile error at the ",[39,142067,124545],{},[39,142069,123290],{}," site.",[15,142072,142073,142085,142156,142199],{"language":111909},[18,142074,142076,142077,142080,142081,142084],{"id":142075},"q14-a-typestate-api-models-a-network-connection-with-disconnected-connecting-connected-states-a-method-needs-to-handle-the-case-where-connecting-can-fail-and-should-return-to-disconnected-how-is-this-typically-expressed-in-the-return-type","Q14. A typestate API models a network connection with ",[39,142078,142079],{},"Disconnected -> Connecting -> Connected"," states. A method needs to handle the case where connecting can fail and should return to ",[39,142082,142083],{},"Disconnected",". How is this typically expressed in the return type?",[257,142086,142087],{"language":111909},[260,142088,142090],{"className":111918,"code":142089,"language":111909,"meta":264,"style":264},"impl Connection\u003CConnecting> {\n    fn finish(self) -> Result\u003CConnection\u003CConnected>, Connection\u003CDisconnected>> {\n        \u002F\u002F ...\n    }\n}\n",[39,142091,142092,142106,142143,142148,142152],{"__ignoreMap":264},[268,142093,142094,142096,142099,142101,142104],{"class":270,"line":271},[268,142095,123290],{"class":274},[268,142097,142098],{"class":278}," Connection",[268,142100,1076],{"class":282},[268,142102,142103],{"class":278},"Connecting",[268,142105,121209],{"class":282},[268,142107,142108,142110,142113,142115,142117,142119,142121,142123,142125,142127,142129,142132,142134,142136,142138,142140],{"class":270,"line":286},[268,142109,120364],{"class":274},[268,142111,142112],{"class":278}," finish",[268,142114,622],{"class":282},[268,142116,87099],{"class":305},[268,142118,6131],{"class":282},[268,142120,113308],{"class":274},[268,142122,116239],{"class":278},[268,142124,1076],{"class":282},[268,142126,124499],{"class":278},[268,142128,1076],{"class":282},[268,142130,142131],{"class":278},"Connected",[268,142133,140584],{"class":282},[268,142135,124499],{"class":278},[268,142137,1076],{"class":282},[268,142139,142083],{"class":278},[268,142141,142142],{"class":282},">> {\n",[268,142144,142145],{"class":270,"line":296},[268,142146,142147],{"class":29390},"        \u002F\u002F ...\n",[268,142149,142150],{"class":270,"line":311},[268,142151,11972],{"class":282},[268,142153,142154],{"class":270,"line":788},[268,142155,314],{"class":282},[23,142157,142159,142172,142178,142188],{"className":142158},[26],[28,142160,142162,142164,142165,142168,142169,142171],{"className":142161},[31],[33,142163],{"disabled":35,"type":36}," Return a ",[39,142166,142167],{},"Result\u003CConnection\u003CConnected>, Connection\u003CDisconnected>>"," (or a similar ",[39,142170,110110],{},"\u002Fenum of the two possible resulting typestates), so callers must handle both outcomes and the compiler enforces that the returned value's state matches what actually happened",[28,142173,142175,142177],{"className":142174},[31],[33,142176],{"disabled":35,"type":36}," Panic on connection failure, since typestate patterns cannot express fallible transitions",[28,142179,142181,142183,142184,142187],{"className":142180},[31],[33,142182],{"disabled":35,"type":36}," Return ",[39,142185,142186],{},"Connection\u003CConnecting>"," unchanged and let the caller retry indefinitely",[28,142189,142191,4353,142193,142196,142197],{"className":142190},[31],[33,142192],{"disabled":35,"type":36},[39,142194,142195],{},"unsafe { std::mem::transmute }"," to force the state type back to ",[39,142198,142083],{},[66,142200,142201,142203,142216],{},[69,142202,71],{},[73,142204,142205,142207,142208,142210,142211,446,142213,142215],{},[76,142206,78],{}," A — return a ",[39,142209,110110],{}," (or equivalent) whose ",[39,142212,120129],{},[39,142214,116301],{}," carry the two possible resulting typestates",[73,142217,142218,355,142220,142222,142223,142226,142227,142229,142230,446,142232,142234,142235,142237,142238,142240,142241,142243],{},[76,142219,84],{},[76,142221,930],{}," Fallible transitions compose naturally with typestate by making the ",[104,142224,142225],{},"return type itself"," encode \"one of these two states is what you'll get,\" typically via ",[39,142228,142167],{}," or a small enum — the caller is then compiler-forced (via ",[39,142231,116378],{},[39,142233,1685],{},") to handle both branches, and whichever branch executes hands back a correctly-typed value for that actual state, preserving the whole pattern's compile-time guarantees through the fallible step. Typestate absolutely can express fallible transitions this way — panicking would be a strictly worse design that throws away the ability to recover from an ordinary, expected failure (a network connect timing out is not exceptional). Returning ",[39,142236,142186],{}," unchanged doesn't reflect reality (the state actually changed to failed\u002Fdisconnected) and invites infinite-retry bugs. Using ",[39,142239,116565],{}," to force a type back is exactly the kind of unsound hack the entire pattern exists to make unnecessary — legitimate typestate code should never need ",[39,142242,112499],{}," to move between states.",[15,142245,142246,142252,142290,142324],{"language":111909},[18,142247,142249,142250,1685],{"id":142248},"q15-when-is-it-idiomatic-to-use-the-builder-pattern-versus-simply-using-a-struct-literal-with-defaultdefault","Q15. When is it idiomatic to use the builder pattern versus simply using a struct literal with ",[39,142251,124583],{},[257,142253,142254],{"language":111909},[260,142255,142257],{"className":111918,"code":142256,"language":111909,"meta":264,"style":264},"let cfg = Config { timeout: 30, ..Default::default() };\n",[39,142258,142259],{"__ignoreMap":264},[268,142260,142261,142263,142266,142268,142270,142273,142275,142277,142279,142281,142283,142285,142287],{"class":270,"line":271},[268,142262,240],{"class":274},[268,142264,142265],{"class":282}," cfg ",[268,142267,302],{"class":274},[268,142269,97944],{"class":278},[268,142271,142272],{"class":282}," { timeout",[268,142274,10728],{"class":274},[268,142276,122968],{"class":305},[268,142278,42],{"class":282},[268,142280,86888],{"class":274},[268,142282,124579],{"class":278},[268,142284,84903],{"class":274},[268,142286,9046],{"class":278},[268,142288,142289],{"class":282},"() };\n",[23,142291,142293,142301,142307,142315],{"className":142292},[26],[28,142294,142296,138919,142298,142300],{"className":142295},[31],[33,142297],{"disabled":35,"type":36},[39,142299,124583],{}," struct-update syntax for simple, all-public-field configs with no cross-field validation needed; reach for a builder when construction needs validation, computed\u002Fderived defaults, required fields enforced at compile time, or a fluent multi-step API",[28,142302,142304,142306],{"className":142303},[31],[33,142305],{"disabled":35,"type":36}," The builder pattern should always be used, even for a two-field public struct, since it's considered more professional",[28,142308,142310,355,142312,142314],{"className":142309},[31],[33,142311],{"disabled":35,"type":36},[39,142313,124583],{}," cannot be combined with named field initialization in the same literal",[28,142316,142318,142320,142321,142323],{"className":142317},[31],[33,142319],{"disabled":35,"type":36}," Builders are strictly for compatibility with older Rust editions; ",[39,142322,124583],{}," fully replaces them in modern code",[66,142325,142326,142328,142336],{},[69,142327,71],{},[73,142329,142330,142332,142333,142335],{},[76,142331,78],{}," A — use ",[39,142334,124583],{}," for simple public-field configs with no validation; use a builder when validation, derived defaults, or required-field enforcement is needed",[73,142337,142338,355,142340,355,142342,142344,142345,142347,142348,142350,142351,142354,142355,42,142357,142360,142361,462],{},[76,142339,84],{},[76,142341,930],{},[39,142343,124583],{}," is lighter-weight and perfectly idiomatic when a struct's fields are all meant to be public and independently valid in any combination — it avoids the ceremony of a whole separate builder type for something trivial. A builder earns its complexity when construction has invariants to check (cross-field validation), needs a required field enforced (impossible to skip ",[39,142346,140946],{},", unlike a ",[39,142349,124579],{},"-based struct literal where every field is implicitly optional-with-a-default), or benefits from a readable fluent chain for many optional settings. \"Always use a builder\" ignores this real trade-off and adds needless boilerplate for simple cases. The syntax shown (",[39,142352,142353],{},"Config { timeout: 30, ..Default::default() }",") is exactly the valid, common combination of named fields plus a base — the claim that they can't be combined is false. And builders remain a first-class, actively-used pattern in modern Rust (e.g. ",[39,142356,139666],{},[39,142358,142359],{},"reqwest::ClientBuilder",") — they were never edition-specific or made obsolete by ",[39,142362,124579],{},[15,142364,142365,142369,142467,142516],{"language":111909},[18,142366,142368],{"id":142367},"q16-what-is-the-idiomatic-way-to-make-a-builders-chained-setter-methods-ergonomic-for-method-chaining-while-still-being-usable-in-a-non-chained-imperative-style","Q16. What is the idiomatic way to make a builder's chained setter methods ergonomic for method chaining while still being usable in a non-chained, imperative style?",[257,142370,142371],{"language":111909},[260,142372,142374],{"className":111918,"code":142373,"language":111909,"meta":264,"style":264},"impl RequestBuilder {\n    pub fn header(mut self, key: &str, val: &str) -> Self {\n        self.headers.push((key.into(), val.into()));\n        self\n    }\n}\n",[39,142375,142376,142384,142425,142454,142459,142463],{"__ignoreMap":264},[268,142377,142378,142380,142382],{"class":270,"line":271},[268,142379,123290],{"class":274},[268,142381,139529],{"class":278},[268,142383,9914],{"class":282},[268,142385,142386,142388,142390,142393,142395,142397,142399,142402,142404,142406,142408,142411,142413,142415,142417,142419,142421,142423],{"class":270,"line":286},[268,142387,138137],{"class":274},[268,142389,37900],{"class":274},[268,142391,142392],{"class":278}," header",[268,142394,622],{"class":282},[268,142396,112025],{"class":274},[268,142398,96472],{"class":305},[268,142400,142401],{"class":282},", key",[268,142403,10728],{"class":274},[268,142405,115951],{"class":274},[268,142407,17109],{"class":278},[268,142409,142410],{"class":282},", val",[268,142412,10728],{"class":274},[268,142414,115951],{"class":274},[268,142416,17109],{"class":278},[268,142418,6131],{"class":282},[268,142420,113308],{"class":274},[268,142422,137207],{"class":305},[268,142424,9914],{"class":282},[268,142426,142427,142429,142431,142433,142435,142437,142440,142442,142445,142448,142450,142452],{"class":270,"line":296},[268,142428,92944],{"class":305},[268,142430,462],{"class":274},[268,142432,15539],{"class":282},[268,142434,462],{"class":274},[268,142436,12499],{"class":278},[268,142438,142439],{"class":282},"((key",[268,142441,462],{"class":274},[268,142443,142444],{"class":278},"into",[268,142446,142447],{"class":282},"(), val",[268,142449,462],{"class":274},[268,142451,142444],{"class":278},[268,142453,39055],{"class":282},[268,142455,142456],{"class":270,"line":311},[268,142457,142458],{"class":305},"        self\n",[268,142460,142461],{"class":270,"line":788},[268,142462,11972],{"class":282},[268,142464,142465],{"class":270,"line":1951},[268,142466,314],{"class":282},[23,142468,142470,142491,142502,142510],{"className":142469},[26],[28,142471,142473,142475,142476,142479,142480,142482,142483,142486,142487,142490],{"className":142472},[31],[33,142474],{"disabled":35,"type":36}," Take ",[39,142477,142478],{},"mut self"," by value and return ",[39,142481,124895],{},", mutating the owned copy and handing it back — this supports both ",[39,142484,142485],{},"builder.header(..).header(..)"," chaining and ",[39,142488,142489],{},"let b = b.header(..);"," reassignment style",[28,142492,142494,142475,142496,142498,142499,142501],{"className":142493},[31],[33,142495],{"disabled":35,"type":36},[39,142497,113013],{}," and return ",[39,142500,16952],{},", which is the only way to support method chaining in Rust",[28,142503,142505,142475,142507,142509],{"className":142504},[31],[33,142506],{"disabled":35,"type":36},[39,142508,112964],{}," (immutable) and return a brand-new heap-allocated builder each call, which is the most performant option",[28,142511,142513,142515],{"className":142512},[31],[33,142514],{"disabled":35,"type":36}," It's impossible to support both chained and non-chained calling styles with the same method signature",[66,142517,142518,142520,142531],{},[69,142519,71],{},[73,142521,142522,142524,142525,142527,142528,142530],{},[76,142523,78],{}," A — take ",[39,142526,142478],{}," by value, return ",[39,142529,124895],{},"; supports both chaining and imperative reassignment",[73,142532,142533,355,142535,124316,142537,142539,142540,142542,142543,142545,142546,142549,142550,142552,142553,142556,142557,142560,142561,142564,142565,142567],{},[76,142534,84],{},[76,142536,930],{},[39,142538,87099],{}," by value (not ",[39,142541,113013],{},") and returning ",[39,142544,124895],{}," is the standard consuming-builder signature: it supports fluent chaining (",[39,142547,142548],{},"RequestBuilder::new(url).header(...).header(...).build()",") because each call produces a new owned value to call the next method on, ",[104,142551,31781],{}," it equally supports the imperative style ",[39,142554,142555],{},"let b = b.header(...);"," since it's just an ordinary function taking and returning a value — no special calling convention required. ",[39,142558,142559],{},"&mut self -> ()"," cannot be chained at all (there's nothing returned to call the next method on — you'd need separate statements), so it's actually the ",[104,142562,142563],{},"opposite"," of what enables chaining, making that option's claim backwards. ",[39,142566,112964],{}," returning a freshly allocated builder is unnecessary allocation churn for no benefit over consuming-and-returning the existing owned value, and it isn't \"more performant\" — it's strictly more allocation for the same result. Supporting both styles with one signature is exactly what the consuming pattern already does, contrary to the last option.",[15,142569,142570,142582],{"language":111909},[18,142571,142573,142574,142576,142577,142579,142580,1685],{"id":142572},"q17-best-practice-should-a-drop-implementation-perform-fallible-io-eg-flushing-a-buffered-writer-to-disk-directly-given-that-drop-cannot-return-a-result","Q17. Best practice: should a ",[39,142575,128979],{}," implementation perform fallible I\u002FO (e.g. flushing a buffered writer to disk) directly, given that ",[39,142578,140445],{}," cannot return a ",[39,142581,110110],{},[257,142583,142584,142591,142597,142599,142635,107924,142667,142858],{"language":111909},[73,142585,142586,142587,142590],{},"struct BufferedLog { writer: std::io::BufWriter",[1223,142588,142589],{"href":142589},"std::fs::File"," }",[260,142592,142595],{"className":142593,"code":142594,"language":107798},[107796],"::\n\n- [ ] No — since `drop()` can't propagate errors, best practice is to expose an explicit fallible `close()`\u002F`flush()` method that callers invoke to handle errors properly, with `Drop` only as a best-effort fallback (often logging-and-swallowing) for callers who forgot\n- [ ] Yes — `Drop` is the only place cleanup should ever happen; explicit `close()` methods are redundant and should be avoided\n- [ ] It doesn't matter; any error inside `drop()` automatically becomes the return value of the enclosing function\n- [ ] Fallible I\u002FO should never appear in RAII types at all; buffered writers should not implement `Drop`\n\n\u003Cdetails>\n\u003Csummary>Show Answer\u003C\u002Fsummary>\n\n**Answer:** A — expose an explicit fallible `close()`\u002F`flush()` for real error handling; `Drop` is only a best-effort fallback\n\n**Explanation:** **Idiom\u002FDebug:** Because `Drop::drop(&mut self)` has a fixed `()` return type, there is no way to propagate a flush failure to the caller from inside it — if flushing fails during `drop()`, the best you can typically do is log the error (or, in truly critical cases, panic — accepting the abort-on-double-panic risk from Q10) and move on; the error is otherwise silently lost. This is exactly why types like `BufWriter` document that callers should call an explicit `.flush()` (which *does* return `io::Result\u003C()>`) before the value is dropped, rather than relying on the implicit drop to handle a failure path correctly — the implicit drop exists as a safety net for panics\u002Fearly-returns, not as the primary error-handling path. Errors inside `drop()` are never auto-propagated to any enclosing function — the calling code has no visibility into `drop()`'s internals at all. And RAII types absolutely can and do wrap fallible resources (files, sockets, locks) — that's a huge fraction of `Drop`'s real-world use; the pattern isn't disqualified by fallibility, it just requires this explicit-close convention to handle errors properly.\n\n\u003C\u002Fdetails>\n::\n\n::question-wrapper{language=\"rust\"}\n### Q18. In a visitor implemented as a trait (`trait Visitor { fn visit_num(&mut self, n: f64); fn visit_add(&mut self, l: &Expr, r: &Expr); }`), what is the best-practice way to allow visitors to skip most node types without writing every method?\n\n::code-wrapper{language=\"rust\"}\n```rust\ntrait Visitor {\n    fn visit_num(&mut self, n: f64) {}\n    fn visit_add(&mut self, l: &Expr, r: &Expr) {}\n    fn visit_mul(&mut self, l: &Expr, r: &Expr) {}\n}\n",[39,142596,142594],{"__ignoreMap":264},[73,142598,84903],{},[23,142600,142602,142611,142620,142626],{"className":142601},[26],[28,142603,142605,142607,142608,142610],{"className":142604},[31],[33,142606],{"disabled":35,"type":36}," Give each method a default (often empty or auto-recursing) implementation in the trait definition, so implementors only override the specific ",[39,142609,140831],{}," methods they actually care about",[28,142612,142614,142616,142617,142619],{"className":142613},[31],[33,142615],{"disabled":35,"type":36}," Make the trait's methods all ",[39,142618,112499],{}," so unimplemented ones default to undefined behavior instead of a compile error",[28,142621,142623,142625],{"className":142622},[31],[33,142624],{"disabled":35,"type":36}," There is no way to make methods optional; every implementor must provide every method or fail to compile",[28,142627,142629,4353,142631,142634],{"className":142628},[31],[33,142630],{"disabled":35,"type":36},[39,142632,142633],{},"#[derive(Visitor)]"," from the standard library to auto-generate no-op defaults",[66,142636,142637,142639,142644],{},[69,142638,71],{},[73,142640,142641,142643],{},[76,142642,78],{}," A — give trait methods default implementations so implementors override only what they need",[73,142645,142646,355,142648,142650,142651,142654,142655,142657,142658,142660,142661,142663,142664,142666],{},[76,142647,84],{},[76,142649,930],{}," Rust traits support default method bodies directly in the trait definition; any implementor can simply omit a method to inherit the default (commonly a no-op, or one that recurses into child nodes to keep traversal working), which is precisely how ecosystem visitor traits (e.g. ",[39,142652,142653],{},"syn::visit::Visit",") let users override only the handful of node types they care about instead of exhaustively implementing dozens of ",[39,142656,140831],{}," methods. Making methods ",[39,142659,112499],{}," has nothing to do with optionality and would just require callers to wrap every call in an ",[39,142662,112499],{}," block for no benefit — it doesn't create \"default to UB,\" which isn't a real Rust mechanism. There is no ",[39,142665,142633],{}," in the standard library; default method bodies in the trait itself are the actual, standard mechanism, and without them every method genuinely would be mandatory, making the \"no way\" option only true in the absence of defaults, which is exactly what this pattern adds.",[15,142668,142669,142689,142752,142804],{"language":111909},[18,142670,142672,142673,42,142676,42,142679,142682,142683,103289,142686,142688],{"id":142671},"q19-a-codebase-has-many-newtypes-like-useridu64-orderidu64-productidu64-what-best-practice-most-directly-prevents-accidentally-passing-an-orderid-where-a-userid-is-expected-beyond-just-wrapping-in-a-struct","Q19. A codebase has many newtypes like ",[39,142674,142675],{},"UserId(u64)",[39,142677,142678],{},"OrderId(u64)",[39,142680,142681],{},"ProductId(u64)",". What best practice most directly prevents accidentally passing an ",[39,142684,142685],{},"OrderId",[39,142687,103211],{}," is expected, beyond just wrapping in a struct?",[257,142690,142691],{"language":111909},[260,142692,142694],{"className":111918,"code":142693,"language":111909,"meta":264,"style":264},"struct UserId(u64);\nstruct OrderId(u64);\n\nfn get_user(id: UserId) -> User { \u002F* ... *\u002F }\n",[39,142695,142696,142709,142722,142726],{"__ignoreMap":264},[268,142697,142698,142700,142703,142705,142707],{"class":270,"line":271},[268,142699,121198],{"class":274},[268,142701,142702],{"class":278}," UserId",[268,142704,622],{"class":282},[268,142706,116207],{"class":278},[268,142708,628],{"class":282},[268,142710,142711,142713,142716,142718,142720],{"class":270,"line":286},[268,142712,121198],{"class":274},[268,142714,142715],{"class":278}," OrderId",[268,142717,622],{"class":282},[268,142719,116207],{"class":278},[268,142721,628],{"class":282},[268,142723,142724],{"class":270,"line":296},[268,142725,5033],{"emptyLinePlaceholder":35},[268,142727,142728,142730,142733,142736,142738,142740,142742,142744,142746,142748,142750],{"class":270,"line":311},[268,142729,37837],{"class":274},[268,142731,142732],{"class":278}," get_user",[268,142734,142735],{"class":282},"(id",[268,142737,10728],{"class":274},[268,142739,142702],{"class":278},[268,142741,6131],{"class":282},[268,142743,113308],{"class":274},[268,142745,122944],{"class":278},[268,142747,20200],{"class":282},[268,142749,29391],{"class":29390},[268,142751,29394],{"class":282},[23,142753,142755,142773,142783,142794],{"className":142754},[26],[28,142756,142758,142760,142761,7501,142764,142767,142768,186,142770,142772],{"className":142757},[31],[33,142759],{"disabled":35,"type":36}," Nothing extra is needed beyond the newtype wrapper itself and using it consistently in function signatures — ",[39,142762,142763],{},"get_user(order_id)",[39,142765,142766],{},"order_id: OrderId"," is already a compile error because ",[39,142769,142685],{},[39,142771,103211],{}," are distinct, non-interchangeable types",[28,142774,142776,142778,142779,142782],{"className":142775},[31],[33,142777],{"disabled":35,"type":36}," Add a runtime assertion inside ",[39,142780,142781],{},"get_user"," that checks a \"type tag\" field to catch mismatches",[28,142784,142786,4353,142788,142790,142791,4866],{"className":142785},[31],[33,142787],{"disabled":35,"type":36},[39,142789,116207],{}," directly everywhere and rely on descriptive parameter names like ",[39,142792,142793],{},"user_id: u64",[28,142795,142797,142799,142800,142803],{"className":142796},[31],[33,142798],{"disabled":35,"type":36}," Implement ",[39,142801,142802],{},"From\u003COrderId> for UserId"," so the two remain freely convertible for flexibility",[66,142805,142806,142808,142813],{},[69,142807,71],{},[73,142809,142810,142812],{},[76,142811,78],{}," A — nothing extra needed; distinct newtypes are already non-interchangeable at compile time when used consistently in signatures",[73,142814,142815,355,142817,142819,142820,186,142822,142824,142825,142828,142829,142831,142832,142834,142835,142837,142838,142840,142841,142843,142844,7501,142847,142850,142851,142853,142854,142857],{},[76,142816,84],{},[76,142818,582],{}," This is the newtype pattern's core payoff restated concretely: once ",[39,142821,103211],{},[39,142823,142685],{}," are separate structs, ",[39,142826,142827],{},"fn get_user(id: UserId)"," simply cannot accept an ",[39,142830,142685],{}," argument — the compiler rejects ",[39,142833,142763],{}," as a type mismatch with zero runtime cost or extra ceremony, as long as the signatures consistently use the specific ID types rather than degrading back to raw ",[39,142836,116207],{}," anywhere in the call chain. A runtime \"type tag\" check is redundant ",[104,142839,31781],{}," strictly worse (it defers a catchable compile-time bug to a runtime check that could be skipped or forgotten) given the compiler already enforces this for free. Using bare ",[39,142842,116207],{}," everywhere and relying on naming conventions is exactly the unsafe baseline this pattern replaces — parameter names provide no compiler enforcement at all, and a caller passing ",[39,142845,142846],{},"user_id",[39,142848,142849],{},"order_id_as_u64"," was expected compiles silently. And implementing ",[39,142852,142802],{}," would be actively counterproductive — it reintroduces easy, silent interchangeability (via ",[39,142855,142856],{},".into()",") between two IDs that should never be conflated, undermining the entire point of separating them.",[15,142859,142860,142875,142963,142997],{"language":111909},[18,142861,142863,142864,446,142866,142868,142869,446,142872,8691],{"id":142862},"q20-which-of-these-is-a-legitimate-best-practice-reason-to-prefer-the-typestate-pattern-over-runtime-state-validation-an-enum-field-checked-with-ifmatch-inside-each-method-for-a-resource-with-a-strict-lifecycle-eg-a-database-transaction-begun-committedrolledback","Q20. Which of these is a legitimate best-practice reason to prefer the typestate pattern over runtime state validation (an enum field checked with ",[39,142865,2179],{},[39,142867,116378],{}," inside each method) for a resource with a strict lifecycle (e.g. a database transaction: ",[39,142870,142871],{},"Begun -> Committed",[39,142873,142874],{},"RolledBack",[257,142876,142877],{"language":111909},[260,142878,142880],{"className":111918,"code":142879,"language":111909,"meta":264,"style":264},"fn commit(&mut self) -> Result\u003C(), TxError> {\n    if self.state != TxState::Begun {\n        return Err(TxError::InvalidState);\n    }\n    \u002F\u002F ...\n}\n",[39,142881,142882,142909,142932,142950,142954,142959],{"__ignoreMap":264},[268,142883,142884,142886,142889,142891,142893,142895,142897,142899,142901,142904,142907],{"class":270,"line":271},[268,142885,37837],{"class":274},[268,142887,142888],{"class":278}," commit",[268,142890,622],{"class":282},[268,142892,114510],{"class":274},[268,142894,96472],{"class":305},[268,142896,6131],{"class":282},[268,142898,113308],{"class":274},[268,142900,116239],{"class":278},[268,142902,142903],{"class":282},"\u003C(), ",[268,142905,142906],{"class":278},"TxError",[268,142908,121209],{"class":282},[268,142910,142911,142913,142915,142917,142920,142922,142925,142927,142930],{"class":270,"line":286},[268,142912,9686],{"class":274},[268,142914,96472],{"class":305},[268,142916,462],{"class":274},[268,142918,142919],{"class":282},"state ",[268,142921,7733],{"class":274},[268,142923,142924],{"class":278}," TxState",[268,142926,84903],{"class":274},[268,142928,142929],{"class":278},"Begun",[268,142931,9914],{"class":282},[268,142933,142934,142936,142939,142941,142943,142945,142948],{"class":270,"line":296},[268,142935,11956],{"class":274},[268,142937,142938],{"class":278}," Err",[268,142940,622],{"class":282},[268,142942,142906],{"class":278},[268,142944,84903],{"class":274},[268,142946,142947],{"class":278},"InvalidState",[268,142949,628],{"class":282},[268,142951,142952],{"class":270,"line":311},[268,142953,11972],{"class":282},[268,142955,142956],{"class":270,"line":788},[268,142957,142958],{"class":29390},"    \u002F\u002F ...\n",[268,142960,142961],{"class":270,"line":1951},[268,142962,314],{"class":282},[23,142964,142966,142976,142985,142991],{"className":142965},[26],[28,142967,142969,142971,142972,142975],{"className":142968},[31],[33,142970],{"disabled":35,"type":36}," Typestate turns \"call ",[39,142973,142974],{},"commit()"," on an already-committed transaction\" from a runtime error path (that must be tested and can be forgotten) into something the compiler refuses to build in the first place, eliminating an entire category of production incident",[28,142977,142979,142981,142982,142984],{"className":142978},[31],[33,142980],{"disabled":35,"type":36}," Typestate is always faster at runtime because it eliminates one ",[39,142983,2179],{}," statement, which dominates performance in most programs",[28,142986,142988,142990],{"className":142987},[31],[33,142989],{"disabled":35,"type":36}," Runtime state validation is impossible to implement correctly in Rust, so typestate is the only valid option",[28,142992,142994,142996],{"className":142993},[31],[33,142995],{"disabled":35,"type":36}," Typestate and runtime validation are functionally identical; the only difference is which one the linter prefers",[66,142998,142999,143001,143006],{},[69,143000,71],{},[73,143002,143003,143005],{},[76,143004,78],{}," A — typestate eliminates the invalid-call category at compile time instead of relying on a tested-and-hopefully-not-forgotten runtime check",[73,143007,143008,355,143010,143012,143013,143015,143016,143019,143020,143023,143024,143026],{},[76,143009,84],{},[76,143011,135055],{}," The runtime-",[39,143014,2179],{}," version shown is a perfectly valid, common Rust pattern, but it has a fundamental weakness the question highlights: its correctness depends on every method remembering to check state and on every caller correctly handling the ",[39,143017,143018],{},"Err(TxError::InvalidState)"," path — a forgotten check, or a caller that unwraps and ignores the error, becomes a real production bug (e.g. double-committing a transaction). Typestate instead makes ",[39,143021,143022],{},"Committed\u003CTx>::commit()"," not exist as a callable method at all, so the mistake can't compile, full stop — no test coverage, code review vigilance, or runtime error handling is needed to catch it, because there is no code path where it's possible. This isn't primarily a performance optimization (the eliminated ",[39,143025,2179],{}," is typically negligible against actual I\u002FO costs like a database round-trip, making that option's performance framing misleading) and it isn't that runtime validation is \"impossible to implement correctly\" (the example compiles and works) — it's a strictly weaker safety guarantee, not a broken one. The two approaches are absolutely not functionally identical: one defers the invalid-state class of bug to runtime, the other removes it from the possibility space entirely.",[2107,143028,143029],{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}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 pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}",{"title":264,"searchDepth":286,"depth":286,"links":143031},[143032,143033,143035,143036,143037,143039,143040,143042,143044,143045,143047,143049,143051,143053,143055,143057,143058],{"id":139509,"depth":296,"text":139510},{"id":139671,"depth":296,"text":143034},"Q2. What core problem does the newtype pattern (struct Meters(f64);) solve?",{"id":139821,"depth":296,"text":139822},{"id":140037,"depth":296,"text":140038},{"id":140338,"depth":296,"text":143038},"Q5. What guarantee does RAII (Resource Acquisition Is Initialization) via Drop provide in Rust?",{"id":140539,"depth":296,"text":140540},{"id":140824,"depth":296,"text":143041},"Q7. Why might a codebase choose the classic trait-based visitor pattern (a Visitor trait with a visit_* method per node type) over a plain match-based enum approach for an AST?",{"id":140937,"depth":296,"text":143043},"Q8. A Config struct has 8 optional fields, most with sensible defaults. What happens if a builder's build() method is called before any required fields (say, api_key) are set?",{"id":141185,"depth":296,"text":141186},{"id":141373,"depth":296,"text":143046},"Q10. In a Drop implementation, what happens if drop() itself panics while the program is already unwinding from a prior panic (i.e. a \"double panic\")?",{"id":141516,"depth":296,"text":143048},"Q11. A struct wraps a Vec\u003Cu8> as a newtype to represent a validated, non-empty buffer. What is the most common mistake that defeats the purpose of this newtype?",{"id":141739,"depth":296,"text":143050},"Q12. A builder's build() method is called twice on the same builder instance. Given standard consuming-builder design (fn build(self) -> T), what happens on the second call?",{"id":141892,"depth":296,"text":143052},"Q13. What happens if a Drop impl is written for a type that also derives Copy?",{"id":142075,"depth":296,"text":143054},"Q14. A typestate API models a network connection with Disconnected -> Connecting -> Connected states. A method needs to handle the case where connecting can fail and should return to Disconnected. How is this typically expressed in the return type?",{"id":142248,"depth":296,"text":143056},"Q15. When is it idiomatic to use the builder pattern versus simply using a struct literal with ..Default::default()?",{"id":142367,"depth":296,"text":142368},{"id":142572,"depth":296,"text":143059},"Q17. Best practice: should a Drop implementation perform fallible I\u002FO (e.g. flushing a buffered writer to disk) directly, given that drop() cannot return a Result?",{},"\u002Frust\u002F30-design-patterns",{"title":139499,"description":264},"rust\u002F30-design-patterns","ZmTkNTy47BApmaTU5IXB1UthYAxWweafAnUSeO0kSkY",{"id":143066,"title":143067,"body":143068,"description":143075,"extension":2144,"meta":143741,"navigation":35,"path":143742,"seo":143743,"stem":143744,"__hash__":143745},"content\u002Frust\u002Findex.md","Rust: Zero to Hero",{"type":8,"value":143069,"toc":143729},[143070,143073,143076,143078,143099,143101,143104,143106,143108,143205,143209,143274,143278,143407,143411,143522,143526,143612,143616],[11,143071,143067],{"id":143072},"rust-zero-to-hero",[73,143074,143075],{},"A complete quiz-based curriculum covering Rust from first principles to expert-level, production-grade knowledge. Ownership and the borrow checker are the spine of the language — the curriculum is sequenced so every later quiz assumes you can reason about them.",[83881,143077,83884],{"id":83883},[23,143079,143080,143083,143085,143093],{},[28,143081,143082],{},"Work through the parts in order; Parts 3 onward lean heavily on the ownership model from Part 2.",[28,143084,83892],{},[28,143086,83895,143087,143089,143090,143092],{},[76,143088,71],{}," only after committing to a choice — many questions hinge on ",[104,143091,127251],{}," the compiler accepts or rejects code, which only the explanation covers.",[28,143094,143095,143096,143098],{},"Expect borrow-checker \"gotchas,\" lifetime elision surprises, and ",[39,143097,112499],{}," footguns — these are where real Rust competency is built.",[83881,143100,83908],{"id":83907},[73,143102,143103],{},"None for Part 1, though familiarity with a statically-typed language (C++, Java, Swift) makes the ownership model click faster.",[83881,143105,83915],{"id":83914},[18,143107,83919],{"id":83918},[83921,143109,143110,143120],{},[83924,143111,143112],{},[83927,143113,143114,143116,143118],{},[83930,143115,78878],{},[83930,143117,83934],{},[83930,143119,83937],{},[83939,143121,143122,143135,143147,143159,143171,143185],{},[83927,143123,143124,143126,143130],{},[83944,143125,83946],{},[83944,143127,143128],{},[1223,143129,83951],{"href":110239},[83944,143131,143132,143134],{},[39,143133,108562],{},", toolchains, and editions set the stage for every later quiz.",[83927,143136,143137,143139,143144],{},[83944,143138,83959],{},[83944,143140,143141],{},[1223,143142,143143],{"href":111895},"Hello World & Cargo",[83944,143145,143146],{},"Cargo is Rust's build tool, package manager, and test runner — non-negotiable daily tooling.",[83927,143148,143149,143151,143156],{},[83944,143150,83978],{},[83944,143152,143153],{},[1223,143154,143155],{"href":114563},"Variables & Mutability",[83944,143157,143158],{},"Immutability by default and shadowing are core Rust idioms that surprise newcomers.",[83927,143160,143161,143163,143168],{},[83944,143162,83995],{},[83944,143164,143165],{},[1223,143166,143167],{"href":117009},"Data Types",[83944,143169,143170],{},"Integer overflow behavior differs sharply between debug and release builds.",[83927,143172,143173,143175,143179],{},[83944,143174,84013],{},[83944,143176,143177],{},[1223,143178,87038],{"href":120677},[83944,143180,143181,143182,143184],{},"Expression-vs-statement semantics (no ",[39,143183,10769],{}," = return value) is a classic first-week trap.",[83927,143186,143187,143189,143194],{},[83944,143188,84026],{},[83944,143190,143191],{},[1223,143192,84000],{"href":143193},"\u002Frust\u002F06-control-flow",[83944,143195,143196,42,143198,143201,143202,143204],{},[39,143197,125318],{},[39,143199,143200],{},"loop"," with break-values, and exhaustive ",[39,143203,116378],{}," are distinctly Rust-flavored.",[18,143206,143208],{"id":143207},"part-2-the-ownership-model","Part 2 — The Ownership Model",[83921,143210,143211,143221],{},[83924,143212,143213],{},[83927,143214,143215,143217,143219],{},[83930,143216,78878],{},[83930,143218,83934],{},[83930,143220,83937],{},[83939,143222,143223,143236,143249,143262],{},[83927,143224,143225,143227,143233],{},[83944,143226,84039],{},[83944,143228,143229],{},[1223,143230,143232],{"href":143231},"\u002Frust\u002F07-ownership","Ownership",[83944,143234,143235],{},"The single idea that makes Rust memory-safe without a garbage collector.",[83927,143237,143238,143240,143246],{},[83944,143239,84052],{},[83944,143241,143242],{},[1223,143243,143245],{"href":143244},"\u002Frust\u002F08-references-and-borrowing","References & Borrowing",[83944,143247,143248],{},"The borrow checker's aliasing rules are the most common source of \"fighting the compiler.\"",[83927,143250,143251,143253,143259],{},[83944,143252,84065],{},[83944,143254,143255],{},[1223,143256,143258],{"href":143257},"\u002Frust\u002F09-slices","Slices",[83944,143260,143261],{},"String slices and array slices avoid needless allocation but come with lifetime constraints.",[83927,143263,143264,143266,143271],{},[83944,143265,5825],{},[83944,143267,143268],{},[1223,143269,143270],{"href":122905},"Lifetimes",[83944,143272,143273],{},"Lifetime elision rules and explicit annotations are the most-feared, most-misunderstood feature.",[18,143275,143277],{"id":143276},"part-3-data-abstraction","Part 3 — Data & Abstraction",[83921,143279,143280,143290],{},[83924,143281,143282],{},[83927,143283,143284,143286,143288],{},[83930,143285,78878],{},[83930,143287,83934],{},[83930,143289,83937],{},[83939,143291,143292,143311,143327,143340,143357,143370,143388],{},[83927,143293,143294,143296,143301],{},[83944,143295,6879],{},[83944,143297,143298],{},[1223,143299,143300],{"href":125226},"Structs",[83944,143302,143303,143304,7507,143306,7507,143308,143310],{},"Struct update syntax and method receivers (",[39,143305,87099],{},[39,143307,112964],{},[39,143309,113013],{},") shape ergonomic APIs.",[83927,143312,143313,143315,143320],{},[83944,143314,16513],{},[83944,143316,143317],{},[1223,143318,143319],{"href":127894},"Enums",[83944,143321,143322,186,143324,143326],{},[39,143323,116852],{},[39,143325,110110],{}," are enums — understanding variants unlocks idiomatic error handling.",[83927,143328,143329,143331,143337],{},[83944,143330,84136],{},[83944,143332,143333],{},[1223,143334,143336],{"href":143335},"\u002Frust\u002F13-pattern-matching","Pattern Matching",[83944,143338,143339],{},"Exhaustiveness checks and guard clauses catch bugs at compile time other languages miss.",[83927,143341,143342,143344,143350],{},[83944,143343,6159],{},[83944,143345,143346],{},[1223,143347,143349],{"href":143348},"\u002Frust\u002F14-collections","Collections",[83944,143351,143352,42,143354,143356],{},[39,143353,112877],{},[39,143355,123045],{},", and entry APIs are the daily-driver data structures.",[83927,143358,143359,143361,143367],{},[83944,143360,24207],{},[83944,143362,143363],{},[1223,143364,143366],{"href":143365},"\u002Frust\u002F15-iterators","Iterators",[83944,143368,143369],{},"Laziness, zero-cost abstraction claims, and adapter chaining are frequently misunderstood.",[83927,143371,143372,143374,143380],{},[83944,143373,84186],{},[83944,143375,143376],{},[1223,143377,143379],{"href":143378},"\u002Frust\u002F16-traits-and-generics","Traits & Generics",[83944,143381,143382,143383,7507,143385,143387],{},"Trait bounds, ",[39,143384,128648],{},[39,143386,137342],{},", and monomorphization drive Rust's polymorphism model.",[83927,143389,143390,143392,143398],{},[83944,143391,84204],{},[83944,143393,143394],{},[1223,143395,143397],{"href":143396},"\u002Frust\u002F17-closures","Closures",[83944,143399,143400,446,143402,446,143404,143406],{},[39,143401,119326],{},[39,143403,119329],{},[39,143405,119332],{}," and capture-by-move are common sources of compiler errors.",[18,143408,143410],{"id":143409},"part-4-robustness-concurrency","Part 4 — Robustness & Concurrency",[83921,143412,143413,143423],{},[83924,143414,143415],{},[83927,143416,143417,143419,143421],{},[83930,143418,78878],{},[83930,143420,83934],{},[83930,143422,83937],{},[83939,143424,143425,143444,143462,143479,143493,143510],{},[83927,143426,143427,143429,143434],{},[83944,143428,75181],{},[83944,143430,143431],{},[1223,143432,84221],{"href":143433},"\u002Frust\u002F18-error-handling",[83944,143435,143436,143438,143439,7507,143441,143443],{},[39,143437,1685],{}," propagation, ",[39,143440,119025],{},[39,143442,110110],{},", and error trait objects define idiomatic reliability.",[83927,143445,143446,143448,143453],{},[83944,143447,84250],{},[83944,143449,143450],{},[1223,143451,143452],{"href":130702},"Smart Pointers",[83944,143454,143455,42,143457,42,143459,143461],{},[39,143456,127945],{},[39,143458,128232],{},[39,143460,113034],{},", and interior mutability trade compile-time checks for runtime ones.",[83927,143463,143464,143466,143471],{},[83944,143465,6149],{},[83944,143467,143468],{},[1223,143469,143470],{"href":132545},"Modules & Crates",[83944,143472,143473,143474,42,143476,143478],{},"Visibility rules (",[39,143475,117577],{},[39,143477,130738],{},") and the module tree shape API design.",[83927,143480,143481,143483,143487],{},[83944,143482,42534],{},[83944,143484,143485],{},[1223,143486,84356],{"href":134518},[83944,143488,143489,143490,143492],{},"Built-in ",[39,143491,129967],{},", integration tests, and doctests are core to Rust's reliability culture.",[83927,143494,143495,143497,143503],{},[83944,143496,84289],{},[83944,143498,143499],{},[1223,143500,143502],{"href":143501},"\u002Frust\u002F22-concurrency","Concurrency",[83944,143504,143505,446,143507,143509],{},[39,143506,128111],{},[39,143508,128114],{}," and ownership transfer make Rust's \"fearless concurrency\" claim concrete.",[83927,143511,143512,143514,143519],{},[83944,143513,84307],{},[83944,143515,143516],{},[1223,143517,84209],{"href":143518},"\u002Frust\u002F23-async-await",[83944,143520,143521],{},"Futures are lazy and runtime-agnostic — a frequent source of \"why didn't this run\" bugs.",[18,143523,143525],{"id":143524},"part-5-metaprogramming-systems","Part 5 — Metaprogramming & Systems",[83921,143527,143528,143538],{},[83924,143529,143530],{},[83927,143531,143532,143534,143536],{},[83930,143533,78878],{},[83930,143535,83934],{},[83930,143537,83937],{},[83939,143539,143540,143557,143570,143587,143600],{},[83927,143541,143542,143544,143550],{},[83944,143543,84338],{},[83944,143545,143546],{},[1223,143547,143549],{"href":143548},"\u002Frust\u002F24-macros","Macros",[83944,143551,143552,143553,143556],{},"Declarative (",[39,143554,143555],{},"macro_rules!",") vs. procedural macros power much of the ecosystem's ergonomics.",[83927,143558,143559,143561,143567],{},[83944,143560,31527],{},[83944,143562,143563],{},[1223,143564,143566],{"href":143565},"\u002Frust\u002F25-unsafe-rust","Unsafe Rust",[83944,143568,143569],{},"Raw pointers and manual invariants are where Rust's safety guarantees can be broken.",[83927,143571,143572,143574,143580],{},[83944,143573,84364],{},[83944,143575,143576],{},[1223,143577,143579],{"href":143578},"\u002Frust\u002F26-ffi","FFI",[83944,143581,143582,143583,143586],{},"Calling into C and ",[39,143584,143585],{},"#[repr(C)]"," layout guarantees are essential for systems interop.",[83927,143588,143589,143591,143597],{},[83944,143590,84377],{},[83944,143592,143593],{},[1223,143594,143596],{"href":143595},"\u002Frust\u002F27-attributes-and-cfg","Attributes & Cfg",[83944,143598,143599],{},"Conditional compilation and derive macros are pervasive in real crates.",[83927,143601,143602,143604,143609],{},[83944,143603,84390],{},[83944,143605,143606],{},[1223,143607,143608],{"href":136620},"Cargo Features",[83944,143610,143611],{},"Feature flags and unification pitfalls affect every multi-crate workspace.",[18,143613,143615],{"id":143614},"part-6-expert-professional","Part 6 — Expert & Professional",[83921,143617,143618,143628],{},[83924,143619,143620],{},[83927,143621,143622,143624,143626],{},[83930,143623,78878],{},[83930,143625,83934],{},[83930,143627,83937],{},[83939,143629,143630,143642,143653,143670,143683,143704,143717],{},[83927,143631,143632,143634,143639],{},[83944,143633,84404],{},[83944,143635,143636],{},[1223,143637,143638],{"href":139493},"Advanced Type System",[83944,143640,143641],{},"Associated types, GATs, and variance explain why some generic code won't compile.",[83927,143643,143644,143646,143650],{},[83944,143645,24274],{},[83944,143647,143648],{},[1223,143649,84344],{"href":143061},[83944,143651,143652],{},"Builder, newtype, and typestate patterns are how Rust expresses OOP-style designs.",[83927,143654,143655,143658,143663],{},[83944,143656,143657],{},"31",[83944,143659,143660],{},[1223,143661,55328],{"href":143662},"\u002Frust\u002F31-performance",[83944,143664,143665,143666,143669],{},"Allocation patterns, ",[39,143667,143668],{},"#[inline]",", and benchmarking pitfalls matter for systems-level code.",[83927,143671,143672,143674,143680],{},[83944,143673,32584],{},[83944,143675,143676],{},[1223,143677,143679],{"href":143678},"\u002Frust\u002F32-documentation","Documentation",[83944,143681,143682],{},"Doc comments and doctests double as both documentation and executable tests.",[83927,143684,143685,143688,143694],{},[83944,143686,143687],{},"33",[83944,143689,143690],{},[1223,143691,143693],{"href":143692},"\u002Frust\u002F33-ecosystem","Ecosystem",[83944,143695,143696,143697,42,143699,137,143701,143703],{},"Knowing ",[39,143698,110818],{},[39,143700,110821],{},[39,143702,108619],{}," conventions is table stakes for real Rust work.",[83927,143705,143706,143708,143714],{},[83944,143707,119752],{},[83944,143709,143710],{},[1223,143711,143713],{"href":143712},"\u002Frust\u002F34-common-pitfalls","Common Pitfalls",[83944,143715,143716],{},"A curated set of the mistakes that trip up developers moving from GC'd languages.",[83927,143718,143719,143721,143726],{},[83944,143720,74375],{},[83944,143722,143723],{},[1223,143724,84425],{"href":143725},"\u002Frust\u002F35-exercises-and-projects",[83944,143727,143728],{},"A mixed-review capstone spanning ownership, traits, error handling, and concurrency.",{"title":264,"searchDepth":286,"depth":286,"links":143730},[143731,143732,143733],{"id":83883,"depth":286,"text":83884},{"id":83907,"depth":286,"text":83908},{"id":83914,"depth":286,"text":83915,"children":143734},[143735,143736,143737,143738,143739,143740],{"id":83918,"depth":296,"text":83919},{"id":143207,"depth":296,"text":143208},{"id":143276,"depth":296,"text":143277},{"id":143409,"depth":296,"text":143410},{"id":143524,"depth":296,"text":143525},{"id":143614,"depth":296,"text":143615},{},"\u002Frust",{"title":143067,"description":143075},"rust\u002Findex","LQ1sk13TzR00r98GzXhiwPQ-Red44ABd6vhE-pQtZp4",1787335397330]