-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
1581 lines (1103 loc) · 166 KB
/
index.html
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="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="keywords" content="前端技术栈 前端技术 前端博客 JavaScript HTML5 CSS3 VUE React Angular node Deno typeSctipt webpack wechat flutter recoil" />
<meta name="description" content="敲着代码,记着BUG,通过博客的方式,记录下工作中的点点滴滴。" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1"
/>
<title> Lee前端技术栈</title>
<meta name="generator" content="hexo-theme-ayer">
<link rel="shortcut icon" href="/favicon.ico" />
<link rel="stylesheet" href="/dist/main.css">
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/Shen-Yu/cdn/css/remixicon.min.css"
/>
<link rel="stylesheet" href="/css/custom.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/pace.min.js"></script>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@sweetalert2/[email protected]/bulma.min.css"
/>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/sweetalert2.min.js"></script>
<!-- mermaid -->
<style>
.swal2-styled.swal2-confirm {
font-size: 1.6rem;
}
</style>
<link rel="alternate" href="/atom.xml" title="Lee前端技术栈" type="application/atom+xml">
</head>
</html>
</html>
<body>
<div id="app">
<main class="content on">
<section class="cover">
<a class="forkMe" href="https://github.com/Leexiaop"
target="_blank"><img width="149" height="149" src="/images/forkme.png"
class="attachment-full size-full" alt="Fork me on GitHub" data-recalc-dims="1"></a>
<div class="cover-frame">
<div class="bg-box">
<img src="/images/cover1.jpg" alt="image frame" />
</div>
<div class="cover-inner text-center text-white">
<h1><a href="/">Lee前端技术栈</a></h1>
<div id="subtitle-box">
<span id="subtitle"></span>
</div>
<div>
</div>
</div>
</div>
<div class="cover-learn-more">
<a href="javascript:void(0)" class="anchor"><i class="ri-arrow-down-line"></i></a>
</div>
</section>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/typed.min.js"></script>
<!-- Subtitle -->
<script>
try {
var typed = new Typed("#subtitle", {
strings: ['读万卷书,行万里路,代码运行了那么久,却总觉得不是最优秀。。。', '愿你一生努力,一生被爱', '想要的都拥有,得不到的都释怀'],
startDelay: 0,
typeSpeed: 200,
loop: true,
backSpeed: 100,
showCursor: true
});
} catch (err) {
console.log(err)
}
</script>
<div id="main">
<section class="outer">
<ul class="ads">
<li>
<a target="_blank" rel="noopener" href="https://curl.qcloud.com/kvO7hb43">
<img src="https://cdn.jsdelivr.net/gh/Shen-Yu/cdn/img/ten_1.jpg" width="300" alt="云服务器限时秒杀">
</a>
</li>
<li>
<a target="_blank" rel="noopener" href="https://www.vultr.com/?ref=8630075">
<img src="https://cdn.jsdelivr.net/gh/Shen-Yu/cdn/img/vultr.png" width="300" alt="vultr优惠vps">
</a>
</li>
</ul>
<div class="notice" style="margin-top:50px">
<i class="ri-heart-fill"></i>
<div class="notice-content" id="broad"></div>
</div>
<script type="text/javascript">
fetch('https://v1.hitokoto.cn')
.then(response => response.json())
.then(data => {
document.getElementById("broad").innerHTML = data.hitokoto;
})
.catch(console.error)
</script>
<style>
.notice {
padding: 20px;
border: 1px dashed #e6e6e6;
color: #969696;
position: relative;
display: inline-block;
width: 100%;
background: #fbfbfb50;
border-radius: 10px;
}
.notice i {
float: left;
color: #999;
font-size: 16px;
padding-right: 10px;
vertical-align: middle;
margin-top: -2px;
}
.notice-content {
display: initial;
vertical-align: middle;
}
</style>
<article class="articles">
<article
id="post-algorithm/47"
class="article article-type-post"
itemscope
itemprop="blogPost"
data-scroll-reveal
>
<div class="article-inner">
<header class="article-header">
<h2 itemprop="name">
<a class="article-title" href="/algorithm/47/"
>JavaScript算法套路之二叉树的层序遍历</a>
</h2>
</header>
<div class="article-meta">
<a href="/algorithm/47/" class="article-date">
<time datetime="2022-02-22T11:47:32.000Z" itemprop="datePublished">2022-02-22</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/algorithm/">algorithm</a>
</div>
</div>
<div class="article-entry" itemprop="articleBody">
<p>二叉树的层序遍历,也就是二叉树的广度月优先遍历,层序遍历,很好理解,就是一层一层的遍历。想要实现二叉树的层序遍历,还需要借助<code>队列</code>。队列的先进先出,符合一层一层的遍历。</p>
<figure class="highlight angelscript"><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="number">1</span></span><br><span class="line"> / \</span><br><span class="line"> <span class="number">2</span> <span class="number">3</span></span><br><span class="line">/ \ / \</span><br><span class="line"><span class="number">4</span> <span class="number">5</span> <span class="number">6</span> <span class="number">7</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 遍历得到</span></span><br><span class="line"><span class="string">[</span></span><br><span class="line"><span class="string"> [1]</span>,</span><br><span class="line"><span class="string"> [2, 3]</span></span><br><span class="line"><span class="string"> [4, 5, 6, 7]</span></span><br><span class="line">]</span><br></pre></td></tr></table></figure>
<p>相对来说,其实层序遍历比较简单,话不多说。我们直接看代码:</p>
<figure class="highlight maxima"><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="built_in">let</span> levelOrder = (root) => {</span><br><span class="line"> <span class="built_in">let</span> result = [];</span><br><span class="line"> <span class="built_in">let</span> queue = [];</span><br><span class="line"> <span class="keyword">if</span> (!root) <span class="built_in">return</span> result;</span><br><span class="line"> queue.<span class="built_in">push</span>(root);</span><br><span class="line"> <span class="keyword">while</span> (queue.<span class="built_in">length</span>) {</span><br><span class="line"> <span class="built_in">let</span> list = [];</span><br><span class="line"> <span class="keyword">for</span> (<span class="built_in">let</span> i = <span class="number">0</span>; i < queue.<span class="built_in">length</span>;i++) {</span><br><span class="line"> <span class="built_in">let</span> cur = queue.shift();</span><br><span class="line"> list.<span class="built_in">push</span>(cur.val);</span><br><span class="line"> cur.left && queue.<span class="built_in">push</span>(cur.left);</span><br><span class="line"> cur.right && queue.<span class="built_in">push</span>(cur.right);</span><br><span class="line"> }</span><br><span class="line"> result.<span class="built_in">push</span>(list);</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">return</span> result;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>是不是很简单呢?</p>
<!-- reward -->
</div>
<!-- copyright -->
<footer class="article-footer">
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/algorithm/" rel="tag">algorithm</a></li></ul>
</footer>
</div>
</article>
<article
id="post-algorithm/46"
class="article article-type-post"
itemscope
itemprop="blogPost"
data-scroll-reveal
>
<div class="article-inner">
<header class="article-header">
<h2 itemprop="name">
<a class="article-title" href="/algorithm/46/"
>JavaScript算法套路之二叉树的前、中、后序迭代遍历</a>
</h2>
</header>
<div class="article-meta">
<a href="/algorithm/46/" class="article-date">
<time datetime="2022-02-18T08:12:04.000Z" itemprop="datePublished">2022-02-18</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/algorithm/">algorithm</a>
</div>
</div>
<div class="article-entry" itemprop="articleBody">
<p>递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,所以这就是递归为什么可以返回上一层位置的原因。所以。我们用栈当然就能实现同样的遍历了。</p>
<p>栈的特点是<code>先进性后出</code>,所以在遍历二叉树的时候,要反过来遍历,比如前序遍历,正常情况下,应该是中,左,右,那么我们的遍历顺序就应该是中,右,左,出栈的时候正好是中,左,右。下面我们来实现以下前序遍历:</p>
<figure class="highlight kotlin"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * function TreeNode(val, left, right) {</span></span><br><span class="line"><span class="comment"> * this.val = (val===undefined ? 0 : val)</span></span><br><span class="line"><span class="comment"> * this.left = (left===undefined ? null : left)</span></span><br><span class="line"><span class="comment"> * this.right = (right===undefined ? null : right)</span></span><br><span class="line"><span class="comment"> * }</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> {TreeNode} root</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> {number[]}</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> preorderTraversal = (root) => {</span><br><span class="line"> <span class="keyword">const</span> result = [];</span><br><span class="line"> <span class="comment">// 判断,如果没有root了,就返回结果</span></span><br><span class="line"> <span class="keyword">if</span> (!root) <span class="keyword">return</span> result;</span><br><span class="line"> <span class="comment">// 把中间节点放入道栈中</span></span><br><span class="line"> <span class="keyword">const</span> stack = [root];</span><br><span class="line"> let cur = <span class="literal">null</span>;</span><br><span class="line"> <span class="keyword">while</span> (stack.length) {</span><br><span class="line"> cur = stack.pop();</span><br><span class="line"> result.push(cur.<span class="keyword">val</span>);</span><br><span class="line"> cur.right && stack.push(cur.<span class="keyword">val</span>);</span><br><span class="line"> cur.left && stack.push(cur.<span class="keyword">val</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> result;</span><br><span class="line">};</span><br></pre></td></tr></table></figure>
<p>这就是迭代方法的前序遍历,那既然能写出来前序遍历,那二叉树的后续遍历是不是也就可以自然而然的写出来了呢?与前序遍历不同的是:<code>先序遍历是中左右,后续遍历是左右中,那么我们只需要调整一下先序遍历的代码顺序,就变成中右左的遍历顺序,然后在反转result数组,输出的结果顺序就是左右中。</code></p>
<figure class="highlight coq"><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></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line"> * <span class="keyword">Definition</span> <span class="keyword">for</span> a binary tree node.</span><br><span class="line"> * function TreeNode(val, <span class="built_in">left</span>, <span class="built_in">right</span>) {</span><br><span class="line"> * this.val = (val===undefined ? <span class="number">0</span> : val)</span><br><span class="line"> * this.<span class="built_in">left</span> = (<span class="built_in">left</span>===undefined ? null : <span class="built_in">left</span>)</span><br><span class="line"> * this.<span class="built_in">right</span> = (<span class="built_in">right</span>===undefined ? null : <span class="built_in">right</span>)</span><br><span class="line"> * }</span><br><span class="line"> */</span><br><span class="line">/**</span><br><span class="line"> * @param {TreeNode} root</span><br><span class="line"> * @<span class="keyword">return</span> {number[]}</span><br><span class="line"> */</span><br><span class="line"></span><br><span class="line">const backOrder = (root) => {</span><br><span class="line"> <span class="keyword">let</span> result = [];</span><br><span class="line"> <span class="keyword">if</span> (!root) <span class="keyword">return</span> result;</span><br><span class="line"> <span class="keyword">let</span> stack = [root];</span><br><span class="line"> <span class="keyword">let</span> cur = null;</span><br><span class="line"> <span class="built_in">do</span> {</span><br><span class="line"> cur = stack.pop();</span><br><span class="line"> result.push(cur.val);</span><br><span class="line"> cur.<span class="built_in">left</span> && stack.push(cur.val);</span><br><span class="line"> cur.<span class="built_in">right</span> && stack.push(cur.val);</span><br><span class="line"> } while (stack.length)</span><br><span class="line"> <span class="keyword">return</span> result.reverse();</span><br><span class="line">};</span><br></pre></td></tr></table></figure>
<p>这个时候,你会不会觉得中序遍历和前序、后续遍历也很相似呢?其实不然,中序遍历的顺序是<code>左中右</code>,要先遍历二叉树的顶部节点,然后再遍历一层一层的向下访问,直到左枝叶的最底部,再开始处理节点。那么这个时候,就需要使用指针的遍历来帮助访问节点,栈则用来处理节点上的元素。来看代码:</p>
<figure class="highlight coq"><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></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line"> * <span class="keyword">Definition</span> <span class="keyword">for</span> a binary tree node.</span><br><span class="line"> * function TreeNode(val, <span class="built_in">left</span>, <span class="built_in">right</span>) {</span><br><span class="line"> * this.val = (val===undefined ? <span class="number">0</span> : val)</span><br><span class="line"> * this.<span class="built_in">left</span> = (<span class="built_in">left</span>===undefined ? null : <span class="built_in">left</span>)</span><br><span class="line"> * this.<span class="built_in">right</span> = (<span class="built_in">right</span>===undefined ? null : <span class="built_in">right</span>)</span><br><span class="line"> * }</span><br><span class="line"> */</span><br><span class="line">/**</span><br><span class="line"> * @param {TreeNode} root</span><br><span class="line"> * @<span class="keyword">return</span> {number[]}</span><br><span class="line"> */</span><br><span class="line"></span><br><span class="line">const midOrder = (root) => {</span><br><span class="line"> <span class="keyword">let</span> stack = [];</span><br><span class="line"> <span class="keyword">let</span> result = [];</span><br><span class="line"> <span class="keyword">let</span> cur = root;</span><br><span class="line"> while (stack.length |<span class="type">| cur</span>) {</span><br><span class="line"> <span class="keyword">if</span> (cur) {</span><br><span class="line"> stack.push(cur);</span><br><span class="line"> cur = cur.<span class="built_in">left</span>;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> stack.pop();</span><br><span class="line"> result.push(cur.val);</span><br><span class="line"> cur = cur.<span class="built_in">right</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> result;</span><br><span class="line">};</span><br></pre></td></tr></table></figure>
<p>写了这么多的代码,好像有点乱,那就二叉树的前、中后序迭代遍历能不能总结个套路呢?当然没问题的啦。。。我们怎么做呢?看:<code>我们将要处理的节点放入到栈中,紧接着放入一个空指针作为标记</code>。上代码:</p>
<figure class="highlight maxima"><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><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * function TreeNode(val, left, right) {</span></span><br><span class="line"><span class="comment"> * this.val = (val===undefined ? 0 : val)</span></span><br><span class="line"><span class="comment"> * this.left = (left===undefined ? null : left)</span></span><br><span class="line"><span class="comment"> * this.right = (right===undefined ? null : right)</span></span><br><span class="line"><span class="comment"> * }</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param {TreeNode} root</span></span><br><span class="line"><span class="comment"> * @return {number[]}</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line">// 前序遍历</span><br><span class="line">const preOrder = (root) => {</span><br><span class="line"> <span class="built_in">let</span> result = [];</span><br><span class="line"> <span class="built_in">let</span> stack = [];</span><br><span class="line"> <span class="keyword">if</span> (root) {</span><br><span class="line"> stack.<span class="built_in">push</span>(root);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">while</span> (stack.<span class="built_in">length</span>) {</span><br><span class="line"> <span class="built_in">let</span> cur = stack.<span class="built_in">pop</span>();</span><br><span class="line"> <span class="keyword">if</span> (!cur) {</span><br><span class="line"> result.<span class="built_in">push</span>(stack.<span class="built_in">pop</span>().val);</span><br><span class="line"> continue;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (cur.right) stack.<span class="built_in">push</span>(cur.right);</span><br><span class="line"> <span class="keyword">if</span> (cur.left) stack.<span class="built_in">push</span>(cur.left)</span><br><span class="line"> stack.<span class="built_in">push</span>(cur);</span><br><span class="line"> stack.<span class="built_in">push</span>(null);</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">return</span> result;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">// 中序遍历</span><br><span class="line">const midOrder = (root) => {</span><br><span class="line"> <span class="built_in">let</span> result = [];</span><br><span class="line"> <span class="built_in">let</span> stack = []</span><br><span class="line"> <span class="keyword">if</span> (root) stack.<span class="built_in">push</span>(root);</span><br><span class="line"> <span class="keyword">while</span> (stack.<span class="built_in">length</span>) {</span><br><span class="line"> <span class="built_in">let</span> cur = stack.<span class="built_in">pop</span>();</span><br><span class="line"> <span class="keyword">if</span> (!cur) {</span><br><span class="line"> result.<span class="built_in">push</span>(stack.<span class="built_in">pop</span>());</span><br><span class="line"> continue;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (cur.right) stack.<span class="built_in">push</span>(cur.right);</span><br><span class="line"> stack.<span class="built_in">push</span>(cur);</span><br><span class="line"> stack.<span class="built_in">push</span>(null);</span><br><span class="line"> <span class="keyword">if</span> (cur.left) stack.<span class="built_in">push</span>(cur.left);</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">return</span> result;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">// 后序遍历</span><br><span class="line"><span class="built_in">let</span> backOrder = (root) => {</span><br><span class="line"> <span class="built_in">let</span> result = [];</span><br><span class="line"> <span class="built_in">let</span> stack = [];</span><br><span class="line"> <span class="keyword">if</span> (root) stack.<span class="built_in">push</span>(root);</span><br><span class="line"> <span class="keyword">while</span> (stack.<span class="built_in">length</span>) {</span><br><span class="line"> <span class="built_in">let</span> cur = stack.<span class="built_in">pop</span>();</span><br><span class="line"> <span class="keyword">if</span> (!cur) {</span><br><span class="line"> result.<span class="built_in">push</span>(stack.<span class="built_in">pop</span>());</span><br><span class="line"> continue;</span><br><span class="line"> }</span><br><span class="line"> stack.<span class="built_in">push</span>(cur);</span><br><span class="line"> stack.<span class="built_in">push</span>(null);</span><br><span class="line"> <span class="keyword">if</span> (cur.right) stack.<span class="built_in">push</span>(cur.right);</span><br><span class="line"> <span class="keyword">if</span> (cur.left) stack.<span class="built_in">push</span>(cur.left);</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">return</span> result;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>理解很重要。。。。</p>
<!-- reward -->
</div>
<!-- copyright -->
<footer class="article-footer">
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/algorithm/" rel="tag">algorithm</a></li></ul>
</footer>
</div>
</article>
<article
id="post-algorithm/44"
class="article article-type-post"
itemscope
itemprop="blogPost"
data-scroll-reveal
>
<div class="article-inner">
<header class="article-header">
<h2 itemprop="name">
<a class="article-title" href="/algorithm/44/"
>JavaScript算法套路之二叉树的前、中、后序递归遍历</a>
</h2>
</header>
<div class="article-meta">
<a href="/algorithm/44/" class="article-date">
<time datetime="2022-02-18T06:23:50.000Z" itemprop="datePublished">2022-02-18</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/algorithm/">algorithm</a>
</div>
</div>
<div class="article-entry" itemprop="articleBody">
<p>Leetcode算法刷了那么多,是不是过了没多久就全忘记了,再遇到类似的题目,只能隐隐约约的记得曾经刷过,但依旧毫无思路。对,这是绝大多数人的通病,当然我也不例外,所以我潜心研究这到底是为什么,到底是为什么。终于找到了终结所在–光刷题,只是做了题,根本没有明白其内在原理,根本没有总结过做算法的套路。那么我就从二叉树的遍历开始,来总结一下相应的算法套路。</p>
<h3 id="二叉树预备知识"><a href="#二叉树预备知识" class="headerlink" title="二叉树预备知识"></a>二叉树预备知识</h3><figure class="highlight livescript"><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="number">1</span></span><br><span class="line"> / <span class="string">\</span></span><br><span class="line"> <span class="number">2</span> <span class="number">5</span></span><br><span class="line">/ <span class="string">\</span> <span class="string">\</span></span><br><span class="line"><span class="number">3</span> <span class="number">4</span> <span class="number">6</span></span><br></pre></td></tr></table></figure>
<p>数据结构<code>树</code>的节点,最多有俩个子节点,就是二叉树。我是前端,那么前端的朋友一定会说,前端没有二叉树这种数据结构,如何表示呢?用<code>数组</code>,对,就是数组来表示,应该是这样的:</p>
<figure class="highlight actionscript"><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> tree = [<span class="number">1</span>, <span class="number">2</span>, <span class="literal">null</span>, <span class="literal">null</span>, <span class="number">5</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="literal">null</span>, <span class="number">6</span>];</span><br></pre></td></tr></table></figure>
<h3 id="二叉树的遍历"><a href="#二叉树的遍历" class="headerlink" title="二叉树的遍历"></a>二叉树的遍历</h3><p>二叉树的遍历由深度优先和广度优先之分,那我们今天就先来说说深度优先,即:</p>
<ul>
<li>前序遍历</li>
<li>中序遍历</li>
<li>后续遍历</li>
</ul>
<p>那么你一定想知道这三种遍历有什么区别呢?对,共同点,都是从左枝叶开始遍历,那区别就是<code>遍历中间节点点的位置在哪儿</code>,我们来看下上面二叉树的遍历顺序:</p>
<figure class="highlight awk"><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="regexp">//</span> 前序遍历</span><br><span class="line"><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 class="number">6</span></span><br><span class="line"></span><br><span class="line"><span class="regexp">//</span> 中序遍历</span><br><span class="line"><span class="number">3</span>、<span class="number">2</span>、<span class="number">4</span>、<span class="number">1</span>、<span class="number">5</span>、<span class="number">6</span></span><br><span class="line"></span><br><span class="line"><span class="regexp">//</span> 后序遍历</span><br><span class="line"><span class="number">3</span>、<span class="number">4</span>、<span class="number">2</span>、<span class="number">6</span>、<span class="number">5</span>、<span class="number">1</span></span><br></pre></td></tr></table></figure>
<p>所以我们就明白了。</p>
<h3 id="总结套路"><a href="#总结套路" class="headerlink" title="总结套路"></a>总结套路</h3><p>标题我们已经写过了,我们是用递归的方法来实现二叉树的遍历。那么我们要总结一下,如果写程序:</p>
<ul>
<li>要确定参数是什么<br>那二叉树的遍历,无论是前序遍历、中序遍历还是后续遍历,我们需要有树,要有节点,那么我们的参数就是<code>节点</code>喽。。。</li>
<li>终止条件是什么<br>递归遍历,我们必须先想好终止的条件是什么。要不然就会造成栈溢出的情况对吧。那么对于二叉树来说,只要没有节点了,我们就改终止遍历了对吧,所以终止条件就是<code>节点不存在</code>。</li>
<li>单层递归的逻辑<br>我们说了,二叉树前、中、后的遍历,是看根节点遍历的位置,所以这就是逻辑,对吧,是不是很简单。。。</li>
</ul>
<h3 id="代码实现"><a href="#代码实现" class="headerlink" title="代码实现"></a>代码实现</h3><p>我们就照着以上总结的逻辑来用Javascript实现吧:</p>
<figure class="highlight xquery"><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><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line"> * Definition <span class="keyword">for</span> a binary tree <span class="type">node</span>.</span><br><span class="line"> * <span class="keyword">function</span> TreeNode(val, left, right) {</span><br><span class="line"> * this.val = (val===undefined ? <span class="number">0</span> : val)</span><br><span class="line"> * this.left = (left===undefined ? null : left)</span><br><span class="line"> * this.right = (right===undefined ? null : right)</span><br><span class="line"> * }</span><br><span class="line"> */</span><br><span class="line">/**</span><br><span class="line"> * @param {TreeNode}<span class="built_in"> root</span></span><br><span class="line"> * @<span class="keyword">return</span> <span class="built_in">{number</span>[]}</span><br><span class="line"> */</span><br><span class="line"></span><br><span class="line">// 前序遍历 </span><br><span class="line">var preOrderTraversal = <span class="keyword">function</span><span class="built_in">(root</span>) {</span><br><span class="line"> <span class="keyword">let</span> result = [];</span><br><span class="line"> <span class="keyword">function</span> <span class="keyword">order</span> (<span class="type">node</span>) {</span><br><span class="line"> <span class="keyword">if</span> (!<span class="type">node</span>) <span class="keyword">return</span>;</span><br><span class="line"> result.push(<span class="type">node</span>.val);</span><br><span class="line"> <span class="keyword">order</span>(<span class="type">node</span>.left);</span><br><span class="line"> <span class="keyword">order</span>(<span class="type">node</span>.right);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">order</span><span class="built_in">(root</span>);</span><br><span class="line"> <span class="keyword">return</span> result;</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line">// 中序遍历</span><br><span class="line">var midOrderTraversal = <span class="keyword">function</span><span class="built_in">(root</span>) {</span><br><span class="line"> <span class="keyword">let</span> result = [];</span><br><span class="line"> <span class="keyword">function</span> <span class="keyword">order</span> (<span class="type">node</span>) {</span><br><span class="line"> <span class="keyword">if</span> (!<span class="type">node</span>) <span class="keyword">return</span>;</span><br><span class="line"> <span class="keyword">order</span>(<span class="type">node</span>.left);</span><br><span class="line"> result.push(<span class="type">node</span>.val);</span><br><span class="line"> <span class="keyword">order</span>(<span class="type">node</span>.right);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">order</span><span class="built_in">(root</span>);</span><br><span class="line"> <span class="keyword">return</span> result;</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line">// 后续遍历</span><br><span class="line">var backOrderTraversal = <span class="keyword">function</span><span class="built_in">(root</span>) {</span><br><span class="line"> <span class="keyword">let</span> result = [];</span><br><span class="line"> <span class="keyword">function</span> <span class="keyword">order</span> (<span class="type">node</span>) {</span><br><span class="line"> <span class="keyword">if</span> (!<span class="type">node</span>) <span class="keyword">return</span>;</span><br><span class="line"> <span class="keyword">order</span>(<span class="type">node</span>.left);</span><br><span class="line"> <span class="keyword">order</span>(<span class="type">node</span>.right);</span><br><span class="line"> result.push(<span class="type">node</span>.val);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">order</span><span class="built_in">(root</span>);</span><br><span class="line"> <span class="keyword">return</span> result;</span><br><span class="line">};</span><br></pre></td></tr></table></figure>
<p>是不是就发现很简答了,所以不要慌,要总结,才能学会。。。</p>
<!-- reward -->
</div>
<!-- copyright -->
<footer class="article-footer">
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/algorithm/" rel="tag">algorithm</a></li></ul>
</footer>
</div>
</article>
<article
id="post-algorithm/45"
class="article article-type-post"
itemscope
itemprop="blogPost"
data-scroll-reveal
>
<div class="article-inner">
<header class="article-header">
<h2 itemprop="name">
<a class="article-title" href="/algorithm/45/"
>JavaScript算法套路之二叉树理论基础</a>
</h2>
</header>
<div class="article-meta">
<a href="/algorithm/45/" class="article-date">
<time datetime="2022-02-17T12:08:19.000Z" itemprop="datePublished">2022-02-17</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/algorithm/">algorithm</a>
</div>
</div>
<div class="article-entry" itemprop="articleBody">
<p>学习算法,数据结构必须了解。据说二叉树是在学习算法路上的第一道要突破的屏障。那么就来总结一下二叉的一些简单理论:</p>
<h3 id="二叉树的定义"><a href="#二叉树的定义" class="headerlink" title="二叉树的定义"></a>二叉树的定义</h3><p>二叉树是树的一种,二叉树最多只能有俩个节点,分为左孩子和右孩子。</p>
<h3 id="二叉树的分类"><a href="#二叉树的分类" class="headerlink" title="二叉树的分类"></a>二叉树的分类</h3><ul>
<li>满二叉树</li>
<li>完全二叉树</li>
<li>二叉搜索树</li>
<li>平衡二叉搜索树<br>…<br>等等,种类很多,这里就不一一细数。</li>
</ul>
<h3 id="二叉树的存储方式"><a href="#二叉树的存储方式" class="headerlink" title="二叉树的存储方式"></a>二叉树的存储方式</h3><p>二叉树的存储方式,可以是链式存储,也可以是顺序存储。</p>
<h5 id="链式存储"><a href="#链式存储" class="headerlink" title="链式存储"></a>链式存储</h5><p>链式存储就是用指针,就是类似于链表,但是二叉树会比链表多一个指针,树有俩个指针,左和右,分别指向自己的左孩子和右孩子。</p>
<h5 id="顺序存储"><a href="#顺序存储" class="headerlink" title="顺序存储"></a>顺序存储</h5><p>顺序存储就是用数组的方式来存储二叉树。一层一层的存储。</p>
<figure class="highlight livescript"><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="number">1</span></span><br><span class="line"> / <span class="string">\</span></span><br><span class="line"> <span class="number">2</span> <span class="number">5</span></span><br><span class="line">/ <span class="string">\</span> <span class="string">\</span></span><br><span class="line"><span class="number">3</span> <span class="number">4</span> <span class="number">6</span></span><br></pre></td></tr></table></figure>
<p>用数组的方式存储就是:</p>
<figure class="highlight actionscript"><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> tree = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">5</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="literal">null</span>, <span class="number">6</span>];</span><br></pre></td></tr></table></figure>
<h3 id="二叉树的遍历"><a href="#二叉树的遍历" class="headerlink" title="二叉树的遍历"></a>二叉树的遍历</h3><p>二叉树的遍历方式有俩种:</p>
<ol>
<li>深度优先:先往深了走,遇到叶子节点再往回走(<code>中间节点的遍历顺序</code>)<ul>
<li>前序遍历</li>
<li>中序遍历</li>
<li>后续遍历<br>实现深度优先的遍历,我们一般都是通过递归的方式实现的。</li>
</ul>
</li>
<li>广度优先:一层一层的遍历<ul>
<li>层序遍历<br>实现广度优先的遍历一般都是通过队列的方式实现的,因为队列先进先出的特点能一层一层的遍历二叉树。<br>接下来,就是我们如何实现了。。。</li>
</ul>
</li>
</ol>
<h3 id="JavaScript创建二叉查找树"><a href="#JavaScript创建二叉查找树" class="headerlink" title="JavaScript创建二叉查找树"></a>JavaScript创建二叉查找树</h3><figure class="highlight kotlin"><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></pre></td><td class="code"><pre><span class="line">function TreeNode (<span class="keyword">data</span>, left, right) {</span><br><span class="line"> <span class="keyword">this</span>.<span class="keyword">val</span> = <span class="keyword">data</span>;</span><br><span class="line"> <span class="keyword">this</span>.left = left;</span><br><span class="line"> <span class="keyword">this</span>.right = right;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">function BST() {</span><br><span class="line"> <span class="comment">// 保存二叉树的节点</span></span><br><span class="line"> <span class="keyword">this</span>.root = <span class="literal">null</span>;</span><br><span class="line"> <span class="keyword">this</span>.insert = insert;</span><br><span class="line">}</span><br><span class="line">function insert(<span class="keyword">data</span>) {</span><br><span class="line"> let node = new TreeNode(<span class="keyword">data</span>, <span class="literal">null</span>, <span class="literal">null</span>);</span><br><span class="line"> <span class="keyword">if</span> (!<span class="keyword">this</span>.root) {</span><br><span class="line"> <span class="keyword">this</span>.root = node;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> let current = <span class="keyword">this</span>.root;</span><br><span class="line"> let parent = <span class="literal">null</span>;</span><br><span class="line"> <span class="keyword">while</span> (<span class="literal">true</span>) {</span><br><span class="line"> parent = current</span><br><span class="line"> <span class="keyword">if</span> (<span class="keyword">data</span> < current.<span class="keyword">val</span>) {</span><br><span class="line"> current = current.left;</span><br><span class="line"> <span class="keyword">if</span> (current === <span class="literal">null</span>) {</span><br><span class="line"> parent.left = node;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> current = current.right;</span><br><span class="line"> <span class="keyword">if</span> (current === <span class="literal">null</span>) {</span><br><span class="line"> parent.right = node;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<!-- reward -->
</div>
<!-- copyright -->
<footer class="article-footer">
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/algorithm/" rel="tag">algorithm</a></li></ul>
</footer>
</div>
</article>
<article
id="post-ts/7"
class="article article-type-post"
itemscope
itemprop="blogPost"
data-scroll-reveal
>
<div class="article-inner">
<header class="article-header">
<h2 itemprop="name">
<a class="article-title" href="/ts/7/"
>Typescript--装饰器</a>
</h2>
</header>
<div class="article-meta">
<a href="/ts/7/" class="article-date">
<time datetime="2021-10-15T07:25:05.000Z" itemprop="datePublished">2021-10-15</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/typescript/">typescript</a>
</div>
</div>
<div class="article-entry" itemprop="articleBody">
<h6 id="装饰器定义"><a href="#装饰器定义" class="headerlink" title="装饰器定义"></a>装饰器定义</h6><p>装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,属性或者参数上,可以修改类的行为。通俗讲,装饰器就是一个方法,可以注入到类,方法,属性参数上来扩展类,属性,方法,参数的功能。<br>常见的装饰器有:类装饰器,属性装饰器,方法装饰器,参数装饰器。<br>装饰器的写法:普通装饰器(无法传参),装饰器工厂(可传参)<br>装饰器是过去几年中js的最大成就之一,已是es7的标准特性之一</p>
<h6 id="类装饰器"><a href="#类装饰器" class="headerlink" title="类装饰器"></a>类装饰器</h6><ul>
<li><p>类装饰器:类装饰器在类声明之前就被声明(紧靠着类声明)。类装饰器应用于类构造函数,可以用来监视,修改或者替换类定义,传入一个参数。</p>
</li>
<li><p>普通装饰器(不带参数)</p>
</li>
</ul>
<figure class="highlight typescript"><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="comment">// 装饰器是一个普通函数,其参数就是类,可以在装饰器中对类的属性和方法等进行扩展</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">logClass</span> (<span class="params">param: <span class="built_in">any</span></span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(param)</span><br><span class="line"> param.prototype.run = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'世界那么大,我想去看看'</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@logClass</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Log</span> </span>{</span><br><span class="line"> contructor () {</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> log = <span class="keyword">new</span> Log()</span><br><span class="line">log.run() <span class="comment">// 世界那么大,我想去看看</span></span><br></pre></td></tr></table></figure>
<ul>
<li>类装饰器(装饰工厂)—-可传参<figure class="highlight typescript"><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="function"><span class="keyword">function</span> <span class="title">logClass</span>(<span class="params">param: <span class="built_in">string</span></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="function"><span class="keyword">function</span> (<span class="params">target: <span class="built_in">any</span></span>) </span>{</span><br><span class="line"> <span class="comment">// target是当前的类</span></span><br><span class="line"> <span class="comment">// param是装饰器接受的参数</span></span><br><span class="line"> <span class="built_in">console</span>.log(param) <span class="comment">// 世界那么大</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="meta">@logClass</span>(<span class="string">'世界那么大'</span>)</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Log</span> </span>{</span><br><span class="line"> contructor () {}</span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> log = <span class="keyword">new</span> Log()</span><br></pre></td></tr></table></figure>
装饰器可以重栽构造函数:类装饰器表达式会在运行时当作函数被调用,类的构造函数作为唯一的参数。如果类装饰器返回一个值,它会使用提供的构造函数来替换类的声明。<figure class="highlight scala"><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">function logClass (target: any) {</span><br><span class="line"> <span class="comment">// 重载构造函数</span></span><br><span class="line"> <span class="keyword">return</span> <span class="class"><span class="keyword">class</span> <span class="keyword">extends</span> <span class="title">target</span> </span>{</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="meta">@logClass</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">HttpClient</span> </span>{</span><br><span class="line"> public apiUrl: string | undefined;</span><br><span class="line"> constructor () {</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h6 id="属性装饰器"><a href="#属性装饰器" class="headerlink" title="属性装饰器"></a>属性装饰器</h6>属性装饰器表达式会在运行时当作函数被调用,传入下列2个参数:</li>
<li>对于静态成员来说是类的构造函数,对于实例成员是类的原型对象;</li>
<li>成员的名字</li>
</ul>
<figure class="highlight typescript"><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="function"><span class="keyword">function</span> <span class="title">logClass</span> (<span class="params">target: <span class="built_in">any</span></span>) </span>{</span><br><span class="line"> <span class="comment">// 重载构造函数</span></span><br><span class="line"> <span class="keyword">return</span> <span class="class"><span class="keyword">class</span> <span class="keyword">extends</span> <span class="title">target</span> </span>{</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">logProperty</span> (<span class="params">params: <span class="built_in">string</span></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="function"><span class="keyword">function</span> (<span class="params">target:<span class="built_in">any</span>, attr: <span class="built_in">any</span></span>) </span>{</span><br><span class="line"> target[arr] = param</span><br><span class="line"> <span class="comment">// target是类的原型对象</span></span><br><span class="line"> <span class="comment">// param是装饰器的参数</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="meta">@logClass</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">HttpClient</span> </span>{</span><br><span class="line"> <span class="meta">@logProperty</span>(<span class="string">'xxxxxx'</span>)</span><br><span class="line"> <span class="keyword">public</span> apiUrl: <span class="built_in">string</span> | <span class="literal">undefined</span>;</span><br><span class="line"> <span class="title">constructor</span> (<span class="params"></span>) {</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h6 id="方法装饰器"><a href="#方法装饰器" class="headerlink" title="方法装饰器"></a>方法装饰器</h6><p>他会被应用到方法的属性描述符上,可以用来监视,修改或者替换方法的定义。<br>方法装饰器会在运行时,传入三个参数:</p>
<ul>
<li>对于静态成员来说是类的构造函数,对于实例成员来说是类的原型对象</li>
<li>成员的名字</li>
<li>成员属性的描述符<figure class="highlight typescript"><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><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">get</span>(<span class="params">params: <span class="built_in">any</span></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="function"><span class="keyword">function</span> (<span class="params">target:<span class="built_in">any</span>,methodName, desc:<span class="built_in">any</span></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> oMethod = desc.value</span><br><span class="line"> desc.value = <span class="function"><span class="keyword">function</span> (<span class="params">...agrs:<span class="built_in">any</span>[]</span>) </span>{</span><br><span class="line"> args = args.map(<span class="function"><span class="params">value</span> =></span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">String</span>(value)</span><br><span class="line"> })</span><br><span class="line"> oMethod.apply(<span class="built_in">this</span>, args)</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">HttpClient</span> </span>{</span><br><span class="line"> <span class="keyword">public</span> url: <span class="built_in">string</span> | <span class="literal">undefined</span>;</span><br><span class="line"> <span class="title">constructor</span> (<span class="params"></span>) {</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"> <span class="meta">@get</span>(<span class="string">"http://www.baidu.com"</span>)</span><br><span class="line"> <span class="function"><span class="title">getData</span>(<span class="params">...args:<span class="built_in">any</span>[]</span>)</span> {</span><br><span class="line"> <span class="built_in">console</span>.log(args)</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> http = <span class="keyword">new</span> HttpClient()</span><br><span class="line">http.getData(<span class="number">1222</span>, <span class="string">'1122'</span>)</span><br></pre></td></tr></table></figure>
<h6 id="方法参数装饰器"><a href="#方法参数装饰器" class="headerlink" title="方法参数装饰器"></a>方法参数装饰器</h6>参数装饰器表达式会在运行时当作函数被调用,可以使用参数装饰器为类的原型增加一些元素数据,传入三个参数:</li>
<li>对于静态成员来说是类的构造函数,对于实例成员来说是类的原型对象</li>
<li>参数的名字</li>
<li>参数在函数参数列表中的索引<figure class="highlight typescript"><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">logParams</span> (<span class="params">params: <span class="built_in">any</span></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params">target:<span class="built_in">any</span>,paramsName:<span class="built_in">any</span></span>) </span>{</span><br><span class="line"> target.url = params</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">HttpClient</span> </span>{</span><br><span class="line"> <span class="keyword">public</span> url: <span class="built_in">any</span> | <span class="literal">undefined</span></span><br><span class="line"> <span class="title">constructor</span> (<span class="params"></span>) {}</span><br><span class="line"> <span class="function"><span class="title">getData</span>(<span class="params"><span class="meta">@logParams</span>(<span class="string">'uuid'</span>) uuid:<span class="built_in">any</span> </span>)</span> {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'ddddd'</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> http = <span class="keyword">new</span> HttpClient()</span><br><span class="line">http.getData(<span class="number">1212132</span>)</span><br><span class="line"></span><br></pre></td></tr></table></figure></li>
</ul>
<h6 id="装饰器的执行顺序"><a href="#装饰器的执行顺序" class="headerlink" title="装饰器的执行顺序"></a>装饰器的执行顺序</h6><p>属性装饰器 > 方法装饰器 > 方法参数装饰器 > 类装饰器<br><code>如果有多个同样的装饰器,那么会从下向上之行</code></p>
<!-- reward -->
</div>
<!-- copyright -->
<footer class="article-footer">
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/typescript/" rel="tag">typescript</a></li></ul>
</footer>
</div>
</article>
<article
id="post-ts/6"
class="article article-type-post"
itemscope
itemprop="blogPost"
data-scroll-reveal
>
<div class="article-inner">
<header class="article-header">
<h2 itemprop="name">
<a class="article-title" href="/ts/6/"
>Typescript--模块和命名空间</a>
</h2>
</header>
<div class="article-meta">
<a href="/ts/6/" class="article-date">
<time datetime="2021-10-15T06:36:36.000Z" itemprop="datePublished">2021-10-15</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/typescript/">typescript</a>
</div>
</div>
<div class="article-entry" itemprop="articleBody">
<h6 id="模块的概念"><a href="#模块的概念" class="headerlink" title="模块的概念"></a>模块的概念</h6><p>模块的概念:关于术语的一点说明。请务必注意一点,typescript1.5里术语名已经发生变化。内部模块现在叫做“命名空间”。外部模块现在简称为“模块”,模块在其自身的作用域里执行,而不是在全局作用域里执行。这意味着定义在一个模块里的变量,函数,类等在模块外部都是不可见的。除非能明确的使用export的形式之一导出他们,相反,如果想使用其他模块到处的变量,函数,类,接口的时候,就比如导入他们,可以用使用import的形式。</p>
<p>理解:<br>我们可以使用一些公共的功能单独抽离一个文件作为模块。<br>模块里的变量,函数,类,默认是私有的。如果哦我们要在外部访问模块里的数据(变量,函数,类),我们需要通过export暴露模块里的数据(变量,函数,类)。暴露后我们通过import引入模块就可以使用模块暴露出来的数据(变量,函数,类)了。</p>
<h6 id="export"><a href="#export" class="headerlink" title="export"></a>export</h6><p>export default 默认导出<br>每个模块都可以有一个default导出,默认导出使用default关键字标记。并且一个模块只能有一个default导出,需要使用特殊形式来导出。</p>
<h6 id="命名空间"><a href="#命名空间" class="headerlink" title="命名空间"></a>命名空间</h6><p>在代码量较大的情况下,为了避免各种变量名相互冲突,可以将相似的函数,类,接口等放到命名空间中间。同java的包,.net的命名空间一样,typescript的命名空间可以将代码包裹起来,只对外暴露需要在外部访问的对象,命名空间内的对象通过export对外暴露。<br>命名空间和模块的区别:</p>
<ul>
<li>命名空间:内部模块,主要用于组织代码,避免命名冲突,命名空间用关键字<code>namespace</code>表示</li>
<li>模块:ts的外部模块的简称,侧重代码的复用,一个模块里可能会有多个命名空间</li>
</ul>
<!-- reward -->
</div>
<!-- copyright -->
<footer class="article-footer">
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/typescript/" rel="tag">typescript</a></li></ul>
</footer>
</div>
</article>
<article
id="post-ts/5"
class="article article-type-post"
itemscope
itemprop="blogPost"
data-scroll-reveal
>
<div class="article-inner">
<header class="article-header">
<h2 itemprop="name">
<a class="article-title" href="/ts/5/"
>Typescript--泛型的使用</a>
</h2>
</header>
<div class="article-meta">
<a href="/ts/5/" class="article-date">
<time datetime="2021-10-14T09:00:40.000Z" itemprop="datePublished">2021-10-14</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/typescript/">typescript</a>
</div>
</div>
<div class="article-entry" itemprop="articleBody">
<h6 id="泛型的定义"><a href="#泛型的定义" class="headerlink" title="泛型的定义"></a>泛型的定义</h6><p>软件工程中,我们不仅仅要建立一致的定义良好的API,同时也要考虑重用性。组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型。这在创建大型系统时提供了十分灵活的功能。</p>
<p>在像C#和Java这样的语言中,可以使用泛型来创建重用的组件,一个组件可以支持多种类型的数据,这样用户就可以以自己的数据类型使用组件。</p>
<p>通俗讲,泛型就是解决类接口方法的复用性,以及对不特定数据类型的支持。</p>
<p>泛型使用<code>T</code>来定义:</p>
<figure class="highlight kotlin"><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">function <span class="function"><span class="keyword">fun</span><span class="type"><T></span><span class="params">(name: <span class="type">T</span>)</span></span>:T {</span><br><span class="line"> <span class="keyword">return</span> name</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>定义了一个函数,函数传入的参数类型和函数的返回值类型保持一致,具体的类型是什么,由调用者决定,比如:</p>
<figure class="highlight kotlin"><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">function <span class="function"><span class="keyword">fun</span><span class="type"><T></span><span class="params">(name:<span class="type">T</span>)</span></span>:T{</span><br><span class="line"> <span class="keyword">return</span> name</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">fun</span>:<span class="type"><string></span><span class="params">(<span class="string">'xiaoming'</span>)</span></span> <span class="comment">// xiaoming</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span><span class="type"><number></span><span class="params">(<span class="string">'小明'</span>)</span></span> <span class="comment">// 这是一个错误写法</span></span><br></pre></td></tr></table></figure>
<p><code>注:</code><br> 我们可能会想起定义函数的时候,使用any关键字,但是这里要强调的是,any关键字其实是放弃了typescript的类型校验。</p>
<h6 id="泛型类"><a href="#泛型类" class="headerlink" title="泛型类"></a>泛型类</h6><p>实现一个有最小堆的算法,需要同时支持返回数字和字符串俩种类型,通过类的泛型实现。</p>
<figure class="highlight csharp"><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><span class="line"><span class="keyword">class</span> <span class="title">MainClass</span><<span class="title">T</span>> {</span><br><span class="line"> <span class="keyword">public</span> list:T[] = []</span><br><span class="line"> <span class="keyword">add</span> (<span class="keyword">value</span>: T): <span class="keyword">void</span> {</span><br><span class="line"> <span class="keyword">this</span>.list.push(<span class="keyword">value</span>)</span><br><span class="line"> }</span><br><span class="line"> min():T{</span><br><span class="line"> <span class="keyword">var</span> minNum = <span class="keyword">this</span>.list[<span class="number">0</span>]</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i < <span class="keyword">this</span>.list.length;i++) {</span><br><span class="line"> <span class="keyword">if</span> (minNum > <span class="keyword">this</span>.list[i]) {</span><br><span class="line"> minNum = <span class="keyword">this</span>.list[i]</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> minNum</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">let</span> m = MinClass<number>() <span class="comment">// 实例化类,并且制定了类的T代表的类型是number</span></span><br><span class="line">m.<span class="keyword">add</span>(<span class="number">10</span>)</span><br><span class="line">m.<span class="keyword">add</span>(<span class="number">45</span>)</span><br><span class="line">m.<span class="keyword">add</span>(<span class="number">6</span>)</span><br><span class="line">m.<span class="keyword">add</span>(<span class="number">2</span>)</span><br><span class="line">m.<span class="keyword">add</span>(<span class="number">1</span>)</span><br><span class="line">m.<span class="keyword">add</span>(<span class="number">9</span>)</span><br><span class="line">m.min() <span class="comment">// 1</span></span><br></pre></td></tr></table></figure>
<h6 id="把类作为参数来约束数据传入的类型"><a href="#把类作为参数来约束数据传入的类型" class="headerlink" title="把类作为参数来约束数据传入的类型"></a>把类作为参数来约束数据传入的类型</h6><figure class="highlight typescript"><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></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MysqlDb</span> <<span class="title">T</span>> </span>{</span><br><span class="line"> add(info:T):<span class="built_in">boolean</span> {</span><br><span class="line"> <span class="built_in">console</span>.log(info)</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">User</span> </span>{</span><br><span class="line"> <span class="attr">username</span>: <span class="built_in">string</span> | <span class="literal">undefined</span>;</span><br><span class="line"> password: <span class="built_in">string</span> | <span class="literal">undefined</span>;</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"><span class="keyword">let</span> user = <span class="keyword">new</span> User()</span><br><span class="line">user.name = <span class="string">'xiaoming'</span></span><br><span class="line">user.password = <span class="string">'123456'</span></span><br><span class="line"><span class="keyword">var</span> db = MysqlDb<User>() <span class="comment">// 此时User起到了教研的作用</span></span><br><span class="line">db.add(user)</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">ArticleCate</span> </span>{</span><br><span class="line"> <span class="attr">title</span>: <span class="built_in">string</span> | <span class="literal">undefined</span>;</span><br><span class="line"> desc: <span class="built_in">string</span> | <span class="literal">undefined</span>;</span><br><span class="line"> status: <span class="built_in">number</span> | <span class="number">0</span>;</span><br><span class="line"> <span class="title">constructor</span> (<span class="params">param: {</span></span><br><span class="line"><span class="params"> title: <span class="built_in">string</span> | <span class="literal">undefined</span>;</span></span><br><span class="line"><span class="params"> desc: <span class="built_in">string</span> | <span class="literal">undefined</span>;</span></span><br><span class="line"><span class="params"> status?: <span class="built_in">number</span> | <span class="number">0</span>;</span></span><br><span class="line"><span class="params"> }</span>) {</span><br><span class="line"> <span class="built_in">this</span>.title = param.title;</span><br><span class="line"> <span class="built_in">this</span>.desc = param.desc;</span><br><span class="line"> <span class="built_in">this</span>.status = param.status;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> a = <span class="keyword">new</span> ArticleCate({</span><br><span class="line"> <span class="attr">title</span>: <span class="string">'世界那么大'</span>,</span><br><span class="line"> <span class="attr">desc</span>: <span class="string">'我想去看看'</span>,</span><br><span class="line"> <span class="attr">status</span>: <span class="number">0</span></span><br><span class="line">})</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> mydb = <span class="keyword">new</span> MysqlDb<ArticleCate>() <span class="comment">// 此时ArticleCate起到了教研的作用</span></span><br><span class="line">mydb.add(a)</span><br></pre></td></tr></table></figure>
<h6 id="泛型接口"><a href="#泛型接口" class="headerlink" title="泛型接口"></a>泛型接口</h6><ul>
<li>方法一<figure class="highlight r"><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">interface Config {</span><br><span class="line"> <<span class="built_in">T</span>>(value: <span class="built_in">T</span>): <span class="built_in">T</span></span><br><span class="line">}</span><br><span class="line">var setData: Config = <span class="keyword">function</span><<span class="built_in">T</span>>(value: <span class="built_in">T</span>):<span class="built_in">T</span> {</span><br><span class="line"> <span class="built_in">return</span> vale</span><br><span class="line">}</span><br><span class="line">setData<number>(<span class="number">12344</span>)</span><br></pre></td></tr></table></figure></li>
<li>方法二<figure class="highlight csharp"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">interface</span> <span class="title">Config</span><<span class="title">T</span>> {</span><br><span class="line"> (<span class="keyword">value</span>: T): T</span><br><span class="line">}</span><br><span class="line"><span class="function">function <span class="title">getData</span><<span class="title">T</span>>(<span class="params"><span class="keyword">value</span>: T</span>):T</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">value</span></span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> myGetData:Config<<span class="built_in">string</span>> = <span class="function">getData</span></span><br><span class="line"><span class="function"><span class="title">myGetData</span>(<span class="params"><span class="string">'xiaoming'</span></span>) <span class="comment">// 正确</span></span></span><br><span class="line"><span class="function"><span class="title">myGetData</span>(<span class="params"><span class="number">12345</span></span>) <span class="comment">// 错误</span></span></span><br></pre></td></tr></table></figure>
That’s all!</li>
</ul>
<!-- reward -->
</div>
<!-- copyright -->
<footer class="article-footer">
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/typescript/" rel="tag">typescript</a></li></ul>
</footer>
</div>
</article>
<article
id="post-algorithm/43"
class="article article-type-post"
itemscope
itemprop="blogPost"
data-scroll-reveal
>
<div class="article-inner">
<header class="article-header">
<h2 itemprop="name">
<a class="article-title" href="/algorithm/43/"
>leeCode算法--各位相加问题</a>
</h2>
</header>
<div class="article-meta">
<a href="/algorithm/43/" class="article-date">
<time datetime="2021-10-14T02:53:48.000Z" itemprop="datePublished">2021-10-14</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/algorithm/">algorithm</a>
</div>
</div>
<div class="article-entry" itemprop="articleBody">
<p>题目:给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。</p>
<p>分析:注意这个结果,直到一位数的时候,就不在计算,那么就意味着小于等于(<=)9的时候就直接return,这是其一。其二,当大于9的时候呢?你会发现,<code>如果是9的倍数,那就是9,否则我们就用9取余,num%9</code>。就是这么简单,难点在于,一下子想不出这个思路。</p>
<figure class="highlight dart"><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">let addDigits => (<span class="built_in">num</span>) {</span><br><span class="line"> <span class="keyword">if</span> (!<span class="built_in">num</span>) <span class="keyword">return</span> <span class="built_in">num</span></span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">num</span> % <span class="number">9</span> || <span class="number">9</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>代码很简单,思路很难。。。。还得练啊。。。。</p>
<!-- reward -->
</div>
<!-- copyright -->
<footer class="article-footer">
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/algorithm/" rel="tag">algorithm</a></li></ul>
</footer>
</div>
</article>
<article
id="post-ts/4"
class="article article-type-post"
itemscope
itemprop="blogPost"
data-scroll-reveal
>
<div class="article-inner">
<header class="article-header">
<h2 itemprop="name">
<a class="article-title" href="/ts/4/"
>Typescript--接口的使用</a>
</h2>
</header>
<div class="article-meta">
<a href="/ts/4/" class="article-date">
<time datetime="2021-10-12T11:30:27.000Z" itemprop="datePublished">2021-10-12</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/typescript/">typescript</a>
</div>
</div>
<div class="article-entry" itemprop="articleBody">
<h6 id="接口的定义"><a href="#接口的定义" class="headerlink" title="接口的定义"></a>接口的定义</h6><p>在面向对象的编程中,接口是一种规范的定义,它定义了行为和动作的规范。在程序设计里,接口起到了限制和规范的作用。接口定义了某一批类所需要遵守的规范,接口不关心类内部的状态数据。也不关心这些类的内部方法实现的具体细节。他只关心这些类必须提供某些方法。提供这些方法的类就可以满足实际需求。typescript中的类有点类似于java,同时还增加了更加灵活的接口类型。包括属性,方法,可索引和类等。</p>
<h6 id="属性接口"><a href="#属性接口" class="headerlink" title="属性接口"></a>属性接口</h6><p>属性接口,就是对JSON的约束。实现一个对函数参数约束的接口。</p>
<figure class="highlight typescript"><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="function"><span class="keyword">function</span> <span class="title">printLabel</span> (<span class="params">labelInfo: {label: <span class="built_in">string</span>}</span>):<span class="title">void</span> </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(labelInfo)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<ul>
<li><p>对批量方法的参数进行约束</p>
<figure class="highlight php"><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></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">interface</span> <span class="title">FullName</span> </span>{</span><br><span class="line"> firstName: <span class="keyword">string</span>;</span><br><span class="line"> secondName: <span class="keyword">string</span>; <span class="comment">// 注意必须是;结尾</span></span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">printName</span> (<span class="params">name: FullName</span>) </span>{</span><br><span class="line"> <span class="comment">// 必须传入的对象中有firstName,secondName,且必须都是string</span></span><br><span class="line">}</span><br><span class="line">printName({firstName: <span class="string">'小明'</span>, secondName: <span class="string">'小红'</span>})</span><br><span class="line">printName(<span class="string">'小红'</span>) <span class="comment">// 错误</span></span><br></pre></td></tr></table></figure>
<p><code>传入的参数必须要有接口中定义的字段一一对应</code>,严格按照接口的定义传参</p>
</li>
<li><p>接口的可选属性<br>接口中的可选属性用<code>?</code>表示</p>
<figure class="highlight angelscript"><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">interface</span> <span class="symbol">FullName</span> {</span><br><span class="line"> firstName: <span class="built_in">string</span>;</span><br><span class="line"> secondName?: <span class="built_in">string</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>在接口FullName中,firstName是一个必传属性,但是secondName则是一个可选属性。</p>
</li>
</ul>
<h6 id="函数类型接口"><a href="#函数类型接口" class="headerlink" title="函数类型接口"></a>函数类型接口</h6><p>对方法的参数以及返回值进行约束。也可以对参数进行批量约束。</p>
<ul>
<li>加密的函数类型接口</li>
</ul>
<figure class="highlight maxima"><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">interface encrypt {</span><br><span class="line"> (<span class="built_in">key</span>:<span class="built_in">string</span>, value:<span class="built_in">string</span>):<span class="built_in">string</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="built_in">var</span> md5:encrypt = function (<span class="built_in">key</span>:<span class="built_in">string</span>, value:<span class="built_in">string</span>): <span class="built_in">string</span> {</span><br><span class="line"> <span class="built_in">return</span> <span class="built_in">key</span> + value</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>encrypt接口对md5函数实现了约束。</p>
<h6 id="可索引接口"><a href="#可索引接口" class="headerlink" title="可索引接口"></a>可索引接口</h6><p>表示对数组和对象的约束。</p>
<ul>
<li>对数组的约束,可索引约束:<figure class="highlight csharp"><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">interface</span> <span class="title">UserArr</span> {</span><br><span class="line"> [<span class="meta">index:number</span>]:<span class="built_in">string</span></span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> arr:UserArr = [<span class="string">'111'</span>, <span class="string">'333'</span>]</span><br></pre></td></tr></table></figure>
接口UserArr约束索引是number,而值是个string</li>
<li>对对象的约束<figure class="highlight angelscript"><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">interface</span> <span class="symbol">UserObj</span> {</span><br><span class="line"><span class="string"> [index:string]</span>:<span class="built_in">string</span></span><br><span class="line">}</span><br><span class="line">var arr:UserObj = {name: <span class="string">'xiaoming‘}</span></span><br></pre></td></tr></table></figure>
接口UserArr约束索引是string,而值是个string</li>
</ul>
<h6 id="类类型接口,对类约束-和抽象类有点相似"><a href="#类类型接口,对类约束-和抽象类有点相似" class="headerlink" title="类类型接口,对类约束 和抽象类有点相似"></a>类类型接口,对类约束 和抽象类有点相似</h6><figure class="highlight typescript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">interface</span> Animal {</span><br><span class="line"> <span class="attr">name</span>: <span class="built_in">string</span>,</span><br><span class="line"> eat(str:<span class="built_in">string</span>):<span class="built_in">void</span></span><br><span class="line">}</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Dog</span> <span class="title">implements</span> <span class="title">Animal</span> </span>{</span><br><span class="line"> <span class="attr">name</span>: <span class="built_in">string</span>,</span><br><span class="line"> <span class="title">constructor</span> (<span class="params">name: <span class="built_in">string</span></span>) {</span><br><span class="line"> <span class="built_in">this</span>.name = name</span><br><span class="line"> }</span><br><span class="line"> eat (food:<span class="built_in">string</span>) {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">this</span>.name + food)</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> d = <span class="keyword">new</span> Dag(<span class="string">'小黑'</span>)</span><br><span class="line">d.eat(<span class="string">'粮食'</span>)</span><br></pre></td></tr></table></figure>
<h5 id="接口扩展:接口可以继承接口"><a href="#接口扩展:接口可以继承接口" class="headerlink" title="接口扩展:接口可以继承接口"></a>接口扩展:接口可以继承接口</h5><p>接口和类一样也可以通过extends字段实现继承。</p>
<figure class="highlight typescript"><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">interface</span> Animal {</span><br><span class="line"> eat():<span class="built_in">void</span></span><br><span class="line">}</span><br><span class="line"><span class="keyword">interface</span> Person <span class="keyword">extends</span> Animal {</span><br><span class="line"> work():<span class="built_in">void</span></span><br><span class="line">}</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Web</span> <span class="title">implements</span> <span class="title">Person</span> </span>{</span><br><span class="line"> <span class="keyword">public</span> name: <span class="built_in">string</span>;</span><br><span class="line"> <span class="function"><span class="title">constructor</span>(<span class="params">name:<span class="built_in">string</span></span>)</span> {</span><br><span class="line"> <span class="built_in">this</span>.name = name</span><br><span class="line"> }</span><br><span class="line"> <span class="function"><span class="title">eat</span>(<span class="params"></span>)</span> {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">this</span>.name + <span class="string">'喜欢吃馒头'</span>)</span><br><span class="line"> }</span><br><span class="line"> work () {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">this</span>.name + <span class="string">'敲代码'</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">let</span> web = <span class="keyword">new</span> Web()</span><br><span class="line">web.eat(<span class="string">'小明'</span>) <span class="comment">// 小明喜欢吃馒头</span></span><br><span class="line">web.work(<span class="string">'小黑'</span>) <span class="comment">// 小黑敲代码</span></span><br></pre></td></tr></table></figure>
<figure class="highlight typescript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">interface</span> Animal {</span><br><span class="line"> eat():<span class="built_in">void</span></span><br><span class="line">}</span><br><span class="line"><span class="keyword">interface</span> Person <span class="keyword">extends</span> Animal {</span><br><span class="line"> work():<span class="built_in">void</span></span><br><span class="line">}</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Progromer</span> </span>{</span><br><span class="line"> <span class="keyword">public</span> name: <span class="built_in">string</span>;</span><br><span class="line"> <span class="function"><span class="title">constructor</span>(<span class="params">name: <span class="built_in">string</span></span>)</span> {</span><br><span class="line"> <span class="built_in">this</span>.name = name</span><br><span class="line"> }</span><br><span class="line"> coding () {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">this</span>.name + <span class="string">'敲打吗'</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Web</span> <span class="keyword">extends</span> <span class="title">Progromer</span> <span class="title">implements</span> <span class="title">Person</span> </span>{</span><br><span class="line"> <span class="function"><span class="title">constructor</span>(<span class="params">name:<span class="built_in">string</span></span>)</span> {</span><br><span class="line"> <span class="built_in">super</span>(name)</span><br><span class="line"> }</span><br><span class="line"> <span class="function"><span class="title">eat</span>(<span class="params"></span>)</span> {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">this</span>.name + <span class="string">'喜欢吃馒头'</span>)</span><br><span class="line"> }</span><br><span class="line"> work () {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">this</span>.name + <span class="string">'敲代码'</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">let</span> web = <span class="keyword">new</span> Web()</span><br><span class="line">web.eat(<span class="string">'小明'</span>) <span class="comment">// 小明喜欢吃馒头</span></span><br><span class="line">web.work(<span class="string">'小黑'</span>) <span class="comment">// 小黑敲代码</span></span><br><span class="line">web.coding(<span class="string">'小李'</span>) <span class="comment">// 小李敲打吗</span></span><br></pre></td></tr></table></figure>
<p>That’s interface!</p>
<!-- reward -->
</div>
<!-- copyright -->
<footer class="article-footer">
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/typescript/" rel="tag">typescript</a></li></ul>
</footer>
</div>
</article>
<article
id="post-ts/3"
class="article article-type-post"
itemscope
itemprop="blogPost"
data-scroll-reveal
>
<div class="article-inner">
<header class="article-header">
<h2 itemprop="name">
<a class="article-title" href="/ts/3/"
>Typescript--类的使用</a>
</h2>
</header>
<div class="article-meta">
<a href="/ts/3/" class="article-date">
<time datetime="2021-09-26T06:56:46.000Z" itemprop="datePublished">2021-09-26</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/typescript/">typescript</a>
</div>
</div>
<div class="article-entry" itemprop="articleBody">
<h6 id="类的定义"><a href="#类的定义" class="headerlink" title="类的定义"></a>类的定义</h6><p>在ts中类的定义是通过class来定义的。</p>
<figure class="highlight typescript"><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="class"><span class="keyword">class</span> <span class="title">Person</span> </span>{</span><br><span class="line"> <span class="attr">name</span>:<span class="built_in">string</span> <span class="comment">// 属性,省略了public字段</span></span><br><span class="line"> <span class="title">constructor</span> (<span class="params">name:<span class="built_in">string</span></span>) { <span class="comment">// 构造函数,实例化类时,触发的方法</span></span><br><span class="line"> <span class="built_in">this</span>.name = name</span><br><span class="line"> }</span><br><span class="line"> run ():<span class="built_in">void</span> {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">this</span>.name)</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> p = <span class="keyword">new</span> Person(<span class="string">'张三'</span>)</span><br><span class="line">p.run() <span class="comment">// 张三</span></span><br></pre></td></tr></table></figure>
<h6 id="ts中实现继承"><a href="#ts中实现继承" class="headerlink" title="ts中实现继承"></a>ts中实现继承</h6><p>在ts中实现继承的方式是通过<code>extends</code>、<code>super</code>字符来实现的。父类和子类的方法一至。子类可以扩展自己的方法。如果子类和父类有同名方法的时候,调用子类方法,那么优先执行子类方法。</p>
<figure class="highlight scala"><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="class"><span class="keyword">class</span> <span class="title">Person</span> </span>{</span><br><span class="line"> name: string</span><br><span class="line"> constructor (name: string) {</span><br><span class="line"> <span class="keyword">this</span>.name = name</span><br><span class="line"> }</span><br><span class="line"> run ():string {</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">this</span>.name</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">children</span> <span class="keyword">extends</span> <span class="title">Person</span> </span>{</span><br><span class="line"> constructor (name: string) {</span><br><span class="line"> <span class="keyword">super</span>(name) <span class="comment">// 初始化父类的构造函数</span></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h6 id="类中的修饰符"><a href="#类中的修饰符" class="headerlink" title="类中的修饰符"></a>类中的修饰符</h6><p>在ts的类中定义属性的时候提供了三种修饰符。<br>public 公有属性,在类,子类,以及类外都可以被访问<br>protected 保护属性,在类,子类,中可以被访问,在类之外不能被访问<br>private 私有属性,在类中可以被访问,在子类,以及类外是不能被访问的</p>
<p>如果属性不加任何修饰符,那么默认是public,表示公有属性。</p>
<h6 id="静态方法和静态属性"><a href="#静态方法和静态属性" class="headerlink" title="静态方法和静态属性"></a>静态方法和静态属性</h6><p>ts中静态方法和属性通过static字符来定义,并且通过类名来调用。</p>
<figure class="highlight typescript"><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></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Person</span> </span>{</span><br><span class="line"> <span class="keyword">static</span> name:<span class="built_in">string</span> = <span class="string">'小明'</span> <span class="comment">// 这是定义的静态属性</span></span><br><span class="line"> <span class="function"><span class="title">constructor</span>(<span class="params">name:<span class="built_in">string</span></span>)</span> {</span><br><span class="line"> <span class="built_in">this</span>.name = name</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// 静态方法</span></span><br><span class="line"> <span class="keyword">static</span> getName ():<span class="built_in">string</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">this</span>.name</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// 实例方法</span></span><br><span class="line"> run ():<span class="built_in">string</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">this</span>.name</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 调用静态方法</span></span><br><span class="line">Person.getName() <span class="comment">// 小明</span></span><br><span class="line"><span class="comment">// 调用实例方法,必须先创建实例,通过实例来调用</span></span><br><span class="line"><span class="keyword">let</span> p = <span class="keyword">new</span> Person(<span class="string">'小刚'</span>)</span><br><span class="line">p.run() <span class="comment">// 小刚</span></span><br></pre></td></tr></table></figure>
<h6 id="继承多态"><a href="#继承多态" class="headerlink" title="继承多态"></a>继承多态</h6><p>父类定义一个方法不去实现,让子类来实现,并且在子类中可以有不同的表现形式。多态也是继承的一种表现。</p>
<figure class="highlight scala"><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></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Person</span> </span>{</span><br><span class="line"> public name:string</span><br><span class="line"> constructor(name:string) {</span><br><span class="line"> <span class="keyword">this</span>.name = name</span><br><span class="line"> }</span><br><span class="line"> eat ():void {</span><br><span class="line"> console.log(`${<span class="keyword">this</span>.name}爱吃肉!`)</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Girl</span> <span class="keyword">extends</span> <span class="title">Person</span> </span>{</span><br><span class="line"> constructor(name:string){</span><br><span class="line"> <span class="keyword">super</span>(name)</span><br><span class="line"> }</span><br><span class="line"> eat ():void {</span><br><span class="line"> <span class="comment">// do something</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Boy</span> <span class="keyword">extends</span> <span class="title">Person</span> </span>{</span><br><span class="line"> constructor(name:string){</span><br><span class="line"> <span class="keyword">super</span>(name)</span><br><span class="line"> }</span><br><span class="line"> eat ():void {</span><br><span class="line"> <span class="comment">// do something</span></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h6 id="抽象类和抽象方法"><a href="#抽象类和抽象方法" class="headerlink" title="抽象类和抽象方法"></a>抽象类和抽象方法</h6><p>ts中的抽象类是提供其他类继承的基类,不能直接实例化。用abstract关键字来实现抽象类和抽象方法。抽象类中的抽象方法不包含具体的实现并且必须在派生类中实现。abstruct字段只能放到抽象类中。要求子类中必须包含抽象类中的方法。</p>
<figure class="highlight scala"><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">abstruct <span class="class"><span class="keyword">class</span> <span class="title">Person</span> </span>{</span><br><span class="line"> abstruct eat():any</span><br><span class="line">}</span><br><span class="line"><span class="comment">// let p = new Person() 错误写法</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Children</span> <span class="keyword">extends</span> <span class="title">Person</span> </span>{</span><br><span class="line"> constructor(name:string) {</span><br><span class="line"> <span class="keyword">super</span>(name)</span><br><span class="line"> }</span><br><span class="line"> eat():any {</span><br><span class="line"> <span class="comment">// do something</span></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<!-- reward -->
</div>
<!-- copyright -->
<footer class="article-footer">
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/typescript/" rel="tag">typescript</a></li></ul>
</footer>
</div>
</article>
<article
id="post-ts/2"
class="article article-type-post"
itemscope
itemprop="blogPost"
data-scroll-reveal
>
<div class="article-inner">
<header class="article-header">
<h2 itemprop="name">
<a class="article-title" href="/ts/2/"
>Typescript--函数方法</a>
</h2>
</header>
<div class="article-meta">
<a href="/ts/2/" class="article-date">
<time datetime="2021-09-26T01:50:46.000Z" itemprop="datePublished">2021-09-26</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/typescript/">typescript</a>
</div>
</div>
<div class="article-entry" itemprop="articleBody">
<h6 id="函数的定义方式"><a href="#函数的定义方式" class="headerlink" title="函数的定义方式"></a>函数的定义方式</h6><p>函数的定义方式有俩种,即function定义方式和匿名函数方式,但是要求指定返回值类型。</p>
<figure class="highlight actionscript"><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="function"><span class="keyword">function</span> <span class="title">fun1</span> <span class="params">()</span>:number </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="number">123</span></span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fun2</span> <span class="params">()</span>:void </span>{</span><br><span class="line"> console.log(<span class="string">'hello world'</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>function方式定义的的函数,并且要求返回值是一个数字。</p>
<figure class="highlight javascript"><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> fun3 = <span class="function"><span class="keyword">function</span> (<span class="params"></span>):<span class="title">string</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="string">'hello world'</span></span><br><span class="line">}</span><br><span class="line"><span class="keyword">let</span> fun4 = <span class="function"><span class="keyword">function</span> (<span class="params"></span>):<span class="title">void</span> </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'hello world'</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h6 id="typescript中的传参方式"><a href="#typescript中的传参方式" class="headerlink" title="typescript中的传参方式"></a>typescript中的传参方式</h6><ul>
<li><p>ts中的参数需要指定参数的类型</p>
<figure class="highlight kotlin"><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">function <span class="function"><span class="title">fun</span> <span class="params">(a:<span class="type">number</span>)</span></span>:number {</span><br><span class="line"> <span class="keyword">return</span> a</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>要求传入的参数a是一个number类型,并且该函数返回一个number类型的返回值。</p>
</li>
<li><p>ts中可以用<code>?</code>来表示某个参数是可选参数,但是<code>必须要放到所有参数的最后面</code>。</p>
<figure class="highlight kotlin"><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">function <span class="function"><span class="title">fun</span> <span class="params">(name:<span class="type">string</span>, age?:<span class="type">number</span>)</span></span>:string {</span><br><span class="line"> <span class="keyword">return</span> `我是${name},我的年龄是${age}`</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>我门可以看到,其中参数age为可选参数,可以不传。</p>
</li>
<li><p>ts中的默认参数</p>
<figure class="highlight kotlin"><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">function <span class="function"><span class="title">fun</span> <span class="params">(name:<span class="type">string</span>, age?:<span class="type">number</span> = <span class="number">30</span>)</span></span>: string {</span><br><span class="line"> <span class="keyword">return</span> `我叫${name},我今年${age}岁`</span><br><span class="line">}</span><br><span class="line">console.log(<span class="function"><span class="title">fun</span><span class="params">(<span class="string">'章三'</span>)</span></span>)</span><br><span class="line"><span class="comment">// 我叫章三,我今年30岁</span></span><br><span class="line">console.log(<span class="function"><span class="title">fun</span><span class="params">(<span class="string">'李四'</span>, <span class="number">90</span>)</span></span>)</span><br><span class="line"><span class="comment">// 我叫李四,问今年90岁</span></span><br></pre></td></tr></table></figure></li>
<li><p>ts中剩余参数,剩余参数可以用拓展符<code>...</code>来表示</p>
<figure class="highlight kotlin"><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">function <span class="function"><span class="title">fun</span> <span class="params">(a:<span class="type">number</span>, b:<span class="type">number</span>, c:<span class="type">number</span>, d:<span class="type">number</span>, e:<span class="type">number</span>)</span></span>:number {</span><br><span class="line"> <span class="keyword">return</span> a + b + c + d + e</span><br><span class="line">}</span><br><span class="line">console.log(<span class="function"><span class="title">fun</span><span class="params">(<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></span>) <span class="comment">// 15</span></span><br></pre></td></tr></table></figure>
<p>这样的参数会很繁琐。那么我们来用…缩减一下参数。</p>
<figure class="highlight actionscript"><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="function"><span class="keyword">function</span> <span class="title">fun</span> <span class="params">(<span class="rest_arg">...res</span>:number[])</span>:number </span>{</span><br><span class="line"> let sum = <span class="number">0</span></span><br><span class="line"> <span class="keyword">for</span> (let i = <span class="number">0</span>;i < res.length - <span class="number">1</span>;i++) {</span><br><span class="line"> sum += res[i]</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> sum</span><br><span class="line">}</span><br><span class="line">console.log(fun(<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 class="comment">// 15</span></span><br></pre></td></tr></table></figure>
<h6 id="函数的重载"><a href="#函数的重载" class="headerlink" title="函数的重载"></a>函数的重载</h6><p>为同一个函数提供多个函数类型定义来进行函数重载。多个函数函数名相同,函数的参数类型,顺序,个数不同。注意函数重载与返回值类型无关。ts的函数重载比较鸡肋,最终函数逻辑的实现还是在一个函数体内去判断它的参数类型,然后做相应的操作。ts重载的作用,感觉只是多了一个参数校验的功能。也就是说在进行函数调用的时候,会对参数进行检查,只有传入的参数类型,顺序,个数与定义的重载函数的参数相同,才能调用成功,否则报错。返回值类型不会进行校验(函数重载与返回值类型无关)。</p>
</li>
</ul>
<figure class="highlight typescript"><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="function"><span class="keyword">function</span> <span class="title">getUser</span> (<span class="params">name:<span class="built_in">string</span></span>):<span class="title">string</span> </span>{}</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getUser</span> (<span class="params">age:<span class="built_in">number</span></span>):<span class="title">number</span> </span>{}</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getUser</span> (<span class="params">str:<span class="built_in">string</span></span>):<span class="title">any</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (<span class="keyword">typeof</span> str === <span class="string">'string'</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="string">`我叫<span class="subst">${str}</span>`</span></span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="string">`我的年龄是<span class="subst">${str}</span>`</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="built_in">console</span>.log(getUser(<span class="string">'张三'</span>)) <span class="comment">// 我叫张三</span></span><br><span class="line"><span class="built_in">console</span>.log(getUser(<span class="number">30</span>)) <span class="comment">// 我的年龄是30</span></span><br><span class="line"><span class="built_in">console</span>.log(getUser(<span class="literal">true</span>)) <span class="comment">// 报错</span></span><br></pre></td></tr></table></figure>
<h6 id="箭头函数"><a href="#箭头函数" class="headerlink" title="箭头函数"></a>箭头函数</h6><p>箭头函数和js中一样,但是需要注意的this的指向问题。</p>
<!-- reward -->
</div>
<!-- copyright -->
<footer class="article-footer">
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/typescript/" rel="tag">typescript</a></li></ul>
</footer>
</div>
</article>
<article
id="post-ts/1"
class="article article-type-post"
itemscope
itemprop="blogPost"
data-scroll-reveal
>
<div class="article-inner">
<header class="article-header">
<h2 itemprop="name">
<a class="article-title" href="/ts/1/"
>Typescript--数据类型</a>
</h2>
</header>
<div class="article-meta">
<a href="/ts/1/" class="article-date">
<time datetime="2021-09-24T06:28:55.000Z" itemprop="datePublished">2021-09-24</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/typescript/">typescript</a>
</div>
</div>
<div class="article-entry" itemprop="articleBody">
<p>Typescript是Javascript的超集,所以大多数的数据类型和Javascript相同。下面是Typescript的数据类型:</p>
<ul>
<li>字符串类型(String)</li>
<li>数字类型(Number)</li>
<li>布尔类型(Boolean)</li>
<li>数组类型(Array)</li>
<li>元组类型(tuple)</li>
<li>枚举类型(enum)</li>
<li>任意类型(any)</li>