[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"knowledge-\u002Fapi\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fscope":3,"knowledge-related-\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fscope":1168,"knowledge-series-\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fscope":1192},{"source":4,"connector":5,"page":6},"sqlite","better-sqlite3",{"path":7,"title":8,"description":9,"category":10,"tags":11,"date":14,"pinned":15,"draft":15,"body":16,"seo":1164,"stem":1165,"id":1166,"extension":1167},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fscope","执行模型与作用域","执行上下文与词法作用域决定变量在何处可访问、闭包如何形成，以及 var \u002F let \u002F const 的差异。语言概览见 JavaScript 基础。","技能小册",[12,13],"javascript","scope","2025-01-29",false,{"type":17,"value":18,"toc":1140},"minimark",[19,22,44,48,66,70,149,153,156,189,192,195,198,201,204,253,256,259,262,265,268,271,274,277,280,424,427,438,441,444,447,450,455,511,516,573,576,585,593,759,762,826,829,832,1009,1012,1053,1056,1059,1136],[20,21,8],"h1",{"id":8},[23,24,25,26,30,31,30,34,37,38,43],"p",{},"执行上下文与词法作用域决定变量在何处可访问、闭包如何形成，以及 ",[27,28,29],"code",{},"var"," \u002F ",[27,32,33],{},"let",[27,35,36],{},"const"," 的差异。语言概览见 ",[39,40,42],"a",{"href":41},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fbasics","JavaScript 基础","。",[45,46,47],"h2",{"id":47},"执行上下文",[23,49,50,51,54,55,58,59,58,62,65],{},"执行上下文是 ",[27,52,53],{},"JavaScript"," 代码执行时的环境。它包含了代码执行所需的所有信息：",[27,56,57],{},"变量","、",[27,60,61],{},"函数声明",[27,63,64],{},"this 指向","等。",[67,68,69],"h3",{"id":69},"类型",[71,72,73,111,122],"ol",{},[74,75,76,77],"li",{},"全局执行上下文：\n",[78,79,80,83,86],"ul",{},[74,81,82],{},"这是默认的、最基础的上下文。",[74,84,85],{},"任何不在函数内部的代码都在全局上下文中。",[74,87,88,89,92,93,96,97,99,100,103,104,107,108,43],{},"在浏览器中，全局对象的 ",[27,90,91],{},"this"," 绑定为 ",[27,94,95],{},"window","（严格模式模块中顶层 ",[27,98,91],{}," 为 ",[27,101,102],{},"undefined","）；在 Node.js 中为 ",[27,105,106],{},"global","；统一可用 ",[27,109,110],{},"globalThis",[74,112,113,114],{},"函数执行上下文：\n",[78,115,116,119],{},[74,117,118],{},"每当一个函数被调用时，都会为该函数创建一个新的执行上下文。",[74,120,121],{},"每个函数都有自己的上下文栈。",[74,123,124,131,132],{},[125,126,127,130],"strong",{},[27,128,129],{},"eval"," 执行上下文","：\n",[78,133,134],{},[74,135,136,137,140,141,143,144,148],{},"在 ",[27,138,139],{},"eval()"," 内执行的代码拥有独立上下文；生产代码应避免 ",[27,142,129],{},"（见 ",[39,145,147],{"href":146},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fsafe","安全","）。",[67,150,152],{"id":151},"执行上下文的生命周期创建阶段与执行阶段","执行上下文的生命周期（创建阶段与执行阶段）",[23,154,155],{},"JavaScript 引擎在执行代码时，主要分为两个阶段：",[71,157,158,181],{},[74,159,160,161],{},"创建阶段：\n",[78,162,163,166,169,175],{},[74,164,165],{},"创建变量对象：初始化函数的参数、变量声明、函数声明。",[74,167,168],{},"建立作用域链：确定对变量的访问权限。",[74,170,171,172,174],{},"确定 ",[27,173,91],{}," 指向。",[74,176,177,178,43],{},"注：此时变量会被赋值为 ",[27,179,180],{},"undefined（变量提升）",[74,182,183,184],{},"执行阶段：\n",[78,185,186],{},[74,187,188],{},"逐行执行代码，为变量赋值，引用函数。",[67,190,191],{"id":191},"执行上下文栈",[23,193,194],{},"引擎用**调用栈（call stack）**管理执行上下文：脚本开始全局上下文入栈；函数调用则入栈新上下文；函数返回后出栈。",[45,196,197],{"id":197},"作用域",[23,199,200],{},"作用域是指程序中定义变量的区域，它决定了当前执行代码对变量的访问权限。作用域是在代码编写时（定义时）确定的，而不是运行时确定的，这被称为“词法作用域”。",[67,202,69],{"id":203},"类型-1",[71,205,206,217,228],{},[74,207,208,209],{},"全局作用域：\n",[78,210,211,214],{},[74,212,213],{},"在代码任何地方都能访问到的变量。",[74,215,216],{},"拥有全局作用域的变量是全局变量。",[74,218,219,220],{},"函数作用域：\n",[78,221,222,225],{},[74,223,224],{},"在函数内部声明的变量，只能在函数内部访问。",[74,226,227],{},"外部无法访问函数内部的变量。",[74,229,230,231],{},"块级作用域：\n",[78,232,233,245],{},[74,234,235,236,30,238,240,241,244],{},"ES6 的 ",[27,237,33],{},[27,239,36],{}," 使 ",[27,242,243],{},"{}"," 块可形成独立作用域。",[74,246,247,249,250,252],{},[27,248,29],{}," 不具备块级作用域（它在 ",[27,251,243],{}," 外依然可见，除非在函数内）。",[67,254,255],{"id":255},"作用域链",[23,257,258],{},"当访问一个变量时，JavaScript 引擎会先在当前作用域查找，如果没有找到，就向上一级作用域查找，直到全局作用域。这种层层向上的链式查找机制就是作用域链。",[45,260,261],{"id":261},"闭包",[23,263,264],{},"闭包是 JavaScript 中最强大的特性之一，也是面试常考点。",[67,266,267],{"id":267},"定义",[23,269,270],{},"简单来说，闭包就是函数能够记住并访问它的词法作用域，即使该函数是在其词法作用域之外执行。",[67,272,273],{"id":273},"原理",[23,275,276],{},"当一个函数内部定义了另一个函数，并把这个内部函数返回或传递到外部时，内部函数会持有外部函数的变量对象的引用。即使外部函数已经执行完毕退出了执行栈，其变量对象依然不会被销毁，因为内部函数还在引用它。",[67,278,279],{"id":279},"代码示例",[281,282,287],"pre",{"className":283,"code":284,"language":285,"meta":286,"style":286},"language-js shiki shiki-themes material-theme-lighter github-light github-dark","function outer() {\n    let a = 10;\n    return function inner() {\n        console.log(a);\n    };\n}\n\nconst closureFunc = outer(); \u002F\u002F outer 执行完毕，通常认为 a 会被销毁\nclosureFunc(); \u002F\u002F 输出 10，依然能访问 a，这就是闭包\n","js","",[27,288,289,309,330,347,370,376,382,389,411],{"__ignoreMap":286},[290,291,294,298,302,306],"span",{"class":292,"line":293},"line",1,[290,295,297],{"class":296},"sbsja","function",[290,299,301],{"class":300},"sGLFI"," outer",[290,303,305],{"class":304},"sP7_E","()",[290,307,308],{"class":304}," {\n",[290,310,312,315,319,323,327],{"class":292,"line":311},2,[290,313,314],{"class":296},"    let",[290,316,318],{"class":317},"su5hD"," a",[290,320,322],{"class":321},"smGrS"," =",[290,324,326],{"class":325},"srdBf"," 10",[290,328,329],{"class":304},";\n",[290,331,333,337,340,343,345],{"class":292,"line":332},3,[290,334,336],{"class":335},"sVHd0","    return",[290,338,339],{"class":296}," function",[290,341,342],{"class":300}," inner",[290,344,305],{"class":304},[290,346,308],{"class":304},[290,348,350,353,356,359,363,365,368],{"class":292,"line":349},4,[290,351,352],{"class":317},"        console",[290,354,355],{"class":304},".",[290,357,358],{"class":300},"log",[290,360,362],{"class":361},"skxfh","(",[290,364,39],{"class":317},[290,366,367],{"class":361},")",[290,369,329],{"class":304},[290,371,373],{"class":292,"line":372},5,[290,374,375],{"class":304},"    };\n",[290,377,379],{"class":292,"line":378},6,[290,380,381],{"class":304},"}\n",[290,383,385],{"class":292,"line":384},7,[290,386,388],{"emptyLinePlaceholder":387},true,"\n",[290,390,392,394,398,400,402,404,407],{"class":292,"line":391},8,[290,393,36],{"class":296},[290,395,397],{"class":396},"s_hVV"," closureFunc",[290,399,322],{"class":321},[290,401,301],{"class":300},[290,403,305],{"class":317},[290,405,406],{"class":304},";",[290,408,410],{"class":409},"sutJx"," \u002F\u002F outer 执行完毕，通常认为 a 会被销毁\n",[290,412,414,417,419,421],{"class":292,"line":413},9,[290,415,416],{"class":300},"closureFunc",[290,418,305],{"class":317},[290,420,406],{"class":304},[290,422,423],{"class":409}," \u002F\u002F 输出 10，依然能访问 a，这就是闭包\n",[67,425,426],{"id":426},"应用场景",[78,428,429,432,435],{},[74,430,431],{},"数据私有化（模拟私有方法）。",[74,433,434],{},"柯里化。",[74,436,437],{},"保持状态（如防抖、节流函数）。",[45,439,440],{"id":440},"变量提升与暂时性死区",[23,442,443],{},"这是理解 var、let 和 const 行为差异的关键。",[67,445,446],{"id":446},"变量提升",[23,448,449],{},"在 ES6 之前，使用 var 声明的变量，无论在函数的何处声明，都会被“提升”到函数的顶部。但是，只有声明被提升，赋值操作留在原地。",[78,451,452],{},[74,453,454],{},"var 的表现：",[281,456,458],{"className":283,"code":457,"language":285,"meta":286,"style":286},"console.log(myVar); \u002F\u002F 输出 undefined，不会报错\nvar myVar = 10;\n\u002F\u002F 等价于：\n\u002F\u002F var myVar;\n\u002F\u002F console.log(myVar);\n\u002F\u002F myVar = 10;\n",[27,459,460,477,491,496,501,506],{"__ignoreMap":286},[290,461,462,465,467,469,472,474],{"class":292,"line":293},[290,463,464],{"class":317},"console",[290,466,355],{"class":304},[290,468,358],{"class":300},[290,470,471],{"class":317},"(myVar)",[290,473,406],{"class":304},[290,475,476],{"class":409}," \u002F\u002F 输出 undefined，不会报错\n",[290,478,479,481,484,487,489],{"class":292,"line":311},[290,480,29],{"class":296},[290,482,483],{"class":317}," myVar ",[290,485,486],{"class":321},"=",[290,488,326],{"class":325},[290,490,329],{"class":304},[290,492,493],{"class":292,"line":332},[290,494,495],{"class":409},"\u002F\u002F 等价于：\n",[290,497,498],{"class":292,"line":349},[290,499,500],{"class":409},"\u002F\u002F var myVar;\n",[290,502,503],{"class":292,"line":372},[290,504,505],{"class":409},"\u002F\u002F console.log(myVar);\n",[290,507,508],{"class":292,"line":378},[290,509,510],{"class":409},"\u002F\u002F myVar = 10;\n",[78,512,513],{},[74,514,515],{},"函数声明也会被提升：",[281,517,519],{"className":283,"code":518,"language":285,"meta":286,"style":286},"sayHello(); \u002F\u002F 可以正常调用，输出 \"Hello\"\nfunction sayHello() {\n    console.log(\"Hello\");\n}\n",[27,520,521,533,544,569],{"__ignoreMap":286},[290,522,523,526,528,530],{"class":292,"line":293},[290,524,525],{"class":300},"sayHello",[290,527,305],{"class":317},[290,529,406],{"class":304},[290,531,532],{"class":409}," \u002F\u002F 可以正常调用，输出 \"Hello\"\n",[290,534,535,537,540,542],{"class":292,"line":311},[290,536,297],{"class":296},[290,538,539],{"class":300}," sayHello",[290,541,305],{"class":304},[290,543,308],{"class":304},[290,545,546,549,551,553,555,559,563,565,567],{"class":292,"line":332},[290,547,548],{"class":317},"    console",[290,550,355],{"class":304},[290,552,358],{"class":300},[290,554,362],{"class":361},[290,556,558],{"class":557},"sjJ54","\"",[290,560,562],{"class":561},"s_sjI","Hello",[290,564,558],{"class":557},[290,566,367],{"class":361},[290,568,329],{"class":304},[290,570,571],{"class":292,"line":349},[290,572,381],{"class":304},[67,574,575],{"id":575},"暂时性死区",[23,577,578,579,581,582,584],{},"ES6 引入了 ",[27,580,33],{}," 和 ",[27,583,36],{},"，它们也存在变量提升，但是行为不同：它们被放入了“暂时性死区”（TDZ）。",[78,586,587,590],{},[74,588,589],{},"TDZ 的含义：从代码块（作用域）的开始，直到变量声明语句运行完成之前，该变量都处于 TDZ。在此期间访问该变量会导致 ReferenceError。",[74,591,592],{},"目的：为了减少运行时错误，强制开发者先声明再使用。",[281,594,596],{"className":283,"code":595,"language":285,"meta":286,"style":286},"console.log(myLet); \u002F\u002F 报错：ReferenceError: Cannot access 'myLet' before initialization\nlet myLet = 20;\n\n{\n    \u002F\u002F TDZ 开始\n    tmp = \"abc\"; \u002F\u002F ReferenceError\n    console.log(tmp); \u002F\u002F ReferenceError\n\n    let tmp; \u002F\u002F TDZ 结束，tmp 被初始化为 undefined\n    console.log(tmp); \u002F\u002F undefined\n\n    tmp = 123;\n    console.log(tmp); \u002F\u002F 123\n}\n",[27,597,598,614,628,632,637,642,662,681,685,697,717,722,734,754],{"__ignoreMap":286},[290,599,600,602,604,606,609,611],{"class":292,"line":293},[290,601,464],{"class":317},[290,603,355],{"class":304},[290,605,358],{"class":300},[290,607,608],{"class":317},"(myLet)",[290,610,406],{"class":304},[290,612,613],{"class":409}," \u002F\u002F 报错：ReferenceError: Cannot access 'myLet' before initialization\n",[290,615,616,618,621,623,626],{"class":292,"line":311},[290,617,33],{"class":296},[290,619,620],{"class":317}," myLet ",[290,622,486],{"class":321},[290,624,625],{"class":325}," 20",[290,627,329],{"class":304},[290,629,630],{"class":292,"line":332},[290,631,388],{"emptyLinePlaceholder":387},[290,633,634],{"class":292,"line":349},[290,635,636],{"class":304},"{\n",[290,638,639],{"class":292,"line":372},[290,640,641],{"class":409},"    \u002F\u002F TDZ 开始\n",[290,643,644,647,649,652,655,657,659],{"class":292,"line":378},[290,645,646],{"class":317},"    tmp",[290,648,322],{"class":321},[290,650,651],{"class":557}," \"",[290,653,654],{"class":561},"abc",[290,656,558],{"class":557},[290,658,406],{"class":304},[290,660,661],{"class":409}," \u002F\u002F ReferenceError\n",[290,663,664,666,668,670,672,675,677,679],{"class":292,"line":384},[290,665,548],{"class":317},[290,667,355],{"class":304},[290,669,358],{"class":300},[290,671,362],{"class":361},[290,673,674],{"class":317},"tmp",[290,676,367],{"class":361},[290,678,406],{"class":304},[290,680,661],{"class":409},[290,682,683],{"class":292,"line":391},[290,684,388],{"emptyLinePlaceholder":387},[290,686,687,689,692,694],{"class":292,"line":413},[290,688,314],{"class":296},[290,690,691],{"class":317}," tmp",[290,693,406],{"class":304},[290,695,696],{"class":409}," \u002F\u002F TDZ 结束，tmp 被初始化为 undefined\n",[290,698,700,702,704,706,708,710,712,714],{"class":292,"line":699},10,[290,701,548],{"class":317},[290,703,355],{"class":304},[290,705,358],{"class":300},[290,707,362],{"class":361},[290,709,674],{"class":317},[290,711,367],{"class":361},[290,713,406],{"class":304},[290,715,716],{"class":409}," \u002F\u002F undefined\n",[290,718,720],{"class":292,"line":719},11,[290,721,388],{"emptyLinePlaceholder":387},[290,723,725,727,729,732],{"class":292,"line":724},12,[290,726,646],{"class":317},[290,728,322],{"class":321},[290,730,731],{"class":325}," 123",[290,733,329],{"class":304},[290,735,737,739,741,743,745,747,749,751],{"class":292,"line":736},13,[290,738,548],{"class":317},[290,740,355],{"class":304},[290,742,358],{"class":300},[290,744,362],{"class":361},[290,746,674],{"class":317},[290,748,367],{"class":361},[290,750,406],{"class":304},[290,752,753],{"class":409}," \u002F\u002F 123\n",[290,755,757],{"class":292,"line":756},14,[290,758,381],{"class":304},[45,760,761],{"id":761},"总结对比",[763,764,765,780],"table",{},[766,767,768],"thead",{},[769,770,771,775,777],"tr",{},[772,773,774],"th",{},"特性",[772,776,29],{},[772,778,779],{},"let \u002F const",[781,782,783,794,804,815],"tbody",{},[769,784,785,788,791],{},[786,787,197],"td",{},[786,789,790],{},"函数作用域",[786,792,793],{},"块级作用域",[769,795,796,798,801],{},[786,797,446],{},[786,799,800],{},"是，提升并初始化为 undefined",[786,802,803],{},"是，提升但进入暂时性死区 (TDZ)",[769,805,806,809,812],{},[786,807,808],{},"重复声明",[786,810,811],{},"允许",[786,813,814],{},"不允许 (报错)",[769,816,817,820,823],{},[786,818,819],{},"全局挂载",[786,821,822],{},"会挂载到 window (浏览器)",[786,824,825],{},"不会挂载到 window",[45,827,828],{"id":828},"综合示例",[23,830,831],{},"为了把这些概念串起来，看下面这个例子：",[281,833,835],{"className":283,"code":834,"language":285,"meta":286,"style":286},"var globalVar = \"I am global\";\n\nfunction createCounter() {\n    let count = 0; \u002F\u002F 局部变量，createCounter 的作用域\n\n    \u002F\u002F 返回一个闭包\n    return function () {\n        count++; \u002F\u002F 访问外部作用域的 count\n        console.log(count);\n        console.log(globalVar); \u002F\u002F 通过作用域链访问全局变量\n    };\n}\n\nconst counter = createCounter();\ncounter(); \u002F\u002F 输出 1, \"I am global\"\ncounter(); \u002F\u002F 输出 2, \"I am global\"\n",[27,836,837,855,859,870,887,891,896,907,920,937,957,961,965,969,984,997],{"__ignoreMap":286},[290,838,839,841,844,846,848,851,853],{"class":292,"line":293},[290,840,29],{"class":296},[290,842,843],{"class":317}," globalVar ",[290,845,486],{"class":321},[290,847,651],{"class":557},[290,849,850],{"class":561},"I am global",[290,852,558],{"class":557},[290,854,329],{"class":304},[290,856,857],{"class":292,"line":311},[290,858,388],{"emptyLinePlaceholder":387},[290,860,861,863,866,868],{"class":292,"line":332},[290,862,297],{"class":296},[290,864,865],{"class":300}," createCounter",[290,867,305],{"class":304},[290,869,308],{"class":304},[290,871,872,874,877,879,882,884],{"class":292,"line":349},[290,873,314],{"class":296},[290,875,876],{"class":317}," count",[290,878,322],{"class":321},[290,880,881],{"class":325}," 0",[290,883,406],{"class":304},[290,885,886],{"class":409}," \u002F\u002F 局部变量，createCounter 的作用域\n",[290,888,889],{"class":292,"line":372},[290,890,388],{"emptyLinePlaceholder":387},[290,892,893],{"class":292,"line":378},[290,894,895],{"class":409},"    \u002F\u002F 返回一个闭包\n",[290,897,898,900,902,905],{"class":292,"line":384},[290,899,336],{"class":335},[290,901,339],{"class":296},[290,903,904],{"class":304}," ()",[290,906,308],{"class":304},[290,908,909,912,915,917],{"class":292,"line":391},[290,910,911],{"class":317},"        count",[290,913,914],{"class":321},"++",[290,916,406],{"class":304},[290,918,919],{"class":409}," \u002F\u002F 访问外部作用域的 count\n",[290,921,922,924,926,928,930,933,935],{"class":292,"line":413},[290,923,352],{"class":317},[290,925,355],{"class":304},[290,927,358],{"class":300},[290,929,362],{"class":361},[290,931,932],{"class":317},"count",[290,934,367],{"class":361},[290,936,329],{"class":304},[290,938,939,941,943,945,947,950,952,954],{"class":292,"line":699},[290,940,352],{"class":317},[290,942,355],{"class":304},[290,944,358],{"class":300},[290,946,362],{"class":361},[290,948,949],{"class":317},"globalVar",[290,951,367],{"class":361},[290,953,406],{"class":304},[290,955,956],{"class":409}," \u002F\u002F 通过作用域链访问全局变量\n",[290,958,959],{"class":292,"line":719},[290,960,375],{"class":304},[290,962,963],{"class":292,"line":724},[290,964,381],{"class":304},[290,966,967],{"class":292,"line":736},[290,968,388],{"emptyLinePlaceholder":387},[290,970,971,973,976,978,980,982],{"class":292,"line":756},[290,972,36],{"class":296},[290,974,975],{"class":396}," counter",[290,977,322],{"class":321},[290,979,865],{"class":300},[290,981,305],{"class":317},[290,983,329],{"class":304},[290,985,987,990,992,994],{"class":292,"line":986},15,[290,988,989],{"class":300},"counter",[290,991,305],{"class":317},[290,993,406],{"class":304},[290,995,996],{"class":409}," \u002F\u002F 输出 1, \"I am global\"\n",[290,998,1000,1002,1004,1006],{"class":292,"line":999},16,[290,1001,989],{"class":300},[290,1003,305],{"class":317},[290,1005,406],{"class":304},[290,1007,1008],{"class":409}," \u002F\u002F 输出 2, \"I am global\"\n",[23,1010,1011],{},"在这个例子中：",[71,1013,1014,1021,1030,1039],{},[74,1015,1016,1017,1020],{},"执行上下文：代码开始运行创建全局上下文；调用 ",[27,1018,1019],{},"createCounter"," 创建函数上下文。",[74,1022,1023,1024,1026,1027,1029],{},"作用域：",[27,1025,932],{}," 拥有函数作用域，",[27,1028,949],{}," 拥有全局作用域。",[74,1031,1032,1033,1035,1036,1038],{},"闭包：返回的匿名函数形成了闭包，使得 ",[27,1034,1019],{}," 执行完毕后，",[27,1037,932],{}," 依然保存在内存中。",[74,1040,1041,1042,1044,1045,1047,1048,1050,1051,43],{},"变量提升：",[27,1043,33],{}," 声明的 ",[27,1046,932],{}," 在声明前处于 TDZ；若改用 ",[27,1049,29],{}," 则提升为 ",[27,1052,102],{},[45,1054,1055],{"id":1055},"参考文献",[23,1057,1058],{},"以下链接在编写时均可正常访问：",[763,1060,1061,1071],{},[766,1062,1063],{},[769,1064,1065,1068],{},[772,1066,1067],{},"资料",[772,1069,1070],{},"说明",[781,1072,1073,1086,1098,1110,1124],{},[769,1074,1075,1083],{},[786,1076,1077],{},[39,1078,1082],{"href":1079,"rel":1080},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FJavaScript\u002FClosures",[1081],"nofollow","MDN：闭包",[786,1084,1085],{},"闭包与词法环境",[769,1087,1088,1095],{},[786,1089,1090],{},[39,1091,1094],{"href":1092,"rel":1093},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FStatements\u002Flet",[1081],"MDN：let",[786,1096,1097],{},"块级作用域与 TDZ",[769,1099,1100,1107],{},[786,1101,1102],{},[39,1103,1106],{"href":1104,"rel":1105},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FStatements\u002Fvar",[1081],"MDN：var",[786,1108,1109],{},"函数作用域与提升",[769,1111,1112,1119],{},[786,1113,1114],{},[39,1115,1118],{"href":1116,"rel":1117},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FOperators\u002Fthis",[1081],"MDN：this",[786,1120,1121,1123],{},[27,1122,91],{}," 与执行上下文",[769,1125,1126,1133],{},[786,1127,1128],{},[39,1129,1132],{"href":1130,"rel":1131},"https:\u002F\u002Ftc39.es\u002Fecma262\u002F#sec-execution-contexts",[1081],"ECMA-262：执行上下文",[786,1134,1135],{},"规范术语（英文）",[1137,1138,1139],"style",{},"html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}",{"title":286,"searchDepth":311,"depth":311,"links":1141},[1142,1147,1151,1157,1161,1162,1163],{"id":47,"depth":311,"text":47,"children":1143},[1144,1145,1146],{"id":69,"depth":332,"text":69},{"id":151,"depth":332,"text":152},{"id":191,"depth":332,"text":191},{"id":197,"depth":311,"text":197,"children":1148},[1149,1150],{"id":203,"depth":332,"text":69},{"id":255,"depth":332,"text":255},{"id":261,"depth":311,"text":261,"children":1152},[1153,1154,1155,1156],{"id":267,"depth":332,"text":267},{"id":273,"depth":332,"text":273},{"id":279,"depth":332,"text":279},{"id":426,"depth":332,"text":426},{"id":440,"depth":311,"text":440,"children":1158},[1159,1160],{"id":446,"depth":332,"text":446},{"id":575,"depth":332,"text":575},{"id":761,"depth":311,"text":761},{"id":828,"depth":311,"text":828},{"id":1055,"depth":311,"text":1055},{"title":8,"description":9},"knowledge\u002Fbooklet\u002Fweb\u002FJs\u002Fscope","knowledge\u002Fknowledge\u002Fbooklet\u002Fweb\u002FJs\u002Fscope.md","md",{"items":1169},[1170,1174,1178,1182,1186,1190],{"path":1171,"title":1172,"description":1173,"category":10,"score":378},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Ferror","错误处理与调试","结构化错误类型、try\u002Fcatch 与全局未捕获处理是健壮应用的基础。",{"path":1175,"title":1176,"description":1177,"category":10,"score":378},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fdom-bom","浏览器相关 API","DOM 事件、存储、fetch、Worker、Observer 等由浏览器提供的 Web API（非 ECMAScript 核心）。HTML 结构见 标签。",{"path":1179,"title":1180,"description":1181,"category":10,"score":378},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fperformance","性能优化","防抖\u002F节流、渲染与内存、资源预加载及引擎行为是前端性能的主要抓手。相关 CSS 见 视觉效果、Head 资源提示。",{"path":1183,"title":1184,"description":1185,"category":10,"score":378},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fcommon","模块化与工程化","ESM、CommonJS 与打包工具（Tree Shaking、代码分割）是前端工程化的基础。入门见 JavaScript 基础 · 模块。",{"path":1187,"title":1188,"description":1189,"category":10,"score":378},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fmap-set","数据结构与集合增强","Map \u002F Set、WeakMap \u002F WeakSet、数组高阶方法、TypedArray 与 Symbol 等扩展了内置数据结构能力。见 语言基础。",{"path":41,"title":42,"description":1191,"category":10,"score":378},"JavaScript（ECMAScript）是 Web 页面与 Node.js 等运行时的脚本语言：在浏览器中操作 DOM、发起网络请求；在服务端处理 I\u002FO。语法与 HTML、CSS 配合构成前端技术栈。",{"series":1193,"title":285,"items":1194,"index":736,"prev":1234,"next":1235},"booklet\u002Fweb\u002Fjs",[1195,1199,1201,1203,1207,1209,1211,1215,1219,1221,1223,1227,1231,1233],{"path":1196,"title":1197,"date":1198,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fadvanced","函数进阶","2022-10-24",{"path":41,"title":42,"date":1200,"pinned":15},"2023-11-24",{"path":1183,"title":1184,"date":1202,"pinned":15},"2025-06-21",{"path":1204,"title":1205,"date":1206,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fdesign","设计模式","2021-10-05",{"path":1175,"title":1176,"date":1208,"pinned":15},"2025-07-10",{"path":1171,"title":1172,"date":1210,"pinned":15},"2026-06-25",{"path":1212,"title":1213,"date":1214,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fevent-loop","异步编程与事件循环","2020-03-23",{"path":1216,"title":1217,"date":1218,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fexec","正则表达式","2022-05-21",{"path":1187,"title":1188,"date":1220,"pinned":15},"2024-07-10",{"path":1179,"title":1180,"date":1222,"pinned":15},"2025-07-04",{"path":1224,"title":1225,"date":1226,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fprototype","原型与面向对象","2020-04-13",{"path":1228,"title":1229,"date":1230,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fproxy","代理与反射","2022-10-23",{"path":146,"title":147,"date":1232,"pinned":15},"2023-06-26",{"path":7,"title":8,"date":14,"pinned":15},{"path":146,"title":147,"date":1232,"pinned":15},null]