[{"data":1,"prerenderedAt":2363},["ShallowReactive",2],{"post:\u002Fposts\u002F2025\u002Fmagic-js":3,"posts:catalog":2089},{"id":4,"title":5,"aiSummary":6,"audio":7,"body":8,"categories":2072,"cover":2074,"description":2075,"extension":2076,"meta":2077,"navigation":6,"path":2078,"pin":2079,"publish":2080,"seo":2081,"series":7,"seriesOrder":7,"stem":2082,"summary":7,"summarySource":2083,"tags":2084,"theme":2085,"update":2080,"wip":2086,"wordCount":2087,"__hash__":2088},"posts\u002Fposts\u002F2025\u002Fmagic-js.md","你能看懂这些 JavaScript 表达式吗？",true,null,{"type":9,"value":10,"toc":2044},"minimark",[11,15,19,32,35,38,211,214,225,257,270,273,332,341,350,392,402,425,435,447,453,482,485,521,528,534,550,563,574,616,619,632,643,646,663,674,698,704,712,715,778,784,808,811,848,851,1005,1016,1022,1092,1098,1107,1140,1143,1212,1222,1225,1274,1280,1285,1288,1299,1305,1348,1351,1373,1376,1423,1426,1450,1460,1465,1490,1499,1502,1518,1524,1536,1539,1562,1565,1610,1617,1620,1623,1654,1657,1692,1701,1727,1744,1752,1758,1773,1776,1801,1809,1812,1827,1835,1838,1871,1877,1929,1934,1966,1969,1999,2002,2008,2012,2022,2031,2040],[12,13,14],"h2",{"id":14},"前言",[16,17,18],"p",{},"在水群时看到了这张图无疑是难蚌的，那么问题来了，这些 JavaScript 表达式的结果为什么会这样？\n实际上，这些结果并不是随机产生的。它们基本都可以归结为三件事：",[20,21,22,26,29],"ol",{},[23,24,25],"li",{},"JavaScript 的数字使用 IEEE 754 双精度浮点数表示",[23,27,28],{},"运算符会触发隐式类型转换",[23,30,31],{},"相同的符号在不同语法环境中可能有不同含义",[16,33,34],{},"理解了之后，图中的大部分“魔法”就只剩下机械推导，以下是关于原理的分析。",[12,36,37],{"id":37},"省流版",[39,40,41,52,58,64,74,80,86,92,98,115,128,139,153,162,175,185,199],"ul",{},[23,42,43,47,48,51],{},[44,45,46],"code",{},"typeof NaN → \"number\"","：",[44,49,50],{},"NaN"," 是数字类型里的特殊值。",[23,53,54,57],{},[44,55,56],{},"9999999999999999 → 10000000000000000","：超过安全整数范围，被浮点数舍入。",[23,59,60,63],{},[44,61,62],{},"0.5 + 0.1 == 0.6 → true","：两边最终保存成了同一个浮点数。",[23,65,66,69,70,73],{},[44,67,68],{},"0.1 + 0.2 == 0.3 → false","：实际结果是 ",[44,71,72],{},"0.30000000000000004","。",[23,75,76,79],{},[44,77,78],{},"Math.max() → -Infinity","：没有参数时，最大值从负无穷开始。",[23,81,82,85],{},[44,83,84],{},"Math.min() → Infinity","：没有参数时，最小值从正无穷开始。",[23,87,88,91],{},[44,89,90],{},"[] + [] → \"\"","：两个空数组都转成空字符串后拼接。",[23,93,94,97],{},[44,95,96],{},"[] + {} → \"[object Object]\"","：空数组变空字符串，对象变成对象字符串。",[23,99,100,103,104,107,108,111,112,73],{},[44,101,102],{},"{} + [] → 0","：开头的 ",[44,105,106],{},"{}"," 可能被当作代码块，",[44,109,110],{},"+[]"," 等于 ",[44,113,114],{},"0",[23,116,117,120,121,124,125,73],{},[44,118,119],{},"true + true + true === 3 → true","：参与加法时，",[44,122,123],{},"true"," 会转成 ",[44,126,127],{},"1",[23,129,130,133,134,136,137,73],{},[44,131,132],{},"true - true → 0","：减法会把两个 ",[44,135,123],{}," 都转成 ",[44,138,127],{},[23,140,141,47,144,147,148,150,151,73],{},[44,142,143],{},"true == 1 → true",[44,145,146],{},"=="," 会先把 ",[44,149,123],{}," 转成 ",[44,152,127],{},[23,154,155,47,158,161],{},[44,156,157],{},"true === 1 → false",[44,159,160],{},"==="," 不转换类型，布尔值不等于数字。",[23,163,164,167,168,171,172,73],{},[44,165,166],{},"(!+[] + [] + ![]).length → 9","：最终得到字符串 ",[44,169,170],{},"\"truefalse\"","，长度为 ",[44,173,174],{},"9",[23,176,177,180,181,184],{},[44,178,179],{},"9 + \"1\" → \"91\"","：遇到字符串，",[44,182,183],{},"+"," 执行字符串拼接。",[23,186,187,47,190,193,194,150,197,73],{},[44,188,189],{},"91 - \"1\" → 90",[44,191,192],{},"-"," 只做数字运算，会把 ",[44,195,196],{},"\"1\"",[44,198,127],{},[23,200,201,204,205,208,209,73],{},[44,202,203],{},"[] == 0 → true","：空数组先变成 ",[44,206,207],{},"\"\"","，再变成数字 ",[44,210,114],{},[12,212,213],{"id":213},"原理",[215,216,218,221,222],"h3",{"id":217},"typeof-nan-为什么是-number",[44,219,220],{},"typeof NaN"," 为什么是 ",[44,223,224],{},"\"number\"",[226,227,232],"pre",{"className":228,"code":229,"language":230,"meta":231,"style":231},"language-js shiki shiki-themes catppuccin-mocha catppuccin-latte","typeof Number.NaN \u002F\u002F \"number\"\n","js","",[44,233,234],{"__ignoreMap":231},[235,236,239,243,247,250,253],"span",{"class":237,"line":238},"line",1,[235,240,242],{"class":241},"siJSA","typeof",[235,244,246],{"class":245},"szT_X"," Number",[235,248,249],{"class":241},".",[235,251,252],{"class":245},"NaN ",[235,254,256],{"class":255},"s0D_2","\u002F\u002F \"number\"\n",[16,258,259,261,262,265,266,269],{},[44,260,50],{}," 是 ",[44,263,264],{},"Not a Number"," 的缩写，它不是一种独立的数据类型，而是 ",[44,267,268],{},"Number"," 类型中的一个特殊值，用来表示“本应得到数值，却无法得到有效数值”的结果：",[16,271,272],{},"比如：",[226,274,276],{"className":228,"code":275,"language":230,"meta":231,"style":231},"Number('hello') \u002F\u002F NaN\nMath.sqrt(-1) \u002F\u002F NaN\n0 \u002F 0 \u002F\u002F NaN\n",[44,277,278,296,318],{"__ignoreMap":231},[235,279,280,283,286,290,293],{"class":237,"line":238},[235,281,268],{"class":282},"s3Fsb",[235,284,285],{"class":245},"(",[235,287,289],{"class":288},"ssZzq","'hello'",[235,291,292],{"class":245},") ",[235,294,295],{"class":255},"\u002F\u002F NaN\n",[235,297,299,302,304,307,309,311,314,316],{"class":237,"line":298},2,[235,300,301],{"class":245},"Math",[235,303,249],{"class":241},[235,305,306],{"class":282},"sqrt",[235,308,285],{"class":245},[235,310,192],{"class":241},[235,312,127],{"class":313},"s_wmW",[235,315,292],{"class":245},[235,317,295],{"class":255},[235,319,321,323,326,329],{"class":237,"line":320},3,[235,322,114],{"class":313},[235,324,325],{"class":241}," \u002F",[235,327,328],{"class":313}," 0",[235,330,331],{"class":255}," \u002F\u002F NaN\n",[16,333,334,335,337,338,340],{},"因此 ",[44,336,220],{}," 返回 ",[44,339,224],{}," 完全符合 JavaScript 的类型系统。",[16,342,343,344,346,347,47],{},"判断一个值是否真的为 ",[44,345,50],{},"，应该使用 ",[44,348,349],{},"Number.isNaN()",[226,351,353],{"className":228,"code":352,"language":230,"meta":231,"style":231},"Number.isNaN(Number.NaN) \u002F\u002F true\nNumber.isNaN('hello') \u002F\u002F false\n",[44,354,355,375],{"__ignoreMap":231},[235,356,357,359,361,364,367,369,372],{"class":237,"line":238},[235,358,268],{"class":245},[235,360,249],{"class":241},[235,362,363],{"class":282},"isNaN",[235,365,366],{"class":245},"(Number",[235,368,249],{"class":241},[235,370,371],{"class":245},"NaN) ",[235,373,374],{"class":255},"\u002F\u002F true\n",[235,376,377,379,381,383,385,387,389],{"class":237,"line":298},[235,378,268],{"class":245},[235,380,249],{"class":241},[235,382,363],{"class":282},[235,384,285],{"class":245},[235,386,289],{"class":288},[235,388,292],{"class":245},[235,390,391],{"class":255},"\u002F\u002F false\n",[16,393,394,395,398,399,401],{},"不要使用 ",[44,396,397],{},"value === NaN","，因为 ",[44,400,50],{}," 是唯一一个不等于自身的 JavaScript 值：",[226,403,405],{"className":228,"code":404,"language":230,"meta":231,"style":231},"Number.NaN === Number.NaN \u002F\u002F false\n",[44,406,407],{"__ignoreMap":231},[235,408,409,411,413,415,417,419,421,423],{"class":237,"line":238},[235,410,268],{"class":245},[235,412,249],{"class":241},[235,414,252],{"class":245},[235,416,160],{"class":241},[235,418,246],{"class":245},[235,420,249],{"class":241},[235,422,252],{"class":245},[235,424,391],{"class":255},[215,426,428,431,432],{"id":427},"_9999999999999999-为什么变成了-10000000000000000",[44,429,430],{},"9999999999999999"," 为什么变成了 ",[44,433,434],{},"10000000000000000",[226,436,438],{"className":228,"code":437,"language":230,"meta":231,"style":231},"9999999999999999 \u002F\u002F 10000000000000000\n",[44,439,440],{"__ignoreMap":231},[235,441,442,444],{"class":237,"line":238},[235,443,430],{"class":313},[235,445,446],{"class":255}," \u002F\u002F 10000000000000000\n",[16,448,449,450,452],{},"JavaScript 的 ",[44,451,268],{}," 以 64 位存储，但其中只有 53 位有效精度可用于表示整数。因此，它只能精确表示下面这个范围内的整数：",[226,454,456],{"className":228,"code":455,"language":230,"meta":231,"style":231},"Number.MIN_SAFE_INTEGER \u002F\u002F -9007199254740991，即 -(2 ** 53 - 1)\nNumber.MAX_SAFE_INTEGER \u002F\u002F  9007199254740991，即  (2 ** 53 - 1)\n",[44,457,458,470],{"__ignoreMap":231},[235,459,460,462,464,467],{"class":237,"line":238},[235,461,268],{"class":245},[235,463,249],{"class":241},[235,465,466],{"class":245},"MIN_SAFE_INTEGER ",[235,468,469],{"class":255},"\u002F\u002F -9007199254740991，即 -(2 ** 53 - 1)\n",[235,471,472,474,476,479],{"class":237,"line":298},[235,473,268],{"class":245},[235,475,249],{"class":241},[235,477,478],{"class":245},"MAX_SAFE_INTEGER ",[235,480,481],{"class":255},"\u002F\u002F  9007199254740991，即  (2 ** 53 - 1)\n",[16,483,484],{},"超过安全整数范围之后，并不是数字立即变成无穷大，而是某些相邻整数开始共用同一个浮点数表示：",[226,486,488],{"className":228,"code":487,"language":230,"meta":231,"style":231},"Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2\n\u002F\u002F true\n",[44,489,490,517],{"__ignoreMap":231},[235,491,492,494,496,498,500,503,506,508,510,512,514],{"class":237,"line":238},[235,493,268],{"class":245},[235,495,249],{"class":241},[235,497,478],{"class":245},[235,499,183],{"class":241},[235,501,502],{"class":313}," 1",[235,504,505],{"class":241}," ===",[235,507,246],{"class":245},[235,509,249],{"class":241},[235,511,478],{"class":245},[235,513,183],{"class":241},[235,515,516],{"class":313}," 2\n",[235,518,519],{"class":237,"line":298},[235,520,374],{"class":255},[16,522,523,525,526,73],{},[44,524,430],{}," 无法被精确表示，只能舍入到最近的可表示值 ",[44,527,434],{},[16,529,530,531,47],{},"需要精确保存大整数时，可以使用 ",[44,532,533],{},"BigInt",[226,535,537],{"className":228,"code":536,"language":230,"meta":231,"style":231},"9999999999999999n \u002F\u002F 9999999999999999n\n",[44,538,539],{"__ignoreMap":231},[235,540,541,543,547],{"class":237,"line":238},[235,542,430],{"class":313},[235,544,546],{"class":545},"sDkzg","n",[235,548,549],{"class":255}," \u002F\u002F 9999999999999999n\n",[16,551,552,553,555,556,558,559,562],{},"不过 ",[44,554,533],{}," 不能与 ",[44,557,268],{}," 直接混算，也不能直接交给 ",[44,560,561],{},"JSON.stringify()","，使用前要先设计好序列化边界。",[215,564,566,567,570,571],{"id":565},"为什么-05-01-06而-01-02-03","为什么 ",[44,568,569],{},"0.5 + 0.1 === 0.6","，而 ",[44,572,573],{},"0.1 + 0.2 !== 0.3",[226,575,577],{"className":228,"code":576,"language":230,"meta":231,"style":231},"0.5 + 0.1 === 0.6 \u002F\u002F true\n0.1 + 0.2 === 0.3 \u002F\u002F false\n",[44,578,579,598],{"__ignoreMap":231},[235,580,581,584,587,590,592,595],{"class":237,"line":238},[235,582,583],{"class":313},"0.5",[235,585,586],{"class":241}," +",[235,588,589],{"class":313}," 0.1",[235,591,505],{"class":241},[235,593,594],{"class":313}," 0.6",[235,596,597],{"class":255}," \u002F\u002F true\n",[235,599,600,603,605,608,610,613],{"class":237,"line":298},[235,601,602],{"class":313},"0.1",[235,604,586],{"class":241},[235,606,607],{"class":313}," 0.2",[235,609,505],{"class":241},[235,611,612],{"class":313}," 0.3",[235,614,615],{"class":255}," \u002F\u002F false\n",[16,617,618],{},"这两个结果并不矛盾。",[16,620,621,622,625,626,628,629,47],{},"十进制中的有限小数，换成二进制后不一定仍然有限。就像十进制无法用有限位数精确写出 ",[44,623,624],{},"1 \u002F 3"," 一样，二进制也无法用有限位数精确写出 ",[44,627,602],{}," 和 ",[44,630,631],{},"0.2",[226,633,637],{"className":634,"code":635,"language":636,"meta":231,"style":231},"language-txt shiki shiki-themes catppuccin-mocha catppuccin-latte","0.1₁₀ ≈ 0.00011001100110011…₂\n","txt",[44,638,639],{"__ignoreMap":231},[235,640,641],{"class":237,"line":238},[235,642,635],{},[16,644,645],{},"计算机只能保存有限位，于是会把真实值舍入到附近一个可表示的二进制浮点数。",[16,647,648,650,651,654,655,658,659,662],{},[44,649,583],{}," 可以写成 ",[44,652,653],{},"1 \u002F 2","，在二进制中能够精确表示。",[44,656,657],{},"0.5 + 0.1"," 经过舍入后，恰好与字面量 ",[44,660,661],{},"0.6"," 落在同一个可表示值上，所以严格相等。",[16,664,665,666,668,669,671,672,47],{},"而 ",[44,667,602],{}," 与 ",[44,670,631],{}," 各自的近似值相加后，结果落在 ",[44,673,72],{},[226,675,677],{"className":228,"code":676,"language":230,"meta":231,"style":231},"0.1 + 0.2 \u002F\u002F 0.30000000000000004\n0.3 \u002F\u002F 0.3\n",[44,678,679,690],{"__ignoreMap":231},[235,680,681,683,685,687],{"class":237,"line":238},[235,682,602],{"class":313},[235,684,586],{"class":241},[235,686,607],{"class":313},[235,688,689],{"class":255}," \u002F\u002F 0.30000000000000004\n",[235,691,692,695],{"class":237,"line":298},[235,693,694],{"class":313},"0.3",[235,696,697],{"class":255}," \u002F\u002F 0.3\n",[16,699,700,701,703],{},"两边最终对应不同的浮点数，自然不会严格相等。问题不在 ",[44,702,160],{},"，而在参与比较的数值本来就不同。",[705,706,708,711],"h4",{"id":707},"tofixed-只负责展示",[44,709,710],{},"toFixed()"," 只负责展示",[16,713,714],{},"如果只是向用户展示一位小数，可以使用：",[226,716,718],{"className":228,"code":717,"language":230,"meta":231,"style":231},"const displayValue = (0.1 + 0.2).toFixed(1)\n\ndisplayValue \u002F\u002F \"0.3\"\ntypeof displayValue \u002F\u002F \"string\"\n",[44,719,720,755,760,768],{"__ignoreMap":231},[235,721,722,725,728,731,734,736,738,740,743,745,748,750,752],{"class":237,"line":238},[235,723,724],{"class":545},"const",[235,726,727],{"class":245}," displayValue ",[235,729,730],{"class":241},"=",[235,732,733],{"class":245}," (",[235,735,602],{"class":313},[235,737,586],{"class":241},[235,739,607],{"class":313},[235,741,742],{"class":245},")",[235,744,249],{"class":241},[235,746,747],{"class":282},"toFixed",[235,749,285],{"class":245},[235,751,127],{"class":313},[235,753,754],{"class":245},")\n",[235,756,757],{"class":237,"line":298},[235,758,759],{"emptyLinePlaceholder":6},"\n",[235,761,762,765],{"class":237,"line":320},[235,763,764],{"class":245},"displayValue ",[235,766,767],{"class":255},"\u002F\u002F \"0.3\"\n",[235,769,771,773,775],{"class":237,"line":770},4,[235,772,242],{"class":241},[235,774,727],{"class":245},[235,776,777],{"class":255},"\u002F\u002F \"string\"\n",[16,779,780,781,783],{},"需要注意：",[44,782,710],{}," 返回的是字符串，它没有提高原始数值的精度，也不应该作为后续计算的通用修复方案。它自身同样会受到输入值已经产生的二进制误差影响：",[226,785,787],{"className":228,"code":786,"language":230,"meta":231,"style":231},"1.005.toFixed(2) \u002F\u002F \"1.00\"\n",[44,788,789],{"__ignoreMap":231},[235,790,791,794,796,798,800,803,805],{"class":237,"line":238},[235,792,793],{"class":313},"1.005",[235,795,249],{"class":241},[235,797,747],{"class":282},[235,799,285],{"class":245},[235,801,802],{"class":313},"2",[235,804,292],{"class":245},[235,806,807],{"class":255},"\u002F\u002F \"1.00\"\n",[16,809,810],{},"因此可以按需求选择方案：",[39,812,813,826,832,838],{},[23,814,815,819,820,822,823,73],{},[816,817,818],"strong",{},"只做展示","：使用 ",[44,821,710],{}," 或 ",[44,824,825],{},"Intl.NumberFormat",[23,827,828,831],{},[816,829,830],{},"判断两个计算结果是否足够接近","：使用符合业务量级的容差。",[23,833,834,837],{},[816,835,836],{},"处理金额、税率等固定小数位数据","：在系统边界把十进制字符串转换为最小单位整数，或使用十进制计算库。",[23,839,840,843,844,847],{},[816,841,842],{},"修正常见四则运算误差","：可以使用 ",[44,845,846],{},"number-precision"," 一类的库。",[16,849,850],{},"近似比较可以写成：",[226,852,854],{"className":228,"code":853,"language":230,"meta":231,"style":231},"function nearlyEqual(a, b, tolerance = Number.EPSILON) {\n  const scale = Math.max(1, Math.abs(a), Math.abs(b))\n  return Math.abs(a - b) \u003C= tolerance * scale\n}\n\nnearlyEqual(0.1 + 0.2, 0.3) \u002F\u002F true\n",[44,855,856,897,942,973,978,983],{"__ignoreMap":231},[235,857,858,861,864,867,871,874,877,879,882,885,887,889,892,894],{"class":237,"line":238},[235,859,860],{"class":545},"function",[235,862,863],{"class":282}," nearlyEqual",[235,865,285],{"class":866},"sxk1D",[235,868,870],{"class":869},"sYNyg","a",[235,872,873],{"class":866},",",[235,875,876],{"class":869}," b",[235,878,873],{"class":866},[235,880,881],{"class":869}," tolerance",[235,883,884],{"class":241}," =",[235,886,246],{"class":245},[235,888,249],{"class":241},[235,890,891],{"class":245},"EPSILON",[235,893,742],{"class":866},[235,895,896],{"class":866}," {\n",[235,898,899,902,905,907,910,912,915,917,919,921,923,925,928,931,933,935,937,939],{"class":237,"line":298},[235,900,901],{"class":545},"  const",[235,903,904],{"class":245}," scale ",[235,906,730],{"class":241},[235,908,909],{"class":245}," Math",[235,911,249],{"class":241},[235,913,914],{"class":282},"max",[235,916,285],{"class":245},[235,918,127],{"class":313},[235,920,873],{"class":866},[235,922,909],{"class":245},[235,924,249],{"class":241},[235,926,927],{"class":282},"abs",[235,929,930],{"class":245},"(a)",[235,932,873],{"class":866},[235,934,909],{"class":245},[235,936,249],{"class":241},[235,938,927],{"class":282},[235,940,941],{"class":245},"(b))\n",[235,943,944,947,949,951,953,956,958,961,964,967,970],{"class":237,"line":320},[235,945,946],{"class":545},"  return",[235,948,909],{"class":245},[235,950,249],{"class":241},[235,952,927],{"class":282},[235,954,955],{"class":245},"(a ",[235,957,192],{"class":241},[235,959,960],{"class":245}," b) ",[235,962,963],{"class":241},"\u003C=",[235,965,966],{"class":245}," tolerance ",[235,968,969],{"class":241},"*",[235,971,972],{"class":245}," scale\n",[235,974,975],{"class":237,"line":770},[235,976,977],{"class":866},"}\n",[235,979,981],{"class":237,"line":980},5,[235,982,759],{"emptyLinePlaceholder":6},[235,984,986,989,991,993,995,997,999,1001,1003],{"class":237,"line":985},6,[235,987,988],{"class":282},"nearlyEqual",[235,990,285],{"class":245},[235,992,602],{"class":313},[235,994,586],{"class":241},[235,996,607],{"class":313},[235,998,873],{"class":866},[235,1000,612],{"class":313},[235,1002,292],{"class":245},[235,1004,374],{"class":255},[16,1006,1007,1010,1011,1013,1014,73],{},[44,1008,1009],{},"Number.EPSILON"," 表示 ",[44,1012,127],{}," 与下一个可表示浮点数之间的距离。数据量级越大、计算步骤越多，累计误差也可能越大，因此生产代码中的容差应由业务精度决定，而不是无条件套用 ",[44,1015,1009],{},[16,1017,1018,1019,1021],{},"使用 ",[44,1020,846],{}," 时，则可以明确表达“我要进行十进制语义下的四则运算”：",[226,1023,1025],{"className":228,"code":1024,"language":230,"meta":231,"style":231},"import NP from 'number-precision'\n\nNP.plus(0.1, 0.2) \u002F\u002F 0.3\nNP.round(0.105, 2) \u002F\u002F 0.11\n",[44,1026,1027,1041,1045,1068],{"__ignoreMap":231},[235,1028,1029,1032,1035,1038],{"class":237,"line":238},[235,1030,1031],{"class":545},"import",[235,1033,1034],{"class":245}," NP ",[235,1036,1037],{"class":545},"from",[235,1039,1040],{"class":288}," 'number-precision'\n",[235,1042,1043],{"class":237,"line":298},[235,1044,759],{"emptyLinePlaceholder":6},[235,1046,1047,1050,1052,1055,1057,1059,1061,1063,1065],{"class":237,"line":320},[235,1048,1049],{"class":313},"NP",[235,1051,249],{"class":241},[235,1053,1054],{"class":282},"plus",[235,1056,285],{"class":245},[235,1058,602],{"class":313},[235,1060,873],{"class":866},[235,1062,607],{"class":313},[235,1064,292],{"class":245},[235,1066,1067],{"class":255},"\u002F\u002F 0.3\n",[235,1069,1070,1072,1074,1077,1079,1082,1084,1087,1089],{"class":237,"line":770},[235,1071,1049],{"class":313},[235,1073,249],{"class":241},[235,1075,1076],{"class":282},"round",[235,1078,285],{"class":245},[235,1080,1081],{"class":313},"0.105",[235,1083,873],{"class":866},[235,1085,1086],{"class":313}," 2",[235,1088,292],{"class":245},[235,1090,1091],{"class":255},"\u002F\u002F 0.11\n",[16,1093,1094,1095,1097],{},"库不是无限精度的魔法。比如 ",[44,1096,846],{}," 在把小数放大为整数时仍会检查安全整数边界；如果系统涉及高精度金融计算，应选择任意精度十进制库，并为舍入模式、精度和序列化方式制定统一规则。",[215,1099,566,1101,261,1104],{"id":1100},"为什么-mathmax-是-infinity",[44,1102,1103],{},"Math.max()",[44,1105,1106],{},"-Infinity",[226,1108,1110],{"className":228,"code":1109,"language":230,"meta":231,"style":231},"Math.max() \u002F\u002F -Infinity\nMath.min() \u002F\u002F Infinity\n",[44,1111,1112,1126],{"__ignoreMap":231},[235,1113,1114,1116,1118,1120,1123],{"class":237,"line":238},[235,1115,301],{"class":245},[235,1117,249],{"class":241},[235,1119,914],{"class":282},[235,1121,1122],{"class":245},"() ",[235,1124,1125],{"class":255},"\u002F\u002F -Infinity\n",[235,1127,1128,1130,1132,1135,1137],{"class":237,"line":298},[235,1129,301],{"class":245},[235,1131,249],{"class":241},[235,1133,1134],{"class":282},"min",[235,1136,1122],{"class":245},[235,1138,1139],{"class":255},"\u002F\u002F Infinity\n",[16,1141,1142],{},"可以把它们想象成一次归约：",[226,1144,1146],{"className":228,"code":1145,"language":230,"meta":231,"style":231},"let max = -Infinity\n\nfor (const value of values)\n  max = value > max ? value : max\n",[44,1147,1148,1165,1169,1187],{"__ignoreMap":231},[235,1149,1150,1153,1156,1158,1161],{"class":237,"line":238},[235,1151,1152],{"class":545},"let",[235,1154,1155],{"class":245}," max ",[235,1157,730],{"class":241},[235,1159,1160],{"class":241}," -",[235,1162,1164],{"class":1163},"s3vbe","Infinity\n",[235,1166,1167],{"class":237,"line":298},[235,1168,759],{"emptyLinePlaceholder":6},[235,1170,1171,1174,1176,1178,1181,1184],{"class":237,"line":320},[235,1172,1173],{"class":545},"for",[235,1175,733],{"class":245},[235,1177,724],{"class":545},[235,1179,1180],{"class":245}," value ",[235,1182,1183],{"class":545},"of",[235,1185,1186],{"class":245}," values)\n",[235,1188,1189,1192,1194,1196,1199,1201,1204,1206,1209],{"class":237,"line":770},[235,1190,1191],{"class":245},"  max ",[235,1193,730],{"class":241},[235,1195,1180],{"class":245},[235,1197,1198],{"class":241},">",[235,1200,1155],{"class":245},[235,1202,1203],{"class":241},"?",[235,1205,1180],{"class":245},[235,1207,1208],{"class":241},":",[235,1210,1211],{"class":245}," max\n",[16,1213,1214,1215,1217,1218,1221],{},"为了让传入的任何有限数都能替换初始值，求最大值从 ",[44,1216,1106],{}," 开始；求最小值则从 ",[44,1219,1220],{},"Infinity"," 开始。没有参数时，循环一次也没有执行，于是直接返回各自的初始值。",[16,1223,1224],{},"这也使它们满足实用的组合规则：",[226,1226,1228],{"className":228,"code":1227,"language":230,"meta":231,"style":231},"Math.max(-Infinity, 3) \u002F\u002F 3\nMath.min(Infinity, 3) \u002F\u002F 3\n",[44,1229,1230,1254],{"__ignoreMap":231},[235,1231,1232,1234,1236,1238,1240,1242,1244,1246,1249,1251],{"class":237,"line":238},[235,1233,301],{"class":245},[235,1235,249],{"class":241},[235,1237,914],{"class":282},[235,1239,285],{"class":245},[235,1241,192],{"class":241},[235,1243,1220],{"class":1163},[235,1245,873],{"class":866},[235,1247,1248],{"class":313}," 3",[235,1250,292],{"class":245},[235,1252,1253],{"class":255},"\u002F\u002F 3\n",[235,1255,1256,1258,1260,1262,1264,1266,1268,1270,1272],{"class":237,"line":298},[235,1257,301],{"class":245},[235,1259,249],{"class":241},[235,1261,1134],{"class":282},[235,1263,285],{"class":245},[235,1265,1220],{"class":1163},[235,1267,873],{"class":866},[235,1269,1248],{"class":313},[235,1271,292],{"class":245},[235,1273,1253],{"class":255},[215,1275,1277,1279],{"id":1276},"为什么一会儿加法一会儿拼接",[44,1278,183],{}," 为什么一会儿加法，一会儿拼接",[16,1281,1282,1284],{},[44,1283,183],{}," 是图中最忙的运算符。它既负责数值加法，也负责字符串拼接。",[16,1286,1287],{},"简化后的判断流程是：",[20,1289,1290,1293,1296],{},[23,1291,1292],{},"先把对象转换为原始值；",[23,1294,1295],{},"只要有一边是字符串，就执行字符串拼接；",[23,1297,1298],{},"否则把两边转换为数值并相加。",[16,1300,1301,1302,47],{},"数组转原始值时，通常会走到 ",[44,1303,1304],{},"toString()",[226,1306,1308],{"className":228,"code":1307,"language":230,"meta":231,"style":231},"[].toString() \u002F\u002F \"\"\n  [1, 2].toString() \u002F\u002F \"1,2\"\n",[44,1309,1310,1325],{"__ignoreMap":231},[235,1311,1312,1315,1317,1320,1322],{"class":237,"line":238},[235,1313,1314],{"class":245},"[]",[235,1316,249],{"class":241},[235,1318,1319],{"class":282},"toString",[235,1321,1122],{"class":245},[235,1323,1324],{"class":255},"\u002F\u002F \"\"\n",[235,1326,1327,1330,1332,1334,1336,1339,1341,1343,1345],{"class":237,"line":298},[235,1328,1329],{"class":245},"  [",[235,1331,127],{"class":313},[235,1333,873],{"class":866},[235,1335,1086],{"class":313},[235,1337,1338],{"class":245},"]",[235,1340,249],{"class":241},[235,1342,1319],{"class":282},[235,1344,1122],{"class":245},[235,1346,1347],{"class":255},"\u002F\u002F \"1,2\"\n",[16,1349,1350],{},"普通对象默认会得到：",[226,1352,1354],{"className":228,"code":1353,"language":230,"meta":231,"style":231},"({}).toString() \u002F\u002F \"[object Object]\"\n",[44,1355,1356],{"__ignoreMap":231},[235,1357,1358,1360,1362,1364,1366,1368,1370],{"class":237,"line":238},[235,1359,285],{"class":245},[235,1361,106],{"class":866},[235,1363,742],{"class":245},[235,1365,249],{"class":241},[235,1367,1319],{"class":282},[235,1369,1122],{"class":245},[235,1371,1372],{"class":255},"\u002F\u002F \"[object Object]\"\n",[16,1374,1375],{},"所以：",[226,1377,1379],{"className":228,"code":1378,"language":230,"meta":231,"style":231},"[] + []\n\u002F\u002F \"\" + \"\"\n\u002F\u002F \"\"\n\n[] + {}\n\u002F\u002F \"\" + \"[object Object]\"\n\u002F\u002F \"[object Object]\"\n",[44,1380,1381,1391,1396,1400,1404,1413,1418],{"__ignoreMap":231},[235,1382,1383,1386,1388],{"class":237,"line":238},[235,1384,1385],{"class":245},"[] ",[235,1387,183],{"class":241},[235,1389,1390],{"class":245}," []\n",[235,1392,1393],{"class":237,"line":298},[235,1394,1395],{"class":255},"\u002F\u002F \"\" + \"\"\n",[235,1397,1398],{"class":237,"line":320},[235,1399,1324],{"class":255},[235,1401,1402],{"class":237,"line":770},[235,1403,759],{"emptyLinePlaceholder":6},[235,1405,1406,1408,1410],{"class":237,"line":980},[235,1407,1385],{"class":245},[235,1409,183],{"class":241},[235,1411,1412],{"class":866}," {}\n",[235,1414,1415],{"class":237,"line":985},[235,1416,1417],{"class":255},"\u002F\u002F \"\" + \"[object Object]\"\n",[235,1419,1421],{"class":237,"line":1420},7,[235,1422,1372],{"class":255},[16,1424,1425],{},"同样的规则也解释了：",[226,1427,1429],{"className":228,"code":1428,"language":230,"meta":231,"style":231},"`${9}1` \u002F\u002F \"91\"\n",[44,1430,1431],{"__ignoreMap":231},[235,1432,1433,1436,1439,1441,1444,1447],{"class":237,"line":238},[235,1434,1435],{"class":288},"`",[235,1437,1438],{"class":866},"${",[235,1440,174],{"class":313},[235,1442,1443],{"class":866},"}",[235,1445,1446],{"class":288},"1`",[235,1448,1449],{"class":255}," \u002F\u002F \"91\"\n",[16,1451,1452,1453,1455,1456,1459],{},"数字 ",[44,1454,174],{}," 被转换成字符串 ",[44,1457,1458],{},"\"9\"","，随后发生拼接。",[16,1461,665,1462,1464],{},[44,1463,192],{}," 没有“字符串相减”这一分支，只会尝试数值运算：",[226,1466,1468],{"className":228,"code":1467,"language":230,"meta":231,"style":231},"91 - '1'\n\u002F\u002F 91 - 1\n\u002F\u002F 90\n",[44,1469,1470,1480,1485],{"__ignoreMap":231},[235,1471,1472,1475,1477],{"class":237,"line":238},[235,1473,1474],{"class":313},"91",[235,1476,1160],{"class":241},[235,1478,1479],{"class":288}," '1'\n",[235,1481,1482],{"class":237,"line":298},[235,1483,1484],{"class":255},"\u002F\u002F 91 - 1\n",[235,1486,1487],{"class":237,"line":320},[235,1488,1489],{"class":255},"\u002F\u002F 90\n",[215,1491,1493,111,1496,1498],{"id":1492},"等于-0其实是控制台制造的错觉",[44,1494,1495],{},"{} + []",[44,1497,114],{},"，其实是控制台制造的错觉",[16,1500,1501],{},"图中这一行尤其值得单独说明：",[226,1503,1505],{"className":228,"code":1504,"language":230,"meta":231,"style":231},"{} +[] \u002F\u002F 0\n",[44,1506,1507],{"__ignoreMap":231},[235,1508,1509,1511,1513,1515],{"class":237,"line":238},[235,1510,106],{"class":866},[235,1512,586],{"class":241},[235,1514,1385],{"class":245},[235,1516,1517],{"class":255},"\u002F\u002F 0\n",[16,1519,1520,1521,1523],{},"当它作为一整条语句出现在某些浏览器控制台中时，开头的 ",[44,1522,106],{}," 会被解析成一个空代码块，剩下的是：",[226,1525,1527],{"className":228,"code":1526,"language":230,"meta":231,"style":231},"+[]\n",[44,1528,1529],{"__ignoreMap":231},[235,1530,1531,1533],{"class":237,"line":238},[235,1532,183],{"class":241},[235,1534,1535],{"class":245},"[]\n",[16,1537,1538],{},"一元加号会把空数组转换成数值：",[226,1540,1542],{"className":228,"code":1541,"language":230,"meta":231,"style":231},"Number([]) \u002F\u002F 0\n+ [] \u002F\u002F 0\n",[44,1543,1544,1553],{"__ignoreMap":231},[235,1545,1546,1548,1551],{"class":237,"line":238},[235,1547,268],{"class":282},[235,1549,1550],{"class":245},"([]) ",[235,1552,1517],{"class":255},[235,1554,1555,1557,1560],{"class":237,"line":298},[235,1556,183],{"class":241},[235,1558,1559],{"class":245}," [] ",[235,1561,1517],{"class":255},[16,1563,1564],{},"但只要明确告诉解析器“这是一个表达式”，结果就不同：",[226,1566,1568],{"className":228,"code":1567,"language":230,"meta":231,"style":231},"({} + []) \u002F\u002F \"[object Object]\"\n\nconst result = {} + []\nresult \u002F\u002F \"[object Object]\"\n",[44,1569,1570,1583,1587,1603],{"__ignoreMap":231},[235,1571,1572,1574,1576,1578,1581],{"class":237,"line":238},[235,1573,285],{"class":245},[235,1575,106],{"class":866},[235,1577,586],{"class":241},[235,1579,1580],{"class":245}," []) ",[235,1582,1372],{"class":255},[235,1584,1585],{"class":237,"line":298},[235,1586,759],{"emptyLinePlaceholder":6},[235,1588,1589,1591,1594,1596,1599,1601],{"class":237,"line":320},[235,1590,724],{"class":545},[235,1592,1593],{"class":245}," result ",[235,1595,730],{"class":241},[235,1597,1598],{"class":866}," {}",[235,1600,586],{"class":241},[235,1602,1390],{"class":245},[235,1604,1605,1608],{"class":237,"line":770},[235,1606,1607],{"class":245},"result ",[235,1609,1372],{"class":255},[16,1611,1612,1613,1616],{},"所以 ",[44,1614,1615],{},"{} + [] === 0"," 不是一条可以脱离上下文记忆的 JavaScript 规则，而是“语句解析 + 类型转换”共同产生的结果。不同控制台也可能先对输入做额外包装，实验时最好把表达式放进括号或赋值语句。",[215,1618,1619],{"id":1619},"布尔值为什么能参与计算",[16,1621,1622],{},"在数值转换中：",[226,1624,1626],{"className":228,"code":1625,"language":230,"meta":231,"style":231},"Number(true) \u002F\u002F 1\nNumber(false) \u002F\u002F 0\n",[44,1627,1628,1641],{"__ignoreMap":231},[235,1629,1630,1632,1634,1636,1638],{"class":237,"line":238},[235,1631,268],{"class":282},[235,1633,285],{"class":245},[235,1635,123],{"class":313},[235,1637,292],{"class":245},[235,1639,1640],{"class":255},"\u002F\u002F 1\n",[235,1642,1643,1645,1647,1650,1652],{"class":237,"line":298},[235,1644,268],{"class":282},[235,1646,285],{"class":245},[235,1648,1649],{"class":313},"false",[235,1651,292],{"class":245},[235,1653,1517],{"class":255},[16,1655,1656],{},"因此：",[226,1658,1660],{"className":228,"code":1659,"language":230,"meta":231,"style":231},"true + true + true === 3 \u002F\u002F true\ntrue - true \u002F\u002F 0\n",[44,1661,1662,1681],{"__ignoreMap":231},[235,1663,1664,1666,1668,1671,1673,1675,1677,1679],{"class":237,"line":238},[235,1665,123],{"class":313},[235,1667,586],{"class":241},[235,1669,1670],{"class":313}," true",[235,1672,586],{"class":241},[235,1674,1670],{"class":313},[235,1676,505],{"class":241},[235,1678,1248],{"class":313},[235,1680,597],{"class":255},[235,1682,1683,1685,1687,1689],{"class":237,"line":298},[235,1684,123],{"class":313},[235,1686,1160],{"class":241},[235,1688,1670],{"class":313},[235,1690,1691],{"class":255}," \u002F\u002F 0\n",[16,1693,1694,628,1697,1700],{},[44,1695,1696],{},"true == 1",[44,1698,1699],{},"true === 1"," 的区别，则来自两种相等判断：",[226,1702,1704],{"className":228,"code":1703,"language":230,"meta":231,"style":231},"true == 1 \u002F\u002F true\ntrue === 1 \u002F\u002F false\n",[44,1705,1706,1717],{"__ignoreMap":231},[235,1707,1708,1710,1713,1715],{"class":237,"line":238},[235,1709,123],{"class":313},[235,1711,1712],{"class":241}," ==",[235,1714,502],{"class":313},[235,1716,597],{"class":255},[235,1718,1719,1721,1723,1725],{"class":237,"line":298},[235,1720,123],{"class":313},[235,1722,505],{"class":241},[235,1724,502],{"class":313},[235,1726,615],{"class":255},[16,1728,1729,1730,1732,1733,1735,1736,1738,1739,1741,1742,73],{},"宽松相等 ",[44,1731,146],{}," 会先进行类型转换，",[44,1734,123],{}," 被转换成 ",[44,1737,127],{},"；严格相等 ",[44,1740,160],{}," 不进行这种跨类型转换，布尔值与数字的类型不同，所以结果为 ",[44,1743,1649],{},[16,1745,1746,1747,1749,1750,73],{},"工程代码中应默认使用 ",[44,1748,160],{},"。只有在确实需要并完全理解宽松相等规则时，才使用 ",[44,1751,146],{},[215,1753,566,1755],{"id":1754},"为什么-0",[44,1756,1757],{},"[] == 0",[226,1759,1761],{"className":228,"code":1760,"language":230,"meta":231,"style":231},"[] == 0 \u002F\u002F true\n",[44,1762,1763],{"__ignoreMap":231},[235,1764,1765,1767,1769,1771],{"class":237,"line":238},[235,1766,1385],{"class":245},[235,1768,146],{"class":241},[235,1770,328],{"class":313},[235,1772,597],{"class":255},[16,1774,1775],{},"这次是宽松相等规则在工作，推导过程如下：",[226,1777,1779],{"className":634,"code":1778,"language":636,"meta":231,"style":231},"[] == 0\n\"\" == 0\n0 == 0\ntrue\n",[44,1780,1781,1786,1791,1796],{"__ignoreMap":231},[235,1782,1783],{"class":237,"line":238},[235,1784,1785],{},"[] == 0\n",[235,1787,1788],{"class":237,"line":298},[235,1789,1790],{},"\"\" == 0\n",[235,1792,1793],{"class":237,"line":320},[235,1794,1795],{},"0 == 0\n",[235,1797,1798],{"class":237,"line":770},[235,1799,1800],{},"true\n",[16,1802,1803,1804,1806,1807,73],{},"空数组先转换为原始值 ",[44,1805,207],{},"，当字符串与数字进行宽松比较时，空字符串又被转换为数字 ",[44,1808,114],{},[16,1810,1811],{},"严格相等不会进行这串转换：",[226,1813,1815],{"className":228,"code":1814,"language":230,"meta":231,"style":231},"[] === 0 \u002F\u002F false\n",[44,1816,1817],{"__ignoreMap":231},[235,1818,1819,1821,1823,1825],{"class":237,"line":238},[235,1820,1385],{"class":245},[235,1822,160],{"class":241},[235,1824,328],{"class":313},[235,1826,615],{"class":255},[215,1828,1830,221,1833],{"id":1829},"length-为什么是-9",[44,1831,1832],{},"(!+[] + [] + ![]).length",[44,1834,174],{},[16,1836,1837],{},"把这道“JavaScript 黑魔法”逐步展开：",[226,1839,1841],{"className":228,"code":1840,"language":230,"meta":231,"style":231},"+[] \u002F\u002F 0\n!+[] \u002F\u002F !0，也就是 true\n![] \u002F\u002F false，因为数组是对象，而所有对象都是真值\n",[44,1842,1843,1851,1861],{"__ignoreMap":231},[235,1844,1845,1847,1849],{"class":237,"line":238},[235,1846,183],{"class":241},[235,1848,1385],{"class":245},[235,1850,1517],{"class":255},[235,1852,1853,1856,1858],{"class":237,"line":298},[235,1854,1855],{"class":241},"!+",[235,1857,1385],{"class":245},[235,1859,1860],{"class":255},"\u002F\u002F !0，也就是 true\n",[235,1862,1863,1866,1868],{"class":237,"line":320},[235,1864,1865],{"class":241},"!",[235,1867,1385],{"class":245},[235,1869,1870],{"class":255},"\u002F\u002F false，因为数组是对象，而所有对象都是真值\n",[16,1872,1873,1874,1876],{},"再根据 ",[44,1875,183],{}," 从左到右计算：",[226,1878,1880],{"className":228,"code":1879,"language":230,"meta":231,"style":231},"!+[] + [] + ![]\ntrue + [] + false`true${false}`\n'truefalse'\n",[44,1881,1882,1899,1924],{"__ignoreMap":231},[235,1883,1884,1886,1888,1890,1892,1894,1897],{"class":237,"line":238},[235,1885,1855],{"class":241},[235,1887,1385],{"class":245},[235,1889,183],{"class":241},[235,1891,1559],{"class":245},[235,1893,183],{"class":241},[235,1895,1896],{"class":241}," !",[235,1898,1535],{"class":245},[235,1900,1901,1903,1905,1907,1909,1912,1915,1917,1919,1921],{"class":237,"line":298},[235,1902,123],{"class":313},[235,1904,586],{"class":241},[235,1906,1559],{"class":245},[235,1908,183],{"class":241},[235,1910,1911],{"class":313}," false",[235,1913,1914],{"class":288},"`true",[235,1916,1438],{"class":866},[235,1918,1649],{"class":313},[235,1920,1443],{"class":866},[235,1922,1923],{"class":288},"`\n",[235,1925,1926],{"class":237,"line":320},[235,1927,1928],{"class":288},"'truefalse'\n",[16,1930,1931,1933],{},[44,1932,170],{}," 正好有 9 个字符：",[226,1935,1937],{"className":228,"code":1936,"language":230,"meta":231,"style":231},"(!+[] + [] + ![]).length \u002F\u002F 9\n",[44,1938,1939],{"__ignoreMap":231},[235,1940,1941,1943,1945,1947,1949,1951,1953,1955,1958,1960,1963],{"class":237,"line":238},[235,1942,285],{"class":245},[235,1944,1855],{"class":241},[235,1946,1385],{"class":245},[235,1948,183],{"class":241},[235,1950,1559],{"class":245},[235,1952,183],{"class":241},[235,1954,1896],{"class":241},[235,1956,1957],{"class":245},"[])",[235,1959,249],{"class":241},[235,1961,1962],{"class":245},"length ",[235,1964,1965],{"class":255},"\u002F\u002F 9\n",[16,1967,1968],{},"它不是语言能力的炫技，而是多个隐式转换叠在一起后的产物。生产代码如果需要读者这样推导，应该主动写出明确转换：",[226,1970,1972],{"className":228,"code":1971,"language":230,"meta":231,"style":231},"String(true) + String(false) \u002F\u002F \"truefalse\"\n",[44,1973,1974],{"__ignoreMap":231},[235,1975,1976,1979,1981,1983,1985,1987,1990,1992,1994,1996],{"class":237,"line":238},[235,1977,1978],{"class":282},"String",[235,1980,285],{"class":245},[235,1982,123],{"class":313},[235,1984,292],{"class":245},[235,1986,183],{"class":241},[235,1988,1989],{"class":282}," String",[235,1991,285],{"class":245},[235,1993,1649],{"class":313},[235,1995,292],{"class":245},[235,1997,1998],{"class":255},"\u002F\u002F \"truefalse\"\n",[16,2000,2001],{},"JavaScript 的这些行为确实容易踩坑，但并非没有规律。",[2003,2004,2005],"blockquote",{},[16,2006,2007],{},"Thanks for inventing Javascript",[12,2009,2011],{"id":2010},"reference","Reference",[39,2013,2014],{},[23,2015,2016],{},[870,2017,2021],{"href":2018,"rel":2019},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FGlobal_Objects\u002FNumber",[2020],"nofollow","MDN：Number",[39,2023,2024],{},[23,2025,2026],{},[870,2027,2030],{"href":2028,"rel":2029},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FGlobal_Objects\u002FNumber\u002FEPSILON",[2020],"MDN：Number.EPSILON",[39,2032,2033],{},[23,2034,2035],{},[870,2036,2039],{"href":2037,"rel":2038},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FGlobal_Objects\u002FSymbol\u002FtoPrimitive",[2020],"MDN：Symbol.toPrimitive",[2041,2042,2043],"style",{},"html pre.shiki code .siJSA, html code.shiki .siJSA{--shiki-default:#94E2D5;--shiki-light:#179299}html pre.shiki code .szT_X, html code.shiki .szT_X{--shiki-default:#CDD6F4;--shiki-light:#4C4F69}html pre.shiki code .s0D_2, html code.shiki .s0D_2{--shiki-default:#9399B2;--shiki-default-font-style:italic;--shiki-light:#7C7F93;--shiki-light-font-style:italic}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 .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 pre.shiki code .s3Fsb, html code.shiki .s3Fsb{--shiki-default:#89B4FA;--shiki-default-font-style:italic;--shiki-light:#1E66F5;--shiki-light-font-style:italic}html pre.shiki code .ssZzq, html code.shiki .ssZzq{--shiki-default:#A6E3A1;--shiki-light:#40A02B}html pre.shiki code .s_wmW, html code.shiki .s_wmW{--shiki-default:#FAB387;--shiki-light:#FE640B}html pre.shiki code .sDkzg, html code.shiki .sDkzg{--shiki-default:#CBA6F7;--shiki-light:#8839EF}html pre.shiki code .sxk1D, html code.shiki .sxk1D{--shiki-default:#9399B2;--shiki-light:#7C7F93}html pre.shiki code .sYNyg, html code.shiki .sYNyg{--shiki-default:#EBA0AC;--shiki-default-font-style:italic;--shiki-light:#E64553;--shiki-light-font-style:italic}html pre.shiki code .s3vbe, html code.shiki .s3vbe{--shiki-default:#F38BA8;--shiki-light:#D20F39}",{"title":231,"searchDepth":2045,"depth":980,"links":2046},12,[2047,2048,2049,2071],{"id":14,"depth":298,"text":14},{"id":37,"depth":298,"text":37},{"id":213,"depth":298,"text":213,"children":2050},[2051,2053,2055,2060,2062,2064,2066,2067,2069],{"id":217,"depth":320,"text":2052},"typeof NaN 为什么是 \"number\"",{"id":427,"depth":320,"text":2054},"9999999999999999 为什么变成了 10000000000000000",{"id":565,"depth":320,"text":2056,"children":2057},"为什么 0.5 + 0.1 === 0.6，而 0.1 + 0.2 !== 0.3",[2058],{"id":707,"depth":770,"text":2059},"toFixed() 只负责展示",{"id":1100,"depth":320,"text":2061},"为什么 Math.max() 是 -Infinity",{"id":1276,"depth":320,"text":2063},"+ 为什么一会儿加法，一会儿拼接",{"id":1492,"depth":320,"text":2065},"{} + [] 等于 0，其实是控制台制造的错觉",{"id":1619,"depth":320,"text":1619},{"id":1754,"depth":320,"text":2068},"为什么 [] == 0",{"id":1829,"depth":320,"text":2070},"(!+[] + [] + ![]).length 为什么是 9",{"id":2010,"depth":298,"text":2011},[2073],"JavaScript","\u002Fimages\u002F2025\u002Fmagic-js\u002Fmagic-js.png","本文解析了JavaScript中多个怪异表达式结果的原因，指出其源于IEEE 754浮点数表示、隐式类型转换及同一符号在不同语法环境中的歧义。例如NaN为number、大整数舍入、0.1+0.2不等于0.3、空数组与对象相加、布尔值运算及宽松相等等行为，均可据此解释。建议工程中使用严格相等和明确转换以避免陷阱。","md",{},"\u002Fposts\u002F2025\u002Fmagic-js",0,"2025-07-31",{"title":5,"description":2075},"posts\u002F2025\u002Fmagic-js","ai",[2073],"#a369ff",false,2035,"d8AINTLgGRYV-W_2BBLUjPeP49vN2kxjTlWHEepCV1s",[2090,2106,2120,2128,2141,2156,2169,2181,2191,2204,2216,2219,2231,2242,2255,2266,2275,2289,2301,2313,2326,2335,2345,2354],{"path":2091,"stem":2092,"title":2093,"description":2094,"wordCount":2095,"publish":2096,"update":2096,"cover":2097,"tags":2098,"categories":2104,"series":7,"seriesOrder":7,"pin":2079,"wip":2086,"theme":2085},"\u002Fposts\u002F2026\u002Fwsl3","posts\u002F2026\u002Fwsl3","WSL 3 正式发布~","微软发布 WSL 3.0.1，正式提供稳定的 WSL 容器功能，无需 Docker 即可原生创建和运行 Linux 容器。该版本改进包括跨操作系统文件访问性能最高提升至原来的两倍（采用 virtiofs），以及网络模式 Consomme 优化端口映射和 VPN 兼容性。文章介绍了 WSL 安装、从 WSL 2 升级的方法，并示例使用 wslc 运行 Ubuntu、Nginx 容器及构建自定义镜像。",1038,"2026-10-01","\u002Fimages\u002F2026\u002Fwsl3\u002Fwsl3.png",[2099,2100,2101,2102,2103],"WSL","Linux","Windows","Docker","容器",[2105],"工具",{"path":2107,"stem":2108,"title":2109,"description":2110,"wordCount":2111,"publish":2112,"update":7,"cover":2113,"tags":2114,"categories":2119,"series":7,"seriesOrder":7,"pin":2079,"wip":2086,"theme":2085},"\u002Fposts\u002F2026\u002Fcodex-prompt","posts\u002F2026\u002Fcodex-prompt","Codex 的 GPT-6 Sol 提示词泄露了？","文章围绕网传Codex GPT-6 Sol提示词泄露展开，选取部分内容解读。提示词要求像同事一样交流、降低认知负担，用具体描述并说明改动、原因、测试与风险；明确禁止使用AI套话；通过高质量和低质量示例约束输出。摘要表还涵盖沟通、执行、权限、长期任务、工具与界面、质量与证据等核心要求。",1073,"2026-09-25","\u002Fimages\u002F2026\u002Fcodex-prompt\u002Fcodex-prompt.png",[2115,2116,2117,2118],"AI","Codex","提示词","Agent",[2115],{"path":2121,"stem":2122,"title":2123,"description":2124,"wordCount":2125,"publish":2112,"update":7,"cover":7,"tags":2126,"categories":2127,"series":7,"seriesOrder":7,"pin":2079,"wip":2086,"theme":2085},"\u002Fposts\u002F2026\u002Fcodex-prompt-translation","posts\u002F2026\u002Fcodex-prompt-translation","Codex GPT-6 Sol 提示词完整中文译文","第三方仓库收录的 Codex GPT-6 Sol 提示词中文译文，按原顺序保留全部 54 个模板。",34261,[2115,2116,2117,2118],[2115],{"path":2129,"stem":2130,"title":2131,"description":2132,"wordCount":2133,"publish":2134,"update":2135,"cover":2136,"tags":2137,"categories":2140,"series":7,"seriesOrder":7,"pin":2079,"wip":2086,"theme":2085},"\u002Fposts\u002F2026\u002Fjev","posts\u002F2026\u002Fjev","JEV 是好模型吗？","本文评析JEV模型，认为其并非通用大模型，而是专做预定义判断的System One模型，通过选择、评分、是非题返回结构化结果，不生成文本。其快与便宜源于非自回归并行输出，但“零幻觉”仅指输出结构合规，判断仍可能出错。该思路适用于答案范围明确、需频繁调用的场景，也可用普通大模型近似实现，核心在于把任务收窄为单一判断。",2429,"2026-09-21","2026-09-23","\u002Fimages\u002F2026\u002Fjev\u002Fjev.webp",[2115,2138,2139],"JEV","LLM",[2115],{"path":2142,"stem":2143,"title":2144,"description":2145,"wordCount":2146,"publish":2147,"update":2148,"cover":7,"tags":2149,"categories":2154,"series":7,"seriesOrder":7,"pin":2079,"wip":2086,"theme":2085},"\u002Fposts\u002Fblog\u002Foverview","posts\u002F2.blog\u002F01.overview","新版博客已上线！","新版博客“mukuchi”上线，具备文章写作、标签分类、全文搜索、阅读目录、代码复制、图片缩放、深浅主题切换及移动端适配等功能。内容以Markdown和MDC编写，后台支持草稿、上传、预览与发布，并可生成AI摘要、朗读和双人播客。技术栈采用Nuxt、Vue、UnoCSS、Nuxt Content及Cloudflare服务，文章存于GitHub仓库。后续计划增加工具、重做账号系统并改为站内评论。",1059,"2026-09-14","2026-09-22",[2150,2151,2152,2153],"博客","Nuxt","Vue","Cloudflare",[2155],"建站记录",{"path":2157,"stem":2158,"title":2159,"description":2160,"wordCount":2161,"publish":2162,"update":7,"cover":7,"tags":2163,"categories":2167,"series":7,"seriesOrder":7,"pin":2079,"wip":2086,"theme":2085},"\u002Fposts\u002F2026\u002Fgame-dlss5","posts\u002F2026\u002Fgame-dlss5","哦，我的上帝！这是真实的！ —— DLSS 5 渲染实测","文章以《崩坏3rd》和《崩坏：星穹铁道》为例，展示DLSS 5渲染在多个场景下开启与关闭的画面对比。教程说明通过XXMI-Launcher注入ReShade的d3d12.dll，启动游戏后按Home键配置RenoDX DLSS参数，并提示下线前需手动关闭。文末附相关工具与网盘资源下载方式。",390,"2026-09-08",[2164,2165,2166],"DLSS5","mod","xxmi",[2168],"游戏",{"path":2170,"stem":2171,"title":2172,"description":2173,"wordCount":2174,"publish":2175,"update":2176,"cover":7,"tags":2177,"categories":2180,"series":7,"seriesOrder":7,"pin":2079,"wip":2086,"theme":2085},"\u002Fposts\u002F2026\u002Fmilanote-api","posts\u002F2026\u002Fmilanote-api","Milanote API","本文介绍了作者开发的 Milanote API 项目，用于在外部使用 Milanote 分享 Board 的内容。项目已完成根据分享链接获取完整 API 数据、解析卡片内容与布局、构建 Playground 在线可视化示例、部署至 Cloudflare Workers 并提供字段筛选功能；待实现免密钥在线解析。文章还说明了获取 Milanote 只读分享链接的步骤，并展示了 Playground 界面效果。",234,"2026-07-22","2026-07-23",[2178,2179],"Milanote","API",[2105],{"path":2182,"stem":2183,"title":2184,"description":2185,"wordCount":2186,"publish":2187,"update":7,"cover":2188,"tags":2189,"categories":2190,"series":7,"seriesOrder":7,"pin":2079,"wip":2086,"theme":2085},"\u002Fposts\u002F2026\u002Fduolingo","posts\u002F2026\u002Fduolingo","今天你 Duolingo 了吗？","本文介绍使用 Cloudflare Workers 构建 Duolingo 用户信息接口，解决跨域与缓存问题。接口支持按环境变量查询固定用户，返回昵称、头像、经验及连续学习天数，并提供搜索和其他用户详情接口。通过 KV 缓存和定时任务减少上游请求，支持带鉴权的手动刷新，并包含超时和错误处理。",1581,"2026-07-14","\u002Fimages\u002F2026\u002Fduolingo\u002Fduolingo.png",[2179,2153],[2105],{"path":2192,"stem":2193,"title":2194,"description":2195,"wordCount":2196,"publish":2197,"update":7,"cover":7,"tags":2198,"categories":2203,"series":7,"seriesOrder":7,"pin":2079,"wip":2086,"theme":2085},"\u002Fposts\u002Fblender","posts\u002Fblender\u002Findex","Blender 专题","本文介绍Blender这一免费开源3D建模软件，涵盖建模、动画、渲染、视频剪辑等功能，适合从入门到高级开发。文档提供官网地址；教程部分包含动画大师课VV purple、角色建模课Zimon3D，并附B站链接；素材推荐BlenderKit官方素材库、Sketchfab及模之屋等免费资源平台。",158,"2026-06-18",[2199,2200,2201,2202],"Blender","3D","建模","动画",[2199],{"path":2205,"stem":2206,"title":2207,"description":2208,"wordCount":2209,"publish":2197,"update":7,"cover":7,"tags":2210,"categories":2215,"series":7,"seriesOrder":7,"pin":2079,"wip":2086,"theme":2085},"\u002Fposts\u002Fthreejs","posts\u002Fthreejs\u002Findex","Three.js 专题","本文介绍Three.js作为Web端主流3D图形库，封装WebGL\u002FWebGPU，用于构建3D场景、动画、游戏和数据可视化等。文章汇总官方资源，包括官网、示例、文档、教程、在线编辑器和GitHub仓库。基础使用方面，说明在Vue3中通过TresJS、React中通过React Three Fiber进行组件化开发，并提及GSAP动画库和Blender建模软件。其他资源推荐Three.js Journey系统教程、The Book of Shaders书籍和Kenney免费游戏素材，AI与问题部分尚在完善中。",418,[2211,2212,2213,2214],"Three.js","WebGL","WebGPU","Shader",[2211],{"path":2078,"stem":2082,"title":5,"description":2075,"wordCount":2087,"publish":2080,"update":2080,"cover":2074,"tags":2217,"categories":2218,"series":7,"seriesOrder":7,"pin":2079,"wip":2086,"theme":2085},[2073],[2073],{"path":2220,"stem":2221,"title":2222,"description":2223,"wordCount":2224,"publish":2225,"update":2226,"cover":2227,"tags":2228,"categories":2230,"series":7,"seriesOrder":7,"pin":2079,"wip":2086,"theme":2085},"\u002Fposts\u002F2021\u002Fgit","posts\u002F2021\u002Fgit","Git 笔记","本文介绍Git的安装与基础配置，涵盖用户名邮箱设置及配置作用域优先级；解释工作区、暂存区和本地仓库的工作流；列举git add、commit、branch、switch、log、diff、stash、rm、mv等常用命令；说明查看日志、比较差异、对象关系、搁置改动、忽略文件等操作；并回答删除分支、修改提交信息、合并提交、取消暂存、丢弃改动和删除文件等常见问题。",878,"2021-09-07","2026-05-17","https:\u002F\u002Fgit-scm.com\u002Fimages\u002Flogo@2x.png",[2229],"Git",[2105],{"path":2232,"stem":2233,"title":2234,"description":2235,"wordCount":2236,"publish":2237,"update":7,"cover":2238,"tags":2239,"categories":2241,"series":7,"seriesOrder":7,"pin":2079,"wip":2086,"theme":2085},"\u002Fposts\u002F2021\u002Fhexo-editor","posts\u002F2021\u002Fhexo-editor","HexoEditor(适用于Hexo的专用编辑器)","本文介绍了专为Hexo优化的Markdown编辑器HexoEditor。该编辑器预览效果与Hexo生成页面高度相似，支持快速执行Hexo命令。软件开源，可从GitHub获取安装程序及中英文手册。配置包括通用、编辑、Hexo路径设置、渲染主题（支持GitHub和Next）以及图片云存储（如SM.MS、腾讯云等）。还提供右键快捷操作Hexo命令。",587,"2021-03-22","\u002Fimages\u002F2021\u002Fhexo-editor\u002Fhexo-editor.jpg",[2105,2240],"Hexo",[2105],{"path":2243,"stem":2244,"title":2245,"description":2246,"wordCount":2247,"publish":2237,"update":7,"cover":2248,"tags":2249,"categories":2253,"series":7,"seriesOrder":7,"pin":2079,"wip":2086,"theme":2085},"\u002Fposts\u002F2021\u002Ftomcat-servlet","posts\u002F2021\u002Ftomcat-servlet","Tomcat和Servlet应用配置及部分问题","本文介绍Tomcat与Servlet的配置及常见问题。Tomcat部分涵盖安装、环境变量、启动关闭、乱码与端口占用处理、项目部署及IDEA集成。Servlet部分说明实现方式、生命周期、请求与响应对象、乱码处理、请求转发与重定向，以及Cookie、Session、ServletContext等对象和三大域对象的作用范围。",4196,"\u002Fimages\u002F2021\u002Ftomcat-servlet\u002Ftomcat-servlet.jpg",[2250,2251,2252],"JavaWEb","Tomcat","Servlet",[2254],"笔记",{"path":2256,"stem":2257,"title":2258,"description":2259,"wordCount":2260,"publish":2261,"update":7,"cover":2262,"tags":2263,"categories":2265,"series":7,"seriesOrder":7,"pin":2079,"wip":2086,"theme":2085},"\u002Fposts\u002F2021\u002Fgithub-actions","posts\u002F2021\u002Fgithub-actions","使用Github Action实现全自动部署","本文介绍使用GitHub Action实现Hexo博客全自动部署的流程。需先获取GitHub与Coding的个人访问令牌，创建存放源码的私有仓库，并在站点配置中设置部署仓库地址和令牌。接着在.github\u002Fworkflows目录创建自动部署工作流文件，配置检出、安装Node与Hexo、缓存依赖、生成静态文件和部署步骤。随后更新远程仓库分支，添加.gitignore屏蔽项并推送源码，最后通过Actions查看部署状态。",910,"2021-01-26","\u002Fimages\u002F2021\u002Fgithub-actions\u002Fgithub-actions.jpg",[2264],"博客优化",[2264],{"path":2267,"stem":2268,"title":2269,"description":2270,"wordCount":2271,"publish":2261,"update":7,"cover":2272,"tags":2273,"categories":2274,"series":7,"seriesOrder":7,"pin":2079,"wip":2086,"theme":2085},"\u002Fposts\u002F2021\u002Fhexo-auto-open-editor","posts\u002F2021\u002Fhexo-auto-open-editor","Hexo添加文章时自动打开编辑器","本文介绍Hexo新建文章后自动打开编辑器的方法。通过监听Hexo的new事件并在scripts目录下添加脚本，利用child_process.exec执行系统命令，Windows使用start、macOS使用open -a启动指定编辑器并打开新文章路径。用户需替换脚本中的编辑器绝对地址，保存后执行hexo new即可自动打开对应文件。",269,"\u002Fimages\u002F2021\u002Fhexo-auto-open-editor\u002Fhexo-auto-open-editor.webp",[2264],[2264],{"path":2276,"stem":2277,"title":2278,"description":2279,"wordCount":2280,"publish":2281,"update":7,"cover":2282,"tags":2283,"categories":2288,"series":7,"seriesOrder":7,"pin":2079,"wip":2086,"theme":2085},"\u002Fposts\u002F2021\u002Fhttp-canary-ca","posts\u002F2021\u002Fhttp-canary-ca","解决部分安卓11HttpCanary无法安装证书及其他诸多问题","本文分享安卓11下HttpCanary证书安装失败等问题的解决方法，需root或虚拟机。MIUI系统点击安装根证书无反应时，将指定缓存路径的HttpCanary.pem复制为HttpCanary.jks并重启应用，再以root权限安装到系统；无效则先导出带.0证书再安装。抓https失败或提示证书不可信，可安装Xposed框架和JustTrustMe插件关闭SSL认证。资源可从酷安或应用商店获取，免费版与付费版主要区别为插件支持。",506,"2021-01-16","\u002Fimages\u002F2021\u002Fhttp-canary-ca\u002Fhttp-canary-ca.png",[2284,2285,2286,2287],"Android","HttpCanary","抓包","问题",[2286],{"path":2290,"stem":2291,"title":2292,"description":2293,"wordCount":2294,"publish":2295,"update":7,"cover":2296,"tags":2297,"categories":2300,"series":7,"seriesOrder":7,"pin":2079,"wip":2086,"theme":2085},"\u002Fposts\u002F2020\u002Fmysql-basics","posts\u002F2020\u002Fmysql-basics","MySQL 基础","本文介绍MySQL关系型数据库管理系统基础知识，包括数据库、数据库管理系统、数据库系统和数据库应用系统的概念，及其数据结构化、共享性高、冗余度低、独立性强和统一管理等特点；简述数据库的创建、查看、打开、修改和删除操作，以及数据表的创建、修改、删除和表数据的添加、更新、删除方法，并提及图形化管理工具。",1825,"2020-06-05","\u002Fimages\u002F2020\u002Fmysql-basics\u002Fmysql-basics.png",[2298,2299],"mysql","数据库",[2254],{"path":2302,"stem":2303,"title":2304,"description":2305,"wordCount":2306,"publish":2307,"update":7,"cover":2308,"tags":2309,"categories":2312,"series":7,"seriesOrder":7,"pin":2079,"wip":2086,"theme":2085},"\u002Fposts\u002F2020\u002Fpython-tkinter","posts\u002F2020\u002Fpython-tkinter","Python图形用户界面(Tkinter)","本文简介Python常用GUI库，重点说明Tkinter的标准控件、共同属性及pack、grid、place三种几何布局管理器。使用Tkinter需导入模块、创建控件、添加交互并编写函数、进入主事件循环。文中以简单登录界面为例，演示标签、输入框、按钮的放置，以及为按钮设置回调函数进行输入校验和登录提示。",965,"2020-05-25","\u002Fimages\u002F2020\u002Fpython-tkinter\u002Fpython-tkinter.jpg",[2310,2311],"Python","GUI",[2254],{"path":2314,"stem":2315,"title":2316,"description":2317,"wordCount":2318,"publish":2319,"update":2320,"cover":7,"tags":2321,"categories":2324,"series":2325,"seriesOrder":980,"pin":2079,"wip":2086,"theme":2085},"\u002Fposts\u002Fmarkdown\u002Fcollapse","posts\u002F1.markdown\u002F05.collapse","在正文中使用折叠内容","本文说明正文中折叠内容的使用方法：折叠块适合放置补充说明、较长代码或可选阅读内容，标题始终可见，点击整行展开，各折叠块独立记录状态。支持默认收起，也可通过 open 属性设置初始展开。折叠内部可包含 Markdown、列表、代码、表格、图片等，目录或锚点访问内部标题会先展开所属折叠块。还支持嵌套折叠，外层使用三个冒号、内层使用两个冒号，内外层独立控制；访问嵌套目标可一次展开沿途两层。",428,"1970-01-01","2026-09-26",[2322,2323],"Markdown","MDC",[2325],"文章示例",{"path":2327,"stem":2328,"title":2329,"description":2330,"wordCount":2331,"publish":2319,"update":2135,"cover":7,"tags":2332,"categories":2334,"series":2325,"seriesOrder":770,"pin":2079,"wip":2086,"theme":2085},"\u002Fposts\u002Fmarkdown\u002Fvideo","posts\u002F1.markdown\u002F04.video","在文章中嵌入视频","本文介绍在文章与关于页中嵌入Bilibili和YouTube视频的MDC组件用法，无需API密钥或手写iframe。播放器按16:9自适应宽度，接近可视区域时加载，默认不自动播放。Bilibili可通过BV号或视频链接指定分P与开始时间，YouTube可通过11位视频ID或链接指定开始时间，标题由title参数设置。组件会过滤分享追踪参数与自动播放设置，无效参数仅显示提示，不影响正文。",597,[2322,2323,2333],"视频",[2325],{"path":2336,"stem":2337,"title":2338,"description":2339,"wordCount":2340,"publish":2319,"update":2341,"cover":7,"tags":2342,"categories":2344,"series":2325,"seriesOrder":320,"pin":2079,"wip":6,"theme":2085},"\u002Fposts\u002Fmarkdown\u002Fmarkdown-extended","posts\u002F1.markdown\u002F03.markdown-extended","Markdown 扩展功能","本文介绍Markdown扩展功能。已实现多风格提醒框，支持GitHub、Obsidian、VitePress、Docusaurus四种主题及折叠嵌套，可通过参数或全站配置设置；同时提供GitHub仓库卡片、Bilibili\u002FYouTube视频卡片与正文图片预览。图片画廊与作品集仍在计划中，当前采用标准图片语法配合图注和链接。GitHub仓库卡片在构建时获取公开仓库数据快照，不可用字段显示短横线。后续将实现图片画廊与作品集。",1822,"2026-09-27",[2322,2323,2343],"功能规划",[2325],{"path":2346,"stem":2347,"title":2348,"description":2349,"wordCount":2350,"publish":2319,"update":2341,"cover":7,"tags":2351,"categories":2353,"series":2325,"seriesOrder":298,"pin":2079,"wip":2086,"theme":2085},"\u002Fposts\u002Fmarkdown\u002Fmdc-tutorial","posts\u002F1.markdown\u002F02.mdc-tutorial","MDC 教程","本文介绍 MDC（Markdown Components）在 Nuxt Content 中的语法与用法，涵盖块级容器、行内属性、Props 传递、插槽、嵌套、绑定文章数据，以及代码块与代码组、图片预览、GitHub 仓库卡片、视频卡片、提醒框和文章自动提醒等已接入功能。文末说明自定义组件需实现并注册，并解答组件不显示、插槽误识别等常见问题。",2594,[2323,2352,2152],"Nuxt Content",[2325],{"path":2355,"stem":2356,"title":2357,"description":2358,"wordCount":2359,"publish":2319,"update":2147,"cover":7,"tags":2360,"categories":2362,"series":2325,"seriesOrder":238,"pin":2079,"wip":2086,"theme":2085},"\u002Fposts\u002Fmarkdown\u002Fmarkdown","posts\u002F1.markdown\u002F01.markdown","Markdown 教程","本文为 Markdown 教程，系统介绍常用语法：段落与换行、标题与目录生成、引用、无序\u002F有序\u002F任务列表、强调与行内代码、普通\u002F引用式\u002F自动链接、图片、代码块、表格、分隔线与转义，并说明本站 Nuxt Content 环境下文章文件位置、frontmatter 要求及后续扩展内容。",1449,[2322,2361],"写作",[2325],1791108779463]