-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path3518582965.html
More file actions
1229 lines (900 loc) · 76.8 KB
/
Copy path3518582965.html
File metadata and controls
1229 lines (900 loc) · 76.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html lang="en" data-default-color-scheme="auto">
<head>
<meta charset="UTF-8">
<link rel="apple-touch-icon" sizes="76x76" href="/img/fluid.png">
<link rel="icon" href="/img/fluid.png">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="theme-color" content="#2f4154">
<meta name="author" content="FangZhou">
<meta name="keywords" content="Vue,React,Nodejs,blogs,frontend,web,developer,programmer">
<meta name="description" content="关于JavaScript核心知识的八股文笔记,包括事件循环、本地存储和数组方法">
<meta property="og:type" content="article">
<meta property="og:title" content="前端深入学习笔记">
<meta property="og:url" content="http://arkpln.github.io/3518582965.html">
<meta property="og:site_name" content="Ark的技术博客">
<meta property="og:description" content="关于JavaScript核心知识的八股文笔记,包括事件循环、本地存储和数组方法">
<meta property="og:locale" content="en_US">
<meta property="og:image" content="http://arkpln.github.io/images/fe.jpg">
<meta property="article:published_time" content="2025-04-06T13:20:29.000Z">
<meta property="article:modified_time" content="2026-01-26T03:59:49.195Z">
<meta property="article:author" content="FangZhou">
<meta property="article:tag" content="frontend">
<meta property="article:tag" content="javascript">
<meta property="article:tag" content="eventloop">
<meta property="article:tag" content="localstorage">
<meta property="article:tag" content="array">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="http://arkpln.github.io/images/fe.jpg">
<title>前端深入学习笔记 - Ark的技术博客</title>
<link rel="stylesheet" href="https://lib.baomitu.com/twitter-bootstrap/4.6.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://lib.baomitu.com/github-markdown-css/4.0.0/github-markdown.min.css">
<link rel="stylesheet" href="https://lib.baomitu.com/hint.css/2.7.0/hint.min.css">
<link rel="stylesheet" href="https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.css">
<!-- 主题依赖的图标库,不要自行修改 -->
<!-- Do not modify the link that theme dependent icons -->
<link rel="stylesheet" href="//at.alicdn.com/t/c/font_1749284_5i9bdhy70f8.css">
<link rel="stylesheet" href="//at.alicdn.com/t/c/font_1736178_k526ubmyhba.css">
<link rel="stylesheet" href="/css/main.css">
<link id="highlight-css" rel="stylesheet" href="/css/highlight.css">
<link id="highlight-css-dark" rel="stylesheet" href="/css/highlight-dark.css">
<script id="fluid-configs">
var Fluid = window.Fluid || {};
Fluid.ctx = Object.assign({}, Fluid.ctx)
var CONFIG = {"hostname":"arkpln.github.io","root":"/","version":"1.9.8","typing":{"enable":true,"typeSpeed":70,"cursorChar":"_","loop":false,"scope":[]},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"left","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"code_language":{"enable":true,"default":"TEXT"},"copy_btn":true,"image_caption":{"enable":true},"image_zoom":{"enable":true,"img_url_replace":["",""]},"toc":{"enable":true,"placement":"right","headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"loading_img":"/img/loading.gif","onlypost":false,"offset_factor":2},"web_analytics":{"enable":true,"follow_dnt":true,"baidu":null,"google":{"measurement_id":null},"tencent":{"sid":null,"cid":null},"leancloud":{"app_id":"mEwkD7geCX7RWNO8srhDE2oP-gzGzoHsz","app_key":"4EF76hyiVA1QILHZThVbfoat","server_url":"https://mewkd7ge.lc-cn-n1-shared.com","path":"window.location.pathname","ignore_local":false},"umami":{"src":null,"website_id":null,"domains":null,"start_time":"2024-01-01T00:00:00.000Z","token":null,"api_server":null}},"search_path":"/local-search.xml","include_content_in_search":true};
if (CONFIG.web_analytics.follow_dnt) {
var dntVal = navigator.doNotTrack || window.doNotTrack || navigator.msDoNotTrack;
Fluid.ctx.dnt = dntVal && (dntVal.startsWith('1') || dntVal.startsWith('yes') || dntVal.startsWith('on'));
}
</script>
<script src="/js/utils.js"></script>
<script src="/js/color-schema.js"></script>
<meta name="google-site-verification" content="5KfTZvtlydmBIzY97rVo-caP5jljAfmD3Qs3sBzY2Go"><style>ins.adsbygoogle[data-ad-status="unfilled"] { display: none !important; }</style>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<header>
<div class="header-inner" style="height: 70vh;">
<nav id="navbar" class="navbar fixed-top navbar-expand-lg navbar-dark scrolling-navbar">
<div class="container">
<a class="navbar-brand" href="/">
<strong>Ark的技术博客</strong>
</a>
<button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<div class="animated-icon"><span></span><span></span><span></span></div>
</button>
<!-- Collapsible content -->
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ml-auto text-center">
<li class="nav-item">
<a class="nav-link" href="/" target="_self">
<i class="iconfont icon-home-fill"></i>
<span>快乐老家</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/archives/" target="_self">
<i class="iconfont icon-archive-fill"></i>
<span>笔岚档案</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/categories/" target="_self">
<i class="iconfont icon-category-fill"></i>
<span>文以类聚</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/tags/" target="_self">
<i class="iconfont icon-tags-fill"></i>
<span>按标签阅览</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/about/" target="_self">
<i class="iconfont icon-user-fill"></i>
<span>联系我</span>
</a>
</li>
<li class="nav-item" id="search-btn">
<a class="nav-link" target="_self" href="javascript:;" data-toggle="modal" data-target="#modalSearch" aria-label="Search">
<i class="iconfont icon-search"></i>
</a>
</li>
<li class="nav-item" id="color-toggle-btn">
<a class="nav-link" target="_self" href="javascript:;" aria-label="Color Toggle">
<i class="iconfont icon-dark" id="color-toggle-icon"></i>
</a>
</li>
</ul>
</div>
</div>
</nav>
<div id="banner" class="banner" parallax="true" style="background: url('/images/fe.jpg') no-repeat center center; background-size: cover;">
<div class="full-bg-img">
<div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
<div class="banner-text text-center fade-in-up">
<div class="h2">
<span id="subtitle" data-typed-text="前端深入学习笔记"></span>
</div>
<div class="mt-3">
<span class="post-meta">
<i class="iconfont icon-date-fill" aria-hidden="true"></i>
<time datetime="2025-04-06 21:20" pubdate>
April 6, 2025 pm
</time>
</span>
</div>
<div class="mt-1">
<span class="post-meta mr-2">
<i class="iconfont icon-chart"></i>
11k words
</span>
<span class="post-meta mr-2">
<i class="iconfont icon-clock-fill"></i>
95 mins
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</header>
<main>
<div class="container-fluid nopadding-x">
<div class="row nomargin-x">
<div class="side-col d-none d-lg-block col-lg-2">
<aside class="sidebar d-none d-xl-block" style="margin-right:-1rem;z-index:-1"><ins class="adsbygoogle" style="display:flex;justify-content:center;min-width:160px;max-width:300px;width:100%;height:600px;position:sticky;top:2rem" data-ad-client="ca-pub-3240358922862141" data-ad-slot="6522434837"></ins><script> (adsbygoogle = window.adsbygoogle || []).push({}); </script></aside>
</div>
<div class="col-lg-8 nopadding-x-md">
<div class="container nopadding-x-md" id="board-ctn">
<div id="board">
<article class="post-content mx-auto">
<h1 id="seo-header">前端深入学习笔记</h1>
<div class="markdown-body">
<h1 id="前端八股文学习笔记"><a href="#前端八股文学习笔记" class="headerlink" title="前端八股文学习笔记"></a>前端八股文学习笔记</h1><h2 id="Javascript"><a href="#Javascript" class="headerlink" title="Javascript"></a>Javascript</h2><h3 id="EventLoop-微任务与宏任务"><a href="#EventLoop-微任务与宏任务" class="headerlink" title="EventLoop 微任务与宏任务"></a>EventLoop 微任务与宏任务</h3><blockquote>
<p>参考资料:<br><a href="https://juejin.cn/post/7484521465200132122" target="_blank" rel="noopener noreferrer">深入浅出 JavaScript 事件循环与异步编程技巧</a><br><a href="https://juejin.cn/post/7108751200262029319" target="_blank" rel="noopener noreferrer">一文详解Event Loop事件循环、微任务、宏任务</a></p>
</blockquote>
<h4 id="1-调用栈"><a href="#1-调用栈" class="headerlink" title="1.调用栈"></a>1.调用栈</h4><p>调用栈是 JavaScript 执行<strong>同步代码</strong>的地方。它是一个<strong>后进先出</strong>的数据结构,用来记录函数的调用顺序。每当一个函数被调用时,它就会被推入调用栈;当函数执行完毕后,它就会从调用栈中弹出。</p>
<p>例如:</p>
<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><span class="line">25</span><br></pre></td><td class="code"><pre><code class="hljs js"><br><span class="hljs-comment">//eloop1.js</span><br><br><br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">foo</span>(<span class="hljs-params"></span>) {<br><br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'foo'</span>);<br><br> }<br><br> <span class="hljs-keyword">function</span> <span class="hljs-title function_">bar</span>(<span class="hljs-params"></span>) {<br><br> <span class="hljs-title function_">foo</span>();<br><br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'bar'</span>);<br><br> }<br><br> <span class="hljs-title function_">bar</span>();<br><br><span class="hljs-comment">// foo</span><br><br><span class="hljs-comment">// bar</span><br><br></code></pre></td></tr></table></figure>
<h4 id="2-任务队列"><a href="#2-任务队列" class="headerlink" title="2.任务队列"></a>2.任务队列</h4><p>任务队列用于存放异步任务的回调函数。当异步任务(如 <code>setTimeout</code>、<code>setInterval</code>、I/O 操作等)完成时,它们的回调函数会被放入任务队列中,等待事件循环处理。</p>
<p>具体的来说,异步任务又分为宏任务(Macrotask)和微任务(Microtask)</p>
<h5 id="宏任务"><a href="#宏任务" class="headerlink" title="宏任务"></a>宏任务</h5><p>宏任务是事件循环中的主要任务单元。每次事件循环会执行一个宏任务,然后检查并执行所有的微任务。</p>
<p>常见宏任务有:</p>
<table>
<thead>
<tr>
<th>宏任务类型</th>
<th>具体形态</th>
</tr>
</thead>
<tbody><tr>
<td>定时器操作</td>
<td><code>setTimeout</code>,<code>setInterval</code></td>
</tr>
<tr>
<td>I/O 操作</td>
<td>文件读写、网络请求等</td>
</tr>
<tr>
<td>UI 渲染</td>
<td>浏览器中的 UI 更新。</td>
</tr>
<tr>
<td>事件回调</td>
<td><code>click</code>、<code>scroll</code> 等 DOM 事件</td>
</tr>
<tr>
<td><code>requestAnimationFrame</code></td>
<td>浏览器中的动画帧回调(优先级高于普通宏任务)</td>
</tr>
<tr>
<td><code>setImmediate</code></td>
<td>(Node.js 特有):在当前事件循环结束后立即执行。</td>
</tr>
</tbody></table>
<h5 id="微任务"><a href="#微任务" class="headerlink" title="微任务"></a>微任务</h5><p>微任务队列用于存放优先级更高的异步任务回调,微任务会在当前任务执行完毕后立即执行且会在下一个宏任务开始之前清空。</p>
<table>
<thead>
<tr>
<th>微任务类型</th>
<th>具体形态</th>
</tr>
</thead>
<tbody><tr>
<td><code>Promise</code>的回调</td>
<td><code>then</code>,<code>catch</code>,<code>finally</code></td>
</tr>
<tr>
<td><code>async / await</code></td>
<td>异步方法</td>
</tr>
<tr>
<td><code>queueMicrotask</code></td>
<td>将任务推入微队列的API</td>
</tr>
<tr>
<td><code>MutationObserver</code></td>
<td>监听DOM变化的回调</td>
</tr>
</tbody></table>
<h4 id="3-事件循环的流程"><a href="#3-事件循环的流程" class="headerlink" title="3.事件循环的流程"></a>3.事件循环的流程</h4><ol>
<li><p><strong>执行同步代码</strong> :从调用栈里执行同步任务</p>
</li>
<li><p><strong>异步任务压入任务队列</strong>:遇到宏/微任务,加入对应的任务队列</p>
</li>
<li><p><strong>清空微任务队列</strong>:循环执行所有微任务(如 Promise 的回调)。</p>
</li>
<li><p><strong>执行一个宏任务</strong>:从宏任务队列中取出一个宏任务执行。</p>
</li>
</ol>
<p>参考示例</p>
<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><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><code class="hljs js"><br><span class="hljs-comment">//eloop2.js</span><br><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'Script start'</span>);<br><br><br><br><span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =></span> {<br><br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'Timeout'</span>);<br><br>}, <span class="hljs-number">0</span>);<br><br><br><br><span class="hljs-title class_">Promise</span>.<span class="hljs-title function_">resolve</span>(<br><br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">"Behind Promise"</span>)<br><br>).<span class="hljs-title function_">then</span>(<span class="hljs-function">() =></span> {<br><br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'Promise'</span>);<br><br>});<br><br><br><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'Script end'</span>);<br><br><span class="hljs-comment">// Script start</span><br><br><span class="hljs-comment">// Behind Promise</span><br><br><span class="hljs-comment">// Script end</span><br><br><span class="hljs-comment">// Promise</span><br><br><span class="hljs-comment">// Timeout</span><br><br><br><br></code></pre></td></tr></table></figure>
<h4 id="4-不得不品的易错点!"><a href="#4-不得不品的易错点!" class="headerlink" title="4.不得不品的易错点!"></a>4.不得不品的易错点!</h4><ol>
<li><code>Promise</code>本身是一个<strong>同步</strong>的代码(只是容器),只有它后面调用的<code>then()</code>方法里面的回调才是微任务</li>
</ol>
<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></pre></td><td class="code"><pre><code class="hljs js"><br><span class="hljs-keyword">new</span> <span class="hljs-title class_">Promise</span>(<span class="hljs-function"><span class="hljs-params">resolve</span> =></span>{<br><br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'111'</span>)<br><br> <span class="hljs-title function_">resolve</span>()<br><br>}).<span class="hljs-title function_">then</span>(<span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){<br><br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">"222"</span>)<br><br>})<br><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'333'</span>)<br><br><br><br><span class="hljs-comment">// 111</span><br><br><span class="hljs-comment">// 333</span><br><br><span class="hljs-comment">// 222</span><br><br></code></pre></td></tr></table></figure>
<ol start="2">
<li><code>await</code>右边的<strong>第一个表达式</strong>还是会<strong>立即执行</strong>,表达式之后的代码才是微任务</li>
</ol>
<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><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><code class="hljs js"><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-number">1</span>) <span class="hljs-comment">//1</span><br><br><span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">async1</span>(<span class="hljs-params"></span>) {<br><br> <span class="hljs-keyword">await</span> <span class="hljs-title function_">async2</span>()<span class="hljs-comment">//3</span><br><br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-number">2</span>)<span class="hljs-comment">//6</span><br><br> <span class="hljs-keyword">await</span> <span class="hljs-title function_">async3</span>()<span class="hljs-comment">//7</span><br><br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-number">3</span>)<br><br>}<br><br><span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">async2</span>(<span class="hljs-params"></span>) {<br><br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-number">4</span>)<span class="hljs-comment">//4</span><br><br>}<br><br><br><br><span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">async3</span>(<span class="hljs-params"></span>) {<br><br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-number">5</span>)<span class="hljs-comment">//8</span><br><br>}<br><br><br><br><span class="hljs-title function_">async1</span>()<span class="hljs-comment">//2</span><br><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-number">6</span>)<span class="hljs-comment">//5</span><br><br><span class="hljs-comment">// 1 4 6 2 5 3</span><br><br></code></pre></td></tr></table></figure>
<h4 id="5-例题"><a href="#5-例题" class="headerlink" title="5.例题"></a>5.例题</h4><p><img src="/bench.webp" srcset="/img/loading.gif" lazyload alt="例题"><br><strong>解析:</strong></p>
<p>1.先执行主线程上的同步代码,打印1</p>
<p>2.执行第9行的函数,进⼊async1内部,async1其实是声明了⼀个promise,promise是同步代码,会顺序执⾏打印async2函数里的4 ,只有.then⾥⾯的代码会加⼊微任务队列⾥,这⾥相当于执⾏了async2()之后,再将后面的代码加⼊⼀个微任务队列中。</p>
<p>3.回主线程中,遇到setTimeout(),加⼊到宏任务队列</p>
<p>4.主线程继续往后执⾏,前⾯说过,promise是同步代码,.then后⾯的回调会加⼊微任务队列,所以会打印13⾏的7</p>
<p>5.主线程执⾏完成,开始执⾏微任务队列内的任务,遵循先进先出的原则,打印第四⾏的2。然后接着执行第5行第二个awaite右边的代码,打印5。第6行这个时候就被加入微任务队列。</p>
<p>6.接着会执行第二个微任务,也就是16行代码,打印8。第17行的then这个时候也会加入微任务队列。再依次执行第6行和第17行的两个微任务,打印3和9</p>
<p>7.微任务执⾏结束,开始执⾏宏任务setTimeout,打印11⾏的6.</p>
<h4 id="6-总结"><a href="#6-总结" class="headerlink" title="6.总结"></a>6.总结</h4><p>所有同步任务都在主线程上执行,形成一个执行栈(call stack)。</p>
<p>遇到异步任务, 进入异步处理模块并注册回调函数; 等到指定的事件完成(如ajax请求响应返回, setTimeout延迟到指定时间)时,异步处理模块会将这个回调函数移入异步任务队列。</p>
<p>当栈中的代码执行完毕,执行栈中的任务为空时,主线程会先检查微任务队列中是否有任务,如果有,就将微任务队列中的所有任务依次执行,直到微任务队列为空; 之后再检查宏任务队列中是否有任务,如果有,则取出第一个宏任务加入到执行栈中,之后再清空执行栈,检查微任务,以此循环,直到全部的任务都执行完成。</p>
<h3 id="本地化存储"><a href="#本地化存储" class="headerlink" title="本地化存储"></a>本地化存储</h3><blockquote>
<p>参考资料<br><a href="https://juejin.cn/post/7273025863981383680" target="_blank" rel="noopener noreferrer">深度解析本地化存储方案与项目实战经验</a><br><a href="https://juejin.cn/post/7490391876743561256" target="_blank" rel="noopener noreferrer">前端知识库</a></p>
</blockquote>
<h4 id="Cookies"><a href="#Cookies" class="headerlink" title="Cookies"></a>Cookies</h4><h5 id="Cookies是什么"><a href="#Cookies是什么" class="headerlink" title="Cookies是什么"></a>Cookies是什么</h5><p>Cookie 是浏览器和服务器之间传递小型数据的一种机制。它通常用于存储客户端(如浏览器)的一些信息,这些信息会在随后的请求中自动发送给服务器,帮助服务器记住用户的状态或者行为。例如,可以用 Cookie 记录用户的登录状态、购物车内容等。<br><strong>特点:</strong></p>
<ol>
<li>容量小:每个Cookie通常只能存储4KB左右的数据。</li>
<li>跨浏览器支持:几乎所有现代浏览器都支持Cookies。</li>
<li>自动发送:浏览器在每次HTTP请求中都会自动发送与网站相关的Cookies。</li>
</ol>
<h5 id="Cookies在HTTP中的使用"><a href="#Cookies在HTTP中的使用" class="headerlink" title="Cookies在HTTP中的使用"></a>Cookies在HTTP中的使用</h5><p>在 HTTP 请求和响应中,Cookie 的使用主要通过 HTTP 头部来进行。</p>
<ol>
<li><p>服务器设置 Cookie:<br>当服务器希望在浏览器中存储一些信息时,它会通过 HTTP 响应头中的 <code>Set-Cookie</code> 字段来设置 Cookie。</p>
<figure class="highlight http"><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><code class="hljs http"><span class="hljs-meta">HTTP/1.1</span> <span class="hljs-number">200</span> OK<br><span class="hljs-attribute">Content-Type</span><span class="hljs-punctuation">: </span>text/html<br><span class="hljs-attribute">Set-Cookie</span><span class="hljs-punctuation">: </span>userId=12345; Expires=Thu, 01 Jan 2026 00:00:00 GMT; Path=/<br></code></pre></td></tr></table></figure>
</li>
<li><p>客户端发送 Cookie:当浏览器向服务器发送请求时,浏览器会自动将存储的 Cookie 通过 Cookie 头发送给服务器。例如:</p>
<figure class="highlight http"><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><code class="hljs http"><span class="hljs-keyword">GET</span> <span class="hljs-string">/index.html</span> <span class="hljs-meta">HTTP/1.1</span><br><span class="hljs-attribute">Host</span><span class="hljs-punctuation">: </span>www.example.com<br><span class="hljs-attribute">Cookie</span><span class="hljs-punctuation">: </span>userId=12345<br></code></pre></td></tr></table></figure>
<h5 id="Cookie-的生命周期"><a href="#Cookie-的生命周期" class="headerlink" title="Cookie 的生命周期"></a>Cookie 的生命周期</h5></li>
</ol>
<ul>
<li><strong>会话 Cookie</strong>:没有设置 <code>Expires</code> 或 <code>Max-Age</code> 的 Cookie 是会话 Cookie,它仅在当前浏览器会话有效,浏览器关闭时会自动删除。</li>
<li><strong>持久 Cookie</strong>:设置了 <code>Expires</code> 或 <code>Max-Age</code>,则该 Cookie 是持久化的,直到指定的时间点才会过期。</li>
</ul>
<h5 id="Cookies的设置"><a href="#Cookies的设置" class="headerlink" title="Cookies的设置"></a>Cookies的设置</h5><p>可以通过 <code>document.cookie</code> 来设置 Cookie。基本语法如下:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-variable language_">document</span>.<span class="hljs-property">cookie</span> = <span class="hljs-string">'name=value; expires=expiration_date; path=path; domain=domain; secure'</span>;<br></code></pre></td></tr></table></figure>
<ul>
<li><code>name=value</code>:Cookie 的键值对。</li>
<li><code>expires</code>:指定过期时间,必须是有效的 UTC 格式。如果不设置,则默认为会话 Cookie。</li>
<li><code>path</code>:指定路径,默认为当前页面路径。</li>
<li><code>domain</code>:指定 Cookie 的有效域名。(解决跨域问题)</li>
<li><code>secure</code>:表示该 Cookie 只通过 HTTPS 协议发送。</li>
</ul>
<h5 id="Cookies的安全性"><a href="#Cookies的安全性" class="headerlink" title="Cookies的安全性"></a>Cookies的安全性</h5><ul>
<li><p><code>HttpOnly</code>:如果设置了 <code>HttpOnly</code> 标志,该 Cookie 不能被 JavaScript 访问,避免 XSS 攻击窃取 Cookie 中的敏感信息。</p>
</li>
<li><p><code>Secure</code>:如果设置了 <code>Secure</code> 标志,Cookie 只能通过 HTTPS 连接发送,避免在 HTTP 连接中泄漏。</p>
</li>
<li><p><code>SameSite</code>:<code>SameSite</code> 属性可以防止跨站请求伪造攻击。它有三种值:</p>
</li>
</ul>
<ol>
<li><p>Strict:严格限制,只有在相同站点内的请求中才会发送 Cookie。</p>
</li>
<li><p>Lax:宽松限制,允许部分跨站请求(如通过链接跳转)。</p>
</li>
<li><p>None:没有限制,允许跨站请求发送 Cookie,但需要同时设置 Secure。</p>
</li>
</ol>
<h5 id="Cookie的问题"><a href="#Cookie的问题" class="headerlink" title="Cookie的问题"></a>Cookie的问题</h5><ol>
<li>储存空间限制,Cookie至多4kb左右</li>
<li>性能问题,Cookie塞在http请求头中会拖慢请求速度</li>
<li>跨域问题,Cookie只能在同域名下收发,可以通过设置<code>domain</code>解决</li>
<li>Cookie 会在客户端存储一些信息,因此容易受到各种安全攻击,可以通过设置好<code>secure</code>,<code>samesite</code>属性来解决</li>
</ol>
<h5 id="Cookies总结"><a href="#Cookies总结" class="headerlink" title="Cookies总结"></a>Cookies总结</h5><p>Cookie 是一种用于存储客户端信息的小型数据,通常用于保持用户会话、保存用户偏好设置或跟踪用户行为。它通过 HTTP 头部在客户端与服务器之间传递,可以是会话 Cookie(在浏览器会话期间有效)或 持久 Cookie(有明确的过期时间)。<br>虽然 Cookie 使用广泛,但它也存在一些缺点,如存储空间有限、性能问题、安全性隐患、隐私问题和跨域限制等。<br>因此,在使用 Cookie 时,需要考虑适当的安全措施并合理管理其生命周期。</p>
<h4 id="localStorage"><a href="#localStorage" class="headerlink" title="localStorage"></a>localStorage</h4><h5 id="localStorage是什么"><a href="#localStorage是什么" class="headerlink" title="localStorage是什么"></a>localStorage是什么</h5><p>LocalStorage 是一种 Web 存储机制,允许在客户端(即浏览器)以键值对的形式存储数据。<br>与 Cookie 相比,LocalStorage 提供了更大的存储空间(通常为 5MB 或更多),并且数据存储在浏览器中。<br>即使关闭浏览器或重新启动电脑,数据也会保持直到被手动删除或过期。<br><strong>特点:</strong></p>
<ol>
<li>容量大:允许每个域名存储5MB甚至更多</li>
<li>永久存储:除非主动删除,否则存储的数据会在浏览器关闭后仍然存在,直到明确地被删除。</li>
<li>数据隔离:LocalStorage 中的数据按 域名 隔离,不同域名间的数据无法访问。</li>
<li>同步操作:LocalStorage 的访问是 同步的,每次操作都会立即影响存储的数据。</li>
<li>安全性好:与Cookie相比,localStorage不会主动发送到服务器</li>
</ol>
<h5 id="localStorage的使用"><a href="#localStorage的使用" class="headerlink" title="localStorage的使用"></a>localStorage的使用</h5><p>LocalStorage 使用 键值对 存储数据,你可以通过 localStorage 对象的 API 来设置、获取、删除数据。</p>
<p>我们可以使用 <code>localStorage.setItem(key, value)</code> 方法存储数据。<br>这里的 key 是数据的键,value 是存储的数据。<br>值必须是<strong>字符串</strong>,如果要存储非字符串数据,需要先将其转换为字符串(通常使用 <code>JSON.stringify()</code>)。</p>
<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><code class="hljs js"><span class="hljs-comment">// 存储数据</span><br><span class="hljs-variable language_">localStorage</span>.<span class="hljs-title function_">setItem</span>(<span class="hljs-string">'username'</span>, <span class="hljs-string">'JohnDoe'</span>);<br><span class="hljs-variable language_">localStorage</span>.<span class="hljs-title function_">setItem</span>(<span class="hljs-string">'age'</span>, <span class="hljs-string">'30'</span>);<br></code></pre></td></tr></table></figure>
<p>通过 <code>localStorage.getItem(key)</code> 方法来读取存储的数据。它会返回该 key 对应的值,如果该键不存在,则返回 null。</p>
<p>使用 <code>localStorage.removeItem(key)</code> 来删除指定的键值对。</p>
<p>使用 <code>localStorage.clear()</code> 清除存储在 LocalStorage 中的所有数据。</p>
<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><code class="hljs js"><span class="hljs-comment">// 存储对象</span><br><span class="hljs-keyword">const</span> user = {<br> <span class="hljs-attr">username</span>: <span class="hljs-string">'JohnDoe'</span>,<br> <span class="hljs-attr">age</span>: <span class="hljs-number">30</span>,<br>};<br><br><span class="hljs-comment">// 使用 JSON.stringify 转换对象为字符串</span><br><span class="hljs-variable language_">localStorage</span>.<span class="hljs-title function_">setItem</span>(<span class="hljs-string">'user'</span>, <span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">stringify</span>(user));<br><br><span class="hljs-comment">// 读取对象并使用 JSON.parse 转换回原对象</span><br><span class="hljs-keyword">const</span> storedUser = <span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">parse</span>(<span class="hljs-variable language_">localStorage</span>.<span class="hljs-title function_">getItem</span>(<span class="hljs-string">'user'</span>));<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(storedUser.<span class="hljs-property">username</span>); <span class="hljs-comment">// "JohnDoe"</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(storedUser.<span class="hljs-property">age</span>); <span class="hljs-comment">// 30</span><br><br></code></pre></td></tr></table></figure>
<h5 id="LocalStorage的缺点"><a href="#LocalStorage的缺点" class="headerlink" title="LocalStorage的缺点"></a>LocalStorage的缺点</h5><ol>
<li>只能存储字符串:LocalStorage 只能存储字符串类型的数据,其他类型的数据需要进行序列化(<code>JSON.Stringify</code>)。</li>
<li>同步操作:LocalStorage 是同步的,可能会对性能产生影响,尤其是当存储的数据量较大时。</li>
<li>同源策略限制:LocalStorage 中的数据是 按域名隔离 的,无法在不同域之间共享数据。</li>
<li>没有过期时间:LocalStorage 中的数据不会自动过期,因此需要手动管理存储数据的生命周期。如果不手动清理过期数据,可能会造成存储空间浪费。</li>
<li>不适用于敏感信息:LocalStorage 数据容易被浏览器中的脚本访问,因此不适合存储敏感的用户数据(如密码、令牌等)。它不具备像 Cookie 的 HttpOnly、Secure 和 SameSite 等安全特性。</li>
</ol>
<h5 id="localStorage总结"><a href="#localStorage总结" class="headerlink" title="localStorage总结"></a>localStorage总结</h5><p>LocalStorage 是一种客户端存储机制,允许在浏览器中存储数据,具有较大的存储空间(通常为 5MB 或更多),并且数据会在浏览器关闭后保持,直到被手动删除。<br>它非常适合用于持久化存储用户数据、缓存数据和管理 SPA(<em>单网页应用</em>) 的状态。但需要注意的是,LocalStorage 存储的数据容易受到 XSS 攻击,因此不适合存储敏感数据.<br>同时,它的数据存储是同步的,可能会影响性能。在使用时,要谨慎选择合适的数据存储方式,确保数据的安全性和有效管理。</p>
<h4 id="SessionStorage"><a href="#SessionStorage" class="headerlink" title="SessionStorage"></a>SessionStorage</h4><h5 id="SessionStorages是什么"><a href="#SessionStorages是什么" class="headerlink" title="SessionStorages是什么"></a>SessionStorages是什么</h5><p>SessionStorage 提供了一种简单的方式来在浏览器会话中存储数据,且该数据是 <strong>仅限于当前会话</strong> 的。<br>每个浏览器标签页或窗口都有独立的 SessionStorage,彼此之间的数据不能共享。SessionStorage 与 LocalStorage 类似,但它的生命周期更加短暂。<br><strong>特点:</strong></p>
<ol>
<li>会话级存储:数据只在当前浏览器会话期间有效。会话结束时,数据会自动清除。</li>
<li>每个标签页独立:每个浏览器标签页或窗口都有独立的 SessionStorage,标签页之间不能共享 SessionStorage 数据。</li>
<li>存储容量:SessionStorage 的存储空间通常与 LocalStorage 相同,通常为 5MB 或更多,具体取决于浏览器。</li>
<li>同步 API:SessionStorage 的 API 是同步的,意味着每次读取、存储或删除数据时,操作会立即完成。</li>
</ol>
<h5 id="sessionStorage的使用"><a href="#sessionStorage的使用" class="headerlink" title="sessionStorage的使用"></a>sessionStorage的使用</h5><p>语法同<code>localStorage</code></p>
<h5 id="localStorage-VS-sessionStorage-你们知道吗"><a href="#localStorage-VS-sessionStorage-你们知道吗" class="headerlink" title="localStorage VS sessionStorage 你们知道吗"></a>localStorage VS sessionStorage 你们知道吗</h5><table>
<thead>
<tr>
<th>特性</th>
<th>SessionStorage</th>
<th>LocalStorage</th>
</tr>
</thead>
<tbody><tr>
<td>存储容量</td>
<td>5MB 或更多,取决于浏览器</td>
<td>5MB 或更多,取决于浏览器</td>
</tr>
<tr>
<td>生命周期</td>
<td>仅在当前会话(标签页)有效,会话结束时删除</td>
<td>永久存储,直到显式删除</td>
</tr>
<tr>
<td>数据隔离性</td>
<td>不同标签页、不同窗口的数据隔离</td>
<td>同一域下的数据共享</td>
</tr>
<tr>
<td>存储方式</td>
<td>键值对,字符串</td>
<td>键值对,字符串</td>
</tr>
<tr>
<td>传输到服务器</td>
<td>不会随每个请求自动发送</td>
<td>会随每个 HTTP 请求自动发送到服务器</td>
</tr>
<tr>
<td>API 异步性</td>
<td>同步 API</td>
<td>同步 API</td>
</tr>
<tr>
<td>适用场景</td>
<td>临时存储会话信息,如用户登录状态、购物车等</td>
<td>长期存储用户设置、偏好、浏览历史等</td>
</tr>
</tbody></table>
<h5 id="sessionStorage总结"><a href="#sessionStorage总结" class="headerlink" title="sessionStorage总结"></a>sessionStorage总结</h5><p>sessionStorage 一般用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据。</p>
<h3 id="JavaScript数组Array"><a href="#JavaScript数组Array" class="headerlink" title="JavaScript数组Array"></a>JavaScript数组Array</h3><blockquote>
<p>参考资料:</p>
<p><a href="https://juejin.cn/post/6844904048106143757" target="_blank" rel="noopener noreferrer">全面介绍JavaScript数组方法</a></p>
<p><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array" target="_blank" rel="external nofollow noopener noreferrer">JavaScript标准对象 > Array</a></p>
<p>菜鸟教程</p>
</blockquote>
<h4 id="Array的描述"><a href="#Array的描述" class="headerlink" title="Array的描述"></a>Array的描述</h4><p>在 JavaScript 中,数组不是<em>原始类型</em>,而是具有以下核心特征的<code>Array</code>对象(引用类型):</p>
<ul>
<li><p><strong>JavaScript 数组是可调整大小的,并且可以包含不同的数据类型。</strong>(当不需要这些特征时,可以使用类型化数组。)</p>
</li>
<li><p><strong>JavaScript 数组不是关联数组</strong>,因此,不能使用任意字符串作为索引访问数组元素,但必须使用非负整数(或它们各自的字符串形式)作为索引访问。</p>
</li>
<li><p><strong>JavaScript 数组的索引从 0 开始</strong>:数组的第一个元素在索引 0 处,第二个在索引 1 处,以此类推,最后一个元素是数组的 length 属性减去 1 的值。</p>
</li>
<li><p><strong>JavaScript 数组复制操作创建浅拷贝。</strong>(所有 JavaScript 对象的标准内置复制操作都会创建浅拷贝,而不是深拷贝)。</p>
<blockquote>
<p><strong>关于深浅拷贝</strong><br>浅拷贝(Shallow Copy)<br>浅拷贝创建一个新对象,但只<strong>复制原始对象的引用类型字段的地址</strong>,而不复制引用指向的对象本身。这意味着新对象和原始对象的引用类型字段将指向相同的对象。如果原始对象中的字段是基本数据类型,则这些字段的值会被复制到新对象中。由于引用类型字段共享,<strong>对新对象的修改可能会影响原始对象。</strong><br>深拷贝(Deep Copy)<br>深拷贝则<strong>创建一个全新的对象</strong>,并递归地复制原始对象的所有字段,包括引用指向的对象。这种方法会复制整个对象结构,确保新对象和原始对象之间的所有关系都是独立的。因此,<strong>对新对象的修改不会影响到原始对象。</strong></p>
</blockquote>
</li>
</ul>
<h4 id="Array的数组索引"><a href="#Array的数组索引" class="headerlink" title="Array的数组索引"></a>Array的数组索引</h4><p>Array 对象不能使用任意字符串作为元素索引(如关联数组),必须使用非负整数(或它们的字符串形式)。<br>JavaScript 语法要求使用方括号表示法来访问以数字开头的属性,形如:</p>
<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><code class="hljs js"><span class="hljs-keyword">let</span> arr = [<span class="hljs-string">'a'</span>,<span class="hljs-string">'b'</span>,<span class="hljs-string">'c'</span>];<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(arr[<span class="hljs-number">0</span>])<br><span class="hljs-comment">//或者</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(arr[<span class="hljs-string">'0'</span>])<br></code></pre></td></tr></table></figure>
<p><strong>注意:</strong> JavaScript 引擎通过隐式的<code>toString</code>,将 years[2] 中的 2 强制转换为字符串。因此,’2’ 和 ‘02’ 将指向 years 对象上的两个不同的槽位。<br>只有<code>years['2']</code>是一个实际的数组索引。而<code>years['02']</code>是一个在数组迭代中不会被访问的任意字符串属性。</p>
<h4 id="Array的数组方法"><a href="#Array的数组方法" class="headerlink" title="Array的数组方法"></a>Array的数组方法</h4><h5 id="1-检测方法"><a href="#1-检测方法" class="headerlink" title="1. 检测方法"></a>1. 检测方法</h5><ol>
<li><p><code>Array.isArray()</code><br>判断传入的值是否是一个数组。</p>
<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><code class="hljs js"><span class="hljs-comment">// true</span><br><span class="hljs-title class_">Array</span>.<span class="hljs-title function_">isArray</span>([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>])<br><span class="hljs-comment">// false</span><br><span class="hljs-title class_">Array</span>.<span class="hljs-title function_">isArray</span>({<span class="hljs-attr">foo</span>: <span class="hljs-number">123</span>})<br><span class="hljs-comment">// false</span><br><span class="hljs-title class_">Array</span>.<span class="hljs-title function_">isArray</span>(<span class="hljs-string">'foobar'</span>) <br><span class="hljs-comment">// false</span><br><span class="hljs-title class_">Array</span>.<span class="hljs-title function_">isArray</span>(<span class="hljs-literal">undefined</span>) <br></code></pre></td></tr></table></figure>
</li>
<li><p><code>typeof</code></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-keyword">typeof</span> [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-string">"a"</span>]); <span class="hljs-comment">// "object"</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>Object.prototype.toString.call()</code> 适用于所有类型的详细判断</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Object</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">toString</span>.<span class="hljs-title function_">call</span>([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-string">"a"</span>])); <span class="hljs-comment">// "[object Array]"</span><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>constructor</code>属性</p>
<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><code class="hljs js"><span class="hljs-keyword">let</span> i = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-string">"a"</span>];<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(i.<span class="hljs-property">constructor</span>.<span class="hljs-property">name</span>); <span class="hljs-comment">// "Array"</span><br></code></pre></td></tr></table></figure></li>
</ol>
<h5 id="2-创建数组方法"><a href="#2-创建数组方法" class="headerlink" title="2. 创建数组方法"></a>2. 创建数组方法</h5><ol>
<li><p><code>Array.from()</code><br><code>Array.from()</code>方法用于将类数组对象和可迭代对象转为真正的数组,并且返回一个新的,浅拷贝的数组实例。</p>
<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><code class="hljs js"><span class="hljs-comment">// 报错</span><br><span class="hljs-title class_">Array</span>.<span class="hljs-title function_">from</span>(<span class="hljs-literal">undefined</span>)<br><span class="hljs-comment">// 报错</span><br><span class="hljs-title class_">Array</span>.<span class="hljs-title function_">from</span>(<span class="hljs-literal">null</span>)<br><span class="hljs-comment">// ["f", "o", "o"]</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Array</span>.<span class="hljs-title function_">from</span>(<span class="hljs-string">'foo'</span>))<br><span class="hljs-comment">// []</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Array</span>.<span class="hljs-title function_">from</span>(<span class="hljs-string">''</span>))<br><span class="hljs-comment">// []</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Array</span>.<span class="hljs-title function_">from</span>(<span class="hljs-number">123</span>))<br><span class="hljs-comment">// []</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Array</span>.<span class="hljs-title function_">from</span>(<span class="hljs-title class_">NaN</span>))<br></code></pre></td></tr></table></figure>
</li>
<li><p><code>Array.of()</code><br>Array.of()创建一个包含所有传入参数的数组,不考虑参数的数量或类型,返回一个新数组。</p>
<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><code class="hljs js"><span class="hljs-title class_">Array</span>.<span class="hljs-title function_">of</span>() <span class="hljs-comment">// []</span><br><span class="hljs-title class_">Array</span>.<span class="hljs-title function_">of</span>(<span class="hljs-literal">undefined</span>) <span class="hljs-comment">// [undefined]</span><br><span class="hljs-title class_">Array</span>.<span class="hljs-title function_">of</span>(<span class="hljs-literal">null</span>) <span class="hljs-comment">// [null]</span><br><span class="hljs-title class_">Array</span>.<span class="hljs-title function_">of</span>(<span class="hljs-title class_">NaN</span>) <span class="hljs-comment">// [NaN]</span><br><span class="hljs-title class_">Array</span>.<span class="hljs-title function_">of</span>(<span class="hljs-number">1</span>) <span class="hljs-comment">// [1]</span><br><span class="hljs-title class_">Array</span>.<span class="hljs-title function_">of</span>(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>) <span class="hljs-comment">// [1, 2]</span><br><span class="hljs-title class_">Array</span>.<span class="hljs-title function_">of</span>([<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>]) <span class="hljs-comment">// [[1,2,3]]</span><br><span class="hljs-title class_">Array</span>.<span class="hljs-title function_">of</span>({<span class="hljs-attr">id</span>: <span class="hljs-number">1</span>},{<span class="hljs-attr">id</span>: <span class="hljs-number">2</span>}) <span class="hljs-comment">// [{id:1}, {id:2}]</span><br></code></pre></td></tr></table></figure></li>
</ol>
<h5 id="3-遍历(迭代)方法"><a href="#3-遍历(迭代)方法" class="headerlink" title="3. 遍历(迭代)方法"></a>3. 遍历(迭代)方法</h5><ol>
<li><p><code>forEach()</code><br>对数组中的每一项运行指定的函数。这个方法返回<code>undefined</code>,即使你return了一个值。</p>
<ol>
<li><p>Array.forEach()参数语法:</p>
<table>
<thead>
<tr>
<th>element</th>
<th>index</th>
<th>array</th>
</tr>
</thead>
<tbody><tr>
<td>当前元素</td>
<td>当前元素的索引</td>
<td>数组本身</td>
</tr>
</tbody></table>
</li>
<li><p>第二个参数(可选):当执行回调函数时用作 this 的值。</p>
</li>
</ol>
</li>
</ol>
<p><strong>注意:</strong> <code>Array.forEach()</code>不能中断循环(使用<code>break</code>,或<code>continue</code>语句)。只能用<code>return</code>退出本次回调,进行下一次回调。</p>
<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><code class="hljs js"><span class="hljs-keyword">const</span> arr = [{<span class="hljs-attr">id</span>: <span class="hljs-number">1</span>,<span class="hljs-attr">name</span>: <span class="hljs-string">'zhangsan'</span>},{<span class="hljs-attr">id</span>: <span class="hljs-number">2</span>,<span class="hljs-attr">name</span>: <span class="hljs-string">'lisi'</span>}]<br><span class="hljs-comment">// 1 - zhangsan</span><br><span class="hljs-comment">// 2 - lisi</span><br>arr.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">el</span> =></span> {<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`<span class="hljs-subst">${el.id}</span> - <span class="hljs-subst">${el.name}</span>`</span>);<br>});<br><br><span class="hljs-keyword">const</span> obj = {<br> <span class="hljs-attr">handle</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">n</span>){<br> <span class="hljs-keyword">return</span> n + <span class="hljs-number">2</span><br> }<br>};<br><span class="hljs-comment">// true </span><br>[{<span class="hljs-attr">id</span>: <span class="hljs-number">1</span>,<span class="hljs-attr">name</span>: <span class="hljs-string">'zhangsan'</span>},{<span class="hljs-attr">id</span>: <span class="hljs-number">2</span>,<span class="hljs-attr">name</span>: <span class="hljs-string">'lisi'</span>}].<span class="hljs-title function_">forEach</span>(<span class="hljs-keyword">function</span>(<span class="hljs-params">el,index,arr</span>){<br> <span class="hljs-keyword">if</span>(el.<span class="hljs-property">id</span> === <span class="hljs-number">1</span>) {<br> <span class="hljs-keyword">return</span><br> }<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-variable language_">this</span> === obj)<br>},obj);<br><br></code></pre></td></tr></table></figure>
<ol start="2">
<li><p><code>map()</code><br>返回一个新数组,结果是该数组中的每个元素都调用提供的函数后返回的结果。</p>
<ol>
<li><p>Array.map()参数语法:</p>
<table>
<thead>
<tr>
<th>参数</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>element</td>
<td>当前元素</td>
</tr>
<tr>
<td>index</td>
<td>当前元素的索引 (可选)</td>
</tr>
<tr>
<td>array</td>
<td>数组本身 (可选)</td>
</tr>
</tbody></table>
</li>
<li><p>第二个参数(可选):当执行回调函数时用作 this 的值。</p>
</li>
</ol>
</li>
</ol>
<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><code class="hljs js"><span class="hljs-keyword">const</span> arr = [{<span class="hljs-attr">id</span>: <span class="hljs-number">1</span>},{<span class="hljs-attr">id</span>: <span class="hljs-number">2</span>},{<span class="hljs-attr">id</span>: <span class="hljs-number">3</span>}]<br><span class="hljs-keyword">const</span> newArr = arr.<span class="hljs-title function_">map</span>(<span class="hljs-function">(<span class="hljs-params">el,index,arr</span>) =></span> {<br> el.<span class="hljs-property">age</span> = <span class="hljs-number">20</span><br> <span class="hljs-keyword">return</span> el<br>});<br><span class="hljs-comment">// [{id: 1,age: 20},{id: 2,age: 20},{id: 3,age: 20}]</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(newArr);<br></code></pre></td></tr></table></figure>
<ol start="3">
<li><p><code>filter()</code><br>对数组中的每一项运行指定的函数,返回该函数会返回true的项组成的新的数组。如果没有任何数组元素通过测试,则返回空数组。</p>
<ol>
<li><p>Array.filter()参数语法:</p>
<table>
<thead>
<tr>
<th>参数</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>element</td>
<td>当前元素</td>
</tr>
<tr>
<td>index</td>
<td>当前元素的索引 (可选)</td>
</tr>
<tr>
<td>array</td>
<td>数组本身 (可选)</td>
</tr>
</tbody></table>
</li>
<li><p>第二个参数(可选):当执行回调函数时用作 this 的值。</p>
<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><code class="hljs js"><span class="hljs-keyword">const</span> arr = [{<span class="hljs-attr">id</span>: <span class="hljs-number">1</span>},{<span class="hljs-attr">id</span>: <span class="hljs-number">2</span>},{<span class="hljs-attr">id</span>: <span class="hljs-number">3</span>}]<br><span class="hljs-keyword">const</span> newArr = arr.<span class="hljs-title function_">filter</span>(<span class="hljs-function">(<span class="hljs-params">el,index,arr</span>) =></span> {<br>el.<span class="hljs-property">age</span> = <span class="hljs-number">20</span><br><span class="hljs-keyword">return</span> el<br>});<br><span class="hljs-comment">// [{id: 1,age: 20},{id: 2,age: 20},{id: 3,age: 20}]</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(newArr);<br><br></code></pre></td></tr></table></figure></li>
</ol>
</li>
<li><p><code>some()</code><br>检测数组中的是否有满足判断条件的元素。</p>
</li>
</ol>
<p>对数组中的每一项运行指定的函数,如果该函数对<strong>任一项返回true</strong>,则返回true,并且剩余的元素不会再执行检测。如果没有满足条件的元素,则返回false。</p>
<ol>
<li><p>Array.some()参数语法:</p>
<table>
<thead>
<tr>
<th>参数</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>element</td>
<td>当前元素</td>
</tr>
<tr>
<td>index</td>
<td>当前元素的索引 (可选)</td>
</tr>
<tr>
<td>array</td>
<td>数组本身 (可选)</td>
</tr>
</tbody></table>
</li>
<li><p>第二个参数(可选):当执行回调函数时用作 this 的值。</p>
<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><code class="hljs js"><span class="hljs-keyword">const</span> arr = [{<span class="hljs-attr">id</span>: <span class="hljs-number">1</span>},{<span class="hljs-attr">id</span>: <span class="hljs-number">2</span>},{<span class="hljs-attr">id</span>: <span class="hljs-number">3</span>}]<br><span class="hljs-keyword">const</span> someResult = arr.<span class="hljs-title function_">some</span>(<span class="hljs-function">(<span class="hljs-params">el,index,arr</span>) =></span> {<br><span class="hljs-keyword">return</span> el.<span class="hljs-property">id</span> === <span class="hljs-number">1</span><br>});<br><span class="hljs-comment">// true</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(someResult)<br><br></code></pre></td></tr></table></figure>
<ol start="5">
<li><code>every()</code><br>检测数组所有元素是否都符合判断条件。</li>
</ol>
</li>
</ol>
<p>对数组中的每一项运行指定的函数,如果该函数对每一项都返回true,则返回true。若收到一个空数组,此方法在一切情况下都会返回true。如果数组中检测到有一个元素不满足,则返回 false,且剩余的元素不会再进行检测。</p>
<h3 id="JavaScript中比较常考的点"><a href="#JavaScript中比较常考的点" class="headerlink" title="JavaScript中比较常考的点"></a>JavaScript中比较常考的点</h3><h4 id="数据类型"><a href="#数据类型" class="headerlink" title="数据类型"></a>数据类型</h4><ol>
<li><p>在Number与String运算时,<strong>只有</strong><code>+</code>操作时Number会隐式转换为String,其余情况下都是String隐式转换为Number</p>
</li>
<li><p>在JavaScript中,数据类型分两大类:<br><strong>原始类型(Primitive Types):</strong></p>
<table>
<thead>
<tr>
<th>类型名</th>
<th>类型英文</th>
<th>备注</th>
</tr>
</thead>
<tbody><tr>
<td>字符串</td>
<td>String</td>
<td></td>
</tr>
<tr>
<td>数字</td>
<td>Number</td>
<td></td>
</tr>
<tr>
<td>布尔值</td>
<td>Boolean</td>
<td></td>
</tr>
<tr>
<td>未定义</td>
<td>Undefined</td>
<td></td>
</tr>
<tr>
<td>空值</td>
<td>Null</td>
<td><em>使用 <code>typeof</code> 操作符的结果是”<code>Object</code>“</em></td>
</tr>
<tr>
<td>符号</td>
<td>Symbol</td>
<td>ES6新特性</td>
</tr>
<tr>
<td>大整数</td>
<td>BigInt</td>
<td>ES6新特性</td>
</tr>
</tbody></table>
<p><strong>引用类型(Reference Types):</strong></p>
<table>
<thead>
<tr>
<th>类型名</th>
<th>类型英文</th>
<th>备注</th>
</tr>
</thead>
<tbody><tr>
<td>对象</td>
<td>Object</td>
<td></td>
</tr>
<tr>
<td>数组</td>
<td>Array</td>
<td></td>
</tr>
<tr>
<td>函数</td>
<td>Function</td>
<td></td>
</tr>
<tr>
<td>日期</td>
<td>Date</td>
<td></td>
</tr>
<tr>
<td>正则表达式</td>
<td>RegExp</td>
<td></td>
</tr>
<tr>
<td>错误</td>
<td>Error</td>
<td></td>
</tr>
</tbody></table>
</li>
</ol>
</div>
<hr>
<div>
<div class="post-metas my-3">
<div class="post-meta mr-3 d-flex align-items-center">
<i class="iconfont icon-category"></i>
<span class="category-chains">
<span class="category-chain">
<a href="/categories/frontend/" class="category-chain-item">frontend</a>
</span>
</span>
</div>
<div class="post-meta">
<i class="iconfont icon-tags"></i>
<a href="/tags/frontend/" class="print-no-link">#frontend</a>
<a href="/tags/javascript/" class="print-no-link">#javascript</a>
<a href="/tags/eventloop/" class="print-no-link">#eventloop</a>
<a href="/tags/localstorage/" class="print-no-link">#localstorage</a>
<a href="/tags/array/" class="print-no-link">#array</a>
</div>
</div>
<div class="license-box my-3">
<div class="license-title">
<div>前端深入学习笔记</div>
<div>http://arkpln.github.io/3518582965.html</div>
</div>
<div class="license-meta">
<div class="license-meta-item">
<div>Author</div>
<div>FangZhou</div>
</div>
<div class="license-meta-item license-meta-date">
<div>Posted on</div>
<div>April 6, 2025</div>
</div>
<div class="license-meta-item">
<div>Licensed under</div>
<div>
<a class="print-no-link" target="_blank" href="https://creativecommons.org/licenses/by/4.0/" rel="external nofollow noopener noreferrer">
<span class="hint--top hint--rounded" aria-label="BY - Attribution">
<i class="iconfont icon-cc-by"></i>
</span>
</a>
</div>
</div>
</div>
<div class="license-icon iconfont"></div>
</div>
<div style="width:100%;display:flex;justify-content:center;margin-bottom:1.5rem"><ins class="adsbygoogle" style="display:flex;justify-content:center;max-width:845px;width:100%;height:90px" data-ad-client="ca-pub-3240358922862141" data-ad-slot="6522434837"></ins><script> (adsbygoogle = window.adsbygoogle || []).push({}); </script></div>
<div class="post-prevnext my-3">
<article class="post-prev col-6">
<a href="/1046180177.html" title="用户中心系统开发日志">
<i class="iconfont icon-arrowleft"></i>
<span class="hidden-mobile">用户中心系统开发日志</span>
<span class="visible-mobile">Previous</span>
</a>
</article>
<article class="post-next col-6">
<a href="/303649792.html" title="React学习笔记">
<span class="hidden-mobile">React学习笔记</span>
<span class="visible-mobile">Next</span>
<i class="iconfont icon-arrowright"></i>
</a>
</article>
</div>
</div>
<article id="comments" lazyload>
<div id="valine"></div>
<script type="text/javascript">
Fluid.utils.loadComments('#valine', function() {
Fluid.utils.createScript('https://lib.baomitu.com/valine/1.5.1/Valine.min.js', function() {
var options = Object.assign(
{"appId":"mEwkD7geCX7RWNO8srhDE2oP-gzGzoHsz","appKey":"4EF76hyiVA1QILHZThVbfoat","path":"window.location.pathname","placeholder":null,"avatar":"retro","meta":["nick","mail","link"],"requiredFields":[],"pageSize":10,"lang":"zh-CN","highlight":false,"recordIP":false,"serverURLs":"","emojiCDN":null,"emojiMaps":null,"enableQQ":false,"el":"#vcomments"},
{
el: "#valine",
path: window.location.pathname
}
)
new Valine(options);
Fluid.utils.waitElementVisible('#valine .vcontent', () => {
var imgSelector = '#valine .vcontent img:not(.vemoji)';
Fluid.plugins.imageCaption(imgSelector);
Fluid.plugins.fancyBox(imgSelector);
})
});
});
</script>
<noscript>Please enable JavaScript to view the comments</noscript>
</article>
</article>
</div>
</div>
</div>
<div class="side-col d-none d-lg-block col-lg-2">
<aside class="sidebar" style="margin-left: -1rem">
<div id="toc">
<p class="toc-header">
<i class="iconfont icon-list"></i>
<span>Table of Contents</span>
</p>
<div class="toc-body" id="toc-body"></div>
</div>
</aside>
</div>
</div>
</div>