[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"knowledge-\u002Fapi\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fbase\u002Fvar":3,"knowledge-related-\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fbase\u002Fvar":1546,"knowledge-series-\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fbase\u002Fvar":1568},{"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":1542,"stem":1543,"id":1544,"extension":1545},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fbase\u002Fvar","全局对象与变量","Node.js 提供模块内可直接使用的全局对象；与浏览器 window 不同，模块顶层的 const\u002Flet 不会挂到 global。见 后端入门概览、模块系统。","技能小册",[12,13],"nodejs","var","2025-01-03",false,{"type":17,"value":18,"toc":1522},"minimark",[19,22,59,66,104,222,233,240,274,300,306,410,417,436,463,470,521,573,579,615,705,711,718,767,854,864,871,948,1115,1122,1193,1375,1391,1395,1456,1459,1462,1518],[20,21,8],"h1",{"id":8},[23,24,25,26,30,31,34,35,38,39,43,44,47,48,53,54,58],"p",{},"Node.js 提供模块内可直接使用的全局对象；与浏览器 ",[27,28,29],"code",{},"window"," 不同，模块顶层的 ",[27,32,33],{},"const","\u002F",[27,36,37],{},"let"," ",[40,41,42],"strong",{},"不会","挂到 ",[27,45,46],{},"global","。见 ",[49,50,52],"a",{"href":51},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fbasics","后端入门概览","、",[49,55,57],{"href":56},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fbase\u002Fmodule","模块系统","。",[60,61,63,64],"h3",{"id":62},"_1-global","1. ",[27,65,46],{},[67,68,69,82],"ul",{},[70,71,72,75,76,78,79,81],"li",{},[40,73,74],{},"作用","：全局命名空间对象，类似于浏览器中的 ",[27,77,29],{},"。在 Node.js 的 REPL 环境中或任意模块中，可以通过 ",[27,80,46],{}," 访问全局作用域。",[70,83,84,87,88,53,90,53,92,94,95,97,98,100,101,103],{},[40,85,86],{},"注意","：在模块文件中，",[27,89,13],{},[27,91,37],{},[27,93,33],{}," 声明的变量",[40,96,42],{},"成为 ",[27,99,46],{}," 的属性，只属于模块局部作用域。如果想定义真正的全局变量，需显式赋值给 ",[27,102,46],{},"（通常不推荐，避免命名冲突）。",[105,106,111],"pre",{"className":107,"code":108,"language":109,"meta":110,"style":110},"language-js shiki shiki-themes material-theme-lighter github-light github-dark","\u002F\u002F 不会挂载到 global\nvar a = 1;\nconsole.log(global.a); \u002F\u002F undefined\n\n\u002F\u002F 显式挂载\nglobal.b = 2;\nconsole.log(global.b); \u002F\u002F 2\n","js","",[27,112,113,122,144,171,178,184,201],{"__ignoreMap":110},[114,115,118],"span",{"class":116,"line":117},"line",1,[114,119,121],{"class":120},"sutJx","\u002F\u002F 不会挂载到 global\n",[114,123,125,128,132,136,140],{"class":116,"line":124},2,[114,126,13],{"class":127},"sbsja",[114,129,131],{"class":130},"su5hD"," a ",[114,133,135],{"class":134},"smGrS","=",[114,137,139],{"class":138},"srdBf"," 1",[114,141,143],{"class":142},"sP7_E",";\n",[114,145,147,150,153,157,160,162,165,168],{"class":116,"line":146},3,[114,148,149],{"class":130},"console",[114,151,152],{"class":142},".",[114,154,156],{"class":155},"sGLFI","log",[114,158,159],{"class":130},"(global",[114,161,152],{"class":142},[114,163,164],{"class":130},"a)",[114,166,167],{"class":142},";",[114,169,170],{"class":120}," \u002F\u002F undefined\n",[114,172,174],{"class":116,"line":173},4,[114,175,177],{"emptyLinePlaceholder":176},true,"\n",[114,179,181],{"class":116,"line":180},5,[114,182,183],{"class":120},"\u002F\u002F 显式挂载\n",[114,185,187,189,191,194,196,199],{"class":116,"line":186},6,[114,188,46],{"class":130},[114,190,152],{"class":142},[114,192,193],{"class":130},"b ",[114,195,135],{"class":134},[114,197,198],{"class":138}," 2",[114,200,143],{"class":142},[114,202,204,206,208,210,212,214,217,219],{"class":116,"line":203},7,[114,205,149],{"class":130},[114,207,152],{"class":142},[114,209,156],{"class":155},[114,211,159],{"class":130},[114,213,152],{"class":142},[114,215,216],{"class":130},"b)",[114,218,167],{"class":142},[114,220,221],{"class":120}," \u002F\u002F 2\n",[23,223,224,225,227,228,53,230,58],{},"Node.js 内置的一些全局 API 实际上是 ",[27,226,46],{}," 的属性，例如 ",[27,229,149],{},[27,231,232],{},"setTimeout",[60,234,236,237],{"id":235},"_2-__dirname","2. ",[27,238,239],{},"__dirname",[67,241,242,250],{},[70,243,244,246,247,58],{},[40,245,74],{},"：返回当前模块文件所在的",[40,248,249],{},"目录的绝对路径",[70,251,252,254,255,258,259,262,263,266,267,269,270,273],{},[40,253,86],{},"：在 ES 模块（使用 ",[27,256,257],{},".mjs"," 文件或 ",[27,260,261],{},"\"type\": \"module\""," 的 ",[27,264,265],{},".js"," 文件）中，",[27,268,239],{}," 不可用，需要通过 ",[27,271,272],{},"import.meta.url"," 手动构造。",[105,275,277],{"className":107,"code":276,"language":109,"meta":110,"style":110},"\u002F\u002F example.js 位于 \u002Fhome\u002Fuser\u002Fproject\u002Fsrc\nconsole.log(__dirname); \u002F\u002F 输出: \u002Fhome\u002Fuser\u002Fproject\u002Fsrc\n",[27,278,279,284],{"__ignoreMap":110},[114,280,281],{"class":116,"line":117},[114,282,283],{"class":120},"\u002F\u002F example.js 位于 \u002Fhome\u002Fuser\u002Fproject\u002Fsrc\n",[114,285,286,288,290,292,295,297],{"class":116,"line":124},[114,287,149],{"class":130},[114,289,152],{"class":142},[114,291,156],{"class":155},[114,293,294],{"class":130},"(__dirname)",[114,296,167],{"class":142},[114,298,299],{"class":120}," \u002F\u002F 输出: \u002Fhome\u002Fuser\u002Fproject\u002Fsrc\n",[23,301,302,305],{},[40,303,304],{},"ES 模块替代方案","：",[105,307,309],{"className":107,"code":308,"language":109,"meta":110,"style":110},"import { fileURLToPath } from \"url\";\nimport { dirname } from \"path\";\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n",[27,310,311,342,364,394],{"__ignoreMap":110},[114,312,313,317,320,323,326,329,333,337,340],{"class":116,"line":117},[114,314,316],{"class":315},"sVHd0","import",[114,318,319],{"class":142}," {",[114,321,322],{"class":130}," fileURLToPath",[114,324,325],{"class":142}," }",[114,327,328],{"class":315}," from",[114,330,332],{"class":331},"sjJ54"," \"",[114,334,336],{"class":335},"s_sjI","url",[114,338,339],{"class":331},"\"",[114,341,143],{"class":142},[114,343,344,346,348,351,353,355,357,360,362],{"class":116,"line":124},[114,345,316],{"class":315},[114,347,319],{"class":142},[114,349,350],{"class":130}," dirname",[114,352,325],{"class":142},[114,354,328],{"class":315},[114,356,332],{"class":331},[114,358,359],{"class":335},"path",[114,361,339],{"class":331},[114,363,143],{"class":142},[114,365,366,368,372,375,377,380,382,384,387,389,392],{"class":116,"line":146},[114,367,33],{"class":127},[114,369,371],{"class":370},"s_hVV"," __filename",[114,373,374],{"class":134}," =",[114,376,322],{"class":155},[114,378,379],{"class":130},"(",[114,381,316],{"class":315},[114,383,152],{"class":142},[114,385,386],{"class":370},"meta",[114,388,152],{"class":142},[114,390,391],{"class":130},"url)",[114,393,143],{"class":142},[114,395,396,398,401,403,405,408],{"class":116,"line":173},[114,397,33],{"class":127},[114,399,400],{"class":370}," __dirname",[114,402,374],{"class":134},[114,404,350],{"class":155},[114,406,407],{"class":130},"(__filename)",[114,409,143],{"class":142},[60,411,413,414],{"id":412},"_3-__filename","3. ",[27,415,416],{},"__filename",[67,418,419,428],{},[70,420,421,423,424,427],{},[40,422,74],{},"：返回当前模块文件的",[40,425,426],{},"绝对路径","（包含文件名和扩展名）。",[70,429,430,432,433,435],{},[40,431,86],{},"：同样，ES 模块中不可直接使用，需通过 ",[27,434,272],{}," 获取。",[105,437,439],{"className":107,"code":438,"language":109,"meta":110,"style":110},"\u002F\u002F \u002Fhome\u002Fuser\u002Fproject\u002Fsrc\u002Fexample.js\nconsole.log(__filename);\n\u002F\u002F 输出: \u002Fhome\u002Fuser\u002Fproject\u002Fsrc\u002Fexample.js\n",[27,440,441,446,458],{"__ignoreMap":110},[114,442,443],{"class":116,"line":117},[114,444,445],{"class":120},"\u002F\u002F \u002Fhome\u002Fuser\u002Fproject\u002Fsrc\u002Fexample.js\n",[114,447,448,450,452,454,456],{"class":116,"line":124},[114,449,149],{"class":130},[114,451,152],{"class":142},[114,453,156],{"class":155},[114,455,407],{"class":130},[114,457,143],{"class":142},[114,459,460],{"class":116,"line":146},[114,461,462],{"class":120},"\u002F\u002F 输出: \u002Fhome\u002Fuser\u002Fproject\u002Fsrc\u002Fexample.js\n",[60,464,466,467],{"id":465},"_4-module","4. ",[27,468,469],{},"module",[67,471,472,495],{},[70,473,474,476,477,479,480,53,483,53,485,53,488,53,491,494],{},[40,475,74],{},"：是一个指向当前模块的引用。每个 Node.js 文件都是一个模块，",[27,478,469],{}," 对象包含了该模块的元信息，如 ",[27,481,482],{},"id",[27,484,359],{},[27,486,487],{},"exports",[27,489,490],{},"parent",[27,492,493],{},"children"," 等。",[70,496,497,500,501],{},[40,498,499],{},"常见属性","：\n",[67,502,503,509,515],{},[70,504,505,508],{},[27,506,507],{},"module.exports","：模块导出的内容（核心）。",[70,510,511,514],{},[27,512,513],{},"module.id","：模块标识符，通常是文件路径。",[70,516,517,520],{},[27,518,519],{},"module.loaded","：模块是否加载完成。",[105,522,524],{"className":107,"code":523,"language":109,"meta":110,"style":110},"console.log(module.id); \u002F\u002F 模块的完整路径\nconsole.log(module.paths); \u002F\u002F 模块查找路径数组\n",[27,525,526,551],{"__ignoreMap":110},[114,527,528,530,532,534,536,539,541,543,546,548],{"class":116,"line":117},[114,529,149],{"class":130},[114,531,152],{"class":142},[114,533,156],{"class":155},[114,535,379],{"class":130},[114,537,469],{"class":538},"s39Yj",[114,540,152],{"class":142},[114,542,482],{"class":538},[114,544,545],{"class":130},")",[114,547,167],{"class":142},[114,549,550],{"class":120}," \u002F\u002F 模块的完整路径\n",[114,552,553,555,557,559,561,563,565,568,570],{"class":116,"line":124},[114,554,149],{"class":130},[114,556,152],{"class":142},[114,558,156],{"class":155},[114,560,379],{"class":130},[114,562,469],{"class":538},[114,564,152],{"class":142},[114,566,567],{"class":130},"paths)",[114,569,167],{"class":142},[114,571,572],{"class":120}," \u002F\u002F 模块查找路径数组\n",[60,574,576,577],{"id":575},"_5-exports","5. ",[27,578,487],{},[67,580,581,597],{},[70,582,583,305,585,587,588,590,591,594,595,58],{},[40,584,74],{},[27,586,487],{}," 是 ",[27,589,507],{}," 的一个",[40,592,593],{},"引用","。通过它可以方便地导出模块内容。最终暴露给外部的是 ",[27,596,507],{},[70,598,599,601,602,604,605,607,608,610,611,614],{},[40,600,86],{},"：直接对 ",[27,603,487],{}," 赋值会切断与 ",[27,606,507],{}," 的联系，使导出失效。必须始终通过 ",[27,609,507],{}," 或 ",[27,612,613],{},"exports.xxx"," 添加属性。",[105,616,618],{"className":107,"code":617,"language":109,"meta":110,"style":110},"\u002F\u002F 正确用法\nexports.foo = \"bar\";\nmodule.exports.baz = \"qux\";\n\n\u002F\u002F 错误用法（会丢失导出）\nexports = { foo: \"bar\" }; \u002F\u002F 此时 exports 不再指向 module.exports\n",[27,619,620,625,645,669,673,678],{"__ignoreMap":110},[114,621,622],{"class":116,"line":117},[114,623,624],{"class":120},"\u002F\u002F 正确用法\n",[114,626,627,629,631,634,636,638,641,643],{"class":116,"line":124},[114,628,487],{"class":538},[114,630,152],{"class":142},[114,632,633],{"class":130},"foo ",[114,635,135],{"class":134},[114,637,332],{"class":331},[114,639,640],{"class":335},"bar",[114,642,339],{"class":331},[114,644,143],{"class":142},[114,646,647,649,651,653,655,658,660,662,665,667],{"class":116,"line":146},[114,648,469],{"class":538},[114,650,152],{"class":142},[114,652,487],{"class":538},[114,654,152],{"class":142},[114,656,657],{"class":130},"baz ",[114,659,135],{"class":134},[114,661,332],{"class":331},[114,663,664],{"class":335},"qux",[114,666,339],{"class":331},[114,668,143],{"class":142},[114,670,671],{"class":116,"line":173},[114,672,177],{"emptyLinePlaceholder":176},[114,674,675],{"class":116,"line":180},[114,676,677],{"class":120},"\u002F\u002F 错误用法（会丢失导出）\n",[114,679,680,682,684,686,690,693,695,697,699,702],{"class":116,"line":186},[114,681,487],{"class":538},[114,683,374],{"class":134},[114,685,319],{"class":142},[114,687,689],{"class":688},"skxfh"," foo",[114,691,692],{"class":142},":",[114,694,332],{"class":331},[114,696,640],{"class":335},[114,698,339],{"class":331},[114,700,701],{"class":142}," };",[114,703,704],{"class":120}," \u002F\u002F 此时 exports 不再指向 module.exports\n",[23,706,707,708,58],{},"如果只需要导出一个函数或对象，推荐直接使用 ",[27,709,710],{},"module.exports = ...",[60,712,714,715],{"id":713},"_6-require","6. ",[27,716,717],{},"require",[67,719,720,725],{},[70,721,722,724],{},[40,723,74],{},"：用于加载其他模块的核心函数。参数可以是模块名、相对路径或绝对路径。",[70,726,727,500,730],{},[40,728,729],{},"机制",[67,731,732,744,747,760],{},[70,733,734,735,53,737,53,740,743],{},"支持加载 ",[27,736,265],{},[27,738,739],{},".json",[27,741,742],{},".node","（C++ 插件）文件。",[70,745,746],{},"加载 JSON 文件时会自动解析为对象。",[70,748,749,750,753,754,756,757,759],{},"具有",[40,751,752],{},"缓存","机制：多次 ",[27,755,717],{}," 同一个模块只会执行一次，返回相同的 ",[27,758,487],{}," 对象。",[70,761,762,763,766],{},"可以通过 ",[27,764,765],{},"require.resolve"," 获取模块的完整路径，而不实际加载模块。",[105,768,770],{"className":107,"code":769,"language":109,"meta":110,"style":110},"const fs = require(\"fs\"); \u002F\u002F 加载内置模块\nconst myModule = require(\".\u002Fmod\"); \u002F\u002F 加载本地模块（可省略 .js）\nconst data = require(\".\u002Fdata.json\"); \u002F\u002F 加载 JSON\n",[27,771,772,800,827],{"__ignoreMap":110},[114,773,774,776,779,781,784,786,788,791,793,795,797],{"class":116,"line":117},[114,775,33],{"class":127},[114,777,778],{"class":370}," fs",[114,780,374],{"class":134},[114,782,783],{"class":155}," require",[114,785,379],{"class":130},[114,787,339],{"class":331},[114,789,790],{"class":335},"fs",[114,792,339],{"class":331},[114,794,545],{"class":130},[114,796,167],{"class":142},[114,798,799],{"class":120}," \u002F\u002F 加载内置模块\n",[114,801,802,804,807,809,811,813,815,818,820,822,824],{"class":116,"line":124},[114,803,33],{"class":127},[114,805,806],{"class":370}," myModule",[114,808,374],{"class":134},[114,810,783],{"class":155},[114,812,379],{"class":130},[114,814,339],{"class":331},[114,816,817],{"class":335},".\u002Fmod",[114,819,339],{"class":331},[114,821,545],{"class":130},[114,823,167],{"class":142},[114,825,826],{"class":120}," \u002F\u002F 加载本地模块（可省略 .js）\n",[114,828,829,831,834,836,838,840,842,845,847,849,851],{"class":116,"line":146},[114,830,33],{"class":127},[114,832,833],{"class":370}," data",[114,835,374],{"class":134},[114,837,783],{"class":155},[114,839,379],{"class":130},[114,841,339],{"class":331},[114,843,844],{"class":335},".\u002Fdata.json",[114,846,339],{"class":331},[114,848,545],{"class":130},[114,850,167],{"class":142},[114,852,853],{"class":120}," \u002F\u002F 加载 JSON\n",[23,855,856,859,860,863],{},[40,857,858],{},"查找规则","：Node.js 会从当前文件目录开始，依次查找 ",[27,861,862],{},"node_modules"," 目录，直到文件系统根目录。",[60,865,867,868],{"id":866},"_7-process","7. ",[27,869,870],{},"process",[67,872,873,882],{},[70,874,875,877,878,881],{},[40,876,74],{},"：提供当前 Node.js 进程的信息和控制能力。它是 ",[27,879,880],{},"EventEmitter"," 的实例，可以监听进程事件。",[70,883,884,500,887],{},[40,885,886],{},"常用属性与方法",[67,888,889,895,901,907,913,919,929,942],{},[70,890,891,894],{},[27,892,893],{},"process.argv","：命令行参数数组。",[70,896,897,900],{},[27,898,899],{},"process.env","：环境变量对象。",[70,902,903,906],{},[27,904,905],{},"process.cwd()","：返回当前工作目录。",[70,908,909,912],{},[27,910,911],{},"process.exit(code)","：退出进程。",[70,914,915,918],{},[27,916,917],{},"process.on('uncaughtException', callback)","：捕获未处理的异常。",[70,920,921,924,925,928],{},[27,922,923],{},"process.nextTick(callback)","：将回调推迟到事件循环的下一个阶段执行（比 ",[27,926,927],{},"setImmediate"," 优先级高）。",[70,930,931,934,935,53,938,941],{},[27,932,933],{},"process.platform","：操作系统平台（如 ",[27,936,937],{},"'win32'",[27,939,940],{},"'linux'","）。",[70,943,944,947],{},[27,945,946],{},"process.version","：Node.js 版本号。",[105,949,951],{"className":107,"code":950,"language":109,"meta":110,"style":110},"\u002F\u002F 打印所有环境变量\nconsole.log(process.env);\n\n\u002F\u002F 监听退出事件\nprocess.on(\"exit\", code => {\n    console.log(`进程退出，退出码：${code}`);\n});\n\n\u002F\u002F 使用 nextTick\nprocess.nextTick(() => {\n    console.log(\"在事件循环当前阶段结束后执行\");\n});\n",[27,952,953,958,976,980,985,1016,1045,1054,1059,1065,1084,1106],{"__ignoreMap":110},[114,954,955],{"class":116,"line":117},[114,956,957],{"class":120},"\u002F\u002F 打印所有环境变量\n",[114,959,960,962,964,966,969,971,974],{"class":116,"line":124},[114,961,149],{"class":130},[114,963,152],{"class":142},[114,965,156],{"class":155},[114,967,968],{"class":130},"(process",[114,970,152],{"class":142},[114,972,973],{"class":130},"env)",[114,975,143],{"class":142},[114,977,978],{"class":116,"line":146},[114,979,177],{"emptyLinePlaceholder":176},[114,981,982],{"class":116,"line":173},[114,983,984],{"class":120},"\u002F\u002F 监听退出事件\n",[114,986,987,989,991,994,996,998,1001,1003,1006,1010,1013],{"class":116,"line":180},[114,988,870],{"class":130},[114,990,152],{"class":142},[114,992,993],{"class":155},"on",[114,995,379],{"class":130},[114,997,339],{"class":331},[114,999,1000],{"class":335},"exit",[114,1002,339],{"class":331},[114,1004,1005],{"class":142},",",[114,1007,1009],{"class":1008},"s99_P"," code",[114,1011,1012],{"class":127}," =>",[114,1014,1015],{"class":142}," {\n",[114,1017,1018,1021,1023,1025,1027,1030,1033,1036,1038,1041,1043],{"class":116,"line":186},[114,1019,1020],{"class":130},"    console",[114,1022,152],{"class":142},[114,1024,156],{"class":155},[114,1026,379],{"class":688},[114,1028,1029],{"class":331},"`",[114,1031,1032],{"class":335},"进程退出，退出码：",[114,1034,1035],{"class":331},"${",[114,1037,27],{"class":130},[114,1039,1040],{"class":331},"}`",[114,1042,545],{"class":688},[114,1044,143],{"class":142},[114,1046,1047,1050,1052],{"class":116,"line":203},[114,1048,1049],{"class":142},"}",[114,1051,545],{"class":130},[114,1053,143],{"class":142},[114,1055,1057],{"class":116,"line":1056},8,[114,1058,177],{"emptyLinePlaceholder":176},[114,1060,1062],{"class":116,"line":1061},9,[114,1063,1064],{"class":120},"\u002F\u002F 使用 nextTick\n",[114,1066,1068,1070,1072,1075,1077,1080,1082],{"class":116,"line":1067},10,[114,1069,870],{"class":130},[114,1071,152],{"class":142},[114,1073,1074],{"class":155},"nextTick",[114,1076,379],{"class":130},[114,1078,1079],{"class":142},"()",[114,1081,1012],{"class":127},[114,1083,1015],{"class":142},[114,1085,1087,1089,1091,1093,1095,1097,1100,1102,1104],{"class":116,"line":1086},11,[114,1088,1020],{"class":130},[114,1090,152],{"class":142},[114,1092,156],{"class":155},[114,1094,379],{"class":688},[114,1096,339],{"class":331},[114,1098,1099],{"class":335},"在事件循环当前阶段结束后执行",[114,1101,339],{"class":331},[114,1103,545],{"class":688},[114,1105,143],{"class":142},[114,1107,1109,1111,1113],{"class":116,"line":1108},12,[114,1110,1049],{"class":142},[114,1112,545],{"class":130},[114,1114,143],{"class":142},[60,1116,1118,1119],{"id":1117},"_8-buffer","8. ",[27,1120,1121],{},"Buffer",[67,1123,1124,1129,1155],{},[70,1125,1126,1128],{},[40,1127,74],{},"：用于处理二进制数据（如文件流、网络数据）。在 TCP 流或文件操作中，数据的传输通常以 Buffer 形式进行。",[70,1130,1131,500,1134],{},[40,1132,1133],{},"特点",[67,1135,1136,1141,1152],{},[70,1137,1138,1139,58],{},"Buffer 是 Node.js 全局类，无需 ",[27,1140,717],{},[70,1142,1143,1144,1147,1148,1151],{},"在 ES6 引入 ",[27,1145,1146],{},"TypedArray"," 之前，Buffer 是 Node.js 处理二进制的主要方式，现在它实现了 ",[27,1149,1150],{},"Uint8Array"," 接口。",[70,1153,1154],{},"Buffer 的大小在创建时就固定，无法动态调整。",[70,1156,1157,500,1160],{},[40,1158,1159],{},"常用方法",[67,1161,1162,1172,1178,1187],{},[70,1163,1164,1167,1168,1171],{},[27,1165,1166],{},"Buffer.from(array)"," \u002F ",[27,1169,1170],{},"Buffer.from(string)","：从数组或字符串创建 Buffer。",[70,1173,1174,1177],{},[27,1175,1176],{},"Buffer.alloc(size)","：创建指定大小的零填充 Buffer。",[70,1179,1180,1183,1184,941],{},[27,1181,1182],{},"buf.toString(encoding)","：将 Buffer 转换为字符串（默认 ",[27,1185,1186],{},"'utf8'",[70,1188,1189,1192],{},[27,1190,1191],{},"buf.length","：Buffer 的字节长度。",[105,1194,1196],{"className":107,"code":1195,"language":109,"meta":110,"style":110},"\u002F\u002F 创建 Buffer\nconst buf1 = Buffer.from(\"Hello\", \"utf8\");\nconsole.log(buf1); \u002F\u002F \u003CBuffer 48 65 6c 6c 6f>\n\nconst buf2 = Buffer.alloc(5); \u002F\u002F 长度为 5 的零填充 Buffer\nbuf2.write(\"Hi\"); \u002F\u002F 写入数据\n\n\u002F\u002F 合并两个 Buffer\nconst combined = Buffer.concat([buf1, buf2]);\nconsole.log(combined.toString()); \u002F\u002F \"HelloHi\"\n",[27,1197,1198,1203,1242,1258,1262,1290,1316,1320,1325,1351],{"__ignoreMap":110},[114,1199,1200],{"class":116,"line":117},[114,1201,1202],{"class":120},"\u002F\u002F 创建 Buffer\n",[114,1204,1205,1207,1210,1212,1215,1217,1220,1222,1224,1227,1229,1231,1233,1236,1238,1240],{"class":116,"line":124},[114,1206,33],{"class":127},[114,1208,1209],{"class":370}," buf1",[114,1211,374],{"class":134},[114,1213,1214],{"class":130}," Buffer",[114,1216,152],{"class":142},[114,1218,1219],{"class":155},"from",[114,1221,379],{"class":130},[114,1223,339],{"class":331},[114,1225,1226],{"class":335},"Hello",[114,1228,339],{"class":331},[114,1230,1005],{"class":142},[114,1232,332],{"class":331},[114,1234,1235],{"class":335},"utf8",[114,1237,339],{"class":331},[114,1239,545],{"class":130},[114,1241,143],{"class":142},[114,1243,1244,1246,1248,1250,1253,1255],{"class":116,"line":146},[114,1245,149],{"class":130},[114,1247,152],{"class":142},[114,1249,156],{"class":155},[114,1251,1252],{"class":130},"(buf1)",[114,1254,167],{"class":142},[114,1256,1257],{"class":120}," \u002F\u002F \u003CBuffer 48 65 6c 6c 6f>\n",[114,1259,1260],{"class":116,"line":173},[114,1261,177],{"emptyLinePlaceholder":176},[114,1263,1264,1266,1269,1271,1273,1275,1278,1280,1283,1285,1287],{"class":116,"line":180},[114,1265,33],{"class":127},[114,1267,1268],{"class":370}," buf2",[114,1270,374],{"class":134},[114,1272,1214],{"class":130},[114,1274,152],{"class":142},[114,1276,1277],{"class":155},"alloc",[114,1279,379],{"class":130},[114,1281,1282],{"class":138},"5",[114,1284,545],{"class":130},[114,1286,167],{"class":142},[114,1288,1289],{"class":120}," \u002F\u002F 长度为 5 的零填充 Buffer\n",[114,1291,1292,1295,1297,1300,1302,1304,1307,1309,1311,1313],{"class":116,"line":186},[114,1293,1294],{"class":130},"buf2",[114,1296,152],{"class":142},[114,1298,1299],{"class":155},"write",[114,1301,379],{"class":130},[114,1303,339],{"class":331},[114,1305,1306],{"class":335},"Hi",[114,1308,339],{"class":331},[114,1310,545],{"class":130},[114,1312,167],{"class":142},[114,1314,1315],{"class":120}," \u002F\u002F 写入数据\n",[114,1317,1318],{"class":116,"line":203},[114,1319,177],{"emptyLinePlaceholder":176},[114,1321,1322],{"class":116,"line":1056},[114,1323,1324],{"class":120},"\u002F\u002F 合并两个 Buffer\n",[114,1326,1327,1329,1332,1334,1336,1338,1341,1344,1346,1349],{"class":116,"line":1061},[114,1328,33],{"class":127},[114,1330,1331],{"class":370}," combined",[114,1333,374],{"class":134},[114,1335,1214],{"class":130},[114,1337,152],{"class":142},[114,1339,1340],{"class":155},"concat",[114,1342,1343],{"class":130},"([buf1",[114,1345,1005],{"class":142},[114,1347,1348],{"class":130}," buf2])",[114,1350,143],{"class":142},[114,1352,1353,1355,1357,1359,1362,1364,1367,1370,1372],{"class":116,"line":1067},[114,1354,149],{"class":130},[114,1356,152],{"class":142},[114,1358,156],{"class":155},[114,1360,1361],{"class":130},"(combined",[114,1363,152],{"class":142},[114,1365,1366],{"class":155},"toString",[114,1368,1369],{"class":130},"())",[114,1371,167],{"class":142},[114,1373,1374],{"class":120}," \u002F\u002F \"HelloHi\"\n",[23,1376,1377,1379,1380,1383,1384,1386,1387,1390],{},[40,1378,86],{},"：Node.js 中很多 API 既接受 ",[27,1381,1382],{},"string"," 也接受 ",[27,1385,1121],{},"，例如 ",[27,1388,1389],{},"fs.readFile"," 可以返回 Buffer。",[1392,1393,1394],"h2",{"id":1394},"相互关系与注意事项",[67,1396,1397,1415,1423,1433],{},[70,1398,1399,1406,1407,1409,1410,1412,1413,58],{},[40,1400,1401,1403,1404],{},[27,1402,487],{}," vs ",[27,1405,507],{},"：初始化时 ",[27,1408,487],{}," 和 ",[27,1411,507],{}," 指向同一个对象。若只添加属性，两者皆可；若要导出对象本身，必须用 ",[27,1414,507],{},[70,1416,1417,1422],{},[40,1418,1419,1421],{},[27,1420,717],{}," 的缓存","：模块首次加载后会被缓存，因此模块内的全局变量不会重复初始化，但也意味着需要小心模块状态的共享。",[70,1424,1425,1432],{},[40,1426,1427,1429,1430],{},[27,1428,239],{}," 与 ",[27,1431,416],{},"：在 CommonJS 模块中可用，在 ES 模块中需自行构造。",[70,1434,1435,1440,1441,1409,1443,1446,1447,1449,1450,1452,1453,1455],{},[40,1436,1437],{},[27,1438,1439],{},"process.nextTick","：它在当前事件循环阶段结束时立即执行，优先级高于 ",[27,1442,927],{},[27,1444,1445],{},"Promise"," 微任务，但 ",[27,1448,1445],{}," 的微任务会在 ",[27,1451,1074],{}," 之前执行（取决于 Node.js 版本，实际顺序：",[27,1454,1074],{}," 队列 > 微任务队列 > 其他阶段）。",[1392,1457,1458],{"id":1458},"参考文献",[23,1460,1461],{},"以下链接在编写时均可正常访问：",[1463,1464,1465,1478],"table",{},[1466,1467,1468],"thead",{},[1469,1470,1471,1475],"tr",{},[1472,1473,1474],"th",{},"资料",[1472,1476,1477],{},"说明",[1479,1480,1481,1495,1506],"tbody",{},[1469,1482,1483,1492],{},[1484,1485,1486],"td",{},[49,1487,1491],{"href":1488,"rel":1489},"https:\u002F\u002Fnodejs.org\u002Fapi\u002Fglobals.html",[1490],"nofollow","Globals",[1484,1493,1494],{},"官方",[1469,1496,1497,1503],{},[1484,1498,1499],{},[49,1500,870],{"href":1501,"rel":1502},"https:\u002F\u002Fnodejs.org\u002Fapi\u002Fprocess.html",[1490],[1484,1504,1505],{},"进程对象",[1469,1507,1508,1515],{},[1484,1509,1510],{},[49,1511,1514],{"href":1512,"rel":1513},"https:\u002F\u002Fnodejs.org\u002Fapi\u002Fmodules.html",[1490],"Modules",[1484,1516,1517],{},"CommonJS",[1519,1520,1521],"style",{},"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 pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}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 .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}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 .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 .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}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}",{"title":110,"searchDepth":124,"depth":124,"links":1523},[1524,1526,1528,1530,1532,1534,1536,1538,1540,1541],{"id":62,"depth":146,"text":1525},"1. global",{"id":235,"depth":146,"text":1527},"2. __dirname",{"id":412,"depth":146,"text":1529},"3. __filename",{"id":465,"depth":146,"text":1531},"4. module",{"id":575,"depth":146,"text":1533},"5. exports",{"id":713,"depth":146,"text":1535},"6. require",{"id":866,"depth":146,"text":1537},"7. process",{"id":1117,"depth":146,"text":1539},"8. Buffer",{"id":1394,"depth":124,"text":1394},{"id":1458,"depth":124,"text":1458},{"title":8,"description":9},"knowledge\u002Fbooklet\u002Fend\u002FNodeJs\u002Fbase\u002Fvar","knowledge\u002Fknowledge\u002Fbooklet\u002Fend\u002FNodeJs\u002Fbase\u002Fvar.md","md",{"items":1547},[1548,1552,1554,1558,1560,1564],{"path":1549,"title":1550,"description":1551,"category":10,"score":186},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fbase\u002Fevent-loop","事件循环","Node.js 的事件循环是其实现非阻塞 I\u002FO 的核心机制。它基于 libuv 库，将各种异步操作（定时器、I\u002FO、setImmediate 等）组织成不同的阶段，每个阶段都有一个先进先出的回调队列。事件循环会按照固定的顺序反复执行…",{"path":56,"title":57,"description":1553,"category":10,"score":186},"Node.js 的模块系统是其核心设计之一，它允许开发者将代码拆分为多个文件（模块），通过 require（CommonJS）或 import\u002Fexport（ESM）进行组织和复用。下面详细介绍 CommonJS、ESM 以及两者的互操作。",{"path":1555,"title":1556,"description":1557,"category":10,"score":186},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fbase\u002Fevent","事件驱动与非阻塞 I\u002FO 模型","Node.js 的底层架构核心是事件驱动与非阻塞 I\u002FO：以 V8 引擎执行 JavaScript、libuv 库处理底层 I\u002FO 与事件循环。涵盖 libuv 线程池、事件循环各阶段、EventEmitter 实践、最佳实践与常见坑。",{"path":51,"title":52,"description":1559,"category":10,"score":173},"本目录覆盖 JavaScript\u002FTypeScript 服务端运行时与框架、数据存储，以及 Rust 系统编程入门，提供从零到部署的完整学习路径。前置建议：JavaScript 基础、工程化 · 环境变量。",{"path":1561,"title":1562,"description":1563,"category":10,"score":173},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Ffs","文件系统","Node.js 的 fs 模块提供了与文件系统交互的 API，几乎涵盖了所有标准文件操作。它支持三种风格的 API：同步、回调式异步 和 Promise 式异步。下面详细介绍这些 API 的选择策略、流式读写、文件监视以及常用操作。",{"path":1565,"title":1566,"description":1567,"category":10,"score":173},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fasync","异步编程与模式","Node.js 的核心优势在于异步非阻塞 I\u002FO，但这也带来了回调地狱、错误处理复杂等问题。下面从解救方案、工具函数、并发控制、异步迭代以及常见反模式等角度展开。",{"series":1569,"title":1570,"items":1571,"index":146,"prev":1579,"next":1580},"booklet\u002Fend\u002Fnodejs\u002Fbase","base",[1572,1574,1576,1578],{"path":1555,"title":1556,"date":1573,"pinned":15},"2020-06-20",{"path":1549,"title":1550,"date":1575,"pinned":15},"2024-11-20",{"path":56,"title":57,"date":1577,"pinned":15},"2020-07-01",{"path":7,"title":8,"date":14,"pinned":15},{"path":56,"title":57,"date":1577,"pinned":15},null]