cainiaoblog 23.2.171

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (401) hide show
  1. package/CNAME +1 -0
  2. package/MP_verify_o6dHCK5mIkxNpzvZ.txt +1 -0
  3. package/README.md +8 -0
  4. package/about/index.html +54 -0
  5. package/ads.txt +1 -0
  6. package/app/manual.html +104 -0
  7. package/appConfigs/config +1 -0
  8. package/archives/2018/index.html +48 -0
  9. package/archives/2019/index.html +48 -0
  10. package/archives/2019/page/2/index.html +48 -0
  11. package/archives/2020/index.html +48 -0
  12. package/archives/2021/index.html +48 -0
  13. package/archives/2022/index.html +48 -0
  14. package/archives/2023/index.html +48 -0
  15. package/archives/index.html +48 -0
  16. package/archives/page/2/index.html +48 -0
  17. package/archives/page/3/index.html +48 -0
  18. package/article/10047.html +148 -0
  19. package/article/10164.html +64 -0
  20. package/article/10624.html +436 -0
  21. package/article/10745.html +586 -0
  22. package/article/11674.html +71 -0
  23. package/article/11939.html +72 -0
  24. package/article/12238.html +86 -0
  25. package/article/1230.html +533 -0
  26. package/article/13265.html +69 -0
  27. package/article/13823.html +78 -0
  28. package/article/14125.html +72 -0
  29. package/article/14192.html +561 -0
  30. package/article/14375.html +85 -0
  31. package/article/14744.html +83 -0
  32. package/article/14936.html +451 -0
  33. package/article/1518.html +250 -0
  34. package/article/15428.html +71 -0
  35. package/article/15518.html +288 -0
  36. package/article/15569.html +418 -0
  37. package/article/1566.html +122 -0
  38. package/article/16017.html +156 -0
  39. package/article/16947.html +440 -0
  40. package/article/17096.html +82 -0
  41. package/article/17246.html +89 -0
  42. package/article/17575.html +350 -0
  43. package/article/179.html +757 -0
  44. package/article/18039.html +233 -0
  45. package/article/18071.html +375 -0
  46. package/article/18142.html +71 -0
  47. package/article/19909.html +160 -0
  48. package/article/20014.html +89 -0
  49. package/article/20021.html +389 -0
  50. package/article/20037.html +280 -0
  51. package/article/20056.html +95 -0
  52. package/article/20093.html +404 -0
  53. package/article/2021.html +607 -0
  54. package/article/20459.html +115 -0
  55. package/article/20613.html +263 -0
  56. package/article/20635.html +71 -0
  57. package/article/21317.html +71 -0
  58. package/article/21320.html +90 -0
  59. package/article/21782.html +548 -0
  60. package/article/22230.html +435 -0
  61. package/article/22237.html +347 -0
  62. package/article/22398.html +109 -0
  63. package/article/22422.html +270 -0
  64. package/article/22565.html +300 -0
  65. package/article/23046.html +250 -0
  66. package/article/23083.html +215 -0
  67. package/article/23195.html +297 -0
  68. package/article/23301.html +835 -0
  69. package/article/23589.html +285 -0
  70. package/article/23655.html +338 -0
  71. package/article/23864.html +76 -0
  72. package/article/23914.html +96 -0
  73. package/article/24169.html +135 -0
  74. package/article/24581.html +349 -0
  75. package/article/2475.html +500 -0
  76. package/article/24826.html +77 -0
  77. package/article/24924.html +247 -0
  78. package/article/25164.html +1495 -0
  79. package/article/25318.html +394 -0
  80. package/article/25710.html +1129 -0
  81. package/article/25734.html +83 -0
  82. package/article/26083.html +174 -0
  83. package/article/26147.html +283 -0
  84. package/article/26291.html +110 -0
  85. package/article/26354.html +71 -0
  86. package/article/26624.html +145 -0
  87. package/article/26639.html +298 -0
  88. package/article/26850.html +138 -0
  89. package/article/26940.html +258 -0
  90. package/article/27796.html +190 -0
  91. package/article/27800.html +161 -0
  92. package/article/28963.html +159 -0
  93. package/article/28976.html +247 -0
  94. package/article/29042.html +72 -0
  95. package/article/29596.html +81 -0
  96. package/article/29619.html +183 -0
  97. package/article/29623.html +329 -0
  98. package/article/29829.html +205 -0
  99. package/article/29abbd1c.html +112 -0
  100. package/article/30215.html +178 -0
  101. package/article/30552.html +78 -0
  102. package/article/30818.html +201 -0
  103. package/article/31330.html +364 -0
  104. package/article/3154.html +577 -0
  105. package/article/31695.html +348 -0
  106. package/article/31826.html +71 -0
  107. package/article/31843.html +132 -0
  108. package/article/32280.html +212 -0
  109. package/article/32431.html +74 -0
  110. package/article/32443.html +72 -0
  111. package/article/32732.html +122 -0
  112. package/article/3286.html +251 -0
  113. package/article/32960.html +198 -0
  114. package/article/33713.html +72 -0
  115. package/article/33899.html +615 -0
  116. package/article/34351.html +74 -0
  117. package/article/34372.html +89 -0
  118. package/article/34410.html +74 -0
  119. package/article/34431.html +118 -0
  120. package/article/3447.html +75 -0
  121. package/article/34474.html +142 -0
  122. package/article/34871.html +147 -0
  123. package/article/35397.html +175 -0
  124. package/article/3544.html +199 -0
  125. package/article/35503.html +115 -0
  126. package/article/35624.html +84 -0
  127. package/article/35697.html +384 -0
  128. package/article/35863.html +73 -0
  129. package/article/36037.html +253 -0
  130. package/article/36118.html +71 -0
  131. package/article/3621.html +119 -0
  132. package/article/36251.html +296 -0
  133. package/article/36642.html +352 -0
  134. package/article/37102.html +763 -0
  135. package/article/37336.html +351 -0
  136. package/article/37351.html +89 -0
  137. package/article/3760.html +294 -0
  138. package/article/37749.html +75 -0
  139. package/article/37789.html +83 -0
  140. package/article/38005.html +765 -0
  141. package/article/38009.html +284 -0
  142. package/article/38269.html +194 -0
  143. package/article/38344.html +88 -0
  144. package/article/38359.html +334 -0
  145. package/article/38423.html +379 -0
  146. package/article/38530.html +213 -0
  147. package/article/38743.html +268 -0
  148. package/article/38753.html +204 -0
  149. package/article/38881.html +71 -0
  150. package/article/39087.html +414 -0
  151. package/article/39309.html +84 -0
  152. package/article/39486.html +74 -0
  153. package/article/39637.html +306 -0
  154. package/article/39839.html +72 -0
  155. package/article/39937.html +152 -0
  156. package/article/39970.html +71 -0
  157. package/article/402.html +559 -0
  158. package/article/40698.html +71 -0
  159. package/article/40811.html +71 -0
  160. package/article/40964.html +462 -0
  161. package/article/41011.html +322 -0
  162. package/article/41152.html +78 -0
  163. package/article/41696.html +71 -0
  164. package/article/41717.html +281 -0
  165. package/article/41777.html +149 -0
  166. package/article/419.html +985 -0
  167. package/article/4233.html +136 -0
  168. package/article/4292.html +86 -0
  169. package/article/43302.html +96 -0
  170. package/article/43397.html +106 -0
  171. package/article/43724.html +281 -0
  172. package/article/43999.html +224 -0
  173. package/article/44426.html +77 -0
  174. package/article/44964.html +137 -0
  175. package/article/45004.html +123 -0
  176. package/article/4510.html +83 -0
  177. package/article/45156.html +320 -0
  178. package/article/45157.html +52 -0
  179. package/article/45267.html +87 -0
  180. package/article/45641.html +207 -0
  181. package/article/45960.html +75 -0
  182. package/article/46100.html +1262 -0
  183. package/article/46366.html +74 -0
  184. package/article/46771.html +96 -0
  185. package/article/46911.html +517 -0
  186. package/article/46948.html +137 -0
  187. package/article/46ee4850.html +349 -0
  188. package/article/47019.html +84 -0
  189. package/article/47532.html +94 -0
  190. package/article/4783.html +429 -0
  191. package/article/47972.html +72 -0
  192. package/article/48216.html +127 -0
  193. package/article/48252.html +185 -0
  194. package/article/48520.html +74 -0
  195. package/article/48722.html +75 -0
  196. package/article/48807.html +99 -0
  197. package/article/49126.html +323 -0
  198. package/article/50001.html +88 -0
  199. package/article/50058.html +151 -0
  200. package/article/50343.html +410 -0
  201. package/article/50510.html +82 -0
  202. package/article/51082.html +98 -0
  203. package/article/51677.html +111 -0
  204. package/article/5204.html +1085 -0
  205. package/article/52500.html +538 -0
  206. package/article/52689.html +259 -0
  207. package/article/52877.html +569 -0
  208. package/article/53125.html +191 -0
  209. package/article/53428.html +251 -0
  210. package/article/53524.html +74 -0
  211. package/article/53698.html +322 -0
  212. package/article/53803e6.html +93 -0
  213. package/article/53924.html +291 -0
  214. package/article/53962.html +253 -0
  215. package/article/54006.html +71 -0
  216. package/article/54018.html +88 -0
  217. package/article/54161.html +83 -0
  218. package/article/54178.html +69 -0
  219. package/article/54258.html +327 -0
  220. package/article/54295.html +214 -0
  221. package/article/54313.html +1976 -0
  222. package/article/54351.html +90 -0
  223. package/article/54604.html +80 -0
  224. package/article/54632.html +71 -0
  225. package/article/54912.html +756 -0
  226. package/article/54918.html +129 -0
  227. package/article/55119.html +136 -0
  228. package/article/55756.html +118 -0
  229. package/article/55769.html +136 -0
  230. package/article/55870.html +161 -0
  231. package/article/56139.html +92 -0
  232. package/article/56557.html +69 -0
  233. package/article/56604.html +69 -0
  234. package/article/56816.html +266 -0
  235. package/article/56926.html +153 -0
  236. package/article/57747.html +409 -0
  237. package/article/57965.html +475 -0
  238. package/article/58816.html +78 -0
  239. package/article/59059.html +435 -0
  240. package/article/59095.html +350 -0
  241. package/article/59349.html +244 -0
  242. package/article/59402.html +216 -0
  243. package/article/59448.html +55 -0
  244. package/article/59870.html +94 -0
  245. package/article/59877.html +208 -0
  246. package/article/5dbb6f41.html +86 -0
  247. package/article/6008.html +75 -0
  248. package/article/60327.html +126 -0
  249. package/article/6035.html +76 -0
  250. package/article/60428.html +71 -0
  251. package/article/60544.html +128 -0
  252. package/article/61319.html +95 -0
  253. package/article/61367.html +93 -0
  254. package/article/624d1918.html +292 -0
  255. package/article/62543.html +71 -0
  256. package/article/62887.html +169 -0
  257. package/article/63074.html +120 -0
  258. package/article/63266.html +311 -0
  259. package/article/63351.html +74 -0
  260. package/article/63542.html +104 -0
  261. package/article/63824.html +275 -0
  262. package/article/64051.html +653 -0
  263. package/article/64189b69.html +72 -0
  264. package/article/64354.html +75 -0
  265. package/article/64869.html +79 -0
  266. package/article/64923.html +596 -0
  267. package/article/65128.html +95 -0
  268. package/article/65295.html +79 -0
  269. package/article/6888.html +75 -0
  270. package/article/7065.html +84 -0
  271. package/article/7455.html +85 -0
  272. package/article/7a3ef8f.html +315 -0
  273. package/article/8140.html +188 -0
  274. package/article/8190.html +85 -0
  275. package/article/8225.html +78 -0
  276. package/article/84c9ccd6.html +159 -0
  277. package/article/8f9a9ae3.html +82 -0
  278. package/article/9174.html +73 -0
  279. package/article/9738.html +294 -0
  280. package/article/a4145266.html +71 -0
  281. package/article/bedea419.html +72 -0
  282. package/article/bf7e7421.html +78 -0
  283. package/article/c1867fbf.html +103 -0
  284. package/article/c5576490.html +70 -0
  285. package/article/dcb0db28.html +76 -0
  286. package/article/fc3b727a.html +79 -0
  287. package/atom.xml +445 -0
  288. package/baidusitemap.xml +1079 -0
  289. package/blocks/dns.txt +264 -0
  290. package/blocks/filter.txt +1070 -0
  291. package/blocks/script.js +42 -0
  292. package/categories/CDN/index.html +48 -0
  293. package/categories/IDE/index.html +48 -0
  294. package/categories/git/index.html +48 -0
  295. package/categories/hexo/index.html +48 -0
  296. package/categories//345/205/254/345/205/261/350/212/202/346/227/245/index.html +48 -0
  297. package/categories//345/210/206/344/272/253/index.html +48 -0
  298. package/categories//345/211/215/347/253/257/index.html +48 -0
  299. package/categories//345/211/215/347/253/257/page/2/index.html +48 -0
  300. package/categories//345/211/215/347/253/257//346/265/217/350/247/210/345/231/250/index.html +48 -0
  301. package/categories//345/211/215/347/253/257//346/265/217/350/247/210/345/231/250//347/275/221/347/273/234/345/215/217/350/256/256/index.html +48 -0
  302. package/categories//345/215/232/345/256/242/index.html +48 -0
  303. package/categories//345/267/245/345/205/267/index.html +48 -0
  304. package/categories//345/271/277/345/221/212/350/277/207/346/273/244/index.html +48 -0
  305. package/categories//345/271/277/345/221/212/350/277/207/346/273/244//350/247/206/351/242/221/347/224/265/350/247/206/345/260/217/350/257/264/346/274/253/347/224/273/350/265/204/350/256/257/351/237/263/344/271/220/index.html +48 -0
  306. package/categories//346/255/243/345/210/231/index.html +48 -0
  307. package/categories//346/265/217/350/247/210/345/231/250/index.html +48 -0
  308. package/categories//347/256/227/346/263/225/index.html +48 -0
  309. package/categories//350/265/204/350/256/257/index.html +48 -0
  310. package/categories//350/275/273/346/235/276/344/270/200/345/210/273/index.html +48 -0
  311. package/cdn/css/font-awesome.min.css +4 -0
  312. package/cdn/css/grids-responsive-min.css +7 -0
  313. package/cdn/css/normalize.css +349 -0
  314. package/cdn/css/pure-min.css +11 -0
  315. package/cdn/fonts/fontawesome-webfont.eot +0 -0
  316. package/cdn/fonts/fontawesome-webfont.svg +2671 -0
  317. package/cdn/fonts/fontawesome-webfont.ttf +0 -0
  318. package/cdn/fonts/fontawesome-webfont.woff +0 -0
  319. package/cdn/fonts/fontawesome-webfont.woff2 +0 -0
  320. package/cdn/js/Valine.min.js +17 -0
  321. package/cdn/js/canvas-nest.js +1 -0
  322. package/cdn/js/clipboard.min.js +7 -0
  323. package/cdn/js/crypto-js.js +25 -0
  324. package/cdn/js/jquery.min.js +2 -0
  325. package/css/default.css +1144 -0
  326. package/css/donate.css +338 -0
  327. package/css/hbe.style.css +749 -0
  328. package/css/style.css +2095 -0
  329. package/donate/index.html +39 -0
  330. package/google917dcf72f6e5c7f5.html +1 -0
  331. package/guestbook/index.html +68 -0
  332. package/hosts/ads.txt +149 -0
  333. package/hosts/flash.txt +9 -0
  334. package/hosts/github.txt +6 -0
  335. package/hosts/google.txt +16936 -0
  336. package/hosts/winrar.txt +2 -0
  337. package/img/alipay.svg +46 -0
  338. package/img/bitcoin.svg +135 -0
  339. package/img/blog.ico +0 -0
  340. package/img/blog.png +0 -0
  341. package/img/gaba.png +0 -0
  342. package/img/github.svg +1 -0
  343. package/img/like.svg +1 -0
  344. package/img/mp-mini.jpg +0 -0
  345. package/img/mp.png +0 -0
  346. package/img/paypal.svg +63 -0
  347. package/img/upy_logo.svg +59 -0
  348. package/img/wechat.svg +49 -0
  349. package/index.html +48 -0
  350. package/jd_root.txt +1 -0
  351. package/js/codeblock-resizer.js +51 -0
  352. package/js/dark.js +12 -0
  353. package/js/donate.js +87 -0
  354. package/js/fixedPage.js +106 -0
  355. package/js/gitment.browser.js +3751 -0
  356. package/js/search.js +86 -0
  357. package/js/share.js +60 -0
  358. package/js/smartresize.js +32 -0
  359. package/js/totop.js +12 -0
  360. package/kankan/index.html +77 -0
  361. package/lib/hbe.js +293 -0
  362. package/package.json +25 -0
  363. package/page/10/index.html +49 -0
  364. package/page/11/index.html +59 -0
  365. package/page/12/index.html +67 -0
  366. package/page/13/index.html +63 -0
  367. package/page/14/index.html +66 -0
  368. package/page/15/index.html +60 -0
  369. package/page/16/index.html +60 -0
  370. package/page/17/index.html +62 -0
  371. package/page/18/index.html +61 -0
  372. package/page/19/index.html +58 -0
  373. package/page/2/index.html +48 -0
  374. package/page/20/index.html +57 -0
  375. package/page/21/index.html +61 -0
  376. package/page/22/index.html +55 -0
  377. package/page/23/index.html +64 -0
  378. package/page/24/index.html +60 -0
  379. package/page/25/index.html +58 -0
  380. package/page/26/index.html +48 -0
  381. package/page/27/index.html +58 -0
  382. package/page/3/index.html +48 -0
  383. package/page/4/index.html +48 -0
  384. package/page/5/index.html +51 -0
  385. package/page/6/index.html +51 -0
  386. package/page/7/index.html +51 -0
  387. package/page/8/index.html +53 -0
  388. package/page/9/index.html +48 -0
  389. package/randomcall/README.html +1 -0
  390. package/randomcall/lucker.html +290 -0
  391. package/randomcall/lucky.png +0 -0
  392. package/robots.txt +22 -0
  393. package/search.xml +6740 -0
  394. package/sitemap.xml +2669 -0
  395. package/tags//345/216/237/345/210/233/index.html +48 -0
  396. package/tags//345/250/261/344/271/220/index.html +48 -0
  397. package/tags//346/211/213/345/206/231/index.html +48 -0
  398. package/tags//347/226/253/346/203/205/index.html +48 -0
  399. package/tags//350/275/254/350/275/275/index.html +48 -0
  400. package/tags//350/275/254/350/275/275/page/2/index.html +48 -0
  401. package/v.html +90 -0
@@ -0,0 +1,315 @@
1
+ <!DOCTYPE html><html lang="zh-CN" data-dark><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport"><meta content="yes" name="apple-mobile-web-app-capable"><meta content="black-translucent" name="apple-mobile-web-app-status-bar-style"><meta content="telephone=no" name="format-detection"><meta name="description" content="前端壹菜鸟,记录工作难题,关注前端知识,收集精彩博文,做技术的搬运工"><meta name="msvalidate.01" content="0FE4D8B3381D3D87088996B886E1E2BD"><title>即将到来的es2022新特性 | 前端壹菜鸟</title><link rel="stylesheet" type="text/css" href="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/css/style.min.css"><link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/normalize.css@latest/normalize.min.css"><link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/purecss@latest/build/pure-min.min.css"><link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/purecss@latest/build/grids-responsive-min.css"><link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css"><link rel="icon" mask="" sizes="any" href="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/img/blog.ico"><link rel="Shortcut Icon" type="image/x-icon" href="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/img/blog.ico"><link rel="apple-touch-icon" href="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/img/blog.png"><link rel="apple-touch-icon-precomposed" href="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/img/blog.png"><link rel="alternate" type="application/atom+xml" href="/atom.xml"><script type="text/javascript" src="//cdn.jsdelivr.net/npm/jquery@latest/dist/jquery.min.js"></script><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-8385136408348258"></script><script src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js" async></script><script>(function(){
2
+ var bp = document.createElement('script');
3
+ var curProtocol = window.location.protocol.split(':')[0];
4
+ if (curProtocol === 'https'){
5
+ bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
6
+ }
7
+ else{
8
+ bp.src = 'http://push.zhanzhang.baidu.com/push.js';
9
+ }
10
+ var s = document.getElementsByTagName("script")[0];
11
+ s.parentNode.insertBefore(bp, s);
12
+ })();
13
+ </script><script>(function(){
14
+ var src = 'https://jspassport.ssl.qhimg.com/11.0.1.js?d182b3f28525f2db83acfaaf6e696dba';
15
+ document.write('<script src="' + src + '" id="sozz"><\/script>');
16
+ })();
17
+ </script><script>var _hmt=_hmt||[];(function(){var hm=document.createElement("script");hm.src='https://hm.baidu.com/hm.js?011f0b44e8452bfa57fbfa23c5fe7683';var s=document.getElementsByTagName("script")[0];s.parentNode.insertBefore(hm, s);})();
18
+ </script><script async src="https://www.googletagmanager.com/gtag/js?id=UA-150860401-1"></script><script>window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);};gtag('js',new Date());gtag('config','UA-150860401-1');
19
+ </script><script type="text/javascript" src="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/js/fixedPage.min.js"></script><meta name="generator" content="Hexo 6.3.0"></head><body><div class="body_container"><div id="header"><div class="site-name"><a id="logo" href="/.">前端壹菜鸟</a><p class="description">关注前端知识,收集精彩博文,做技术的搬运工</p></div><div id="nav-menu"><a class="current" href="/." target="_self"><i class="fa fa-home"> 首页</i></a><a href="/archives/" target="_self"><i class="fa fa-archive"> 归档</i></a><a href="/guestbook/" target="_self"><i class="fa fa-comments"> 留言</i></a><a href="/about/" target="_self"><i class="fa fa-user"> 关于</i></a><a href="https://laonongmin.online/" target="_target"><i class="fa fa-group"> 看看</i></a><a href="https://love.xuehuayu.cn/" target="_target"><i class="fa fa-heart"> LOVE</i></a></div></div><div class="pure-g" id="layout"><div class="pure-u-1 pure-u-md-3-4"><div class="content_container"><div class="post"><h1 class="post-title c-post">即将到来的es2022新特性</h1><div class="post-meta"><span class="date">2022-02-15</span><span> | </span><span class="tag"><a href="/tags/%E8%BD%AC%E8%BD%BD/">转载 </a></span><span> | </span><span class="category"><a href="/categories/%E5%89%8D%E7%AB%AF/">前端 </a></span><span id="busuanzi_container_page_pv"> | <span id="busuanzi_value_page_pv"><i class="fa fa-spinner"></i></span><span> 阅读</span></span><span class="post-time"><span class="post-meta-item-text"> | </span><span class="post-meta-item-icon"><i class="fa fa-keyboard-o"></i><span class="post-count"> 5.7k</span><span class="post-meta-item-text"> 字</span></span></span><span class="post-time"> | <span class="post-meta-item-icon"><i class="fa fa-hourglass-half"></i><span class="post-count"> 25</span><span class="post-meta-item-text"> 分钟</span></span></span></div><a class="disqus-comment-count" href="/article/7a3ef8f.html#vcomment"><span class="waline-comment-count" data-path="/article/7a3ef8f.html"></span><span> 条评论</span></a><div class="post-content"><p>ECMAScript 规范每年都会更新一次,正式标准化 JavaScript 语言的 ECMAScript 的下一次年度更新将在 2022 年 6 月左右获得批准。自 2015 年以来,TC39 团队成员每年都会一起讨论可用的提案,并发布已接受的提案。今年是 ECMAScript 的第 13 版,其中包括许多实用的功能。所有在 2022 年 3 月之前达到阶段 4 的提案都将包含在全新的 ECMAScript 2022 标准中。</p>
20
+ <span id="more"></span>
21
+ <p><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="ECMAScript 2022 新特性介绍"><img src="https://media.mybj123.com/wp-content/uploads/2022/01/1643433785-4ffce04d92a4d6c.webp" alt="ECMAScript 2022 新特性介绍"></p>
22
+ <p>对于一个提案,从提出到最后被纳入ES新特性,TC39的规范中分为五步:</p>
23
+ <ul>
24
+ <li>stage0(strawman),任何TC39的成员都可以提交。</li>
25
+ <li>stage1(proposal),进入此阶段就意味着这一提案被认为是正式的了,需要对此提案的场景与API进行详尽的描述。</li>
26
+ <li>stage2(draft),演进到这一阶段的提案如果能最终进入到标准,那么在之后的阶段都不会有太大的变化,因为理论上只接受增量修改。</li>
27
+ <li>state3(candidate),这一阶段的提案只有在遇到了重大问题才会修改,规范文档需要被全面的完成。</li>
28
+ <li>state4(finished),这一阶段的提案将会被纳入到ES每年发布的规范之中</li>
29
+ </ul>
30
+ <p>目前,一些提案还处于第三阶段,一些提案已经进入第四阶段。提案的功能将在达到第 4 阶段后被添加到新的ECMAScript标准中,这意味着它们已获得 TC-39 的批准,通过了测试,并且至少有两个实现。下面就来看看 ECMAScript 2022 预计会推出的新功能吧~</p>
31
+ <h2 id="一、Top-level-Await"><a href="#一、Top-level-Await" class="headerlink" title="一、Top-level Await"></a>一、Top-level Await</h2><p>在ES2017中引入了 <code>async</code> 函数和 <code>await</code> 关键字,以简化 <code>Promise</code> 的使用,但是 <code>await</code> 关键字只能在 <code>async</code> 函数内部使用。尝试在异步函数之外使用 <code>await</code> 就会报错:<code>SyntaxError - SyntaxError: await is only valid in async function</code>。</p>
32
+ <p>顶层 <code>await</code> 允许我们在 <code>async</code> 函数外面使用 <code>await</code> 关键字,目前提案正处于第 4 阶段,并且已经在三个主要的浏览器的 JavaScript 引擎中实现,模块系统会协调所有的异步 <code>promise</code>。</p>
33
+ <p>顶层 <code>await</code> 允许模块充当大型异步函数,通过顶层 <code>await</code>,这些ECMAScript模块可以等待资源加载。这样其他导入这些模块的模块在执行代码之前要等待资源加载完再去执行。下面来看一个简单的例子。</p>
34
+ <p>由于 <code>await</code> 仅在 <code>async</code> 函数中可用,因此模块可以通过将代码包装在 <code>async</code> 函数中来在代码中包含 <code>await</code>:</p>
35
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// a.js</span></span><br><span class="line"><span class="keyword">import</span> fetch <span class="keyword">from</span> <span class="string">&quot;node-fetch&quot;</span>;</span><br><span class="line"><span class="keyword">let</span> users;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> <span class="title function_">fetchUsers</span> = <span class="keyword">async</span> (<span class="params"></span>) =&gt; &#123;</span><br><span class="line"> <span class="keyword">const</span> resp = <span class="keyword">await</span> <span class="title function_">fetch</span>(<span class="string">&#x27;https://jsonplaceholder.typicode.com/users&#x27;</span>);</span><br><span class="line"> users = resp.<span class="title function_">json</span>();</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">fetchUsers</span>();</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> &#123; users &#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// usingAwait.js</span></span><br><span class="line"><span class="keyword">import</span> &#123;users&#125; <span class="keyword">from</span> <span class="string">&#x27;./a.js&#x27;</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;users: &#x27;</span>, users);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;usingAwait module&#x27;</span>);</span><br></pre></td></tr></table></figure>
36
+
37
+ <p>我们还可以立即调用顶层<code>async</code>函数(IIAFE):</p>
38
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> fetch <span class="keyword">from</span> <span class="string">&quot;node-fetch&quot;</span>;</span><br><span class="line">(<span class="keyword">async</span> () =&gt; &#123;</span><br><span class="line"> <span class="keyword">const</span> resp = <span class="keyword">await</span> <span class="title function_">fetch</span>(<span class="string">&#x27;https://jsonplaceholder.typicode.com/users&#x27;</span>);</span><br><span class="line"> users = resp.<span class="title function_">json</span>();</span><br><span class="line">&#125;)();</span><br><span class="line"><span class="keyword">export</span> &#123; users &#125;;</span><br></pre></td></tr></table></figure>
39
+
40
+ <p>这样会有一个缺点,直接导入的 users 是 undefined,需要在异步执行完成之后才能访问它:</p>
41
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// usingAwait.js</span></span><br><span class="line"><span class="keyword">import</span> &#123;users&#125; <span class="keyword">from</span> <span class="string">&#x27;./a.js&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;users:&#x27;</span>, users); <span class="comment">// undefined</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;users:&#x27;</span>, users);</span><br><span class="line">&#125;, <span class="number">100</span>);</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;usingAwait module&#x27;</span>);</span><br></pre></td></tr></table></figure>
42
+
43
+ <p>当然,这种方法并不安全,因为如果异步函数执行花费的时间超过100毫秒, 它就不会起作用了,users 仍然是 undefined。</p>
44
+ <p>另一个方法是导出一个 promise,让导入模块知道数据已经准备好了:</p>
45
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//a.js</span></span><br><span class="line"><span class="keyword">import</span> fetch <span class="keyword">from</span> <span class="string">&quot;node-fetch&quot;</span>;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> (<span class="keyword">async</span> () =&gt; &#123;</span><br><span class="line"> <span class="keyword">const</span> resp = <span class="keyword">await</span> <span class="title function_">fetch</span>(<span class="string">&#x27;https://jsonplaceholder.typicode.com/users&#x27;</span>);</span><br><span class="line"> users = resp.<span class="title function_">json</span>();</span><br><span class="line">&#125;)();</span><br><span class="line"><span class="keyword">export</span> &#123; users &#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">//usingAwait.js</span></span><br><span class="line"><span class="keyword">import</span> promise, &#123;users&#125; <span class="keyword">from</span> <span class="string">&#x27;./a.js&#x27;</span>;</span><br><span class="line">promise.<span class="title function_">then</span>(<span class="function">() =&gt;</span> &#123; </span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;usingAwait module&#x27;</span>);</span><br><span class="line"> <span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;users:&#x27;</span>, users), <span class="number">100</span>); </span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
46
+
47
+ <p>虽然这种方法似乎是给出了预期的结果,但是有一定的局限性:导入模块必须了解这种模式才能正确使用它。</p>
48
+ <p>而顶层<code>await</code>就可以消除这些缺点:</p>
49
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// a.js</span></span><br><span class="line"><span class="keyword">const</span> resp = <span class="keyword">await</span> <span class="title function_">fetch</span>(<span class="string">&#x27;https://jsonplaceholder.typicode.com/users&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> users = resp.<span class="title function_">json</span>();</span><br><span class="line"><span class="keyword">export</span> &#123; users &#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// usingAwait.js</span></span><br><span class="line"><span class="keyword">import</span> &#123; users &#125; <span class="keyword">from</span> <span class="string">&#x27;./a.mjs&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(users);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;usingAwait module&#x27;</span>);</span><br></pre></td></tr></table></figure>
50
+
51
+ <p>顶级 await 在以下场景中将非常有用:</p>
52
+ <p><strong>(1)动态加载模块</strong></p>
53
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> strings = <span class="keyword">await</span> <span class="title function_">import</span>(<span class="string">`/i18n/<span class="subst">$&#123;navigator.language&#125;</span>`</span>);</span><br></pre></td></tr></table></figure>
54
+
55
+ <p><strong>(2)资源初始化</strong></p>
56
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> connection = <span class="keyword">await</span> <span class="title function_">dbConnector</span>();</span><br></pre></td></tr></table></figure>
57
+
58
+ <p><strong>(3)依赖回退</strong></p>
59
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> translations;</span><br><span class="line"><span class="keyword">try</span> &#123;</span><br><span class="line"> translations = <span class="keyword">await</span> <span class="title function_">import</span>(<span class="string">&#x27;https://app.fr.json&#x27;</span>);</span><br><span class="line">&#125; <span class="keyword">catch</span> &#123;</span><br><span class="line"> translations = <span class="keyword">await</span> <span class="title function_">import</span>(<span class="string">&#x27;https://fallback.en.json&#x27;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
60
+
61
+ <p>目前,在这些地方已经支持 Top-level await:</p>
62
+ <ul>
63
+ <li>V8 v8.9</li>
64
+ <li>Webpack 5.0.0</li>
65
+ <li>Babel</li>
66
+ <li>Chrome DevTools REPL</li>
67
+ <li>Node REPL</li>
68
+ </ul>
69
+ <h2 id="二、类的实例成员"><a href="#二、类的实例成员" class="headerlink" title="二、类的实例成员"></a>二、类的实例成员</h2><h3 id="1-公共实例字段"><a href="#1-公共实例字段" class="headerlink" title="1. 公共实例字段"></a>1. 公共实例字段</h3><p>公共类字段允许我们使用赋值运算符 (&#x3D;) 将实例属性添加到类定义中。下面来一个计数器的例子:</p>
70
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, &#123; <span class="title class_">Component</span> &#125; <span class="keyword">from</span> <span class="string">&quot;react&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">class</span> <span class="title class_">Incrementor</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Component</span> &#123;</span><br><span class="line"> <span class="title function_">constructor</span>(<span class="params"></span>) &#123;</span><br><span class="line"> <span class="variable language_">super</span>();</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">state</span> = &#123;</span><br><span class="line"> <span class="attr">count</span>: <span class="number">0</span>,</span><br><span class="line"> &#125;;</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">increment</span> = <span class="variable language_">this</span>.<span class="property">increment</span>.<span class="title function_">bind</span>(<span class="variable language_">this</span>);</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="title function_">increment</span>(<span class="params"></span>) &#123;</span><br><span class="line"> <span class="variable language_">this</span>.<span class="title function_">setState</span>(&#123; <span class="attr">count</span>: <span class="variable language_">this</span>.<span class="property">state</span>.<span class="property">count</span> + <span class="number">1</span> &#125;);</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> (</span><br><span class="line"> <span class="language-xml"><span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.increment&#125;</span>&gt;</span>Increment: &#123;this.state.count&#125;<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span></span><br><span class="line"> );</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
71
+
72
+ <p>在这个例子中,在构造函数中定义了实例字段和绑定方法,通过新的类语法,我们可以使代码更加直观。新的公共类字段语法允许我们直接将实例属性作为属性添加到类上,而无需使用构造函数方法。这样就简化了类的定义,使代码更加简洁、可读:</p>
73
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span> <span class="keyword">from</span> <span class="string">&quot;react&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">class</span> <span class="title class_">Incrementor</span> <span class="keyword">extends</span> <span class="title class_ inherited__">React.Component</span> &#123;</span><br><span class="line"> state = &#123; <span class="attr">count</span>: <span class="number">0</span> &#125;;</span><br><span class="line"></span><br><span class="line"> increment = <span class="function">() =&gt;</span> <span class="variable language_">this</span>.<span class="title function_">setState</span>(&#123; <span class="attr">count</span>: <span class="variable language_">this</span>.<span class="property">state</span>.<span class="property">count</span> + <span class="number">1</span> &#125;);</span><br><span class="line"></span><br><span class="line"> render = <span class="function">() =&gt;</span> (</span><br><span class="line"> <span class="language-xml"><span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.increment&#125;</span>&gt;</span>Increment: &#123;this.state.count&#125;<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span></span><br><span class="line"> );</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
74
+
75
+ <p>有些小伙伴可能就疑问了,这个功能很早就可以使用了呀。但是它现在还不是标准的 ECMAScript,默认是不开启的,如果使用 create-react-app 创建 React 项目,那么它默认是启用的,否则我们必须使用正确的babel插件才能正常使用(@babel&#x2F;preset-env)。</p>
76
+ <p>下面来看看关于公共实例字段的注意事项:</p>
77
+ <p>(1)公共实例字段存在于每个创建的类实例上。它们要么是在<code>Object.defineProperty()</code>中添加,要么是在基类中的构造时添加(构造函数主体执行之前执行),要么在子类的<code>super()</code>返回之后添加:</p>
78
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Incrementor</span> &#123;</span><br><span class="line"> count = <span class="number">0</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> instance = <span class="keyword">new</span> <span class="title class_">Incrementor</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(instance.<span class="property">count</span>); <span class="comment">// 0</span></span><br></pre></td></tr></table></figure>
79
+
80
+ <p>(2)未初始化的字段会自动设置为 undefined:</p>
81
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Incrementor</span> &#123;</span><br><span class="line"> count</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> instance = <span class="keyword">new</span> <span class="title class_">Incrementor</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">assert</span>(instance.<span class="title function_">hasOwnProperty</span>(<span class="string">&#x27;count&#x27;</span>));</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(instance.<span class="property">count</span>); <span class="comment">// undefined</span></span><br></pre></td></tr></table></figure>
82
+
83
+ <p>(3)可以进行字段的计算:</p>
84
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="variable constant_">PREFIX</span> = <span class="string">&#x27;main&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Incrementor</span> &#123;</span><br><span class="line"> [<span class="string">`<span class="subst">$&#123;PREFIX&#125;</span>Count`</span>] = <span class="number">0</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> instance = <span class="keyword">new</span> <span class="title class_">Incrementor</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(instance.<span class="property">mainCount</span>); <span class="comment">// 0</span></span><br></pre></td></tr></table></figure>
85
+
86
+ <h3 id="2-私有实例字段、方法和访问器"><a href="#2-私有实例字段、方法和访问器" class="headerlink" title="2. 私有实例字段、方法和访问器"></a>2. 私有实例字段、方法和访问器</h3><p>默认情况下,ES6 中所有属性都是公共的,可以在类外检查或修改。下面来看一个例子:</p>
87
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">TimeTracker</span> &#123;</span><br><span class="line"> name = <span class="string">&#x27;zhangsan&#x27;</span>;</span><br><span class="line"> project = <span class="string">&#x27;blog&#x27;</span>;</span><br><span class="line"> hours = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">set</span> <span class="title function_">addHours</span>(<span class="params">hour</span>) &#123;</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">hours</span> += hour;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">get</span> <span class="title function_">timeSheet</span>() &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="string">`<span class="subst">$&#123;<span class="variable language_">this</span>.name&#125;</span> works <span class="subst">$&#123;<span class="variable language_">this</span>.hours || <span class="string">&#x27;nothing&#x27;</span>&#125;</span> hours on <span class="subst">$&#123;<span class="variable language_">this</span>.project&#125;</span>`</span>;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> person = <span class="keyword">new</span> <span class="title class_">TimeTracker</span>();</span><br><span class="line">person.<span class="property">addHours</span> = <span class="number">2</span>; <span class="comment">// 标准 setter</span></span><br><span class="line">person.<span class="property">hours</span> = <span class="number">4</span>; <span class="comment">// 绕过 setter 进行设置</span></span><br><span class="line">person.<span class="property">timeSheet</span>;</span><br></pre></td></tr></table></figure>
88
+
89
+ <p>可以看到,在类中没有任何措施可以防止在不调用 setter 的情况下更改属性。</p>
90
+ <p>而私有类字段将使用哈希#前缀定义,从上面的示例中,我们可以修改它以包含私有类字段,以防止在类方法之外更改属性:</p>
91
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">TimeTracker</span> &#123;</span><br><span class="line"> name = <span class="string">&#x27;zhangsan&#x27;</span>;</span><br><span class="line"> project = <span class="string">&#x27;blog&#x27;</span>;</span><br><span class="line"> #hours = <span class="number">0</span>; <span class="comment">// 私有类字段</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">set</span> <span class="title function_">addHours</span>(<span class="params">hour</span>) &#123;</span><br><span class="line"> <span class="variable language_">this</span>.#hours += hour;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">get</span> <span class="title function_">timeSheet</span>() &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="string">`<span class="subst">$&#123;<span class="variable language_">this</span>.name&#125;</span> works <span class="subst">$&#123;<span class="variable language_">this</span>.#hours || <span class="string">&#x27;nothing&#x27;</span>&#125;</span> hours on <span class="subst">$&#123;<span class="variable language_">this</span>.project&#125;</span>`</span>;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> person = <span class="keyword">new</span> <span class="title class_">TimeTracker</span>();</span><br><span class="line">person.<span class="property">addHours</span> = <span class="number">4</span>; <span class="comment">// 标准 setter</span></span><br><span class="line">person.<span class="property">timeSheet</span> <span class="comment">// zhangsan works 4 hours on blog</span></span><br></pre></td></tr></table></figure>
92
+ <p>当我们尝试在 setter 方法之外修改私有类字段时,就会报错:</p>
93
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">person.<span class="property">hours</span> = <span class="number">4</span> <span class="comment">// Error Private field &#x27;#hours&#x27; must be declared in an enclosing class</span></span><br></pre></td></tr></table></figure>
94
+
95
+ <p>我们还可以将方法或 <code>getter/setter</code> 设为私有,只需要给这些方法名称前面加<code>#</code>即可:</p>
96
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">TimeTracker</span> &#123;</span><br><span class="line"> name = <span class="string">&#x27;zhangsan&#x27;</span>;</span><br><span class="line"> project = <span class="string">&#x27;blog&#x27;</span>;</span><br><span class="line"> #hours = <span class="number">0</span>; <span class="comment">// 私有类字段</span></span><br><span class="line"></span><br><span class="line"> set #<span class="title function_">addHours</span>(<span class="params">hour</span>) &#123;</span><br><span class="line"> <span class="variable language_">this</span>.#hours += hour;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> get #<span class="title function_">timeSheet</span>(<span class="params"></span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="string">`<span class="subst">$&#123;<span class="variable language_">this</span>.name&#125;</span> works <span class="subst">$&#123;<span class="variable language_">this</span>.#hours || <span class="string">&#x27;nothing&#x27;</span>&#125;</span> hours on <span class="subst">$&#123;<span class="variable language_">this</span>.project&#125;</span>`</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="title function_">constructor</span>(<span class="params">hours</span>) &#123;</span><br><span class="line"> <span class="variable language_">this</span>.#addHours = hours;</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.#timeSheet);</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> person = <span class="keyword">new</span> <span class="title class_">TimeTracker</span>(<span class="number">4</span>); <span class="comment">// zhangsan works 4 hours on blog</span></span><br></pre></td></tr></table></figure>
97
+
98
+ <p>由于尝试访问对象上不存在的私有字段会发生异常,因此需要能够检查对象是否具有给定的私有字段。可以使用 <code>in</code> 运算符来检查对象上是否有私有字段:</p>
99
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Example</span> &#123;</span><br><span class="line"> #field</span><br><span class="line"></span><br><span class="line"> <span class="keyword">static</span> <span class="title function_">isExampleInstance</span>(<span class="params">object</span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> #field <span class="keyword">in</span> object;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
100
+
101
+ <p>查看更多公有和私有字段提案信息:点击<a target="_blank" rel="noopener" href="https://www.mybj123.com/gohref.php?url=https://github.com/tc39/proposal-class-fields">这里</a></p>
102
+ <h3 id="3-静态公共字段"><a href="#3-静态公共字段" class="headerlink" title="3. 静态公共字段"></a>3. 静态公共字段</h3><p>在ES6中,不能在类的每个实例中访问静态字段或方法,只能在原型中访问。ES 2022 将提供一种在 JavaScript 中使用 <code>static</code> 关键字声明静态类字段的方法。下面来看一个例子:</p>
103
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Shape</span> &#123;</span><br><span class="line"> <span class="keyword">static</span> color = <span class="string">&#x27;blue&#x27;</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">static</span> <span class="title function_">getColor</span>(<span class="params"></span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">color</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="title function_">getMessage</span>(<span class="params"></span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="string">`color:<span class="subst">$&#123;<span class="variable language_">this</span>.color&#125;</span>`</span> ;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
104
+
105
+ <p>我们可以从类本身访问静态字段和方法:</p>
106
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Shape</span>.<span class="property">color</span>); <span class="comment">// blue</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Shape</span>.<span class="title function_">getColor</span>()); <span class="comment">// blue</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;color&#x27;</span> <span class="keyword">in</span> <span class="title class_">Shape</span>); <span class="comment">// true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;getColor&#x27;</span> <span class="keyword">in</span> <span class="title class_">Shape</span>); <span class="comment">// true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;getMessage&#x27;</span> <span class="keyword">in</span> <span class="title class_">Shape</span>); <span class="comment">// false</span></span><br></pre></td></tr></table></figure>
107
+
108
+ <p>实例不能访问静态字段和方法:</p>
109
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> shapeInstance = <span class="keyword">new</span> <span class="title class_">Shape</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(shapeInstance.<span class="property">color</span>); <span class="comment">// undefined</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(shapeInstance.<span class="property">getColor</span>); <span class="comment">// undefined</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(shapeInstance.<span class="title function_">getMessage</span>());<span class="comment">// color:undefined</span></span><br></pre></td></tr></table></figure>
110
+
111
+ <p>静态字段只能通过静态方法访问:</p>
112
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Shape</span>.<span class="title function_">getColor</span>()); <span class="comment">// blue</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Shape</span>.<span class="title function_">getMessage</span>()); <span class="comment">//TypeError: Shape.getMessage is not a function</span></span><br></pre></td></tr></table></figure>
113
+
114
+ <p>这里的 Shape.getMessage() 就报错了,这是因为 getMessage 不是一个静态函数,所以它不能通过类名 Shape 访问。可以通过以下方式来解决这个问题:</p>
115
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">getMessage</span>(<span class="params"></span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="string">`color:<span class="subst">$&#123;Shape.color&#125;</span>`</span> ;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
116
+
117
+ <p>静态字段和方法是从父类继承的:</p>
118
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Rectangle</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Shape</span> &#123; &#125;</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Rectangle</span>.<span class="property">color</span>); <span class="comment">// blue</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Rectangle</span>.<span class="title function_">getColor</span>()); <span class="comment">// blue</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;color&#x27;</span> <span class="keyword">in</span> <span class="title class_">Rectangle</span>); <span class="comment">// true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;getColor&#x27;</span> <span class="keyword">in</span> <span class="title class_">Rectangle</span>); <span class="comment">// true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;getMessage&#x27;</span> <span class="keyword">in</span> <span class="title class_">Rectangle</span>); <span class="comment">// false</span></span><br></pre></td></tr></table></figure>
119
+
120
+ <h3 id="4-静态私有字段和方法"><a href="#4-静态私有字段和方法" class="headerlink" title="4. 静态私有字段和方法"></a>4. 静态私有字段和方法</h3><p>与私有实例字段和方法一样,静态私有字段和方法也使用哈希 (<code>#</code>) 前缀来定义:</p>
121
+ <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">class Shape &#123;</span><br><span class="line"> static #color = &#x27;blue&#x27;;</span><br><span class="line"></span><br><span class="line"> static #getColor() &#123;</span><br><span class="line"> return this.#color;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> getMessage() &#123;</span><br><span class="line"> return `color:$&#123;Shape.#getColor()&#125;` ;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br><span class="line">const shapeInstance = new Shape();</span><br><span class="line">shapeInstance.getMessage(); // color:blue</span><br></pre></td></tr></table></figure>
122
+
123
+ <p>私有静态字段有一个限制:只有定义私有静态字段的类才能访问该字段。这可能在我们使用 this 时导致出乎意料的情况:</p>
124
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Shape</span> &#123;</span><br><span class="line"> <span class="keyword">static</span> #color = <span class="string">&#x27;blue&#x27;</span>;</span><br><span class="line"><span class="keyword">static</span> #<span class="title function_">getColor</span>(<span class="params"></span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">this</span>.#color;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">static</span> <span class="title function_">getMessage</span>(<span class="params"></span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="string">`color:<span class="subst">$&#123;<span class="variable language_">this</span>.#color&#125;</span>`</span> ;</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">getMessageNonStatic</span>(<span class="params"></span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="string">`color:<span class="subst">$&#123;<span class="variable language_">this</span>.#getColor()&#125;</span>`</span> ;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Rectangle</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Shape</span> &#123;&#125;</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Rectangle</span>.<span class="title function_">getMessage</span>()); <span class="comment">// Uncaught TypeError: Cannot read private member #color from an object whose class did not declare it</span></span><br><span class="line"><span class="keyword">const</span> rectangle = <span class="keyword">new</span> <span class="title class_">Rectangle</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(rectangle.<span class="title function_">getMessageNonStatic</span>()); <span class="comment">// TypeError: Cannot read private member #getColor from an object whose class did not declare it</span></span><br></pre></td></tr></table></figure>
125
+
126
+ <p>在这个例子中,this 指向的是 Rectangle 类,它无权访问私有字段 #color。当我们尝试调用 Rectangle.getMessage() 时,它无法读取 #color 并抛出了 TypeError。可以这样来进行修改:</p>
127
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Shape</span> &#123;</span><br><span class="line"> <span class="keyword">static</span> #color = <span class="string">&#x27;blue&#x27;</span>;</span><br><span class="line"> <span class="keyword">static</span> #<span class="title function_">getColor</span>(<span class="params"></span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">this</span>.#color;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">static</span> <span class="title function_">getMessage</span>(<span class="params"></span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="string">`<span class="subst">$&#123;Shape.#color&#125;</span>`</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="title function_">getMessageNonStatic</span>(<span class="params"></span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="string">`color:<span class="subst">$&#123;Shape.#getColor()&#125;</span> color`</span>;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Rectangle</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Shape</span> &#123;&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Rectangle</span>.<span class="title function_">getMessage</span>()); <span class="comment">// color:blue</span></span><br><span class="line"><span class="keyword">const</span> rectangle = <span class="keyword">new</span> <span class="title class_">Rectangle</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(rectangle.<span class="title function_">getMessageNonStatic</span>()); <span class="comment">// color:blue</span></span><br></pre></td></tr></table></figure>
128
+
129
+ <p>静态字段目前是比较稳定的,并且提供了各种实现:</p>
130
+ <p><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="静态字段各种实现表"><img src="https://media.mybj123.com/wp-content/uploads/2022/01/1643434935-0b70bc0c4393cc8.webp" alt="静态字段各种实现表"></p>
131
+ <h3 id="5-类静态初始化块"><a href="#5-类静态初始化块" class="headerlink" title="5. 类静态初始化块"></a>5. 类静态初始化块</h3><p>静态私有和公共字段只能让我们在类定义期间执行静态成员的每个字段初始化。如果我们需要在初始化期间像 try … catch 一样进行异常处理,就不得不在类之外编写此逻辑。该提案就提供了一种在类声明&#x2F;定义期间评估静态初始化代码块的优雅方法,可以访问类的私有字段。</p>
132
+ <p>先来看一个例子:</p>
133
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span> &#123;</span><br><span class="line"> <span class="keyword">static</span> <span class="variable constant_">GENDER</span> = <span class="string">&quot;Male&quot;</span></span><br><span class="line"> <span class="keyword">static</span> <span class="variable constant_">TOTAL_EMPLOYED</span>;</span><br><span class="line"> <span class="keyword">static</span> <span class="variable constant_">TOTAL_UNEMPLOYED</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">try</span> &#123;</span><br><span class="line"> <span class="comment">// ...</span></span><br><span class="line"> &#125; <span class="keyword">catch</span> &#123;</span><br><span class="line"> <span class="comment">// ...</span></span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
134
+
135
+ <p>上面的代码就会引发错误,可以使用类静态块来重构它,只需将try…catch包裹在 static 中即可:</p>
136
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span> &#123;</span><br><span class="line"> <span class="keyword">static</span> <span class="variable constant_">GENDER</span> = <span class="string">&quot;Male&quot;</span></span><br><span class="line"> <span class="keyword">static</span> <span class="variable constant_">TOTAL_EMPLOYED</span>;</span><br><span class="line"> <span class="keyword">static</span> <span class="variable constant_">TOTAL_UNEMPLOYED</span>;</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">static</span> &#123;</span><br><span class="line"> <span class="keyword">try</span> &#123;</span><br><span class="line"> <span class="comment">// ...</span></span><br><span class="line"> &#125; <span class="keyword">catch</span> &#123;</span><br><span class="line"> <span class="comment">// ...</span></span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
137
+
138
+ <p>此外,类静态块提供对词法范围的私有字段和方法的特权访问。这里需要在具有实例私有字段的类和同一范围内的函数之间共享信息的情况下很有用。</p>
139
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> getData;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span> &#123;</span><br><span class="line"> #x</span><br><span class="line"> </span><br><span class="line"> <span class="title function_">constructor</span>(<span class="params">x</span>) &#123;</span><br><span class="line"> <span class="variable language_">this</span>.#x = &#123; <span class="attr">data</span>: x &#125;;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">static</span> &#123;</span><br><span class="line"> getData = <span class="function">(<span class="params">obj</span>) =&gt;</span> obj.#x;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">readPrivateData</span>(<span class="params">obj</span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">getData</span>(obj).<span class="property">data</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> john = <span class="keyword">new</span> <span class="title class_">Person</span>([<span class="number">2</span>,<span class="number">4</span>,<span class="number">6</span>,<span class="number">8</span>]);</span><br><span class="line"></span><br><span class="line"><span class="title function_">readPrivateData</span>(john); <span class="comment">// [2,4,6,8]</span></span><br></pre></td></tr></table></figure>
140
+
141
+ <p>这里,Person 类与 readPrivateData 函数共享了私有实例属性。</p>
142
+ <h2 id="三、Temporal"><a href="#三、Temporal" class="headerlink" title="三、Temporal"></a>三、Temporal</h2><p>JavaScript 中的日期处理 <code>[Date()](https://www.mybj123.com/tag/date/)</code> 对象一直是饱受诟病,该对象是1995 年受到 Java 的启发而实现的,自此就一直没有改变过。虽然Java已经放弃了这个对象,但是 <code>Date()</code> 仍保留在 JavaScript 中来实现浏览器的兼容。</p>
143
+ <p>Date() API 存在的问题:</p>
144
+ <ul>
145
+ <li>只支持UTC和用户的PC时间;</li>
146
+ <li>不支持公历以外的日历;</li>
147
+ <li>字符串到日期解析容易出错;</li>
148
+ <li>Date 对象是可变的,比如:</li>
149
+ </ul>
150
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> today = <span class="keyword">new</span> <span class="title class_">Date</span>();</span><br><span class="line"><span class="keyword">const</span> tomorrow = <span class="keyword">new</span> <span class="title class_">Date</span>(today.<span class="title function_">setDate</span>(today.<span class="title function_">getDate</span>() + <span class="number">1</span>));</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(tomorrow); </span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(today);</span><br></pre></td></tr></table></figure>
151
+
152
+ <p>此时,两个时间输出是一样的,不符合我们的预期。正因为 Date() 对象存在的种种问题。平时我们经常需要借助<code>moment.js</code>、<code>Day.js</code>等日期库,但是它们的体积较大,有时一个简单的日期处理就需要引入一个库,得不偿失。</p>
153
+ <p>目前,由于Date API 在很多库和浏览器引擎中的广泛使用,没有办法修复API的不好的部分。而改变Date API 的工作方式也很可能会破坏许多网站和库。</p>
154
+ <p>正因如此,TC39提出了一个全新的用于处理日期和时间的标准对象和函数——Temporal。新的Temporal API 提案旨在解决Date API的问题。它为 JavaScript 日期&#x2F;时间操作带来了以下修复:</p>
155
+ <ul>
156
+ <li>仅可以创建和处理不可变Temporal对象;</li>
157
+ <li>提供用于日期和时间计算的简单 API;</li>
158
+ <li>支持所有时区;</li>
159
+ <li>从 ISO-8601 格式进行严格的日期解析;</li>
160
+ <li>支持非公历。</li>
161
+ </ul>
162
+ <p>Temporal 将取代 Moment.js 之类的库,这些库很好地填补了 JavaScript 中的空白,这种空白非常普遍,因此将功能作为语言的一部分更有意义。</p>
163
+ <p>由于该提案还未正式发布,所以,可以借助官方提供的prlyfill来测试。首选进行安装:</p>
164
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install @js-temporal/polyfill</span><br></pre></td></tr></table></figure>
165
+
166
+ <p>导入并使用:</p>
167
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123; <span class="title class_">Temporal</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;@js-temporal/polyfill&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Temporal</span>);</span><br></pre></td></tr></table></figure>
168
+
169
+ <p>Temporal 对象如下:</p>
170
+ <p><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="Temporal 对象"><img src="https://media.mybj123.com/wp-content/uploads/2022/01/1643435164-e4fe75af2011b87.webp" alt="Temporal 对象"></p>
171
+ <p>下面就来看看 Temporal 对象有哪些实用的功能。</p>
172
+ <h3 id="1-当前时间和日期"><a href="#1-当前时间和日期" class="headerlink" title="1. 当前时间和日期"></a>1. 当前时间和日期</h3><p><code>Temporal.Now</code> 会返回一个表示当前日期和时间的对象:</p>
173
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 自1970年1月1日以来的时间(秒和毫秒)</span></span><br><span class="line"><span class="title class_">Temporal</span>.<span class="property">Now</span>.<span class="title function_">instant</span>().<span class="property">epochSeconds</span>;</span><br><span class="line"><span class="title class_">Temporal</span>.<span class="property">Now</span>.<span class="title function_">instant</span>().<span class="property">epochMilliseconds</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 当前位置的时间</span></span><br><span class="line"><span class="title class_">Temporal</span>.<span class="property">Now</span>.<span class="title function_">zonedDateTimeISO</span>();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 当前时区</span></span><br><span class="line"><span class="title class_">Temporal</span>.<span class="property">Now</span>.<span class="title function_">timeZone</span>();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 指定时区的当前时间</span></span><br><span class="line"><span class="title class_">Temporal</span>.<span class="property">Now</span>.<span class="title function_">zonedDateTimeISO</span>(<span class="string">&#x27;Europe/London&#x27;</span>);</span><br></pre></td></tr></table></figure>
174
+
175
+ <h3 id="2-实例时间和日期"><a href="#2-实例时间和日期" class="headerlink" title="2. 实例时间和日期"></a>2. 实例时间和日期</h3><p><code>Temporal.Instant</code> 根据 ISO 8601 格式的字符串返回一个表示日期和时间的对象,结果会精确到纳秒:</p>
176
+ <p><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="实例时间和日期"><img src="https://media.mybj123.com/wp-content/uploads/2022/01/1643435243-b87f0c4dcc3e91d.webp" alt="实例时间和日期"></p>
177
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Temporal</span>.<span class="property">Instant</span>.<span class="title function_">from</span>(<span class="string">&#x27;2022-02-01T05:56:78.999999999+02:00[Europe/Berlin]&#x27;</span>);</span><br><span class="line"><span class="comment">// 输出结果:2022-02-01T03:57:18.999999999Z </span></span><br><span class="line"><span class="title class_">Temporal</span>.<span class="property">Instant</span>.<span class="title function_">from</span>(<span class="string">&#x27;2022-02-011T05:06+07:00&#x27;</span>);</span><br><span class="line"><span class="comment">// 输出结果:2022-01-31T22:06:00Z</span></span><br></pre></td></tr></table></figure>
178
+
179
+ <p>除此之外,我们还可以获取纪元时间的对应的日期(UTC 1970年1月1日0点是纪元时间):</p>
180
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Temporal</span>.<span class="property">Instant</span>.<span class="title function_">fromEpochSeconds</span>(<span class="number">1.0e8</span>);</span><br><span class="line"><span class="comment">// 输出结果:1973-03-03T09:46:40Z</span></span><br></pre></td></tr></table></figure>
181
+
182
+ <h3 id="3-时区日期和时间"><a href="#3-时区日期和时间" class="headerlink" title="3. 时区日期和时间"></a>3. 时区日期和时间</h3><p><code>Temporal.ZonedDateTime</code> 返回一个对象,该对象表示在特定时区的日期&#x2F;时间:</p>
183
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> <span class="title class_">Temporal</span>.<span class="title class_">ZonedDateTime</span>(</span><br><span class="line"> <span class="number">1234567890000</span>, <span class="comment">// 纪元时间</span></span><br><span class="line"> <span class="title class_">Temporal</span>.<span class="property">TimeZone</span>.<span class="title function_">from</span>(<span class="string">&#x27;Europe/London&#x27;</span>), <span class="comment">// 时区</span></span><br><span class="line"> <span class="title class_">Temporal</span>.<span class="property">Calendar</span>.<span class="title function_">from</span>(<span class="string">&#x27;iso8601&#x27;</span>) <span class="comment">// 默认日历</span></span><br><span class="line">);</span><br><span class="line"></span><br><span class="line"><span class="title class_">Temporal</span>.<span class="property">ZonedDateTime</span>.<span class="title function_">from</span>(<span class="string">&#x27;2025-09-05T02:55:00+02:00[Africa/Cairo]&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="title class_">Temporal</span>.<span class="title class_">Instant</span>(<span class="string">&#x27;2022-08-05T20:06:13+05:45&#x27;</span>).<span class="title function_">toZonedDateTime</span>(<span class="string">&#x27;+05:45&#x27;</span>);</span><br><span class="line"><span class="comment">// 输出结果:</span></span><br><span class="line"></span><br><span class="line"><span class="title class_">Temporal</span>.<span class="property">ZonedDateTime</span>.<span class="title function_">from</span>(&#123;</span><br><span class="line"> <span class="attr">timeZone</span>: <span class="string">&#x27;America/New_York&#x27;</span>,</span><br><span class="line"> <span class="attr">year</span>: <span class="number">2025</span>,</span><br><span class="line"> <span class="attr">month</span>: <span class="number">2</span>,</span><br><span class="line"> <span class="attr">day</span>: <span class="number">28</span>,</span><br><span class="line"> <span class="attr">hour</span>: <span class="number">10</span>,</span><br><span class="line"> <span class="attr">minute</span>: <span class="number">15</span>,</span><br><span class="line"> <span class="attr">second</span>: <span class="number">0</span>,</span><br><span class="line"> <span class="attr">millisecond</span>: <span class="number">0</span>,</span><br><span class="line"> <span class="attr">microsecond</span>: <span class="number">0</span>,</span><br><span class="line"> <span class="attr">nanosecond</span>: <span class="number">0</span></span><br><span class="line">&#125;);</span><br><span class="line"><span class="comment">// 输出结果:2025-02-28T10:15:00-05:00[America/New_York]</span></span><br></pre></td></tr></table></figure>
184
+
185
+ <h3 id="4-简单的日期和时间"><a href="#4-简单的日期和时间" class="headerlink" title="4. 简单的日期和时间"></a>4. 简单的日期和时间</h3><p>我们并不会总是需要使用精确的时间,因此 Temporal API 提供了独立于时区的对象。这些可以用于更简单的活动。</p>
186
+ <ul>
187
+ <li>Temporal.PlainDateTime:指日历日期和时间;</li>
188
+ <li>Temporal.PlainDate:指特定的日历日期;</li>
189
+ <li>Temporal.PlainTime:指一天中的特定时间;</li>
190
+ <li>Temporal.PlainYearMonth:指没有日期成分的日期,例如“2022 年 2 月”;Temporal.PlainMonthDay:指没有年份的日期,例如“10 月 1 日”。</li>
191
+ </ul>
192
+ <p>它们都有类似的构造函数,以下有两种形式来创建简单的时间和日期:</p>
193
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> <span class="title class_">Temporal</span>.<span class="title class_">PlainDateTime</span>(<span class="number">2021</span>, <span class="number">5</span>, <span class="number">4</span>, <span class="number">13</span>, <span class="number">14</span>, <span class="number">15</span>);</span><br><span class="line"><span class="title class_">Temporal</span>.<span class="property">PlainDateTime</span>.<span class="title function_">from</span>(<span class="string">&#x27;2021-05-04T13:14:15&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">new</span> <span class="title class_">Temporal</span>.<span class="title class_">PlainDate</span>(<span class="number">2021</span>, <span class="number">5</span>, <span class="number">4</span>);</span><br><span class="line"><span class="title class_">Temporal</span>.<span class="property">PlainDate</span>.<span class="title function_">from</span>(<span class="string">&#x27;2021-05-04&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">new</span> <span class="title class_">Temporal</span>.<span class="title class_">PlainTime</span>(<span class="number">13</span>, <span class="number">14</span>, <span class="number">15</span>);</span><br><span class="line"><span class="title class_">Temporal</span>.<span class="property">PlainTime</span>.<span class="title function_">from</span>(<span class="string">&#x27;13:14:15&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">new</span> <span class="title class_">Temporal</span>.<span class="title class_">PlainYearMonth</span>(<span class="number">2021</span>, <span class="number">4</span>);</span><br><span class="line"><span class="title class_">Temporal</span>.<span class="property">PlainYearMonth</span>.<span class="title function_">from</span>(<span class="string">&#x27;2019-04&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">new</span> <span class="title class_">Temporal</span>.<span class="title class_">PlainMonthDay</span>(<span class="number">3</span>, <span class="number">14</span>);</span><br><span class="line"><span class="title class_">Temporal</span>.<span class="property">PlainMonthDay</span>.<span class="title function_">from</span>(<span class="string">&#x27;03-14&#x27;</span>);</span><br></pre></td></tr></table></figure>
194
+
195
+ <h3 id="5-日期和时间值"><a href="#5-日期和时间值" class="headerlink" title="5. 日期和时间值"></a>5. 日期和时间值</h3><p>所有 Temporal 对象都可以返回特定的日期&#x2F;时间值。例如,使用<code>ZonedDateTime</code>:</p>
196
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> t1 = <span class="title class_">Temporal</span>.<span class="property">ZonedDateTime</span>.<span class="title function_">from</span>(<span class="string">&#x27;2025-12-07T03:24:30+02:00[Africa/Cairo]&#x27;</span>);</span><br><span class="line"></span><br><span class="line">t1.<span class="property">year</span>; <span class="comment">// 2025</span></span><br><span class="line">t1.<span class="property">month</span>; <span class="comment">// 12</span></span><br><span class="line">t1.<span class="property">day</span>; <span class="comment">// 7</span></span><br><span class="line">t1.<span class="property">hour</span>; <span class="comment">// 3</span></span><br><span class="line">t1.<span class="property">minute</span>; <span class="comment">// 24</span></span><br><span class="line">t1.<span class="property">second</span>; <span class="comment">// 30</span></span><br><span class="line">t1.<span class="property">millisecond</span>; <span class="comment">// 0</span></span><br><span class="line">t1.<span class="property">microsecond</span>; <span class="comment">// 0</span></span><br><span class="line">t1.<span class="property">nanosecond</span>; <span class="comment">// 0</span></span><br></pre></td></tr></table></figure>
197
+
198
+ <p>其他有用的属性包括:</p>
199
+ <ul>
200
+ <li><code>dayOfWeek</code>(周一为 1 至周日为 7)</li>
201
+ <li><code>dayOfYear</code>(1 至 365 或 366)</li>
202
+ <li><code>weekOfYear</code>(1 到 52,有时是 53)</li>
203
+ <li><code>daysInMonth</code>(28、29、30、31)</li>
204
+ <li><code>daysInYear</code>(365 或 366)</li>
205
+ <li><code>inLeapYear</code>(true或false)</li>
206
+ </ul>
207
+ <h3 id="6-比较和排序日期"><a href="#6-比较和排序日期" class="headerlink" title="6. 比较和排序日期"></a>6. 比较和排序日期</h3><p>所有 Temporal 对象都可以使用 <code>compare()</code> 返回整数的函数进行比较。例如,比较两个<code>ZonedDateTime</code>对象:</p>
208
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Temporal</span>.<span class="property">ZonedDateTime</span>.<span class="title function_">compare</span>(t1, t2);</span><br></pre></td></tr></table></figure>
209
+
210
+ <p>这个比较结果会有三种情况:</p>
211
+ <ul>
212
+ <li>当两个时间值相等时,返回 0;</li>
213
+ <li>当 t1 在 t2 之后时,返回 1;</li>
214
+ <li>当 t1 在 t2 之前时,但会 -1;</li>
215
+ </ul>
216
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> date1 = <span class="title class_">Temporal</span>.<span class="property">Now</span>,</span><br><span class="line"><span class="keyword">const</span> date2 = <span class="title class_">Temporal</span>.<span class="property">PlainDateTime</span>.<span class="title function_">from</span>(<span class="string">&#x27;2022-05-01&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="title class_">Temporal</span>.<span class="property">ZonedDateTime</span>.<span class="title function_">compare</span>(date1, date2); <span class="comment">// -1</span></span><br></pre></td></tr></table></figure>
217
+
218
+ <p><code>compare()</code> 的结果可以用于数组的 <code>sort()</code> 方法来对时间按照升序进行排列(从早到晚):</p>
219
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> t = [</span><br><span class="line"> <span class="string">&#x27;2022-01-01T00:00:00+00:00[Europe/London]&#x27;</span>,</span><br><span class="line"> <span class="string">&#x27;2022-01-01T00:00:00+00:00[Africa/Cairo]&#x27;</span>,</span><br><span class="line"> <span class="string">&#x27;2022-01-01T00:00:00+00:00[America/New_York]&#x27;</span></span><br><span class="line">].<span class="title function_">map</span>(<span class="function"><span class="params">d</span> =&gt;</span> <span class="title class_">Temporal</span>.<span class="property">ZonedDateTime</span>.<span class="title function_">from</span>(d))</span><br><span class="line"> .<span class="title function_">sort</span>(<span class="title class_">Temporal</span>.<span class="property">ZonedDateTime</span>.<span class="property">compare</span>);</span><br></pre></td></tr></table></figure>
220
+
221
+ <h3 id="7-日期计算"><a href="#7-日期计算" class="headerlink" title="7. 日期计算"></a>7. 日期计算</h3><p>提案还提供了几种方法来对任何 Temporal 对象执行日期计算。当传递一个Temporal.Duration对象时,它们都会返回一个相同类型的新的 Temporal,该对象使用<code>years</code>, <code>months</code>, <code>weeks</code>, <code>days</code>, <code>hours</code>, <code>minutes</code>, <code>seconds</code>, <code>milliseconds</code>, <code>microseconds</code> 和 <code>nanoseconds</code> 字段来设置时间。</p>
222
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> t1 = <span class="title class_">Temporal</span>.<span class="property">ZonedDateTime</span>.<span class="title function_">from</span>(<span class="string">&#x27;2022-01-01T00:00:00+00:00[Europe/London]&#x27;</span>);</span><br><span class="line"></span><br><span class="line">t1.<span class="title function_">add</span>(&#123; <span class="attr">hours</span>: <span class="number">8</span>, <span class="attr">minutes</span>: <span class="number">30</span> &#125;); <span class="comment">// 往后8小时30分</span></span><br><span class="line"></span><br><span class="line">t1.<span class="title function_">subtract</span>(&#123; <span class="attr">days</span>: <span class="number">5</span> &#125;); <span class="comment">// 往前5天</span></span><br><span class="line"></span><br><span class="line">t1.<span class="title function_">round</span>(&#123; <span class="attr">smallestUnit</span>: <span class="string">&#x27;month&#x27;</span> &#125;); <span class="comment">// 四舍五入到最近的月份</span></span><br></pre></td></tr></table></figure>
223
+
224
+ <p><code>until()</code> 和 <code>since()</code> 方法会返回一个对象,该 <code>Temporal.Duration</code> 对象描述基于当前日期&#x2F;时间的特定日期和时间之前或之后的时间,例如:</p>
225
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">t1.<span class="title function_">until</span>().<span class="property">months</span>; <span class="comment">// 到t1还有几个月</span></span><br><span class="line"></span><br><span class="line">t2.<span class="title function_">until</span>().<span class="property">days</span>; <span class="comment">// 到t2还有几天</span></span><br><span class="line"></span><br><span class="line">t3.<span class="title function_">since</span>().<span class="property">weeks</span>; <span class="comment">// t3已经过去了几周</span></span><br></pre></td></tr></table></figure>
226
+
227
+ <p><code>[equals()](https://www.mybj123.com/tag/equals/)</code> 方法用来确定两个日期&#x2F;时间值是否相同:</p>
228
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> d1 = <span class="title class_">Temporal</span>.<span class="property">PlainDate</span>.<span class="title function_">from</span>(<span class="string">&#x27;2022-01-31&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> d2 = <span class="title class_">Temporal</span>.<span class="property">PlainDate</span>.<span class="title function_">from</span>(<span class="string">&#x27;2023-01-31&#x27;</span>);</span><br><span class="line">d1.<span class="title function_">equals</span>(d2); <span class="comment">// false</span></span><br></pre></td></tr></table></figure>
229
+
230
+ <h3 id="8-使用国际化-API-格式化日期"><a href="#8-使用国际化-API-格式化日期" class="headerlink" title="8. 使用国际化 API 格式化日期"></a>8. 使用国际化 API 格式化日期</h3><p>虽然这不是 Temporal API 的一部分,但 JavaScript Intl(国际化)API提供了一个 <code>[DateTimeFormat()](https://www.mybj123.com/tag/datetimeformat/)</code> 构造函数,可以用于格式化 Temporal 或 Date 对象:</p>
231
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> d = <span class="keyword">new</span> <span class="title class_">Temporal</span>.<span class="title class_">PlainDate</span>(<span class="number">2022</span>, <span class="number">3</span>, <span class="number">14</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 美国日期格式:3/14/2022</span></span><br><span class="line"><span class="keyword">new</span> <span class="title class_">Intl</span>.<span class="title class_">DateTimeFormat</span>(<span class="string">&#x27;en-US&#x27;</span>).<span class="title function_">format</span>(d);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 英国日期格式:14/3/2022</span></span><br><span class="line"><span class="keyword">new</span> <span class="title class_">Intl</span>.<span class="title class_">DateTimeFormat</span>(<span class="string">&#x27;en-GB&#x27;</span>).<span class="title function_">format</span>(d);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 西班牙长日期格式:miércoles, 14 de abril de 2022</span></span><br><span class="line"><span class="keyword">new</span> <span class="title class_">Intl</span>.<span class="title class_">DateTimeFormat</span>(<span class="string">&#x27;es-ES&#x27;</span>, &#123; <span class="attr">dateStyle</span>: <span class="string">&#x27;full&#x27;</span> &#125;).<span class="title function_">format</span>(d);</span><br></pre></td></tr></table></figure>
232
+
233
+ <p>附:</p>
234
+ <ul>
235
+ <li>TC39 关于 Temporal 的提案进度:<a target="_blank" rel="noopener" href="https://www.mybj123.com/gohref.php?url=https://tc39.es/proposal-temporal/">传送门</a></li>
236
+ <li>Chrome 关于 Temporal 的实现进度:<a target="_blank" rel="noopener" href="https://www.mybj123.com/gohref.php?url=https://chromestatus.com/feature/5668291307634688#details">传送门</a></li>
237
+ </ul>
238
+ <h2 id="四、内置对象"><a href="#四、内置对象" class="headerlink" title="四、内置对象"></a>四、内置对象</h2><h3 id="1-Object-hasOwn"><a href="#1-Object-hasOwn" class="headerlink" title="1. Object.hasOwn()"></a>1. Object.hasOwn()</h3><p>在ES2022之前,可以使用 <code>Object.prototype.hasOwnProperty()</code> 来检查一个属性是否属于对象。</p>
239
+ <p>提案中的 <code>Object.hasOwn</code> 特性是一种更简洁、更可靠的检查属性是否直接设置在对象上的方法。</p>
240
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> example = &#123;</span><br><span class="line"> <span class="attr">property</span>: <span class="string">&#x27;123&#x27;</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">hasOwnProperty</span>.<span class="title function_">call</span>(example, <span class="string">&#x27;property&#x27;</span>));</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="title function_">hasOwn</span>(example, <span class="string">&#x27;property&#x27;</span>));</span><br></pre></td></tr></table></figure>
241
+
242
+ <h3 id="2-at"><a href="#2-at" class="headerlink" title="2. at()"></a>2. <a target="_blank" rel="noopener" href="https://www.mybj123.com/tag/at/">at()</a></h3><p><code>at()</code> 是一个数组方法,用于通过给定索引来获取数组元素。当给定索引为正时,这种新方法与使用括号表示法访问具有相同的行为。当给出负整数索引时,就会从数组的最后一项开始检索:</p>
243
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> array = [<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>];</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(array[array.<span class="property">length</span>-<span class="number">1</span>]); <span class="comment">// 5</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(array.<span class="title function_">at</span>(-<span class="number">1</span>)); <span class="comment">// 5</span></span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(array[array.<span class="property">lenght</span>-<span class="number">2</span>]); <span class="comment">// 4</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(array.<span class="title function_">at</span>(-<span class="number">2</span>)); <span class="comment">// 4</span></span><br></pre></td></tr></table></figure>
244
+
245
+ <p>除了数组,字符串也可以使用<code>at()</code>方法进行索引:</p>
246
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> str = <span class="string">&quot;hello world&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(str[str.<span class="property">length</span> - <span class="number">1</span>]); <span class="comment">// d</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(str.<span class="title function_">at</span>(-<span class="number">1</span>)); <span class="comment">// d</span></span><br></pre></td></tr></table></figure>
247
+
248
+ <h3 id="3-cause"><a href="#3-cause" class="headerlink" title="3. cause"></a>3. cause</h3><p>在 ECMAScript 2022 提案中,new Error() 中可以指定导致它的原因:</p>
249
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">readFiles</span>(<span class="params">filePaths</span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> filePaths.<span class="title function_">map</span>(</span><br><span class="line"> <span class="function">(<span class="params">filePath</span>) =&gt;</span> &#123;</span><br><span class="line"> <span class="keyword">try</span> &#123;</span><br><span class="line"> <span class="comment">// ···</span></span><br><span class="line"> &#125; <span class="keyword">catch</span> (error) &#123;</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">Error</span>(</span><br><span class="line"> <span class="string">`While processing <span class="subst">$&#123;filePath&#125;</span>`</span>,</span><br><span class="line"> &#123;<span class="attr">cause</span>: error&#125;</span><br><span class="line"> );</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
250
+
251
+ <h3 id="4-正则表达式匹配索引"><a href="#4-正则表达式匹配索引" class="headerlink" title="4. 正则表达式匹配索引"></a>4. 正则表达式匹配索引</h3><p>这个新提案已经进入第 4 阶段,它将允许我们利用 d 字符来表示我们想要匹配字符串的开始和结束索引。以前,我们只能在字符串匹配操作期间获得一个包含提取的字符串和索引信息的数组。在某些情况下,这是不够的。因此,在这个新提案中,如果设置标志 <code>/d</code>,将额外获得一个带有开始和结束索引的数组。</p>
252
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> matchObj = <span class="regexp">/(a+)(b+)/</span>d.<span class="title function_">exec</span>(<span class="string">&#x27;aaaabb&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(matchObj[<span class="number">1</span>]) <span class="comment">// &#x27;aaaa&#x27;</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(matchObj[<span class="number">2</span>]) <span class="comment">// &#x27;bb&#x27;</span></span><br></pre></td></tr></table></figure>
253
+
254
+ <p>由于 <code>/d</code> 标识的存在,matchObj还有一个属性<code>.indices</code>,它用来记录捕获的每个编号组:</p>
255
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(matchObj.<span class="property">indices</span>[<span class="number">1</span>]) <span class="comment">// [0, 4]</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(matchObj.<span class="property">indices</span>[<span class="number">2</span>]) <span class="comment">// [4, 6]</span></span><br></pre></td></tr></table></figure>
256
+
257
+ <p>我们还可以使用命名组:</p>
258
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> matchObj = <span class="regexp">/(?&lt;as&gt;a+)(?&lt;bs&gt;b+)/</span>d.<span class="title function_">exec</span>(<span class="string">&#x27;aaaabb&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(matchObj.<span class="property">groups</span>.<span class="property">as</span>); <span class="comment">// &#x27;aaaa&#x27;</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(matchObj.<span class="property">groups</span>.<span class="property">bs</span>); <span class="comment">// &#x27;bb&#x27;</span></span><br></pre></td></tr></table></figure>
259
+
260
+ <p>这里给两个字符匹配分别命名为<code>as</code>和<code>bs</code>,然后就可以通过groups来获取到这两个命名分别匹配到的字符串。</p>
261
+ <p>它们的索引存储在 <code>matchObj.indices.groups</code> 中:</p>
262
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(matchObj.<span class="property">indices</span>.<span class="property">groups</span>.<span class="property">as</span>); <span class="comment">// [0, 4]</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(matchObj.<span class="property">indices</span>.<span class="property">groups</span>.<span class="property">bs</span>); <span class="comment">// [4, 6]</span></span><br></pre></td></tr></table></figure>
263
+
264
+ <p>匹配索引的一个重要用途就是指向语法错误所在位置的解析器。下面的代码解决了一个相关问题:它指向引用内容的开始和结束位置。</p>
265
+ <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> reQuoted = <span class="regexp">/“([^”]+)”/</span>dgu;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">pointToQuotedText</span>(<span class="params">str</span>) &#123;</span><br><span class="line"> <span class="keyword">const</span> startIndices = <span class="keyword">new</span> <span class="title class_">Set</span>();</span><br><span class="line"> <span class="keyword">const</span> endIndices = <span class="keyword">new</span> <span class="title class_">Set</span>();</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">const</span> match <span class="keyword">of</span> str.<span class="title function_">matchAll</span>(reQuoted)) &#123;</span><br><span class="line"> <span class="keyword">const</span> [start, end] = match.<span class="property">indices</span>[<span class="number">1</span>];</span><br><span class="line"> startIndices.<span class="title function_">add</span>(start);</span><br><span class="line"> endIndices.<span class="title function_">add</span>(end);</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">let</span> result = <span class="string">&#x27;&#x27;</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">let</span> index=<span class="number">0</span>; index &lt; str.<span class="property">length</span>; index++) &#123;</span><br><span class="line"> <span class="keyword">if</span> (startIndices.<span class="title function_">has</span>(index)) &#123;</span><br><span class="line"> result += <span class="string">&#x27;[&#x27;</span>;</span><br><span class="line"> &#125; <span class="keyword">else</span> <span class="keyword">if</span> (endIndices.<span class="title function_">has</span>(index+<span class="number">1</span>)) &#123;</span><br><span class="line"> result += <span class="string">&#x27;]&#x27;</span>;</span><br><span class="line"> &#125; <span class="keyword">else</span> &#123;</span><br><span class="line"> result += <span class="string">&#x27; &#x27;</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> result;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">pointToQuotedText</span>(<span class="string">&#x27;They said “hello” and “goodbye”.&#x27;</span>));</span><br><span class="line"><span class="comment">// &#x27; [ ] [ ] &#x27;</span></span><br></pre></td></tr></table></figure>
266
+ </div><iframe src="/donate/?AliPayQR=https://store.xuehuayu.cn/store/public/alipay_qr.jpg&amp;WeChatQR=https://store.xuehuayu.cn/store/public/wechat_qr.png&amp;UnionPayQR=null&amp;GitHub=null&amp;BTCQR=null&amp;BTCKEY=null&amp;PayPal=https://www.paypal.com/paypalme/OrdinaryPerson" style="overflow-x:hidden; overflow-y:hidden; border:0xp none #fff; min-height:240px; width:100%;" frameborder="0" scrolling="no"></iframe><div><ul class="post-copyright"><li class="post-copyright-author"><strong>本文作者:</strong>雪花雨</li><li class="post-copyright-link"><strong>本文链接:</strong><a href="/article/7a3ef8f.html">https://xuehuayu.cn/article/7a3ef8f.html</a></li><li class="post-copyright-license"><strong>版权声明:</strong>① 标为原创的文章为博主原创,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接。② 转载文章来自网络,已标明出处,<a href="mailto:cainiaoblog@126.com">侵删</a>。</li></ul></div><br><div class="tags"><a href="/tags/%E8%BD%AC%E8%BD%BD/">转载</a></div><div class="post-nav"><a class="pre" href="/article/c1867fbf.html">程序员都应该知道的一个辅助工具</a><a class="next" href="/article/5dbb6f41.html">支持扩展的安卓手机浏览器</a></div><div id="vcomment"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@waline/client@v2/dist/waline.min.css"><script src="//cdn.jsdelivr.net/npm/@waline/client@v2/dist/waline.js"></script><script>const origin = window.location.origin
267
+ const serverURL = origin.includes('cainiaoblog') ? 'https://cmts.cainiaoblog.cn' : 'https://cmts.xuehuayu.cn'
268
+ const locale = {
269
+ placeholder: '请正确填写昵称和邮箱,方便接收回复通知~',
270
+ sofa: '沙发空缺中,还不快抢~',
271
+ };
272
+ Waline.init({
273
+ el: '#vcomment',
274
+ serverURL: serverURL,
275
+ pageSize: '20',
276
+ visitor: true, // 阅读量统计
277
+ requiredMeta: ['nick', 'mail'],
278
+ emoji: [
279
+ 'https://cdn.jsdelivr.net/gh/walinejs/emojis@1.0.0/weibo',
280
+ 'https://cdn.jsdelivr.net/gh/walinejs/emojis@1.0.0/qq',
281
+ 'https://cdn.jsdelivr.net/gh/walinejs/emojis@1.0.0/tw-emoji',
282
+ ],
283
+ locale,
284
+ pageview: true
285
+ })
286
+ </script></div></div></div><div class="pure-u-1 pure-u-md-1-4 fixed-search hidden_mid_and_down"><div id="sidebar"><script type="text/javascript" src="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/js/search.min.js"></script><div class="widget"><div class="widget-search"><input class="search" type="radio" name="search" value="baidu" id="baidu" checked="checked"/><label class="label" for="baidu" title="百度全站搜索">百度</label><input class="search" type="radio" name="search" value="google" id="google"/><label class="label" for="google" title="谷歌全站搜索">谷歌</label><input class="search" type="radio" name="search" value="self" id="self"/><label class="label" for="self" title="使用站内搜索">站内</label></div><div class="widget" id="search"><form class="search-form" action="//www.baidu.com/baidu" method="get" accept-charset="utf-8" target="_blank"><input type="search" name="word" maxlength="30" placeholder="百度全站搜索"/><input type="hidden" name="si" value="xuehuayu.cn"/><input type="hidden" name="cl" value="3"/><input type="hidden" name="ct" value="2097152"/><input type="hidden" name="s" value="on"/><input class="search-submit" type="submit" value=""/></form></div></div><script>$('input[type=radio][name=search]').change(function() {
287
+ var val = $(this).val()
288
+ var self = '<div class="search-form"><input id="local-search-input" placeholder="站内搜索,首次慢" type="search" name="q" results="0"><input class="search-submit" type="submit" value=""/><div id="local-search-result"></div></div>'
289
+ var google = '<form class="search-form" action="//www.google.com/search" method="get" accept-charset="utf-8" target="_blank"><input type="search" name="q" maxlength="30" placeholder="谷歌全站搜索"><input type="hidden" name="sitesearch" value="xuehuayu.cn"><input class="search-submit" type="submit" value=""/></form>'
290
+ var baidu = '<form class="search-form" action="//www.baidu.com/baidu" method="get" accept-charset="utf-8" target="_blank"><input type="search" name="word" maxlength="30" placeholder="百度全站搜索"><input type="hidden" name="si" value="xuehuayu.cn"><input type="hidden" name="cl" value="3"><input type="hidden" name="ct" value="2097152"><input type="hidden" name="s" value="on"><input class="search-submit" type="submit" value=""/></form>'
291
+
292
+ if (val === 'self') {
293
+ $('#search').html(self)
294
+ var search_path = 'search.xml';
295
+ if (search_path.length == 0) {
296
+ search_path = 'search.xml';
297
+ }
298
+ var path = 'https://cdn.staticaly.com/gh/npljy/npljy.github.io/main/' + search_path;
299
+ searchFunc(path, 'local-search-input', 'local-search-result');
300
+ } else if (val === 'baidu') {
301
+ $('#search').html(baidu)
302
+ } else if (val === 'google') {
303
+ $('#search').html(google)
304
+ }
305
+ })</script><div class="widget widget-wxmp"><img alt="微信公众号" width="100%" src="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/img/mp-mini.jpg"/></div><div class="widget widget-categories"><div class="widget-title"><i class="fa fa-folder-o"> 分类</i></div><ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/categories/CDN/">CDN</a><span class="category-list-count">2</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/IDE/">IDE</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/git/">git</a><span class="category-list-count">2</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/hexo/">hexo</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%85%AC%E5%85%B1%E8%8A%82%E6%97%A5/">公共节日</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%88%86%E4%BA%AB/">分享</a><span class="category-list-count">29</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%89%8D%E7%AB%AF/">前端</a><span class="category-list-count">191</span><ul class="category-list-child"><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%89%8D%E7%AB%AF/%E6%B5%8F%E8%A7%88%E5%99%A8/">浏览器</a><span class="category-list-count">1</span><ul class="category-list-child"><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%89%8D%E7%AB%AF/%E6%B5%8F%E8%A7%88%E5%99%A8/%E7%BD%91%E7%BB%9C%E5%8D%8F%E8%AE%AE/">网络协议</a><span class="category-list-count">1</span></li></ul></li></ul></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%8D%9A%E5%AE%A2/">博客</a><span class="category-list-count">3</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%B7%A5%E5%85%B7/">工具</a><span class="category-list-count">2</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%B9%BF%E5%91%8A%E8%BF%87%E6%BB%A4/">广告过滤</a><span class="category-list-count">8</span><ul class="category-list-child"><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%B9%BF%E5%91%8A%E8%BF%87%E6%BB%A4/%E8%A7%86%E9%A2%91%E7%94%B5%E8%A7%86%E5%B0%8F%E8%AF%B4%E6%BC%AB%E7%94%BB%E8%B5%84%E8%AE%AF%E9%9F%B3%E4%B9%90/">视频电视小说漫画资讯音乐</a><span class="category-list-count">2</span></li></ul></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E6%AD%A3%E5%88%99/">正则</a><span class="category-list-count">5</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E6%B5%8F%E8%A7%88%E5%99%A8/">浏览器</a><span class="category-list-count">5</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E7%AE%97%E6%B3%95/">算法</a><span class="category-list-count">2</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E8%B5%84%E8%AE%AF/">资讯</a><span class="category-list-count">16</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E8%BD%BB%E6%9D%BE%E4%B8%80%E5%88%BB/">轻松一刻</a><span class="category-list-count">1</span></li></ul></div><div class="widget widget-tags"><div class="widget-title"><i class="fa fa-star-o"> 标签</i></div><div class="tagcloud"><a href="/tags/%E5%8E%9F%E5%88%9B/" style="font-size: 15px;">原创</a> <a href="/tags/%E8%BD%AC%E8%BD%BD/" style="font-size: 15px;">转载</a> <a href="/tags/%E6%89%8B%E5%86%99/" style="font-size: 15px;">手写</a> <a href="/tags/%E7%96%AB%E6%83%85/" style="font-size: 15px;">疫情</a> <a href="/tags/%E5%A8%B1%E4%B9%90/" style="font-size: 15px;">娱乐</a></div></div><div class="widget widget-recent-posts"><div class="widget-title"><i class="fa fa-file-o"> 最近文章</i></div><ul class="post-list"><li class="post-list-item"><a class="post-list-link" href="/article/c5576490.html">面试准备</a></li><li class="post-list-item"><a class="post-list-link" href="/article/84c9ccd6.html">精读《SolidJS》</a></li><li class="post-list-item"><a class="post-list-link" href="/article/53803e6.html">git提交注释规范</a></li><li class="post-list-item"><a class="post-list-link" href="/article/a4145266.html">前端数组拍平flat一行代码</a></li><li class="post-list-item"><a class="post-list-link" href="/article/bedea419.html">一道前端this面试题</a></li><li class="post-list-item"><a class="post-list-link" href="/article/bf7e7421.html">git多账号配置</a></li></ul></div><div class="widget widget-links"><div class="widget-title"><i class="fa fa-external-link"> 友情链接</i></div><ul></ul><a href="https://github.com/npljy?utm_source=xuehuayu.cn" title="GitHub" target="_blank">GitHub</a><ul></ul><a href="https://laonongmin.online?utm_source=xuehuayu.cn" title="看看" target="_blank">看看</a><ul></ul><a href="https://cainiaoblog.cn?utm_source=xuehuayu.cn" title="菜鸟博客" target="_blank">菜鸟博客</a><ul></ul><a href="mailto:cainiaoblog@126.com" title="友链联系" target="_blank">友链联系</a></div></div></div><div class="pure-u-1 pure-u-md-3-4"><div id="footer"><div class="flex-block justify-center align-center flex-wrap"><a class="gxba-link" id="gxba" rel="nofollow" target="_blank" href="http://beian.miit.gov.cn/">京ICP备20007647号-2</a><a class="gaba-link" id="gaba-link" rel="nofollow" target="_blank" href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=11010802031264"><img class="nofancybox" src="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/img/gaba.png" alt=""/><span id="gaba">京公网安备 11010802031264号</span><span style="padding-right: 10px;"></span></a><span>Copyright © 2023 </span><a href="/." rel="nofollow">前端壹菜鸟. </a><script>(function(){
306
+ var cnb =window.location.origin.indexOf('cainiaoblog') !==-1
307
+ if (cnb) {
308
+ var gxba =document.getElementById('gxba')
309
+ var gaba =document.getElementById('gaba')
310
+ var gabaLink =document.getElementById('gaba-link')
311
+ gxba.innerText ='京ICP备20007647号-1'
312
+ gaba.innerText ='京公网安备 11010802031254号'
313
+ gabaLink.setAttribute('href','http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=11010802031254')
314
+ }
315
+ })()</script></div><div class="flex-block justify-center align-center flex-wrap"><a rel="nofollow" target="_blank" href="https://v6.51.la/s/Guz3lwHCsVme9Cu"><div class="busuanzi_container" id="busuanzi_container"><span class="busuanzi_container_site_pv" id="busuanzi_container_site_pv">访问量:<span id="busuanzi_value_site_pv"><i class="fa fa-spinner"></i></span></span><span class="busuanzi_container_site_uv" id="busuanzi_container_site_uv">访客数:<span id="busuanzi_value_site_uv"><i class="fa fa-spinner"></i></span></span><span style="padding-right: 10px;"></span></div></a><a rel="nofollow" target="_blank" href="https://www.upyun.com/?utm_source=lianmeng&amp;utm_medium=referral"><span style="font-weight:bold;letter-spacing: 1px;">本网站由 </span><img class="nofancybox" height="32" style="vertical-align: middle" src="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/img/upy_logo.min.svg" alt=""/><span style="font-weight:bold;letter-spacing: 1px;">提供CDN加速/云存储服务</span></a><span style="padding-right: 10px;"></span><a rel="nofollow" style="font-size:18px;font-weight:bold;vertical-align: middle" target="_blank" title="注册就送代金券可直接使用" href="https://console.upyun.com/register/?invite=HyDsjZHIL">注册</a></div></div></div></div><a class="show" id="rocket" href="#top"></a><div class="darkmode-toggle">🌓</div><script type="text/javascript" src="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/js/totop.min.js" async></script><script type="text/javascript" src="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/js/dark.min.js" async></script><script type="text/javascript" src="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/js/codeblock-resizer.min.js"></script><script type="text/javascript" src="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/js/smartresize.min.js"></script></div></body></html>