[{"data":1,"prerenderedAt":1433},["ShallowReactive",2],{"doc-\u002Fdocs\u002Finterview-javascript-core":3,"docs-all":1328},{"id":4,"title":5,"body":6,"category":1313,"date":1314,"description":1315,"draft":1316,"extension":1317,"meta":1318,"navigation":346,"path":1319,"seo":1320,"source":1321,"stem":1322,"tags":1323,"__hash__":1327},"docs\u002Fdocs\u002Finterview-javascript-core.md","JavaScript 核心考点",{"type":7,"value":8,"toc":1297},"minimark",[9,13,52,57,93,97,104,160,177,182,243,246,253,256,394,418,427,434,437,446,460,463,478,487,493,496,500,510,519,623,642,646,656,673,692,695,1070,1086,1089,1181,1193,1197,1210,1219,1229,1233,1236,1242,1252,1256,1269,1272,1275,1278,1293],[10,11,12],"h2",{"id":12},"数据类型",[14,15,16,17,21,22,21,25,21,28,21,31,34,35,38,39,42,43,21,45,21,48,51],"p",{},"基本数据类型有 ",[18,19,20],"code",{},"undefined","、",[18,23,24],{},"null",[18,26,27],{},"number",[18,29,30],{},"string",[18,32,33],{},"boolean","，ES6 新增 ",[18,36,37],{},"Symbol","。引用类型统一归为 ",[18,40,41],{},"Object","，包括 ",[18,44,41],{},[18,46,47],{},"Array",[18,49,50],{},"Function","。",[14,53,54,56],{},[18,55,37],{}," 的特点是即使传入相同的值创建出的对象也互不相等，因此常用来解决属性名冲突，作为唯一标记使用。",[14,58,59,62,63,66,67,69,70,69,72,69,75,77,78,81,82,85,86,89,90,92],{},[18,60,61],{},"Object.is()"," 在以下情况返回 ",[18,64,65],{},"true","：两值都是 ",[18,68,20],{},"；都是 ",[18,71,24],{},[18,73,74],{},"NaN",[18,76,65],{}," 或都是 ",[18,79,80],{},"false","；是相同顺序相同字符组成的字符串；指向同一个对象；都是 ",[18,83,84],{},"+0","、都是 ",[18,87,88],{},"-0","，或是除零和 ",[18,91,74],{}," 外的同一个数字。",[10,94,96],{"id":95},"this-绑定callapplybind","this 绑定：call、apply、bind",[14,98,99,100,103],{},"三者都用于改变 ",[18,101,102],{},"this"," 指向，区别在于传参形式和执行时机。",[105,106,111],"pre",{"className":107,"code":108,"language":109,"meta":110,"style":110},"language-js shiki shiki-themes github-light github-dark","fn.call(thisArg, arg1, arg2)      \u002F\u002F 逐个传参，立即执行\nfn.apply(thisArg, [arg1, arg2])   \u002F\u002F 数组传参，立即执行\nfn.bind(thisArg, arg1, arg2)      \u002F\u002F 逐个传参，返回新函数不执行\n","js","",[18,112,113,133,147],{"__ignoreMap":110},[114,115,118,122,126,129],"span",{"class":116,"line":117},"line",1,[114,119,121],{"class":120},"sVt8B","fn.",[114,123,125],{"class":124},"sScJk","call",[114,127,128],{"class":120},"(thisArg, arg1, arg2)      ",[114,130,132],{"class":131},"sJ8bj","\u002F\u002F 逐个传参，立即执行\n",[114,134,136,138,141,144],{"class":116,"line":135},2,[114,137,121],{"class":120},[114,139,140],{"class":124},"apply",[114,142,143],{"class":120},"(thisArg, [arg1, arg2])   ",[114,145,146],{"class":131},"\u002F\u002F 数组传参，立即执行\n",[114,148,150,152,155,157],{"class":116,"line":149},3,[114,151,121],{"class":120},[114,153,154],{"class":124},"bind",[114,156,128],{"class":120},[114,158,159],{"class":131},"\u002F\u002F 逐个传参，返回新函数不执行\n",[14,161,162,163,21,165,167,168,170,171,174,175,51],{},"非严格模式下，第一个参数传 ",[18,164,24],{},[18,166,20],{}," 或不传，",[18,169,102],{}," 指向 ",[18,172,173],{},"window","；严格模式下传什么就是什么，不传则为 ",[18,176,20],{},[14,178,179,181],{},[18,180,154],{}," 的典型用途是事件绑定。下面两行的差别很关键：",[105,183,185],{"className":107,"code":184,"language":109,"meta":110,"style":110},"document.onclick = fn.call(obj, 1, 2)   \u002F\u002F fn 立即执行，绑定的是它的返回值\ndocument.onclick = fn.bind(obj, 1, 2)   \u002F\u002F fn 不执行，点击时才执行\n",[18,186,187,220],{"__ignoreMap":110},[114,188,189,192,196,199,201,204,208,211,214,217],{"class":116,"line":117},[114,190,191],{"class":120},"document.onclick ",[114,193,195],{"class":194},"szBVR","=",[114,197,198],{"class":120}," fn.",[114,200,125],{"class":124},[114,202,203],{"class":120},"(obj, ",[114,205,207],{"class":206},"sj4cs","1",[114,209,210],{"class":120},", ",[114,212,213],{"class":206},"2",[114,215,216],{"class":120},")   ",[114,218,219],{"class":131},"\u002F\u002F fn 立即执行，绑定的是它的返回值\n",[114,221,222,224,226,228,230,232,234,236,238,240],{"class":116,"line":135},[114,223,191],{"class":120},[114,225,195],{"class":194},[114,227,198],{"class":120},[114,229,154],{"class":124},[114,231,203],{"class":120},[114,233,207],{"class":206},[114,235,210],{"class":120},[114,237,213],{"class":206},[114,239,216],{"class":120},[114,241,242],{"class":131},"\u002F\u002F fn 不执行，点击时才执行\n",[10,244,245],{"id":245},"闭包",[14,247,248,252],{},[249,250,251],"strong",{},"闭包是能够读取其他函数内部变量的函数","，通常表现为定义在函数内部的函数。",[14,254,255],{},"JS 的作用域是链式的：子函数可以访问父函数的所有变量，反之不行。把内部函数作为返回值抛出，就能在外部读取到函数内部的变量。",[105,257,259],{"className":107,"code":258,"language":109,"meta":110,"style":110},"function f1 () {\n  var n = 999\n  nAdd = function () { n += 1 }\n  function f2 () { alert(n) }\n  return f2\n}\n\nvar result = f1()\nresult()   \u002F\u002F 999\nnAdd()\nresult()   \u002F\u002F 1000\n",[18,260,261,272,285,308,326,335,341,348,364,376,384],{"__ignoreMap":110},[114,262,263,266,269],{"class":116,"line":117},[114,264,265],{"class":194},"function",[114,267,268],{"class":124}," f1",[114,270,271],{"class":120}," () {\n",[114,273,274,277,280,282],{"class":116,"line":135},[114,275,276],{"class":194},"  var",[114,278,279],{"class":120}," n ",[114,281,195],{"class":194},[114,283,284],{"class":206}," 999\n",[114,286,287,290,293,296,299,302,305],{"class":116,"line":149},[114,288,289],{"class":124},"  nAdd",[114,291,292],{"class":194}," =",[114,294,295],{"class":194}," function",[114,297,298],{"class":120}," () { n ",[114,300,301],{"class":194},"+=",[114,303,304],{"class":206}," 1",[114,306,307],{"class":120}," }\n",[114,309,311,314,317,320,323],{"class":116,"line":310},4,[114,312,313],{"class":194},"  function",[114,315,316],{"class":124}," f2",[114,318,319],{"class":120}," () { ",[114,321,322],{"class":124},"alert",[114,324,325],{"class":120},"(n) }\n",[114,327,329,332],{"class":116,"line":328},5,[114,330,331],{"class":194},"  return",[114,333,334],{"class":120}," f2\n",[114,336,338],{"class":116,"line":337},6,[114,339,340],{"class":120},"}\n",[114,342,344],{"class":116,"line":343},7,[114,345,347],{"emptyLinePlaceholder":346},true,"\n",[114,349,351,354,357,359,361],{"class":116,"line":350},8,[114,352,353],{"class":194},"var",[114,355,356],{"class":120}," result ",[114,358,195],{"class":194},[114,360,268],{"class":124},[114,362,363],{"class":120},"()\n",[114,365,367,370,373],{"class":116,"line":366},9,[114,368,369],{"class":124},"result",[114,371,372],{"class":120},"()   ",[114,374,375],{"class":131},"\u002F\u002F 999\n",[114,377,379,382],{"class":116,"line":378},10,[114,380,381],{"class":124},"nAdd",[114,383,363],{"class":120},[114,385,387,389,391],{"class":116,"line":386},11,[114,388,369],{"class":124},[114,390,372],{"class":120},[114,392,393],{"class":131},"\u002F\u002F 1000\n",[14,395,396,397,400,401,404,405,408,409,411,412,414,415,417],{},"这段代码证明了 ",[18,398,399],{},"f1"," 的局部变量 ",[18,402,403],{},"n"," 一直保存在内存中，没有在调用结束后被回收。原因是 ",[18,406,407],{},"f2"," 被赋给了全局变量始终存在于内存，而 ",[18,410,407],{}," 依赖 ",[18,413,399],{},"，导致 ",[18,416,399],{}," 也无法被垃圾回收。",[14,419,420,421,423,424,426],{},"注意 ",[18,422,381],{}," 前面没有 ",[18,425,353],{},"，它是个全局变量，且其值是一个匿名函数——这个匿名函数本身也是闭包，相当于一个 setter，可以在外部修改函数内部的局部变量。",[14,428,429,430,433],{},"闭包的两个主要用途是读取函数内部变量，以及让这些变量常驻内存。但也正因如此需要注意：",[249,431,432],{},"闭包会使变量无法被回收，滥用会造成性能问题","，退出函数前应删除不再使用的局部变量。另外闭包能在外部改变父函数的内部变量，如果把父函数当对象、闭包当公开方法、内部变量当私有属性来用，务必谨慎。",[10,435,436],{"id":436},"箭头函数与普通函数的区别",[14,438,439,440,442,443,445],{},"普通函数的 ",[18,441,102],{}," 是动态的，取决于调用方式；箭头函数没有自己的执行上下文，",[18,444,102],{}," 取自父级作用域。",[14,447,448,449,452,453,456,457,459],{},"普通函数可以作为构造函数，箭头函数不行。普通函数内部有 ",[18,450,451],{},"arguments"," 类数组对象，箭头函数没有。箭头函数单条语句时可以省略 ",[18,454,455],{},"return"," 实现隐式返回。在类中用箭头函数定义方法，",[18,458,102],{}," 会绑定到类的实例。",[10,461,462],{"id":462},"原型与原型链",[14,464,465,466,469,470,473,474,477],{},"所有函数都有 ",[18,467,468],{},"prototype"," 属性指向原型对象（实例没有），原型对象中的 ",[18,471,472],{},"constructor"," 指回构造函数，实例的 ",[18,475,476],{},"__proto__"," 指向原型。",[14,479,480,483,484,486],{},[249,481,482],{},"原型链的原理","：访问实例的属性或方法时，如果实例本身没有就往原型上找，还找不到就继续向上一级原型查找，直到 ",[18,485,41],{},"（原型链顶端）。原型中的方法可以被所有实例共享，这也是继承的实现基础。",[14,488,489,492],{},[18,490,491],{},"instanceof"," 用于判断实例属于哪个构造函数。",[14,494,495],{},"继承的实现方式有三种：借用构造函数、原型链继承，以及组合两者的构造函数加原型链继承。",[10,497,499],{"id":498},"forin-与-forof","for...in 与 for...of",[14,501,502,505,506,509],{},[18,503,504],{},"for...in"," 遍历的是键名（索引），",[18,507,508],{},"for...of"," 遍历的是元素值。",[14,511,512,513,515,516,51],{},"用 ",[18,514,504],{}," 遍历数组有三个缺点：索引是字符串型数字不能直接参与运算；遍历顺序不保证与数组实际顺序一致；会遍历所有可枚举属性，",[249,517,518],{},"包括原型上的",[105,520,522],{"className":107,"code":521,"language":109,"meta":110,"style":110},"var arr = [1, 2, 3]\narr.name = '数组'\nArray.prototype.method = function () {}\n\nfor (var index in arr) {\n  console.log(arr[index])   \u002F\u002F 会输出 name 和 method\n}\n",[18,523,524,550,561,582,586,605,619],{"__ignoreMap":110},[114,525,526,528,531,533,536,538,540,542,544,547],{"class":116,"line":117},[114,527,353],{"class":194},[114,529,530],{"class":120}," arr ",[114,532,195],{"class":194},[114,534,535],{"class":120}," [",[114,537,207],{"class":206},[114,539,210],{"class":120},[114,541,213],{"class":206},[114,543,210],{"class":120},[114,545,546],{"class":206},"3",[114,548,549],{"class":120},"]\n",[114,551,552,555,557],{"class":116,"line":135},[114,553,554],{"class":120},"arr.name ",[114,556,195],{"class":194},[114,558,560],{"class":559},"sZZnC"," '数组'\n",[114,562,563,565,568,570,572,575,577,579],{"class":116,"line":149},[114,564,47],{"class":206},[114,566,567],{"class":120},".",[114,569,468],{"class":206},[114,571,567],{"class":120},[114,573,574],{"class":124},"method",[114,576,292],{"class":194},[114,578,295],{"class":194},[114,580,581],{"class":120}," () {}\n",[114,583,584],{"class":116,"line":310},[114,585,347],{"emptyLinePlaceholder":346},[114,587,588,591,594,596,599,602],{"class":116,"line":328},[114,589,590],{"class":194},"for",[114,592,593],{"class":120}," (",[114,595,353],{"class":194},[114,597,598],{"class":120}," index ",[114,600,601],{"class":194},"in",[114,603,604],{"class":120}," arr) {\n",[114,606,607,610,613,616],{"class":116,"line":337},[114,608,609],{"class":120},"  console.",[114,611,612],{"class":124},"log",[114,614,615],{"class":120},"(arr[index])   ",[114,617,618],{"class":131},"\u002F\u002F 会输出 name 和 method\n",[114,620,621],{"class":116,"line":343},[114,622,340],{"class":120},[14,624,625,626,628,629,631,632,635,636,638,639,641],{},"因此 ",[18,627,504],{}," 更适合遍历对象，而 ",[18,630,508],{}," 遍历普通对象会报错。只要部署了 ",[18,633,634],{},"Symbol.iterator"," 属性的数据结构就能用 ",[18,637,508],{},"，包括数组、Map、Set、String、",[18,640,451],{}," 对象和 NodeList。这些结构同样支持扩展运算符和解构赋值。",[10,643,645],{"id":644},"for-循环与-foreach","for 循环与 forEach",[14,647,648,649,651,652,655],{},"长度固定或无需计算长度时 ",[18,650,590],{}," 效率更高；不确定长度或计算长度有性能损耗时用 ",[18,653,654],{},"forEach"," 更方便。",[14,657,658,660,661,663,664,666,667,669,670,672],{},[18,659,654],{}," 适合单纯遍历，复杂循环用 ",[18,662,590],{}," 效率更高。需要修改集合中的值时必须用 ",[18,665,590],{},"——",[18,668,654],{}," 内部基于 iterator 但无法人为控制。",[18,671,654],{}," 的优势在于处理稀疏数组时会跳过空位。",[14,674,675,678,679,681,682,685,686,688,689,691],{},[249,676,677],{},"关键差异","：",[18,680,654],{}," 中 ",[18,683,684],{},"break"," 无法中断循环，",[18,687,455],{}," 也无法返回到外层函数，而 ",[18,690,590],{}," 可以中断。",[10,693,694],{"id":694},"数组去重",[105,696,698],{"className":107,"code":697,"language":109,"meta":110,"style":110},"\u002F\u002F 1. Set（最简洁，ES6 首选）\nconst unique = arr => Array.from(new Set(arr))\n\u002F\u002F 或 [...new Set(arr)]\n\n\u002F\u002F 2. filter + indexOf\nconst unique = arr => arr.filter((item, index) => arr.indexOf(item) === index)\n\n\u002F\u002F 3. includes\nfunction unique (arr) {\n  const res = []\n  for (const item of arr) {\n    if (!res.includes(item)) res.push(item)\n  }\n  return res\n}\n\n\u002F\u002F 4. 双重循环 + splice（ES5 常用）\nfunction unique (arr) {\n  for (let i = 0; i \u003C arr.length; i++) {\n    for (let j = i + 1; j \u003C arr.length; j++) {\n      if (arr[i] === arr[j]) {\n        arr.splice(j, 1)\n        j--\n      }\n    }\n  }\n  return arr\n}\n",[18,699,700,705,740,745,749,754,803,807,812,826,839,856,882,888,896,901,906,912,925,962,1000,1014,1031,1040,1046,1052,1057,1065],{"__ignoreMap":110},[114,701,702],{"class":116,"line":117},[114,703,704],{"class":131},"\u002F\u002F 1. Set（最简洁，ES6 首选）\n",[114,706,707,710,713,715,719,722,725,728,731,734,737],{"class":116,"line":135},[114,708,709],{"class":194},"const",[114,711,712],{"class":124}," unique",[114,714,292],{"class":194},[114,716,718],{"class":717},"s4XuR"," arr",[114,720,721],{"class":194}," =>",[114,723,724],{"class":120}," Array.",[114,726,727],{"class":124},"from",[114,729,730],{"class":120},"(",[114,732,733],{"class":194},"new",[114,735,736],{"class":124}," Set",[114,738,739],{"class":120},"(arr))\n",[114,741,742],{"class":116,"line":149},[114,743,744],{"class":131},"\u002F\u002F 或 [...new Set(arr)]\n",[114,746,747],{"class":116,"line":310},[114,748,347],{"emptyLinePlaceholder":346},[114,750,751],{"class":116,"line":328},[114,752,753],{"class":131},"\u002F\u002F 2. filter + indexOf\n",[114,755,756,758,760,762,764,766,769,772,775,778,780,783,786,789,791,794,797,800],{"class":116,"line":337},[114,757,709],{"class":194},[114,759,712],{"class":124},[114,761,292],{"class":194},[114,763,718],{"class":717},[114,765,721],{"class":194},[114,767,768],{"class":120}," arr.",[114,770,771],{"class":124},"filter",[114,773,774],{"class":120},"((",[114,776,777],{"class":717},"item",[114,779,210],{"class":120},[114,781,782],{"class":717},"index",[114,784,785],{"class":120},") ",[114,787,788],{"class":194},"=>",[114,790,768],{"class":120},[114,792,793],{"class":124},"indexOf",[114,795,796],{"class":120},"(item) ",[114,798,799],{"class":194},"===",[114,801,802],{"class":120}," index)\n",[114,804,805],{"class":116,"line":343},[114,806,347],{"emptyLinePlaceholder":346},[114,808,809],{"class":116,"line":350},[114,810,811],{"class":131},"\u002F\u002F 3. includes\n",[114,813,814,816,818,820,823],{"class":116,"line":366},[114,815,265],{"class":194},[114,817,712],{"class":124},[114,819,593],{"class":120},[114,821,822],{"class":717},"arr",[114,824,825],{"class":120},") {\n",[114,827,828,831,834,836],{"class":116,"line":378},[114,829,830],{"class":194},"  const",[114,832,833],{"class":206}," res",[114,835,292],{"class":194},[114,837,838],{"class":120}," []\n",[114,840,841,844,846,848,851,854],{"class":116,"line":386},[114,842,843],{"class":194},"  for",[114,845,593],{"class":120},[114,847,709],{"class":194},[114,849,850],{"class":206}," item",[114,852,853],{"class":194}," of",[114,855,604],{"class":120},[114,857,859,862,864,867,870,873,876,879],{"class":116,"line":858},12,[114,860,861],{"class":194},"    if",[114,863,593],{"class":120},[114,865,866],{"class":194},"!",[114,868,869],{"class":120},"res.",[114,871,872],{"class":124},"includes",[114,874,875],{"class":120},"(item)) res.",[114,877,878],{"class":124},"push",[114,880,881],{"class":120},"(item)\n",[114,883,885],{"class":116,"line":884},13,[114,886,887],{"class":120},"  }\n",[114,889,891,893],{"class":116,"line":890},14,[114,892,331],{"class":194},[114,894,895],{"class":120}," res\n",[114,897,899],{"class":116,"line":898},15,[114,900,340],{"class":120},[114,902,904],{"class":116,"line":903},16,[114,905,347],{"emptyLinePlaceholder":346},[114,907,909],{"class":116,"line":908},17,[114,910,911],{"class":131},"\u002F\u002F 4. 双重循环 + splice（ES5 常用）\n",[114,913,915,917,919,921,923],{"class":116,"line":914},18,[114,916,265],{"class":194},[114,918,712],{"class":124},[114,920,593],{"class":120},[114,922,822],{"class":717},[114,924,825],{"class":120},[114,926,928,930,932,935,938,940,943,946,949,951,954,957,960],{"class":116,"line":927},19,[114,929,843],{"class":194},[114,931,593],{"class":120},[114,933,934],{"class":194},"let",[114,936,937],{"class":120}," i ",[114,939,195],{"class":194},[114,941,942],{"class":206}," 0",[114,944,945],{"class":120},"; i ",[114,947,948],{"class":194},"\u003C",[114,950,768],{"class":120},[114,952,953],{"class":206},"length",[114,955,956],{"class":120},"; i",[114,958,959],{"class":194},"++",[114,961,825],{"class":120},[114,963,965,968,970,972,975,977,979,982,984,987,989,991,993,996,998],{"class":116,"line":964},20,[114,966,967],{"class":194},"    for",[114,969,593],{"class":120},[114,971,934],{"class":194},[114,973,974],{"class":120}," j ",[114,976,195],{"class":194},[114,978,937],{"class":120},[114,980,981],{"class":194},"+",[114,983,304],{"class":206},[114,985,986],{"class":120},"; j ",[114,988,948],{"class":194},[114,990,768],{"class":120},[114,992,953],{"class":206},[114,994,995],{"class":120},"; j",[114,997,959],{"class":194},[114,999,825],{"class":120},[114,1001,1003,1006,1009,1011],{"class":116,"line":1002},21,[114,1004,1005],{"class":194},"      if",[114,1007,1008],{"class":120}," (arr[i] ",[114,1010,799],{"class":194},[114,1012,1013],{"class":120}," arr[j]) {\n",[114,1015,1017,1020,1023,1026,1028],{"class":116,"line":1016},22,[114,1018,1019],{"class":120},"        arr.",[114,1021,1022],{"class":124},"splice",[114,1024,1025],{"class":120},"(j, ",[114,1027,207],{"class":206},[114,1029,1030],{"class":120},")\n",[114,1032,1034,1037],{"class":116,"line":1033},23,[114,1035,1036],{"class":120},"        j",[114,1038,1039],{"class":194},"--\n",[114,1041,1043],{"class":116,"line":1042},24,[114,1044,1045],{"class":120},"      }\n",[114,1047,1049],{"class":116,"line":1048},25,[114,1050,1051],{"class":120},"    }\n",[114,1053,1055],{"class":116,"line":1054},26,[114,1056,887],{"class":120},[114,1058,1060,1062],{"class":116,"line":1059},27,[114,1061,331],{"class":194},[114,1063,1064],{"class":120}," arr\n",[114,1066,1068],{"class":116,"line":1067},28,[114,1069,340],{"class":120},[14,1071,1072,1073,1075,1076,1078,1079,1082,1083,1085],{},"需要注意 ",[18,1074,793],{}," 方案无法处理 ",[18,1077,74],{}," 和空对象，",[18,1080,1081],{},"Set"," 方案能去掉 ",[18,1084,74],{}," 但去不掉不同引用的空对象。",[10,1087,1088],{"id":1088},"二维数组转一维",[105,1090,1092],{"className":107,"code":1091,"language":109,"meta":110,"style":110},"\u002F\u002F flat，可指定深度，默认 1\n[1, 2, [3, 4, [5, 6]]].flat(2)   \u002F\u002F [1, 2, 3, 4, 5, 6]\n[1, 2, [3, 4, [5, 6]]].flat()    \u002F\u002F [1, 2, 3, 4, [5, 6]]\n",[18,1093,1094,1099,1145],{"__ignoreMap":110},[114,1095,1096],{"class":116,"line":117},[114,1097,1098],{"class":131},"\u002F\u002F flat，可指定深度，默认 1\n",[114,1100,1101,1104,1106,1108,1110,1113,1115,1117,1120,1122,1125,1127,1130,1133,1136,1138,1140,1142],{"class":116,"line":135},[114,1102,1103],{"class":120},"[",[114,1105,207],{"class":206},[114,1107,210],{"class":120},[114,1109,213],{"class":206},[114,1111,1112],{"class":120},", [",[114,1114,546],{"class":206},[114,1116,210],{"class":120},[114,1118,1119],{"class":206},"4",[114,1121,1112],{"class":120},[114,1123,1124],{"class":206},"5",[114,1126,210],{"class":120},[114,1128,1129],{"class":206},"6",[114,1131,1132],{"class":120},"]]].",[114,1134,1135],{"class":124},"flat",[114,1137,730],{"class":120},[114,1139,213],{"class":206},[114,1141,216],{"class":120},[114,1143,1144],{"class":131},"\u002F\u002F [1, 2, 3, 4, 5, 6]\n",[114,1146,1147,1149,1151,1153,1155,1157,1159,1161,1163,1165,1167,1169,1171,1173,1175,1178],{"class":116,"line":149},[114,1148,1103],{"class":120},[114,1150,207],{"class":206},[114,1152,210],{"class":120},[114,1154,213],{"class":206},[114,1156,1112],{"class":120},[114,1158,546],{"class":206},[114,1160,210],{"class":120},[114,1162,1119],{"class":206},[114,1164,1112],{"class":120},[114,1166,1124],{"class":206},[114,1168,210],{"class":120},[114,1170,1129],{"class":206},[114,1172,1132],{"class":120},[114,1174,1135],{"class":124},[114,1176,1177],{"class":120},"()    ",[114,1179,1180],{"class":131},"\u002F\u002F [1, 2, 3, 4, [5, 6]]\n",[14,1182,1183,1186,1187,1189,1190,1192],{},[18,1184,1185],{},"flat()"," 会移除数组中的空项，但 ",[18,1188,20],{}," 和 ",[18,1191,24],{}," 会保留。",[10,1194,1196],{"id":1195},"object-静态方法","Object 静态方法",[14,1198,1199,1202,1203,1206,1207,1209],{},[18,1200,1201],{},"Object.keys()"," 返回自身可枚举属性名组成的数组（不含继承的）。",[18,1204,1205],{},"Object.values()"," 返回属性值数组，顺序与 ",[18,1208,504],{}," 一致。",[14,1211,1212,1215,1216,51],{},[18,1213,1214],{},"Object.assign(target, ...sources)"," 用于合并对象，将源对象的可枚举属性合并到目标对象，",[249,1217,1218],{},"执行的是浅拷贝",[14,1220,1221,1224,1225,1228],{},[18,1222,1223],{},"Object.create(proto, propertiesObject)"," 以指定原型创建新对象。",[18,1226,1227],{},"Object.freeze()"," 冻结对象。",[10,1230,1232],{"id":1231},"promiseall-与-promiserace","Promise.all 与 Promise.race",[14,1234,1235],{},"两者都将多个 Promise 实例包装成一个新实例，区别在于状态决议规则。",[14,1237,1238,1241],{},[18,1239,1240],{},"Promise.all([p1, p2, p3])"," 需要全部 fulfilled 才 fulfilled，返回值组成数组传给回调；只要有一个 rejected 就立即 rejected，第一个被 reject 的返回值传给回调。",[14,1243,1244,1247,1248,1251],{},[18,1245,1246],{},"Promise.race([p1, p2, p3])"," 只要有一个实例率先改变状态，新实例就跟着改变。注意它",[249,1249,1250],{},"不是只执行一个 Promise","，而是只返回最快那个的结果，其余仍在执行。",[10,1253,1255],{"id":1254},"async-await","async \u002F await",[14,1257,1258,1261,1262,1265,1266,1268],{},[18,1259,1260],{},"async"," 修饰函数声明，使其变成异步函数。",[18,1263,1264],{},"await"," 修饰函数调用，被修饰的函数必须返回 Promise 对象，加上 ",[18,1267,1264],{}," 后会将异步操作转换为同步写法。",[10,1270,1271],{"id":1271},"函数柯里化",[14,1273,1274],{},"将一个接受多个参数的函数，转化为一系列只接受一个参数的函数。",[10,1276,1277],{"id":1277},"防抖与节流",[14,1279,1280,1281,1284,1285,1288,1289,1292],{},"两者都用于限制函数执行次数。",[249,1282,1283],{},"防抖","通过 ",[18,1286,1287],{},"setTimeout","，在一定时间间隔内将多次触发合并为一次触发；",[249,1290,1291],{},"节流","则是减少一段时间内的触发频率。",[1294,1295,1296],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-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 .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 .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":110,"searchDepth":149,"depth":149,"links":1298},[1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,1310,1311,1312],{"id":12,"depth":135,"text":12},{"id":95,"depth":135,"text":96},{"id":245,"depth":135,"text":245},{"id":436,"depth":135,"text":436},{"id":462,"depth":135,"text":462},{"id":498,"depth":135,"text":499},{"id":644,"depth":135,"text":645},{"id":694,"depth":135,"text":694},{"id":1088,"depth":135,"text":1088},{"id":1195,"depth":135,"text":1196},{"id":1231,"depth":135,"text":1232},{"id":1254,"depth":135,"text":1255},{"id":1271,"depth":135,"text":1271},{"id":1277,"depth":135,"text":1277},"interview","2024-11-03","数据类型、this 绑定、闭包、原型链、异步与数组方法，前端面试中 JS 部分的高频考点与代码示例。",false,"md",{},"\u002Fdocs\u002Finterview-javascript-core",{"title":5,"description":1315},null,"docs\u002Finterview-javascript-core",[1324,1325,1326],"javascript","es6","notes","dDovihN3Uj102PwlAMGy0mbwWnWpYT-EjLVCRjyhPTI",[1329,1340,1349,1355,1365,1371,1379,1384,1392,1394,1401,1407,1414,1421,1427],{"path":1330,"title":1331,"description":1332,"date":1333,"category":1334,"tags":1335},"\u002Fdocs\u002Ffrontend-coding-standards","前端团队编码规范","HTML \u002F CSS \u002F JavaScript 三端统一的团队编码约定，含缩进、命名、语法与禁用项，可直接作为 Code Review 依据。","2025-12-17","standards",[1336,1337,1324,1325,1338,1339],"html","css","best-practice","guide",{"path":1341,"title":1342,"description":1343,"date":1344,"category":1345,"tags":1346},"\u002Fdocs\u002Fwindows-mklink","Windows mklink 符号链接用法","mklink 各参数区别与实用场景：目录联接、符号链接与硬链接的选择。","2024-12-18","toolchain",[1347,1348],"windows","cheatsheet",{"path":1350,"title":1351,"description":1352,"date":1353,"category":1345,"tags":1354},"\u002Fdocs\u002Frandom-color-utils","JS 随机颜色生成方法","几种生成随机 RGB \u002F HEX 颜色的实现方式与各自适用场景。","2024-12-11",[1324,1348],{"path":1356,"title":1357,"description":1358,"date":1359,"category":1360,"tags":1361},"\u002Fdocs\u002Fcanvas-vs-svg","Canvas 与 SVG 绘图方案选型","对比 Canvas 与 SVG 两种绘图方案的优缺点与适用场景，给出选型判断依据。","2024-12-09","visualization",[1362,1363,1364,1338],"canvas","svg","performance",{"path":1366,"title":1367,"description":1368,"date":1314,"category":1345,"tags":1369},"\u002Fdocs\u002Ffree-commercial-fonts","免费可商用字体整理","整理思源黑体、思源宋体等可商用中文字体，规避字体版权风险。",[1370,1337,1326],"font",{"path":1372,"title":1373,"description":1374,"date":1314,"category":1313,"tags":1375},"\u002Fdocs\u002Finterview-browser-network","浏览器与网络考点","从输入 URL 到页面呈现的完整链路，涵盖渲染流程、回流重绘、HTTP 报文与状态码、跨域同源策略与常见攻击方式。",[1376,1377,1378,1364,1326],"browser","http","network",{"path":1380,"title":1381,"description":1382,"date":1314,"category":1313,"tags":1383},"\u002Fdocs\u002Finterview-css-layout","CSS 与布局考点","em 与 rem 的区别、移动端三种适配方案对比、viewport 标准设置与 REM 布局的媒体查询实现。",[1337,1336,1338,1326],{"path":1385,"title":1386,"description":1387,"date":1314,"category":1313,"tags":1388},"\u002Fdocs\u002Finterview-framework-tooling","框架与工程化考点","React diff 与 setState 机制、Redux 核心组成、Vue 常考清单，以及 Webpack、Vite、Git 的面试要点。",[1389,1324,1390,1391,1326],"vue","webpack","vite",{"path":1319,"title":5,"description":1315,"date":1314,"category":1313,"tags":1393},[1324,1325,1326],{"path":1395,"title":1396,"description":1397,"date":1314,"category":1398,"tags":1399},"\u002Fdocs\u002Fjs-module-systems","JavaScript 模块化方案","梳理 CommonJS、AMD、ES Module 等模块化方案的差异与使用方式。","fundamentals",[1324,1400,1325,1326],"module-system",{"path":1402,"title":1403,"description":1404,"date":1314,"category":1398,"tags":1405},"\u002Fdocs\u002Fwebsocket-basics","WebSocket 基础","WebSocket 全双工通信协议的事件、方法与基本用法整理。",[1406,1378,1324,1326],"websocket",{"path":1408,"title":1409,"description":1410,"date":1411,"category":1360,"tags":1412},"\u002Fdocs\u002Fgojs-getting-started","GoJS 入门实战","从引入方式、画布初始化到节点模板与数据绑定，一份可直接上手的 GoJS 流程图开发笔记。","2024-08-22",[1413,1324,1326],"gojs",{"path":1415,"title":1416,"description":1417,"date":1418,"category":1360,"tags":1419},"\u002Fdocs\u002Fecharts-options-notes","ECharts 配置项速查","整理 ECharts 常用 option 配置：数据格式、坐标轴、图例与交互项的实际用法。","2024-08-09",[1420,1324,1348],"echarts",{"path":1422,"title":1423,"description":1424,"date":1425,"category":1398,"tags":1426},"\u002Fdocs\u002Fhttp-status-codes","HTTP 响应状态码详解","按 1xx 到 5xx 分类梳理 HTTP 状态码的含义与典型使用场景。","2024-06-27",[1377,1378,1348],{"path":1428,"title":1429,"description":1430,"date":1431,"category":1398,"tags":1432},"\u002Fdocs\u002Fhtml-basics","HTML 基础笔记","HTML 语法规范、常用标签、表格与表单元素速查。","2022-06-10",[1336,1326,1348],1788337378852]