-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
3123 lines (2842 loc) · 678 KB
/
search.xml
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
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>Javscript复杂判断</title>
<url>/2019/08/Javscript_complex_judge/</url>
<content><![CDATA[<p>在公司维护前人代码的时候,经常会遇见一堆的if-else语句</p>
<h3 id="if-else"><a href="#if-else" class="headerlink" title="if-else"></a>if-else</h3><figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="title function_">flag</span> = (<span class="params">status</span>)=>{</span><br><span class="line"> <span class="keyword">if</span>(status ==<span class="number">0</span>){</span><br><span class="line"> <span class="comment">//do somethind</span></span><br><span class="line"> }<span class="keyword">else</span> <span class="keyword">if</span>(status==<span class="number">1</span>){</span><br><span class="line"> <span class="comment">//do somethind</span></span><br><span class="line"> }<span class="keyword">else</span> <span class="keyword">if</span>(status ==<span class="number">2</span>){</span><br><span class="line"> <span class="comment">//do something</span></span><br><span class="line"> }<span class="keyword">else</span> <span class="keyword">if</span>(status ==<span class="number">3</span>){</span><br><span class="line"> <span class="comment">//do something</span></span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//...</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<span id="more"></span>
<p>或许还可以用switch-case的写法</p>
<h3 id="switch-case"><a href="#switch-case" class="headerlink" title="switch-case"></a>switch-case</h3><figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="title function_">flag</span> = (<span class="params">status</span>)=>{</span><br><span class="line"> <span class="title function_">swtich</span>(<span class="params">status</span>){</span><br><span class="line"> <span class="keyword">case</span> <span class="number">0</span>:</span><br><span class="line"> <span class="comment">//do something</span></span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> <span class="number">1</span>:</span><br><span class="line"> <span class="keyword">case</span> <span class="number">2</span>:</span><br><span class="line"> <span class="comment">//do something</span></span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> <span class="number">3</span>:</span><br><span class="line"> <span class="comment">//do something</span></span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="attr">default</span>:</span><br><span class="line"> <span class="keyword">return</span> ;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>假如case 1和 case 2的处理情况都一样,可以像上面的写法.</p>
<p>然鹅如果需要判断的条件多的时候,如果继续用if-else的写法,那么工作量会翻倍</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="title function_">flag</span> = (<span class="params">status,type</span>)=>{</span><br><span class="line"> <span class="keyword">if</span>(type==<span class="number">0</span>){</span><br><span class="line"> <span class="keyword">if</span>(status ==<span class="number">0</span>){</span><br><span class="line"> <span class="comment">//do somethind</span></span><br><span class="line"> }<span class="keyword">else</span> <span class="keyword">if</span>(status==<span class="number">1</span>){</span><br><span class="line"> <span class="comment">//do somethind</span></span><br><span class="line"> }<span class="keyword">else</span> <span class="keyword">if</span>(status ==<span class="number">2</span>){</span><br><span class="line"> <span class="comment">//do something</span></span><br><span class="line"> }<span class="keyword">else</span> <span class="keyword">if</span>(status ==<span class="number">3</span>){</span><br><span class="line"> <span class="comment">//do something</span></span><br><span class="line"> }</span><br><span class="line"> }<span class="keyword">else</span> <span class="keyword">if</span>(type==<span class="number">1</span>){</span><br><span class="line"> <span class="keyword">if</span>(status ==<span class="number">0</span>){</span><br><span class="line"> <span class="comment">//do somethind</span></span><br><span class="line"> }<span class="keyword">else</span> <span class="keyword">if</span>(status==<span class="number">1</span>){</span><br><span class="line"> <span class="comment">//do somethind</span></span><br><span class="line"> }<span class="keyword">else</span> <span class="keyword">if</span>(status ==<span class="number">2</span>){</span><br><span class="line"> <span class="comment">//do something</span></span><br><span class="line"> }<span class="keyword">else</span> <span class="keyword">if</span>(status ==<span class="number">3</span>){</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></pre></td></tr></table></figure>
<p>这种写法太麻瓜了吧,简直反人类</p>
<h3 id="Map"><a href="#Map" class="headerlink" title="Map"></a>Map</h3><figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="title function_">actions</span> = (<span class="params"></span>)=>{</span><br><span class="line"> <span class="keyword">function</span> <span class="title function_">A</span>(<span class="params"></span>){</span><br><span class="line"> <span class="keyword">return</span> <span class="string">'A'</span></span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">function</span> <span class="title function_">B</span>(<span class="params"></span>){</span><br><span class="line"> <span class="keyword">return</span> <span class="string">'B'</span></span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Map</span>([</span><br><span class="line"> [<span class="string">'0_0'</span>,A],</span><br><span class="line"> [<span class="string">'0_1'</span>,A],</span><br><span class="line"> [<span class="string">'0_2'</span>,B]</span><br><span class="line"> ])</span><br><span class="line">}</span><br><span class="line"><span class="keyword">const</span> <span class="title function_">flag</span> =(<span class="params">status ,type</span>)=>{</span><br><span class="line"> <span class="keyword">const</span> action = <span class="title function_">actions</span>().<span class="title function_">get</span>(<span class="string">`<span class="subst">${type}</span>_<span class="subst">${status}</span>`</span>);</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">action</span>());</span><br><span class="line">}</span><br><span class="line"><span class="title function_">flag</span>(<span class="number">0</span>,<span class="number">0</span>);<span class="comment">//A</span></span><br></pre></td></tr></table></figure>
<p>直接将逻辑封装起来,然后在另一个函数调用,看起来就干净很多!!!</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="title function_">actions</span> = (<span class="params"></span>)=>{</span><br><span class="line"> <span class="keyword">function</span> <span class="title function_">A</span>(<span class="params"></span>){</span><br><span class="line"> <span class="keyword">return</span> <span class="string">'A'</span></span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">function</span> <span class="title function_">B</span>(<span class="params"></span>){</span><br><span class="line"> <span class="keyword">return</span> <span class="string">'B'</span></span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Map</span>([</span><br><span class="line"> [<span class="regexp">/^0_[0-3]/</span>,A],</span><br><span class="line"> [<span class="regexp">/1_[0-2]/</span>,A],</span><br><span class="line"> [<span class="regexp">/1_1/</span>,B]</span><br><span class="line"> ])</span><br><span class="line">}</span><br><span class="line"><span class="keyword">const</span> <span class="title function_">flag</span> =(<span class="params">status ,type</span>)=>{</span><br><span class="line"> <span class="keyword">const</span> action = [...<span class="title function_">actions</span>()].<span class="title function_">filter</span>(<span class="function">(<span class="params">[key,value]</span>)=></span>{</span><br><span class="line"> <span class="keyword">return</span> key.<span class="title function_">test</span>(<span class="string">`<span class="subst">${type}</span>_<span class="subst">${status}</span>`</span>)</span><br><span class="line"> })</span><br><span class="line"> action.<span class="title function_">forEach</span>(<span class="function">(<span class="params">[_,value]</span>)=></span>{</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"value.apply(this):"</span>, value.<span class="title function_">apply</span>(<span class="variable language_">this</span>));<span class="comment">//A</span></span><br><span class="line"> value.<span class="title function_">call</span>(<span class="variable language_">this</span>);</span><br><span class="line"> })</span><br><span class="line">}</span><br><span class="line"><span class="title function_">flag</span>(<span class="number">1</span>,<span class="number">1</span>);</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category>JavaScript</category>
</categories>
<tags>
<tag>JavaScript</tag>
</tags>
</entry>
<entry>
<title>ObjectKeys</title>
<url>/2020/07/ObjectKeys/</url>
<content><![CDATA[<h3 id="Object-keys"><a href="#Object-keys" class="headerlink" title="Object.keys"></a>Object.keys</h3><p>上一个Object.keys()在js中的用法</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">const obj = {</span><br><span class="line"> name:<span class="string">'John'</span>,</span><br><span class="line"> age:12,</span><br><span class="line"> <span class="built_in">id</span>:1</span><br><span class="line">}</span><br><span class="line">Object.keys(obj).forEach(key=>{</span><br><span class="line"> //output <span class="string">'John'</span>,12,1</span><br><span class="line"> console.log(obj[key])</span><br><span class="line">})</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<span id="more"></span>
<p>试试ts版的</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">type</span> Person ={</span><br><span class="line"> name:string,</span><br><span class="line"> <span class="built_in">id</span>:number,</span><br><span class="line"> age:number</span><br><span class="line">}</span><br><span class="line"><span class="built_in">declare</span> const me:Person;</span><br><span class="line"></span><br><span class="line">Object.keys(me).forEach(key=>{</span><br><span class="line"> // 在ts里面这个时候编辑器会提示我们错误</span><br><span class="line"> console.log(me[key])</span><br><span class="line">})</span><br></pre></td></tr></table></figure>
<p><code>Element implicitly has an ‘any’ type because expression of type ‘string’ can’t be used to index type ‘Person’. No index signature with a parameter of type ‘string’ was found on type ‘Person’</code></p>
<p>来看一下Object.keys的类型声明</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">interface ObjectConstructor {</span><br><span class="line"> keys(o: object): string[];</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>方法接收任意类型的object作为输入并且返回string类型的数组作为输出。</p>
<p>来回到之前的问题,为什么会报错?</p>
<p>在Person中,具体的key值分别是name|age|id,但是它们的索引签名并不是string类型,所以当在keys方法中返回的string数组的每一个key都是string类型时,跟Person中的每个key的索引签名并不匹配,所以是不能通过string类型的key访问到me中的数据,<br>如果Person这样定义:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">interface Person{</span><br><span class="line"> [key:string]:string</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>如果这样写,那么之前的forEach语句就可以正常执行不报错,而且循环中的每个item的类型推导是string类型<br><img src="/images/ObjectKeys/code2.png" alt="code"><br></br><br><strong>注意</strong>:那么这个就很有可能是报错的原因。更具体的类型在已经建立索引的库中引发的问题,或者是因为类型过于复杂导致类型不能正确推导</p>
<p>那么遇到这个问题该怎么解决?</p>
<p>最菜的方法就是把tsconfig.json里面的noImplicitAny选项给关了,那回家用JS吧</p>
<h3 id="Type-casting-类型转换"><a href="#Type-casting-类型转换" class="headerlink" title="Type-casting(类型转换)"></a>Type-casting(类型转换)</h3><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">Object.keys(me).forEach(key=>{</span><br><span class="line"> (me as any)[key]</span><br><span class="line">})</span><br></pre></td></tr></table></figure>
<p>这样写法虽然可以,但是不推荐</p>
<p>第二种可以把loop里面的key的类型设置为Person的key,这样就能让ts理解我们在做什么</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">Object.keys(me).forEach(key=>{</span><br><span class="line"> me[key as keyof Person]</span><br><span class="line">})</span><br></pre></td></tr></table></figure>
<p>这种比之前的要好点,还可以试试其他的,比如让ts自己能够完成这项工作</p>
<h3 id="Extending-Object-Constructor-继承接口ObjectConstructor"><a href="#Extending-Object-Constructor-继承接口ObjectConstructor" class="headerlink" title="Extending Object Constructor(继承接口ObjectConstructor)"></a>Extending Object Constructor(继承接口ObjectConstructor)</h3><p>在ts里面有一个声明合并的特性</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">interface Person {</span><br><span class="line"> name: string;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">interface Person {</span><br><span class="line"> age: number;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">interface Person {</span><br><span class="line"> height: number;</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>上面的code对Person接口进行了三次的声明,等同于下面这个code</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">interface Person{</span><br><span class="line"> name: string;</span><br><span class="line"> age: number;</span><br><span class="line"> height: number;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>所以同理我们可以写ObjectConstructor的接口,写key方法的重载,这次我们需要对object的value值进行细分,并且决定应该返回什么类型</p>
<p>三种行为</p>
<ol>
<li>如果我们传递进来一个number类型,那么应该返回空数组</li>
<li>如果我们传递进来一个字符串或者一个数组,那么应该返回string[],也就是字符串数组</li>
<li>如果我们传递进来一个any类型,那么直接返回它的key</li>
</ol>
<p>看一下怎么构造这个类型</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">type</span> ObjectKeys<T> = T extends object?(keyof T)[]:</span><br><span class="line">T extends number?[]:</span><br><span class="line">T extends string|Array<any> ?string[]:</span><br><span class="line">never</span><br></pre></td></tr></table></figure>
<p>以never结尾来捕捉异常错误</p>
<p>然后写ObjectConstructor</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">interface ObjectConstructor{</span><br><span class="line"> keys(o:T):ObjectKeys<T></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>把这两段代码放在声明文件中,比如lib.d.ts</p>
<p>然后这个时候执行文章开头的那个loop</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">Object.keys(me).forEach((key) => {</span><br><span class="line"> //这个时候就可以正常输出了</span><br><span class="line"> console.log(me[key])</span><br><span class="line">})</span><br></pre></td></tr></table></figure>
</br>
<div style="overflow:hidden">
<img src="/images/ObjectKeys/code.png" style="float:left;"
title="Codes" alt="picture"/>
</div>
]]></content>
<categories>
<category>TypeScript</category>
</categories>
<tags>
<tag>TypeScript</tag>
</tags>
</entry>
<entry>
<title>Traversing</title>
<url>/2019/09/Traversing/</url>
<content><![CDATA[<h3 id="深度优先遍历"><a href="#深度优先遍历" class="headerlink" title="深度优先遍历"></a>深度优先遍历</h3><p>从某个顶点v出发,首先访问该顶点然后依次从它的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和v有路径相通的顶点都被访问到</p>
<span id="more"></span>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 递归</span></span><br><span class="line"><span class="built_in">let</span> deepTraversal1 = (node, nodeList = []) => {</span><br><span class="line"> <span class="keyword">if</span> (node !== null) {</span><br><span class="line"> nodeList.push(node)</span><br><span class="line"> <span class="built_in">let</span> children = node.children</span><br><span class="line"> <span class="keyword">if</span>(children!==null||children.length!==0){</span><br><span class="line"> <span class="keyword">for</span> (<span class="built_in">let</span> i = 0; i < children.length; i++) {</span><br><span class="line"> deepTraversal1(children[i], nodeList)</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">return</span> nodeList</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 递归</span></span><br><span class="line"><span class="built_in">let</span> deepTraversal2= (node)=>{</span><br><span class="line"> <span class="built_in">let</span> nodes=[];</span><br><span class="line"> <span class="keyword">if</span>(node!== null){</span><br><span class="line"> nodes.push(node);</span><br><span class="line"> <span class="built_in">let</span> children = node.children;</span><br><span class="line"> <span class="keyword">if</span>(children!==null||children.length!==0){</span><br><span class="line"> <span class="keyword">for</span>(<span class="built_in">let</span> i=0;i<children.length;i++){</span><br><span class="line"> nodes= nodes.concat(deepTraversal2(children[i]));</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">return</span> nodes;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 非递归</span></span><br><span class="line"><span class="built_in">let</span> deepTraversal2=(node)=>{</span><br><span class="line"> <span class="built_in">let</span> stack =[];</span><br><span class="line"> <span class="built_in">let</span> nodes=[];</span><br><span class="line"> <span class="keyword">if</span>(node){</span><br><span class="line"> /*如果node节点存在*/</span><br><span class="line"> stack.push(node);</span><br><span class="line"> <span class="keyword">while</span>(stack.length){</span><br><span class="line"> <span class="built_in">let</span> item= stack.pop();//取出队尾元素</span><br><span class="line"> <span class="built_in">let</span> children = item.children;//获取元素子节点</span><br><span class="line"> nodes.push(children);//推进子节点,结构与父节点一样</span><br><span class="line"> <span class="keyword">if</span>(children!==null||children.length!==0){</span><br><span class="line"> <span class="keyword">for</span>(<span class="built_in">let</span> i =0;i<children.length;i++){</span><br><span class="line"> stack.push(children[i]);</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="built_in">return</span> nodes;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="广度优先遍历"><a href="#广度优先遍历" class="headerlink" title="广度优先遍历"></a>广度优先遍历</h3><p>从某顶点v出发,在访问了v之后依次访问v的各个未曾访问过的邻接点,然后分别从这些邻接点出发依次访问它们的邻接点,并使得“先被访问的顶点的邻接点先于后被访问的顶点的邻接点被访问,直至图中所有已被访问的顶点的邻接点都被访问到</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">let</span> widthTraversal2=(node)=>{</span><br><span class="line"> <span class="built_in">let</span> nodes=[];</span><br><span class="line"> <span class="built_in">let</span> stack=[];</span><br><span class="line"> <span class="keyword">if</span>(node){</span><br><span class="line"> stack.push(node);</span><br><span class="line"> <span class="keyword">while</span>(stack.length){</span><br><span class="line"> <span class="built_in">let</span> item = stack.shift();</span><br><span class="line"> <span class="built_in">let</span> children = item.children;</span><br><span class="line"> nodes.push(node);</span><br><span class="line"> <span class="keyword">if</span>(children!==null||children.length!==0){</span><br><span class="line"> <span class="keyword">for</span>(<span class="built_in">let</span> i =0;i<children.length;i++){</span><br><span class="line"> stack.push(children[i]);</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><span class="line"> <span class="built_in">return</span> nodes;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<tags>
<tag>JavaScript</tag>
</tags>
</entry>
<entry>
<title>axios</title>
<url>/2020/09/axios/</url>
<content><![CDATA[<h3 id="为什么-axios-既可以用-axios-这样请求-,也可以-axios-get-这样请求?"><a href="#为什么-axios-既可以用-axios-这样请求-,也可以-axios-get-这样请求?" class="headerlink" title="为什么 axios 既可以用 axios({})这样请求 ,也可以 axios.get()这样请求?"></a>为什么 axios 既可以用 axios({})这样请求 ,也可以 axios.get()这样请求?</h3><p>在使<code>axios.create</code>的时候,调用了这个方法</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">/**</span><br><span class="line"> * Create an instance of Axios</span><br><span class="line"> *</span><br><span class="line"> * @param {Object} defaultConfig The default config <span class="keyword">for</span> the instance</span><br><span class="line"> * @<span class="built_in">return</span> {Axios} A new instance of Axios</span><br><span class="line"> */</span><br><span class="line"><span class="keyword">function</span> createInstance(defaultConfig) {</span><br><span class="line"> var context = new Axios(defaultConfig);//生成配置 和拦截器</span><br><span class="line"> <span class="comment"># 在这里,instance 是一个 wrapped 函数,将context作为参数传递给request,所以调用axios({})就是在调用request({})</span></span><br><span class="line"> var instance = <span class="built_in">bind</span>(Axios.prototype.request, context);</span><br><span class="line"></span><br><span class="line"> <span class="comment">#Copy axios.prototype to instance</span></span><br><span class="line"> <span class="comment"># 这个是把Axios原型链的东西挂载到instance上去</span></span><br><span class="line"> <span class="comment"># 因为instance 是个一个functoin,所以在直接赋值的时候不能直接看到</span></span><br><span class="line"> <span class="comment"># 能在instance 的prototype上可以看到</span></span><br><span class="line"> <span class="comment"># 所以在调用类似axios.get()这类的方法是能正常运行</span></span><br><span class="line"> utils.extend(instance, Axios.prototype, context);</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Copy context to instance</span></span><br><span class="line"> utils.extend(instance, context);</span><br><span class="line"> <span class="comment"># console.log(instance)</span></span><br><span class="line"> <span class="built_in">return</span> instance;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>从图中可以看到,方法之类的确实挂载到了原型链上<br><img src="/images/axios/prototype.png" alt="prototype"></p>
<h3 id="cancalToken-怎么取消请求的"><a href="#cancalToken-怎么取消请求的" class="headerlink" title="cancalToken 怎么取消请求的"></a>cancalToken 怎么取消请求的</h3><p>那么其实什么时候需要取消请求,举一个很常见的例子,取消重复请求,就是当前已经发出请求的情况下,后续同样的请求如果发送就会被取消(如果是表单的提交也可以使用 dom 的 disabld 禁止点击 2333)<br>举个栗子:<br>在 axios 上是挂载了 Cancel 相应的东西</p>
<ul>
<li>axios.Cancel = require(‘./cancel/Cancel’);</li>
<li>axios.CancelToken = require(‘./cancel/CancelToken’);</li>
<li>axios.isCancel = require(‘./cancel/isCancel’);</li>
</ul>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">var data = document.getElementById(<span class="string">"data"</span>).value;</span><br><span class="line"> const CancelToken = axios.CancelToken;</span><br><span class="line"> axios</span><br><span class="line"> .post(</span><br><span class="line"> <span class="string">"/post/server"</span>,</span><br><span class="line"> {</span><br><span class="line"> data,</span><br><span class="line"> },</span><br><span class="line"> {</span><br><span class="line"> cancelToken: new CancelToken((c) => {</span><br><span class="line"> cancel = c;</span><br><span class="line"> console.log(c)</span><br><span class="line"> }),</span><br><span class="line"> }</span><br><span class="line"> )</span><br><span class="line"> .then(function (res) {</span><br><span class="line"> output.className = "container";</span><br><span class="line"> output.innerHTML = res.data;</span><br><span class="line"> })</span><br><span class="line"> .catch(function (err) {</span><br><span class="line"> output.className = "container text-danger";</span><br><span class="line"> output.innerHTML = err.message;</span><br><span class="line"> });</span><br><span class="line"> cancel('sdfsd');</span><br></pre></td></tr></table></figure>
<p>然后这里 axios.post 实际上就是调用了<code>request</code>方法,方法的返回值是一个 promise,最后一个执行的 promise 是一个叫<code>dispatchRequest</code>的函数,函数位置在 core/dispatchRequest.js 文件下,因为返回的是一个 promise ,状态是 pendding,加入到微任务队列,然后执行主线程的<code>cancel</code>方法。cancel 方法是在初始化 cancelToken 的时候给 cancel 赋值了。</p>
<p><code>cancelToken:</code></p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">function</span> CancelToken(executor) {</span><br><span class="line"> <span class="keyword">if</span> (typeof executor !== <span class="string">'function'</span>) {</span><br><span class="line"> throw new TypeError(<span class="string">'executor must be a function.'</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> var resolvePromise;</span><br><span class="line"> <span class="comment"># 这里把resolve钩子赋值给resolvePromise 为了让cancel函数能够改变promise的状态</span></span><br><span class="line"> this.promise = new Promise(<span class="keyword">function</span> promiseExecutor(resolve) {</span><br><span class="line"> resolvePromise = resolve;</span><br><span class="line"> });</span><br><span class="line"></span><br><span class="line"> var token = this;</span><br><span class="line"> executor(<span class="keyword">function</span> cancel(message) {</span><br><span class="line"> <span class="keyword">if</span> (token.reason) {</span><br><span class="line"> <span class="comment"># Cancellation has already been requested</span></span><br><span class="line"> <span class="built_in">return</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> token.reason = new Cancel(message);</span><br><span class="line"> <span class="comment"># 这里改变promise状态位fulfilled</span></span><br><span class="line"> resolvePromise(token.reason);</span><br><span class="line"> });</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>主线程任务执行完成的时候开始进入下一轮任务执行,没有宏任务需要执行,直接执行微任务,先执行刚刚 request 返回的 promise,其实是开始执行了<code>dispatchRequest</code></p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"></span><br><span class="line">module.exports = <span class="keyword">function</span> dispatchRequest(config) {</span><br><span class="line"> throwIfCancellationRequested(config);</span><br><span class="line"> <span class="comment"># 省略其他代码</span></span><br><span class="line">}</span><br><span class="line">/**</span><br><span class="line"> * Throws a `Cancel` <span class="keyword">if</span> cancellation has been requested.</span><br><span class="line"> */</span><br><span class="line"><span class="keyword">function</span> throwIfCancellationRequested(config) {</span><br><span class="line"> <span class="keyword">if</span> (config.cancelToken) {</span><br><span class="line"> <span class="comment"># 这个方法挂载在canceltoken原型链傻姑娘</span></span><br><span class="line"> config.cancelToken.throwIfRequested();</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line">CancelToken.prototype.throwIfRequested = <span class="keyword">function</span> <span class="function"><span class="title">throwIfRequested</span></span>() {</span><br><span class="line"> <span class="keyword">if</span> (this.reason) {</span><br><span class="line"> <span class="comment"># 这里抛出错误,然后在主程序代码中的catch捕获,然后程序返回,不进行后续创建xhr对象的过程</span></span><br><span class="line"> throw this.reason;</span><br><span class="line"> }</span><br><span class="line">};</span><br></pre></td></tr></table></figure>
<p>在xhr文件中看到有一段代码,长这样:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="keyword">if</span> (config.cancelToken) {</span><br><span class="line"> // Handle cancellation</span><br><span class="line"> config.cancelToken.promise.then(<span class="keyword">function</span> onCanceled(cancel) {</span><br><span class="line"> <span class="keyword">if</span> (!request) {</span><br><span class="line"> <span class="built_in">return</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> request.abort();</span><br><span class="line"> reject(cancel);</span><br><span class="line"> // Clean up request</span><br><span class="line"> request = null;</span><br><span class="line"> });</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>
<p>那么上文中的resolvePromise改变后的promise就是在这里调用,那什么情况会到这里来执行请求,假如有A,B两个请求,A请求响应时间过长,然后等到B执行回调都回来的时候,直接把A请求给取(gan)消(diao)了</p>
]]></content>
</entry>
<entry>
<title>自适应布局</title>
<url>/2019/08/adaptive/</url>
<content><![CDATA[<h2 id="grid"><a href="#grid" class="headerlink" title="grid"></a>grid</h2><p>css</p>
<figure class="highlight css"><table><tr><td class="code"><pre><span class="line"><span class="selector-class">.main</span>{</span><br><span class="line"> <span class="attribute">display</span>: grid;</span><br><span class="line"> <span class="attribute">grid-template-columns</span>:<span class="built_in">repeat</span>(auto-fill,<span class="number">27rem</span>);</span><br><span class="line"> <span class="attribute">grid-gap</span>:<span class="number">3rem</span> <span class="number">1.5rem</span>;</span><br><span class="line">} </span><br><span class="line"><span class="selector-class">.main</span> > <span class="selector-class">.item</span>{</span><br><span class="line"> <span class="attribute">background-color</span>: blue;</span><br><span class="line"> <span class="attribute">width</span>:<span class="number">100%</span>;</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">100px</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>html</p>
<span id="more"></span>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"main"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"><span class="tag"></<span class="name">div</span>></span></span><br></pre></td></tr></table></figure>
<p>以上代码效果能让每一行都尽量铺满</p>
<html>
<head>
<style>
.main{
display: grid;
grid-template-columns:repeat(auto-fill,27rem);
grid-gap:3rem 1.5rem;
}
.main > .item{
background:linear-gradient(45deg,black,transparent);
width:100%;
height: 100px;
}
</style>
</head>
<body>
<div class="main">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</body>
</html>
<h2 id="table"><a href="#table" class="headerlink" title="table"></a>table</h2><p>css</p>
<figure class="highlight css"><table><tr><td class="code"><pre><span class="line"><span class="selector-class">.container</span>{</span><br><span class="line"> <span class="attribute">display</span>: table;</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">100%</span>;</span><br><span class="line"> <span class="attribute">border-spacing</span>: <span class="number">30px</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"><span class="selector-class">.container</span> ><span class="selector-tag">div</span>{</span><br><span class="line"> <span class="attribute">display</span>: table-cell;</span><br><span class="line"> <span class="attribute">background-color</span>: <span class="number">#00ffff</span>;</span><br><span class="line"> <span class="attribute">border</span>: <span class="number">1px</span> solid black;</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">200px</span>;</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">25vw</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>html</p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"container"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item"</span>></span>item<span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item"</span>></span>item<span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item"</span>></span>item<span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item"</span>></span>item<span class="tag"></<span class="name">div</span>></span></span><br><span class="line"><span class="tag"></<span class="name">div</span>></span></span><br></pre></td></tr></table></figure>
<html>
<head>
<style>
.container{
display: table;
width: 100%;
border-spacing: 30px 0;
}
.container >.item{
display: table-cell;
background-color: #00ffff;
border: 1px solid black;
height: 200px;
width: 25vw;
}
</style>
</head>
<body>
<div class="container">
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
</div>
</body>
</html>
<h2 id="flex"><a href="#flex" class="headerlink" title="flex"></a>flex</h2><p>css</p>
<figure class="highlight css"><table><tr><td class="code"><pre><span class="line"><span class="selector-class">.main</span>{</span><br><span class="line"> <span class="attribute">display</span>: flex;</span><br><span class="line"> <span class="attribute">flex-wrap</span>: wrap;</span><br><span class="line"> <span class="attribute">justify-content</span>: flex-start; </span><br><span class="line">}</span><br><span class="line"><span class="selector-class">.main</span> > <span class="selector-class">.item</span>{</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">300px</span>;</span><br><span class="line"> <span class="attribute">background</span>:<span class="built_in">linear-gradient</span>(<span class="number">45deg</span>,black,transparent);</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">100px</span>;</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>html</p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"main"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"item"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"><span class="tag"></<span class="name">div</span>></span></span><br></pre></td></tr></table></figure>
<html>
<head>
<style>
.main{
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
}
.main > .item{
width: 300px;
background:linear-gradient(45deg,black,transparent);
height: 100px;
}
</style>
</head>
<body>
<div class="main">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</body>
</html>
<p>以下<a href="https://juejin.im/post/5b90e07ce51d450e6a2dd140">原文</a></p>
<h2 id="媒体查询"><a href="#媒体查询" class="headerlink" title="媒体查询"></a>媒体查询</h2><figure class="highlight css"><table><tr><td class="code"><pre><span class="line"><span class="keyword">@media</span> screen <span class="keyword">and</span> (<span class="attribute">min-width</span>:<span class="number">240px</span>) {</span><br><span class="line"> <span class="selector-tag">html</span>, <span class="selector-tag">body</span>, <span class="selector-tag">button</span>, <span class="selector-tag">input</span>, select, <span class="selector-tag">textarea</span> {</span><br><span class="line"> <span class="attribute">font-size</span>:<span class="number">9px</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">@media</span> screen <span class="keyword">and</span> (<span class="attribute">min-width</span>:<span class="number">320px</span>) {</span><br><span class="line"> <span class="selector-tag">html</span>, <span class="selector-tag">body</span>, <span class="selector-tag">button</span>, <span class="selector-tag">input</span>, select, <span class="selector-tag">textarea</span> {</span><br><span class="line"> <span class="attribute">font-size</span>:<span class="number">12px</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line">// 红米Note2</span><br><span class="line"><span class="keyword">@media</span> screen <span class="keyword">and</span> (<span class="attribute">min-width</span>:<span class="number">360px</span>) {</span><br><span class="line"> <span class="selector-tag">html</span>, <span class="selector-tag">body</span>, <span class="selector-tag">button</span>, <span class="selector-tag">input</span>, select, <span class="selector-tag">textarea</span> {</span><br><span class="line"> <span class="attribute">font-size</span>:<span class="number">13.5px</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">@media</span> screen <span class="keyword">and</span> (<span class="attribute">min-width</span>:<span class="number">375px</span>) {</span><br><span class="line"> <span class="selector-tag">html</span>, <span class="selector-tag">body</span>, <span class="selector-tag">button</span>, <span class="selector-tag">input</span>, select, <span class="selector-tag">textarea</span> {</span><br><span class="line"> <span class="attribute">font-size</span>:<span class="number">14.0625px</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h2 id="JS设置html的font-size大小"><a href="#JS设置html的font-size大小" class="headerlink" title="JS设置html的font-size大小"></a>JS设置html的font-size大小</h2><figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="variable language_">document</span>.<span class="property">documentElement</span>.<span class="property">style</span>.<span class="property">fontSize</span> = <span class="variable language_">document</span>.<span class="property">documentElement</span>.<span class="property">clientWidth</span> / <span class="number">750</span> + <span class="string">'px'</span>;</span><br></pre></td></tr></table></figure>
<h2 id="vw"><a href="#vw" class="headerlink" title="vw"></a>vw</h2><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">//使用vw设置,vw也是一个相对单位,100vw等于屏幕宽度</span><br><span class="line">html{</span><br><span class="line"> font-size: 10vw;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>JavaScript</category>
</categories>
<tags>
<tag>JavaScript</tag>
<tag>css</tag>
</tags>
</entry>
<entry>
<title>部署hexo踩坑记录</title>
<url>/2020/11/bugsForNode/</url>
<content><![CDATA[<p>在执行下面这句代码的时候</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">hexo clean && hexo g -d</span><br></pre></td></tr></table></figure>
<p>报错信息</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">Something<span class="string">'s wrong. Maybe you can find the solution here: https://hexo.io/docs/troubleshooting.html</span></span><br><span class="line"><span class="string">TypeError [ERR_INVALID_ARG_TYPE]: The "mode" argument must be integer. Received an instance of Object</span></span><br><span class="line"><span class="string"> at copyFile (fs.js:1924:10)</span></span><br><span class="line"><span class="string"> at tryCatcher (/Users/zjs/Desktop/blog/node_modules/bluebird/js/release/util.js:16:23)</span></span><br><span class="line"><span class="string"> at ret (eval at makeNodePromisifiedEval (/Users/zjs/.nvm/versions/node/v14.10.0/lib/node_modules/hexo-cli/node_modules/bluebird/js/release/promisify.js:184:12), <anonymous>:13:39)</span></span><br></pre></td></tr></table></figure>
<p>解决方案<br> NodeJs 版本从 14 回到 12 就🉑️!</p>
]]></content>
</entry>
<entry>
<title>Chrome调试工具的那点事</title>
<url>/2019/09/chorme-panel/</url>
<content><![CDATA[<h3 id=""><a href="#" class="headerlink" title="$_"></a>$_</h3><p>调试的过程中,你经常会通过打印查看一些变量的值,但如果你想看一下上次执行的结果呢?再输一遍表达式吗</p>
<span id="more"></span>
<p>这时候 $_ 就派上了用场,$_ 是对上次执行的结果的 引用 :<br><img src="/images/chrome_panel/demo1.png" alt="demo"></p>
<h3 id="-1"><a href="#-1" class="headerlink" title="$$"></a>$$</h3><p>用Jquery库的同学都知道$是Jquery的缩写,在Chrome的调试面板中,如果你没有定义$这个变量,它在 console 中就是对这一大串函数 document.querySelector 的别名。$$则是==Array.from(document.querySelector),返回的是一个数组,而不是一个nodeList,可以帮我们省却很多时间</p>
<h3 id="0"><a href="#0" class="headerlink" title="$0"></a>$0</h3><p>$0保存的是当前选中节点的引用,$1是上个节点,$2是上上个,到4截止。</p>
<h3 id="截屏"><a href="#截屏" class="headerlink" title="截屏"></a>截屏</h3><p>截屏的时候你们肯定用的是qq或者tim的ctrl+alt+a或者微信的alt+a,其实浏览器本身也支持截屏<br><img src="/images/chrome_panel/demo2.gif" alt="图片"></p>
<h3 id="切换主题"><a href="#切换主题" class="headerlink" title="切换主题"></a>切换主题</h3><p><img src="/images/chrome_panel/demo3.gif" alt="图片"></p>
<p>PS:Ummm,还有其他命令我就不玩啦。忘了说,ctrl+shift+p打开那个command面板</p>
<h3 id="打断点"><a href="#打断点" class="headerlink" title="打断点"></a>打断点</h3><p>大部分人打断点都是这样打滴<br><img src="/images/chrome_panel/demo4.png" alt="图片"><br>然鹅如果你只想看第50次循环中的数据是什么样的,难道需要前面的49次都断电吗?烦不烦?所以你可以酱紫:<br><img src="/images/chrome_panel/demo5.gif" alt="图片"></p>
<p>设置条件断点后,可以指定在某个条件的时候断点,并且在右侧可以移除所有断点而不用手动一个个点取消。</p>
]]></content>
<tags>
<tag>Chrome</tag>
</tags>
</entry>
<entry>
<title>cdn</title>
<url>/2022/01/cdn/</url>
<content><![CDATA[<p>CDN(Content Delivery Network)是指内容分发网络,也称为内容传送网络,</p>
<h3 id="组成"><a href="#组成" class="headerlink" title="组成"></a>组成</h3><p>CDN由以下几个关键技术组成:</p>
<ul>
<li>内容缓存设备</li>
<li>内容交换机</li>
<li>内容路由器</li>
<li>CDN内容管理系统<span id="more"></span>
<code>内容缓存设备</code>:是CDN网络节点,位于用户接入点,是面向最终用户的内容提供设备,可以缓存静态web内容和流媒体内容,实现内容的边缘传播和存储,以便用户可以就近访问</li>
</ul>
<p><code>内容交换机</code>:处于用户接入集中点,可以均衡单点多个内容缓存设备的负载,并对内容进行缓存负载平衡及访问控制 </p>
<p><code>内容路由器</code>:负责将用户的请求调度到适当的设备上。</p>
<p><code>内容管理系统</code>:负责整个CDN的管理,作用是进行内容管理,如内容的注入和发布、内容的分发、内容的审核、内容的服务等</p>
<h3 id="功能"><a href="#功能" class="headerlink" title="功能"></a>功能</h3><p>cdn具有一下几个功能:</p>
<ul>
<li>节省骨干网宽带,减少带宽需求量</li>
<li>提供服务端加速,解决由于用户访问量大造成的服务器过载问题</li>
<li>服务器商能通过cache技术在本地缓存用户访问过的web页面和对象,实现相同对象的访问无须占用主干的出口带宽,并提高首屏加载速度</li>
<li>克服网站分布不均问题,降低网站自身建设和维护成本</li>
<li>降低‘通信风暴’的影响,提高网络访问的稳定性</li>
</ul>
<h3 id="CDN原理"><a href="#CDN原理" class="headerlink" title="CDN原理"></a>CDN原理</h3><p>基本原理是广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的地区或者网络中,在用户访问网站时,利用全局负载技术将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应用户的请求。</p>
<h3 id="流程"><a href="#流程" class="headerlink" title="流程"></a>流程</h3><p>源服务器push内容到CDN,在用户每次请求页面的时候,相对应的边缘服务器就返回内容给用户,这样用户就不用每次都向源服务器请求数据;</p>
<p>如果源服务器没有把网页内容提前给CDN进行备份,那么当用户请求网页的时候,CDN就得向源服务器索取网页内容了,也叫做pull;</p>
<h3 id="问题:"><a href="#问题:" class="headerlink" title="问题:"></a>问题:</h3><ul>
<li>服务器过载怎么办?<ul>
<li>通过负载均衡来解决,把用户的请求转移到没有超载的缓存服务器上去</li>
</ul>
</li>
<li>负载均衡怎么实现?<ul>
<li>采用任播的通信方式,服务器对外都有同样的一个ip地址,在收到请求后,由离用户最近的服务器来作出响应</li>
</ul>
</li>
<li>回源怎么实现?<ul>
<li>当cdn缓存服务器中没有符合用户要求的资源的时候,缓存服务器会请求上一级的缓存服务器,当所有的缓存服务器中都没有符合要求的资源的时候,就会到源服务器中去寻找对应的资源。</li>
</ul>
</li>
<li>什么时候触发回源?<ul>
<li>没有资源,资源过期或者缓存的资源不是缓存资源等情况</li>
</ul>
</li>
</ul>
]]></content>
<tags>
<tag>cdn</tag>
</tags>
</entry>
<entry>
<title>思考如何使a==1&&a==2&&a==3为true</title>
<url>/2019/11/closure/</url>
<content><![CDATA[<p>涉及运算符比较过程,运算符在比较两个值是否相等的时候做了什么,第二个涉及闭包JS比较两个数值是否相等可以用== 和=== ,<span id="more"></span>其中 == 会有隐式类型转换的操作,===则不会,在两个数比较时,先调用valueOf,如果返回的不是原始类型,继续调用toString,如果不是原始类型,抛出异常</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">const b = {</span><br><span class="line"> value :1,</span><br><span class="line"> toString(){</span><br><span class="line"> return {</span><br><span class="line"> name:1</span><br><span class="line"> }</span><br><span class="line"> },</span><br><span class="line"> valueOf(){</span><br><span class="line"> return {</span><br><span class="line"> name:1</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line">console.log(`toString : ${b==3}`)</span><br><span class="line">console.log(`valueOf : ${b==4}`)</span><br><span class="line">//抛出异常TypeError: Cannot convert object to primitive value</span><br></pre></td></tr></table></figure>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">const b = {</span><br><span class="line"> value :1,</span><br><span class="line"> toString(){</span><br><span class="line"> return 3</span><br><span class="line"> },</span><br><span class="line"> valueOf(){</span><br><span class="line"> return {</span><br><span class="line"> name:1</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line">console.log(`toString : ${b==3}`)</span><br><span class="line">console.log(`valueOf : ${b==4}`)</span><br><span class="line">//toString:true,valueOf:false</span><br></pre></td></tr></table></figure>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">const b = {</span><br><span class="line"> value :1,</span><br><span class="line"> toString(){</span><br><span class="line"> return 3</span><br><span class="line"> },</span><br><span class="line"> valueOf(){</span><br><span class="line"> return 4</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">console.log(`toString : ${b==3}`)//false</span><br><span class="line">console.log(`valueOf : ${b==4}`)//true</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>OK,接下来说正题, a==1的时候先调用了a.valueOf(),然后根据valueOf的返回值与1进行比较,但是在a==1为真的情况下如何确保a==2以及a==3也同时成立呢?还记得里两个数比较时做的操作吗?先调用valueOf,然后是toString,所以只要覆写其中一个方法</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">const a ={</span><br><span class="line"> value:1,</span><br><span class="line"> toString(){</span><br><span class="line"> return this.value++;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line">//由于这时的a是一个Object,所以调用valueOf的时候返回的并不是原始类型,因此我们覆写toString方法即可</span><br><span class="line">console.log(a==1&&a==2&&a==3)//true</span><br></pre></td></tr></table></figure>]]></content>
<tags>
<tag>JavaScript</tag>
</tags>
</entry>
<entry>
<title>随笔</title>
<url>/2020/10/conclusion/</url>
<content><![CDATA[<h3 id="笔记一"><a href="#笔记一" class="headerlink" title="笔记一"></a>笔记一</h3><p>在vue项目中使用ts-class的形式来编写组件的时候,要记得在export上面➕<code>@Component</code>装饰器,不然组件不能正常注册</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">import {</span><br><span class="line"> Component,</span><br><span class="line"> Vue,</span><br><span class="line"> InjectReactive</span><br><span class="line">} from <span class="string">'vue-property-decorator'</span>;</span><br><span class="line"></span><br><span class="line">@Component</span><br><span class="line">class Child extends Vue {</span><br><span class="line"> @InjectReactive() node: number;</span><br><span class="line"> <span class="function"><span class="title">mounted</span></span>() {</span><br><span class="line"> console.log(this.node)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>如果在页面中需要用到子组件的情况,需要像这样注册,并且<code>@Component</code>装饰器只需要写一次</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">import {</span><br><span class="line"> Vue,</span><br><span class="line"> Component,</span><br><span class="line"> ProvideReactive</span><br><span class="line">} from <span class="string">'vue-property-decorator'</span>;</span><br><span class="line">import Child from <span class="string">'./child.vue'</span></span><br><span class="line">@Component({</span><br><span class="line"> components: {</span><br><span class="line"> Child</span><br><span class="line"> }</span><br><span class="line">})</span><br><span class="line">class Parent extends Vue {</span><br><span class="line"> @ProvideReactive() node = {}</span><br><span class="line"> <span class="function"><span class="title">mounted</span></span>() {</span><br><span class="line"> this.node = 1</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="笔记二-—-ProvideReactive来做数据透传的注意点"><a href="#笔记二-—-ProvideReactive来做数据透传的注意点" class="headerlink" title="笔记二 — ProvideReactive来做数据透传的注意点"></a>笔记二 — ProvideReactive来做数据透传的注意点</h3><p>如果在组件中使用Provide来进行数据透传的话,数据是不带响应式的。如果需要数据具有响应式,那么需要用ProvideReactive来做属性的透传,代码例子可以看上一个代码,另外由于在路由跳转的时候,有时候会有Provide的值重新定义的问题,这时候控制台会抛出异常,具体可以看这个<br><a href="https://github.com/kaorun343/vue-property-decorator/issues/277">issue</a>,有临时的解决方案</p>
<h3 id="笔记三-—-在弹窗中保证数据的实时性"><a href="#笔记三-—-在弹窗中保证数据的实时性" class="headerlink" title="笔记三 — 在弹窗中保证数据的实时性"></a>笔记三 — 在弹窗中保证数据的实时性</h3><p>需要把数据以Provide的形式传递给弹窗,但是数据仅仅只在第一次显示的时候是正常的数据,在关闭弹窗后再一次开启弹窗,显示的数据是上一次的数据。原因暂时不知道。所以我在关闭弹窗的时候同时用v-if来销毁元素,这样每次打开的元素都是一个最新的元素,同时这个时候获取到的数据也是最新的数据。</p>
<h3 id="笔记四-—-数据获取完后保证子组件获取最新的数据"><a href="#笔记四-—-数据获取完后保证子组件获取最新的数据" class="headerlink" title="笔记四 — 数据获取完后保证子组件获取最新的数据"></a>笔记四 — 数据获取完后保证子组件获取最新的数据</h3><p>在父组件用axios获取数据的时候,然后传递给子组件,但是子组件渲染的时候是定义时就给的默认值。<br>原因:父组件在请求数据的时候,子组件的生命周期已经走完并且已经渲染完成,所以这时候是拿不到请求后返回的真实数据<br>方案:我这里用v-if来判断获取的数据的长度是否为空来判断是否要渲染子组件,缺点:数据量很大的时候会有很长时间的空白。</p>
<h3 id="笔记五-—-自定义组件绑定v-models"><a href="#笔记五-—-自定义组件绑定v-models" class="headerlink" title="笔记五 — 自定义组件绑定v-models"></a>笔记五 — 自定义组件绑定v-models</h3><p>想让自定义组件能够使用v-model语法糖,这样子组件的数据就可以实时的反馈到父组件中去</p>
<p>在vue中,对input来说,v-model是value和input事件的语法糖,对于checkbox来说,监听的事件是change,给对应的元素添加对应的事件,然后在自组件emit出去,把相应的value值绑定到对应的dom元素中去。</p>
]]></content>
</entry>
<entry>
<title>递归求阶层</title>
<url>/2022/01/dfs-hierarchy/</url>
<content><![CDATA[<p>问题背景: 递归求两数之间所有数之和</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">dfs</span>(<span class="params">n,current</span>){ </span><br><span class="line"> <span class="keyword">if</span>(n > <span class="number">0</span>){</span><br><span class="line"> <span class="comment">// current 是累加数,只要没有到最后一个就继续累加</span></span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">dfs</span>(n-<span class="number">1</span>,current + n)</span><br><span class="line"> }<span class="keyword">else</span> <span class="keyword">return</span> current</span><br><span class="line">}</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">test</span>(<span class="params">n1,n2</span>){</span><br><span class="line"> <span class="keyword">if</span>(n1 > n2) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> <span class="comment">// 两数到阶层相减就是两数之间所有数之和</span></span><br><span class="line"> <span class="keyword">const</span> result = <span class="title function_">dfs</span>(n2,<span class="number">0</span>) - <span class="title function_">dfs</span>(n1 - <span class="number">1</span>,<span class="number">0</span>)</span><br><span class="line"> <span class="keyword">return</span> result</span><br><span class="line">}</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">test</span>(<span class="number">1</span>,<span class="number">100</span>))</span><br></pre></td></tr></table></figure>
<p>ummm 我一开始想法是分别求两个数的阶层,然后相减就是两数之间所有数之和,不过这个应该可以不用相减就可以处理的,如下</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">dfs2</span>(<span class="params">n1,n2,current</span>){</span><br><span class="line"> <span class="keyword">if</span>(n2 >= n1){</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">dfs2</span>(n1,n2 -<span class="number">1</span>,current + n2)</span><br><span class="line"> }<span class="keyword">else</span> <span class="keyword">return</span> current</span><br><span class="line">}</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">test2</span>(<span class="params">n1,n2</span>){</span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">dfs2</span>(n1,n2,<span class="number">0</span>)</span><br><span class="line">}</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">test2</span>(<span class="number">1</span>,<span class="number">100</span>))</span><br></pre></td></tr></table></figure>
<p>直接在计算阶层的时候处理一下累加的判断条件就行了。</p>
]]></content>
<tags>
<tag>JavaScript</tag>
<tag>算法</tag>
</tags>
</entry>
<entry>
<title>GET 和 POST 的区别</title>
<url>/2020/09/diff-between-get-post/</url>
<content><![CDATA[<h2 id="GET请求"><a href="#GET请求" class="headerlink" title="GET请求"></a>GET请求</h2><ol>
<li>GET请求返回的资源会被浏览器缓存</li>
<li>GET请求会保存在浏览器的历史记录中</li>
<li>GET请求能当书签</li>
<li>GET不能用来处理敏感数据</li>
<li>有长度限制(具体长度参见各个浏览器规范)</li>
<li>仅仅用来获取数据,不能修改</li>
<li>参数的数据类型,只接收ascll编码</li>
<li>仅支持url编码</li>
<li>产生一个数据包</li>
<li>页面重载或者回退没有影响</li>
</ol>
<h2 id="POST请求"><a href="#POST请求" class="headerlink" title="POST请求"></a>POST请求</h2><ol>
<li>请求不会被缓存</li>
<li>不会保存在历史记录中</li>
<li>不能作为书签</li>
<li>数据长度没有限制</li>
<li>参数的数据类型没有限制</li>
<li>支持多种编码</li>
<li>两个数据包,需要服务器响应100后继续发出请求之后服务器(可能)响应200</li>
<li>刷新或者回退 数据会重新提交</li>
</ol>
<h2 id="其他http方法"><a href="#其他http方法" class="headerlink" title="其他http方法"></a>其他http方法</h2><h3 id="put"><a href="#put" class="headerlink" title="put"></a>put</h3><p>put方法跟post一样,也是用来创建或者更新资源的,但是跟post不一样的地方在于put请求是幂等的,也就是说put请求发起多次所产生的结果是跟第一个一样的;那么对于post请求,重复请求就会产生多次创建相同资源的副作用</p>
<h3 id="head"><a href="#head" class="headerlink" title="head"></a>head</h3><p>head请求跟get请求是差不多相同的,不同的地方在于head请求没有返回体<br>那么head 请求通常是在发起get请求之前检查get请求返回的是什么,比如在下载文件的时候或者下载请求体的时候</p>
<h3 id="delete"><a href="#delete" class="headerlink" title="delete"></a>delete</h3><p>删除方法用来删除资源</p>
<h3 id="options"><a href="#options" class="headerlink" title="options"></a>options</h3><p>是复杂请求的预检请求</p>
]]></content>
</entry>
<entry>
<title>loader和plugin的区别</title>
<url>/2022/01/diff-loader-plugin/</url>
<content><![CDATA[<p>loader,它是一个转换器,将A文件进行编译成B文件,比如:将A.less转换为A.css,单纯的文件转换过程。</p>
<p>plugin是一个扩展器,它丰富了webpack本身,针对是loader结束后,webpack打包的整个过程,它并不直接操作文件,而是基于事件机制工作,会监听webpack打包过程中的某些节点,执行广泛的任务</p>
]]></content>
<tags>
<tag>webpack</tag>
</tags>
</entry>
<entry>
<title>dh算法</title>
<url>/2022/01/dh%E7%AE%97%E6%B3%95/</url>
<content><![CDATA[<p>全称 Diffie Hellman密钥交换算法</p>
<p>DH算法属于公钥加密算法,https加密过程客户端C与服务端需要用到dh算法或者RSA算法来协商用户加密数据的session key</p>
<p>在加密数据时使用对称密码算法,密钥管理使用公钥密码技术</p>
<span id="more"></span>
<h3 id="背景介绍-–-离散对数"><a href="#背景介绍-–-离散对数" class="headerlink" title="背景介绍 – 离散对数"></a>背景介绍 – 离散对数</h3><p>假设a, p均为素数,则有以下等式:<br>{a<sup>1</sup>mod p, a<sup>2</sup>mod p,…, a<sup>(p-1)</sup>mod p} ={1, 2, …, p-1} //{}表示集合 ,假定为T</p>
<p>对于任意⼀个数x,若0<x<p,则必定存在唯⼀的y (0<y<p),使得x = a<sup>y</sup>mod p,当p很⼤时,很难求出y。</p>
<p>有以下公式:</p>
<p>((a<sup>x</sup>mod p)<sup>y</sup>)mod p = a<sup>xy</sup>mod p</p>
<p>example:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">a = 3,p = 7</span><br><span class="line"></span><br><span class="line">3mod7 = 3</span><br><span class="line">9mod7 = 2</span><br><span class="line">27mod7 = 6 </span><br><span class="line"></span><br><span class="line">此时集合T为{2,3,6}</span><br></pre></td></tr></table></figure>
<p>dh算法的安全性则是基于这个问题的难解性。</p>
<h3 id="DH算法基本原理"><a href="#DH算法基本原理" class="headerlink" title="DH算法基本原理"></a>DH算法基本原理</h3><p><img src="/images/dh%E7%AE%97%E6%B3%95/%E5%8E%9F%E7%90%86.png" alt="原理"></p>
<p>此时两个计算的共享密钥是相等的,中间人通过窃听双方在通信过程中的信息是可以获取到Ya,Yb,a,q这四个值的,而中间人若想知道双方计算出来的K的话,就需要知道某一方的指数,即Xb或者Xa,假设说中间人要获取Xb的值,那么Xb就等于${log_a{Yb}}$,而计算离散对数的结果是非常困难的,而对于大素数来说,求解离散对数被认为是不可能的,因此当q取极大值时,计算Xb是不可能的。</p>
<p>example:</p>
<p>a = 3 q = 17</p>
<p>当Xa = 15 时</p>
<p>Ya = 3<sup>15</sup> mod 17 = 6</p>
<p>6 – > 发送给了Blob</p>
<p>当Xb = 13 时</p>
<p>Yb = 3<sup>13</sup> mode 17 = 12</p>
<p>12 –> 发送给Alice</p>
<p>Alice的共享密钥为 12<sup>15</sup> mode 17 = 10</p>
<p>Blob的共享密钥为 6<sup>13</sup> mode 17 = 10</p>
<p>以上即为DH加密算法</p>
<p>摘自<a href="https://www.bilibili.com/video/BV12w411f7c5?from=search&seid=7708955631160057078&spm_id_from=333.337.0.0">blibli</a></p>
]]></content>
<tags>
<tag>dh</tag>
</tags>
</entry>
<entry>
<title>dynamic_size_list</title>
<url>/2023/09/dynamic-size-list/</url>
<content><![CDATA[<h3 id="背景描述"><a href="#背景描述" class="headerlink" title="背景描述"></a>背景描述</h3><p>实现一个虚拟滚动组件,可以满足列表和瀑布流两种模式</p>
<p>线上预览环境</p>
<p><a href="https://codesandbox.io/s/dong-tai-gao-du-xu-ni-gun-dong-4945px?file=/Masonry.tsx">https://codesandbox.io/s/dong-tai-gao-du-xu-ni-gun-dong-4945px?file=/Masonry.tsx</a></p>
<p>具体代码实现可以看以上链接</p>
<p>动态高度的计算是在子项渲染之后做的,因此在渲染的时候这里会渲染两次,一次是预渲染,一次是计算过后的渲染</p>
<p>实现高度的组件思路类似,具体可以看代码:</p>
<figure class="highlight tsx"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, { useRef, useEffect } <span class="keyword">from</span> <span class="string">"react"</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="title function_">RowRenderer</span> = (<span class="params">{</span></span><br><span class="line"><span class="params"> index,</span></span><br><span class="line"><span class="params"> isScrolling,</span></span><br><span class="line"><span class="params"> key,</span></span><br><span class="line"><span class="params"> style,</span></span><br><span class="line"><span class="params"> state,</span></span><br><span class="line"><span class="params"> render,</span></span><br><span class="line"><span class="params"> setRowHeight</span></span><br><span class="line"><span class="params">}</span>) => {</span><br><span class="line"> <span class="keyword">const</span> rowRef = useRef<<span class="title class_">HTMLDivElement</span> | <span class="literal">null</span>>(<span class="literal">null</span>);</span><br><span class="line"> <span class="keyword">const</span> { showScrollingPlaceholder } = state;</span><br><span class="line"> <span class="keyword">const</span> placeholderContent = (</span><br><span class="line"> <span class="language-xml"><span class="tag"><<span class="name">div</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> // <span class="attr">className</span>=<span class="string">{clsx(styles.row,</span> <span class="attr">styles.isScrollingPlaceholder</span>)}</span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">key</span>=<span class="string">{key}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">style</span>=<span class="string">{style}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> ></span></span></span><br><span class="line"><span class="language-xml"> Scrolling...</span></span><br><span class="line"><span class="language-xml"> <span class="tag"></<span class="name">div</span>></span></span></span><br><span class="line"> );</span><br><span class="line"></span><br><span class="line"> <span class="title function_">useEffect</span>(<span class="function">() =></span> {</span><br><span class="line"> <span class="keyword">if</span> (rowRef) {</span><br><span class="line"> <span class="title function_">setRowHeight</span>(index, rowRef.<span class="property">current</span>.<span class="property">clientHeight</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="function">() =></span> {};</span><br><span class="line"> }, [rowRef, index]);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> showScrollingPlaceholder && isScrolling ? (</span><br><span class="line"> <span class="language-xml"><span class="tag"><<span class="name">div</span>></span>{placeholderContent}<span class="tag"></<span class="name">div</span>></span></span></span><br><span class="line"> ) : (</span><br><span class="line"> <span class="language-xml"><span class="tag"><<span class="name">div</span> <span class="attr">key</span>=<span class="string">{key}</span> <span class="attr">className</span>=<span class="string">"row"</span> <span class="attr">style</span>=<span class="string">{style}</span>></span></span></span><br><span class="line"><span class="language-xml"> <span class="tag"><<span class="name">div</span> <span class="attr">ref</span>=<span class="string">{rowRef}</span>></span></span></span><br><span class="line"><span class="language-xml"> <span class="tag"><<span class="name">div</span>></span>{render()}<span class="tag"></<span class="name">div</span>></span></span></span><br><span class="line"><span class="language-xml"> <span class="tag"></<span class="name">div</span>></span></span></span><br><span class="line"><span class="language-xml"> <span class="tag"></<span class="name">div</span>></span></span></span><br><span class="line"> );</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="title class_">RowRenderer</span>;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>如果只是需要实现虚拟列表模式,可以考虑用<code>react-window</code>来实现,因为这个库更小,这里使用了<code>react-virtualized</code>是因为react-window支持的是网格布局,而瀑布流不属于网格布局,所以对于react-window的话不考虑</p>
<p>来看列表的实现:<br>示例代码,基本可以直接用,有额外需要可以自己做修改</p>
<figure class="highlight tsx"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, { useEffect, useRef, useState } <span class="keyword">from</span> <span class="string">"react"</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">AutoSizer</span>, <span class="title class_">List</span> } <span class="keyword">from</span> <span class="string">"react-virtualized"</span>;</span><br><span class="line"><span class="keyword">import</span> <span class="string">"./list.css"</span>;</span><br><span class="line"><span class="keyword">import</span> <span class="title class_">RowRenderer</span> <span class="keyword">from</span> <span class="string">"./Rowrenderer"</span>;</span><br><span class="line"><span class="keyword">interface</span> <span class="title class_">Props</span><T <span class="keyword">extends</span> <span class="title class_">Record</span><<span class="built_in">string</span>, <span class="built_in">any</span>>> {</span><br><span class="line"> <span class="attr">children</span>: <span class="function">(<span class="params">p: { index; isScrolling?: <span class="built_in">boolean</span>; item: T }</span>) =></span> <span class="title class_">React</span>.<span class="property">ReactNode</span>;</span><br><span class="line"> <span class="attr">data</span>: T[];</span><br><span class="line"> height?: <span class="built_in">number</span>;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">function</span> <span class="title class_">VirtualList</span><T <span class="keyword">extends</span> <span class="title class_">Record</span><<span class="built_in">string</span>, <span class="built_in">any</span>>>({</span><br><span class="line"> data,</span><br><span class="line"> height = <span class="number">400</span>,</span><br><span class="line"> children</span><br><span class="line">}: <span class="title class_">Props</span><T>) {</span><br><span class="line"> <span class="keyword">const</span> listRef = useRef<<span class="title class_">List</span>>();</span><br><span class="line"> <span class="keyword">const</span> itemCount = data?.<span class="property">length</span>;</span><br><span class="line"> <span class="keyword">const</span> [state, setState] = <span class="title function_">useState</span>({</span><br><span class="line"> <span class="attr">listHeight</span>: height,</span><br><span class="line"> <span class="attr">listRowHeight</span>: <span class="number">50</span>,</span><br><span class="line"> <span class="attr">overscanRowCount</span>: <span class="number">10</span>,</span><br><span class="line"> <span class="attr">rowCount</span>: itemCount,</span><br><span class="line"> <span class="attr">scrollToIndex</span>: <span class="literal">undefined</span>,</span><br><span class="line"> <span class="attr">showScrollingPlaceholder</span>: <span class="literal">false</span>,</span><br><span class="line"> <span class="attr">useDynamicRowHeight</span>: <span class="literal">false</span></span><br><span class="line"> });</span><br><span class="line"> <span class="keyword">const</span> rowHeight = <span class="title function_">useRef</span>({});</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> <span class="title function_">setRowHeight</span> = (<span class="params">index: <span class="built_in">number</span>, value: <span class="built_in">number</span></span>) => {</span><br><span class="line"> rowHeight.<span class="property">current</span> = {</span><br><span class="line"> ...rowHeight.<span class="property">current</span>,</span><br><span class="line"> [index]: value</span><br><span class="line"> };</span><br><span class="line"></span><br><span class="line"> listRef.<span class="property">current</span>.<span class="title function_">recomputeRowHeights</span>();</span><br><span class="line"> };</span><br><span class="line"> <span class="keyword">const</span> <span class="title function_">_getRowHeight</span> = (<span class="params">{ index }</span>) => {</span><br><span class="line"> <span class="keyword">return</span> rowHeight.<span class="property">current</span>[index] || state.<span class="property">listRowHeight</span>;</span><br><span class="line"> };</span><br><span class="line"> <span class="keyword">return</span> (</span><br><span class="line"> <span class="language-xml"><span class="tag"><<span class="name">AutoSizer</span> <span class="attr">disableHeight</span>></span></span></span><br><span class="line"><span class="language-xml"> {({ width }) => {</span></span><br><span class="line"><span class="language-xml"> return (</span></span><br><span class="line"><span class="language-xml"> <span class="tag"><<span class="name">List</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">ref</span>=<span class="string">{listRef}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">className</span>=<span class="string">{</span>"<span class="attr">List</span>"}</span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">height</span>=<span class="string">{state.listHeight}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">overscanRowCount</span>=<span class="string">{state.overscanRowCount}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> // <span class="attr">noRowsRenderer</span>=<span class="string">{this._noRowsRenderer}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">rowCount</span>=<span class="string">{state.rowCount}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">rowHeight</span>=<span class="string">{_getRowHeight}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">rowRenderer</span>=<span class="string">{({</span> <span class="attr">index</span>, <span class="attr">isScrolling</span>, <span class="attr">key</span>, <span class="attr">style</span> }) =></span> {</span></span><br><span class="line"><span class="language-xml"> return (</span></span><br><span class="line"><span class="language-xml"> <span class="tag"><<span class="name">RowRenderer</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">index</span>=<span class="string">{index}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">isScrolling</span>=<span class="string">{isScrolling}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">style</span>=<span class="string">{style}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">key</span>=<span class="string">{key}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">setRowHeight</span>=<span class="string">{setRowHeight}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">render</span>=<span class="string">{()</span> =></span> {</span></span><br><span class="line"><span class="language-xml"> return children({ index, isScrolling, item: data[index] });</span></span><br><span class="line"><span class="language-xml"> }}</span></span><br><span class="line"><span class="language-xml"> state={state}</span></span><br><span class="line"><span class="language-xml"> /></span></span><br><span class="line"><span class="language-xml"> );</span></span><br><span class="line"><span class="language-xml"> }}</span></span><br><span class="line"><span class="language-xml"> scrollToIndex={state.scrollToIndex}</span></span><br><span class="line"><span class="language-xml"> width={width}</span></span><br><span class="line"><span class="language-xml"> /></span></span><br><span class="line"><span class="language-xml"> );</span></span><br><span class="line"><span class="language-xml"> }}</span></span><br><span class="line"><span class="language-xml"> <span class="tag"></<span class="name">AutoSizer</span>></span></span></span><br><span class="line"> );</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>这是瀑布流的实现:</p>
<figure class="highlight tsx"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, { useEffect, useRef } <span class="keyword">from</span> <span class="string">"react"</span>;</span><br><span class="line"><span class="keyword">import</span> {</span><br><span class="line"> <span class="title class_">AutoSizer</span>,</span><br><span class="line"> <span class="title class_">CellMeasurer</span>,</span><br><span class="line"> <span class="title class_">CellMeasurerCache</span>,</span><br><span class="line"> <span class="title class_">Masonry</span></span><br><span class="line">} <span class="keyword">from</span> <span class="string">"react-virtualized"</span>;</span><br><span class="line"><span class="keyword">import</span> { createCellPositioner } <span class="keyword">from</span> <span class="string">"react-virtualized/dist/es/Masonry"</span>;</span><br><span class="line"><span class="keyword">interface</span> <span class="title class_">Props</span> {</span><br><span class="line"> <span class="attr">itemCount</span>: <span class="built_in">number</span>;</span><br><span class="line"> <span class="attr">children</span>: <span class="function">(<span class="params">{</span></span></span><br><span class="line"><span class="params"><span class="function"> index,</span></span></span><br><span class="line"><span class="params"><span class="function"> isScrolling</span></span></span><br><span class="line"><span class="params"><span class="function"> }: {</span></span></span><br><span class="line"><span class="params"><span class="function"> index: <span class="built_in">number</span>;</span></span></span><br><span class="line"><span class="params"><span class="function"> isScrolling: <span class="built_in">boolean</span>;</span></span></span><br><span class="line"><span class="params"><span class="function"> }</span>) =></span> <span class="title class_">React</span>.<span class="property">ReactNode</span>;</span><br><span class="line"> height?: <span class="built_in">number</span>;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">function</span> <span class="title function_">VirtualMasonry</span>(<span class="params">{</span></span><br><span class="line"><span class="params"> itemCount,</span></span><br><span class="line"><span class="params"> children,</span></span><br><span class="line"><span class="params"> height = <span class="number">300</span></span></span><br><span class="line"><span class="params">}: Props</span>) {</span><br><span class="line"> <span class="keyword">const</span> cache = <span class="title function_">useRef</span>(</span><br><span class="line"> <span class="keyword">new</span> <span class="title class_">CellMeasurerCache</span>({</span><br><span class="line"> <span class="attr">defaultHeight</span>: <span class="number">250</span>,</span><br><span class="line"> <span class="attr">defaultWidth</span>: <span class="number">200</span>,</span><br><span class="line"> <span class="attr">fixedWidth</span>: <span class="literal">true</span></span><br><span class="line"> })</span><br><span class="line"> );</span><br><span class="line"> <span class="keyword">const</span> state = <span class="title function_">useRef</span>({</span><br><span class="line"> <span class="attr">columnWidth</span>: <span class="number">200</span>,</span><br><span class="line"> height,</span><br><span class="line"> <span class="attr">gutterSize</span>: <span class="number">10</span>,</span><br><span class="line"> <span class="attr">overscanByPixels</span>: <span class="number">0</span>,</span><br><span class="line"> <span class="attr">windowScrollerEnabled</span>: <span class="literal">false</span></span><br><span class="line"> });</span><br><span class="line"> <span class="keyword">const</span> width = <span class="title function_">useRef</span>(<span class="number">0</span>);</span><br><span class="line"> <span class="keyword">const</span> columnCount = <span class="title function_">useRef</span>(<span class="number">0</span>);</span><br><span class="line"> <span class="keyword">const</span> scrollTopRefVal = <span class="title function_">useRef</span>(<span class="number">0</span>);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> cellPositioner = <span class="title function_">useRef</span>(</span><br><span class="line"> <span class="title function_">createCellPositioner</span>({</span><br><span class="line"> <span class="attr">cellMeasurerCache</span>: cache.<span class="property">current</span>,</span><br><span class="line"> <span class="attr">columnCount</span>: columnCount.<span class="property">current</span>,</span><br><span class="line"> <span class="attr">columnWidth</span>: state.<span class="property">current</span>.<span class="property">columnWidth</span>,</span><br><span class="line"> <span class="attr">spacer</span>: state.<span class="property">current</span>.<span class="property">gutterSize</span></span><br><span class="line"> })</span><br><span class="line"> );</span><br><span class="line"> <span class="keyword">const</span> masonryRef = <span class="title function_">useRef</span>();</span><br><span class="line"> <span class="keyword">const</span> <span class="title function_">setMasonryRef</span> = (<span class="params">ref</span>) => {</span><br><span class="line"> masonryRef.<span class="property">current</span> = ref;</span><br><span class="line"> };</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> <span class="title function_">resetCellPositioner</span> = (<span class="params"></span>) => {</span><br><span class="line"> <span class="keyword">const</span> { columnWidth, gutterSize } = state.<span class="property">current</span>;</span><br><span class="line"> <span class="keyword">if</span> (!cellPositioner) <span class="keyword">return</span>;</span><br><span class="line"> cellPositioner.<span class="property">current</span>?.<span class="property">reset</span>?.({</span><br><span class="line"> <span class="attr">columnCount</span>: columnCount.<span class="property">current</span>,</span><br><span class="line"> columnWidth,</span><br><span class="line"> <span class="attr">spacer</span>: gutterSize</span><br><span class="line"> });</span><br><span class="line"> };</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> <span class="title function_">calculateColumnCount</span> = (<span class="params"></span>) => {</span><br><span class="line"> <span class="keyword">const</span> { columnWidth, gutterSize } = state.<span class="property">current</span>;</span><br><span class="line"></span><br><span class="line"> columnCount.<span class="property">current</span> = <span class="title class_">Math</span>.<span class="title function_">floor</span>(</span><br><span class="line"> width.<span class="property">current</span> / (columnWidth + gutterSize)</span><br><span class="line"> );</span><br><span class="line"> };</span><br><span class="line"> <span class="keyword">const</span> <span class="title function_">onResize</span> = (<span class="params">{ width: w }</span>) => {</span><br><span class="line"> width.<span class="property">current</span> = w;</span><br><span class="line"> <span class="comment">// 重新计算列的个数</span></span><br><span class="line"> <span class="title function_">calculateColumnCount</span>();</span><br><span class="line"> <span class="comment">// 根据列的个数重新计算位置</span></span><br><span class="line"> <span class="title function_">resetCellPositioner</span>();</span><br><span class="line"> <span class="comment">// 让组件根据位置重新计算</span></span><br><span class="line"> <span class="keyword">if</span> (masonryRef) masonryRef?.<span class="property">current</span>?.<span class="property">recomputeCellPositions</span>?.();</span><br><span class="line"> };</span><br><span class="line"> <span class="title function_">useEffect</span>(<span class="function">() =></span> {</span><br><span class="line"> <span class="comment">// 初始化宽度</span></span><br><span class="line"> <span class="title function_">calculateColumnCount</span>();</span><br><span class="line"> }, [width]);</span><br><span class="line"> <span class="title function_">useEffect</span>(<span class="function">() =></span> {</span><br><span class="line"> <span class="comment">// 初始化cell position</span></span><br><span class="line"></span><br><span class="line"> cellPositioner.<span class="property">current</span> = <span class="title function_">createCellPositioner</span>({</span><br><span class="line"> <span class="attr">cellMeasurerCache</span>: cache.<span class="property">current</span>,</span><br><span class="line"> <span class="attr">columnCount</span>: columnCount.<span class="property">current</span>,</span><br><span class="line"> <span class="attr">columnWidth</span>: state.<span class="property">current</span>.<span class="property">columnWidth</span>,</span><br><span class="line"> <span class="attr">spacer</span>: state.<span class="property">current</span>.<span class="property">gutterSize</span></span><br><span class="line"> });</span><br><span class="line"> <span class="comment">// console.info("effect:", cellPositioner.current);</span></span><br><span class="line"> }, [columnCount]);</span><br><span class="line"> <span class="comment">// console.info("out:", cellPositioner.current);</span></span><br><span class="line"> <span class="keyword">const</span> rowHeight = <span class="title function_">useRef</span>({});</span><br><span class="line"> <span class="keyword">const</span> <span class="title function_">setRowHeight</span> = (<span class="params">index, value</span>) => {</span><br><span class="line"> rowHeight.<span class="property">current</span> = {</span><br><span class="line"> ...rowHeight.<span class="property">current</span>,</span><br><span class="line"> [index]: value</span><br><span class="line"> };</span><br><span class="line"> <span class="comment">// onResize({ width: width.current });</span></span><br><span class="line"> };</span><br><span class="line"> <span class="keyword">const</span> <span class="title function_">CellRenderer</span> = (<span class="params">{ index, key, parent, style, isScrolling }</span>) => {</span><br><span class="line"> <span class="keyword">const</span> { columnWidth } = state.<span class="property">current</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> divRef = useRef<<span class="title class_">HTMLDivElement</span> | <span class="literal">null</span>>(<span class="literal">null</span>);</span><br><span class="line"> <span class="title function_">useEffect</span>(<span class="function">() =></span> {</span><br><span class="line"> <span class="keyword">if</span> (divRef) {</span><br><span class="line"> <span class="title function_">setRowHeight</span>(index, divRef.<span class="property">current</span>.<span class="property">clientHeight</span>);</span><br><span class="line"> }</span><br><span class="line"> }, [divRef]);</span><br><span class="line"> <span class="keyword">return</span> (</span><br><span class="line"> <span class="language-xml"><span class="tag"><<span class="name">CellMeasurer</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">cache</span>=<span class="string">{cache.current}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">index</span>=<span class="string">{index}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">key</span>=<span class="string">{key}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">parent</span>=<span class="string">{parent}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> ></span></span></span><br><span class="line"><span class="language-xml"> <span class="tag"><<span class="name">div</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">style</span>=<span class="string">{{</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">...style</span>,</span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">width:</span> <span class="attr">columnWidth</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> }}</span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> ></span></span></span><br><span class="line"><span class="language-xml"> <span class="tag"><<span class="name">div</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">ref</span>=<span class="string">{divRef}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">style</span>=<span class="string">{{</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">backgroundColor:</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> "#" + <span class="attr">Math.floor</span>(<span class="attr">Math.random</span>() * <span class="attr">16777215</span>)<span class="attr">.toString</span>(<span class="attr">16</span>),</span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">borderRadius:</span> "<span class="attr">0.5rem</span>",</span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">height:</span> <span class="attr">rowHeight.current</span>[<span class="attr">index</span>],</span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">marginBottom:</span> "<span class="attr">0.5rem</span>",</span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">width:</span> "<span class="attr">100</span>%",</span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">fontSize:</span> <span class="attr">20</span>,</span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">color:</span> "<span class="attr">white</span>",</span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">display:</span> "<span class="attr">flex</span>",</span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">alignItems:</span> "<span class="attr">center</span>",</span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">justifyContent:</span> "<span class="attr">center</span>"</span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> }}</span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> ></span></span></span><br><span class="line"><span class="language-xml"> {children({ index, isScrolling })}</span></span><br><span class="line"><span class="language-xml"> <span class="tag"></<span class="name">div</span>></span></span></span><br><span class="line"><span class="language-xml"> <span class="tag"></<span class="name">div</span>></span></span></span><br><span class="line"><span class="language-xml"> <span class="tag"></<span class="name">CellMeasurer</span>></span></span></span><br><span class="line"> );</span><br><span class="line"> };</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> <span class="title function_">renderMasonry</span> = (<span class="params">{ width: w }</span>) => {</span><br><span class="line"> width.<span class="property">current</span> = w;</span><br><span class="line"> <span class="keyword">return</span> (</span><br><span class="line"> <span class="language-xml"><span class="tag"><<span class="name">Masonry</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">autoHeight</span>=<span class="string">{false}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">cellCount</span>=<span class="string">{itemCount}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">cellMeasurerCache</span>=<span class="string">{cache.current}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">cellPositioner</span>=<span class="string">{cellPositioner.current}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">cellRenderer</span>=<span class="string">{({</span> <span class="attr">index</span>, <span class="attr">key</span>, <span class="attr">parent</span>, <span class="attr">style</span>, <span class="attr">isScrolling</span> }) =></span> {</span></span><br><span class="line"><span class="language-xml"> return (</span></span><br><span class="line"><span class="language-xml"> <span class="tag"><<span class="name">CellRenderer</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">index</span>=<span class="string">{index}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">key</span>=<span class="string">{key}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">parent</span>=<span class="string">{parent}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">style</span>=<span class="string">{style}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">isScrolling</span>=<span class="string">{isScrolling}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> /></span></span></span><br><span class="line"><span class="language-xml"> );</span></span><br><span class="line"><span class="language-xml"> }}</span></span><br><span class="line"><span class="language-xml"> height={state.current.height}</span></span><br><span class="line"><span class="language-xml"> overscanByPixels={state.current.overscanByPixels}</span></span><br><span class="line"><span class="language-xml"> ref={setMasonryRef}</span></span><br><span class="line"><span class="language-xml"> scrollTop={scrollTopRefVal.current}</span></span><br><span class="line"><span class="language-xml"> width={w}</span></span><br><span class="line"><span class="language-xml"> /></span></span><br><span class="line"> );</span><br><span class="line"> };</span><br><span class="line"> <span class="keyword">const</span> <span class="title function_">renderAutoSizer</span> = (<span class="params">{ height, scrollTop }</span>) => {</span><br><span class="line"> scrollTopRefVal.<span class="property">current</span> = scrollTop;</span><br><span class="line"> <span class="keyword">return</span> (</span><br><span class="line"> <span class="language-xml"><span class="tag"><<span class="name">AutoSizer</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">disableHeight</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">height</span>=<span class="string">{height}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">onResize</span>=<span class="string">{onResize}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">overscanByPixels</span>=<span class="string">{state.current.overscanByPixels}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">scrollTop</span>=<span class="string">{scrollTopRefVal.current}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> ></span></span></span><br><span class="line"><span class="language-xml"> {renderMasonry}</span></span><br><span class="line"><span class="language-xml"> <span class="tag"></<span class="name">AutoSizer</span>></span></span></span><br><span class="line"> );</span><br><span class="line"> };</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">renderAutoSizer</span>({ <span class="attr">height</span>: state.<span class="property">current</span>.<span class="property">height</span>, <span class="attr">scrollTop</span>: <span class="number">0</span> });</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
<tags>
<tag>Typescript React React-Virtualized 瀑布流</tag>
</tags>
</entry>
<entry>
<title>今日随笔(7-29)</title>
<url>/2020/07/essay-1/</url>
<content><![CDATA[<h2 id="runAsync"><a href="#runAsync" class="headerlink" title="runAsync"></a>runAsync</h2><p>使用 web worker 在一个单独的线程中执行函数,能够允许执行不阻塞 UI 渲染的耗时函数</p>
<ol>
<li><p>使用 blob 形式的 url 来创建<code>worker</code>,<code>worker</code>的内容应该是函数的系列化版本,然后立即返回函数的返回值</p>
</li>
<li><p>返回值是一个<code>promise</code>,它监听了<code>worker</code>的<code>onmessage</code> and <code>onerror</code>两个事件,返回从主线程发送过来的数据或者是抛出一个错误</p>
<span id="more"></span>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">const runAsync = fn => {</span><br><span class="line"> const worker = new Worker(</span><br><span class="line"> URL.createObjectURL(new Blob([`postMessage((<span class="variable">${fn}</span>)());`]), {</span><br><span class="line"> <span class="built_in">type</span>: <span class="string">'application/javascript; charset=utf-8'</span></span><br><span class="line"> })</span><br><span class="line"> );</span><br><span class="line"> <span class="built_in">return</span> new Promise((res, rej) => {</span><br><span class="line"> worker.onmessage = ({ data }) => {</span><br><span class="line"> res(data), worker.terminate();</span><br><span class="line"> };</span><br><span class="line"> worker.onerror = err => {</span><br><span class="line"> rej(err), worker.terminate();</span><br><span class="line"> };</span><br><span class="line"> });</span><br><span class="line">};</span><br></pre></td></tr></table></figure></li>
</ol>
<p>example</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"> const longRunningFunction = () => {</span><br><span class="line"> <span class="built_in">let</span> result = 0;</span><br><span class="line"> <span class="keyword">for</span> (<span class="built_in">let</span> i = 0; i < 1000; i++)</span><br><span class="line"> <span class="keyword">for</span> (<span class="built_in">let</span> j = 0; j < 700; j++)</span><br><span class="line"> <span class="keyword">for</span> (<span class="built_in">let</span> k = 0; k < 300; k++) result = result + i + j + k;</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">runAsync(longRunningFunction).<span class="keyword">then</span>(console.log); // 209685000000</span><br></pre></td></tr></table></figure>
<p>然后由于代码是在不同的上下文执行的,因此所有的变量以及函数声明都要在内部定义,<br>比如下面这个是不行滴。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">let</span> outsideVariable = 50;</span><br><span class="line">runAsync(() => typeof outsideVariable).then(console.log); // 'undefined'</span><br></pre></td></tr></table></figure>
<h2 id="Copy-to-Clipboard"><a href="#Copy-to-Clipboard" class="headerlink" title="Copy to Clipboard"></a>Copy to Clipboard</h2><ol>
<li>创建一个<code>textarea</code>或者<code>input</code>元素添加到<code>document</code>中,让它的值等于要我们想要复制到粘贴板上的值</li>
<li>使用<code>HTMLInputElement.select()</code> 选择 刚刚创建的元素的内容</li>
<li>调用<code>Document.execCommand('copy')</code>复制刚刚选中的内容</li>
<li>将刚刚创建的元素移除</li>
</ol>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">const copy = val=>{</span><br><span class="line"> const el = document.createElement(<span class="string">'input'</span>)</span><br><span class="line"> input.value = val</span><br><span class="line"> document.body.appendChild(el)</span><br><span class="line"> el.select()</span><br><span class="line"> document.execCommand(<span class="string">'copy'</span>)</span><br><span class="line"> documnet.body.removeChild(el)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>但是在执行这个方法的时候,在插入以及移除元素的时候可能会发生闪烁,一个常见的解决方案就是把创建的这个元素放置在不可见区域,看一下改造后的方法</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">const copyToClipboard = str => {</span><br><span class="line"> const el = document.createElement(<span class="string">'textarea'</span>);</span><br><span class="line"> el.value = str;</span><br><span class="line"> el.setAttribute(<span class="string">'readonly'</span>, <span class="string">''</span>);</span><br><span class="line"> el.style.position = <span class="string">'absolute'</span>;</span><br><span class="line"> el.style.left = <span class="string">'-9999px'</span>;</span><br><span class="line"> document.body.appendChild(el);</span><br><span class="line"> el.select();</span><br><span class="line"> document.execCommand(<span class="string">'copy'</span>);</span><br><span class="line"> document.body.removeChild(el);</span><br><span class="line">};</span><br></pre></td></tr></table></figure>
<h2 id="修改-url-来重载页面"><a href="#修改-url-来重载页面" class="headerlink" title="修改 url 来重载页面"></a>修改 url 来重载页面</h2></br>
<p><strong>使用 h5 的 history</strong></p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">const nextURL = <span class="string">'https://my-website.com/page_b'</span>;</span><br><span class="line">const nextTitle = <span class="string">'My new page title'</span>;</span><br><span class="line">const nextState = { additionalInformation: <span class="string">'Updated the URL with JS'</span> };</span><br><span class="line"><span class="comment"># 在浏览器历史新建一个入口并且无需重新加载</span></span><br><span class="line">window.history.pushState(nextState, nextTitle, nextURL);</span><br><span class="line"><span class="comment"># 取代当前入口</span></span><br><span class="line">window.history.replaceState(nextState, nextTitle, nextURL);</span><br></pre></td></tr></table></figure>
<p>history api 只允许访问同源网站,所以你不能导航到域名完全不一样的网站</p>
<p><strong>location</strong></p>
<p>location api 是比较旧的东西了,它需要重载页面才可以改变浏览器记录</p>
<h2 id="获取当前-url"><a href="#获取当前-url" class="headerlink" title="获取当前 url"></a>获取当前 url</h2><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">const getBaseUrl = url =>{</span><br><span class="line"> <span class="built_in">return</span> url.indexOf(<span class="string">'?'</span>) >0 ?url.slice(0,url.indexOf(<span class="string">'?'</span>)):url</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>EXAMPLES</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">getBaseURL(<span class="string">'http://url.com/page?name=Adam&surname=Smith'</span>);</span><br><span class="line"><span class="comment"># 'http://url.com/page'</span></span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>essay</category>
</categories>
<tags>
<tag>essay</tag>
</tags>
</entry>
<entry>
<title>今日随笔</title>
<url>/2021/03/essay-10/</url>
<content><![CDATA[<h3 id="removeNonASCII"><a href="#removeNonASCII" class="headerlink" title="removeNonASCII"></a>removeNonASCII</h3><p>Removes non-printable ASCII characters.</p>
<p>Use a regular expression to remove non-printable ASCII characters.</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="title function_">removeNonASCII</span> = str => str.<span class="title function_">replace</span>(<span class="regexp">/[^\x20-\x7E]/g</span>, <span class="string">''</span>)</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="title function_">removeNonASCII</span>(<span class="string">'äÄçÇéÉêlorem-ipsumöÖÐþúÚ'</span>); <span class="comment">// 'lorem-ipsum'</span></span><br></pre></td></tr></table></figure>
<span id="more"></span>
<h3 id="Constant-width-to-height-ratio"><a href="#Constant-width-to-height-ratio" class="headerlink" title="Constant width to height ratio"></a>Constant width to height ratio</h3><p>iven an element of variable width, it will ensure its height remains proportionate in a responsive fashion (i.e., its width to height ratio remains constant).</p>
<p><code>html</code></p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"constant-width-to-height-ratio"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br></pre></td></tr></table></figure>
<p><code>css</code></p>
<figure class="highlight css"><table><tr><td class="code"><pre><span class="line"><span class="selector-class">.constant-width-to-height-ratio</span> {</span><br><span class="line"> <span class="attribute">background</span>: <span class="number">#333</span>;</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">50%</span>;</span><br><span class="line">}</span><br><span class="line"><span class="selector-class">.constant-width-to-height-ratio</span><span class="selector-pseudo">::before</span> {</span><br><span class="line"> <span class="attribute">content</span>: <span class="string">''</span>;</span><br><span class="line"> <span class="attribute">padding-top</span>: <span class="number">100%</span>;</span><br><span class="line"> <span class="attribute">float</span>: left;</span><br><span class="line">}</span><br><span class="line"><span class="selector-class">.constant-width-to-height-ratio</span><span class="selector-pseudo">::after</span> {</span><br><span class="line"> <span class="attribute">content</span>: <span class="string">''</span>;</span><br><span class="line"> <span class="attribute">display</span>: block;</span><br><span class="line"> <span class="attribute">clear</span>: both;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><code>description</code><br>padding-top on the ::before pseudo-element causes the height of the element to equal a percentage of its width. 100% therefore means the element’s height will always be 100% of the width, creating a responsive square.</p>
<p>This method also allows content to be placed inside the element normally.</p>
<p><code>browser support</code></p>
<p>✅ No caveats.</p>
]]></content>
<tags>
<tag>JavaScript</tag>
</tags>
</entry>
<entry>
<title>今日随笔(3.21))</title>
<url>/2021/03/essay-11/</url>
<content><![CDATA[<h4 id="How-to-Make-Badass-Shadows"><a href="#How-to-Make-Badass-Shadows" class="headerlink" title="How to Make Badass Shadows"></a>How to Make Badass Shadows</h4><p><a href="https://blog.prototypr.io/how-to-make-badass-shadows-564b3a30aba4">Tips to help create better UI shadows.</a> </p>
<h4 id="Jest"><a href="#Jest" class="headerlink" title="Jest"></a>Jest</h4><p><a href="https://pragmaticpineapple.com/7-ways-to-debug-jest-tests-in-terminal/">7 Ways to Debug Jest Tests in Terminal</a></p>
<span id="more"></span>]]></content>
<tags>
<tag>JavaScript</tag>
<tag>css</tag>
<tag>Jest</tag>
</tags>
</entry>
<entry>
<title>今日随笔(7-30)</title>
<url>/2020/07/essay-2/</url>
<content><![CDATA[<h2 id="用-ts-开发-react-组件"><a href="#用-ts-开发-react-组件" class="headerlink" title="用 ts 开发 react 组件"></a>用 ts 开发 react 组件</h2></br>
<p><strong>基础函数式组件</strong></p>
<p>不用传递任何的 prop,直接返回一个 jsx 作为 react 组件</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="function"><span class="title">Title</span></span>() {</span><br><span class="line"> <span class="built_in">return</span> <h1>Welcome to this application</h1>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<span id="more"></span>
<p><strong>带有 prop 的函数式组件</strong></p>
<p>声明 props 类型并将 prop 传递给 jsx</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">type</span> GreetingProps = {</span><br><span class="line"> name: string;</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> Greeting(props: GreetingProps) {</span><br><span class="line"> <span class="built_in">return</span> <p>Hi {props.name} 👋</p></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>对 prop 进行解构或许可读性更好</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="keyword">function</span> Greeting({ name }: GreetingProps) {</span><br><span class="line"> <span class="built_in">return</span> <p>Hi {name} 👋</p>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>假如 GreetingProps 中的 name 可选,那么就要给 name 一个默认值,以防 name 会变成 undefined</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">type</span> LoginMsgProps = {</span><br><span class="line"> name?: string;</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> LoginMsg({ name = <span class="string">"Guest"</span> }: LoginMsgProps) {</span><br><span class="line"> <span class="built_in">return</span> <p>Logged <span class="keyword">in</span> as {name}</p>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><strong>Children</strong></p>
<p>对于 children,更倾向于显示定义,而对于 ReactNode 类型来说,已经能够接受大多数的东西,比如 jsx,string 字符串等等</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">type</span> CardProps = {</span><br><span class="line"> title: string;</span><br><span class="line"> children: React.ReactNode;</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="built_in">export</span> <span class="keyword">function</span> Card({ title, children }: CardProps) {</span><br><span class="line"> <span class="built_in">return</span> (</span><br><span class="line"> <section className=<span class="string">"cards"</span>></span><br><span class="line"> <h2>{title}</h2></span><br><span class="line"> {children}</span><br><span class="line"> </section></span><br><span class="line"> );</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>当不需要 children 元素时,可以显示定义 children 的类型为 never</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">type</span> SaveButtonProps = {</span><br><span class="line"></span><br><span class="line"> children: never</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>这样当传递了 children 时就会抛出错误</p>
<p><strong>对 html 元素使用拓展符</strong></p>
<p>拓展符对于 html 元素来说是个很好的特性,因为它能帮助你确保你把所有的 html 属性都给挪到你需要的元素上</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">type</span> ButtonProps = JSX.IntrinsicElements[<span class="string">"button"</span>];</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> Button({ ...allProps }: ButtonProps) {</span><br><span class="line"> <span class="built_in">return</span> <button {...allProps} />;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><strong>属性可以自定义设计</strong></p>
<p>当需要对 html 某些属性进行约束时,可以对它们进行自定义设定</p>
<p>如下这个例子,对 type 进行类型约束,这样仅能被赋予<code>"primary" | "secondary"</code>这两个值了</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">type</span> StyledButton = Omit<</span><br><span class="line"> JSX.IntrinsicElements[<span class="string">"button"</span>],</span><br><span class="line"> <span class="string">"type"</span> | <span class="string">"className"</span></span><br><span class="line">> & {</span><br><span class="line"> <span class="built_in">type</span>: <span class="string">"primary"</span> | <span class="string">"secondary"</span>;</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> StyledButton({ <span class="built_in">type</span>, ...allProps }: StyledButton) {</span><br><span class="line"> <span class="built_in">return</span> <Button className={`btn-<span class="variable">${type}</span>`} />;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><strong>Required</strong></p>
<p>为了防止被 omit 出来的属性会忘记进行添加,封装一个 helper 来进行约束,</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">type</span> MakeRequired<T, K extends keyof T> = Omit<T, K> &</span><br><span class="line"> Required<{ [P <span class="keyword">in</span> K]: T[P] }>;</span><br></pre></td></tr></table></figure>
<p>这样既可以将需要约束的属性omit出来,同时还能够防止忘记添加被omit出来的属性</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">type</span> ImgProps</span><br><span class="line"> = MakeRequired<</span><br><span class="line"> JSX.IntrinsicElements[<span class="string">"img"</span>],</span><br><span class="line"> <span class="string">"alt"</span> | <span class="string">"src"</span></span><br><span class="line"> >;</span><br><span class="line"></span><br><span class="line"><span class="built_in">export</span> <span class="keyword">function</span> Img({ alt, ...allProps }: ImgProps) {</span><br><span class="line"> <span class="built_in">return</span> <img alt={alt} {...allProps} />;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">const zz = <Img alt=<span class="string">"..."</span> src=<span class="string">"..."</span> />;</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>essay</category>
</categories>
<tags>
<tag>essay</tag>
</tags>
</entry>
<entry>
<title>今日随笔</title>
<url>/2021/11/essay-12/</url>
<content><![CDATA[<h4 id="tinymce爬坑记录"><a href="#tinymce爬坑记录" class="headerlink" title="tinymce爬坑记录"></a>tinymce爬坑记录</h4></br>
若是需要使用tinymce并且要让tinymce的样式不受其他样式干扰时,vue中的使用scope给html标签增加自定义属性是不太可取的。应该是要使用shadow dom(与主dom分开渲染)或者iframe内嵌(可以理解为单独开一个窗体)
<h5 id="Note"><a href="#Note" class="headerlink" title="Note"></a>Note</h5><ol>
<li>非inline模式下的tinymce是可以挂载在shadow dom下的,而inline模式下的tinymce挂载在shadow dom下是无效的,大致原因是浏览器的api selection对于shadow dom的支持还没搞定,具体可以查看tinymce的issue或者selection api的介绍,或者可以查看源代码16100+行左右的applyFormat函数,挂载在shadow dom中和不挂载在shadow dom中走的逻辑是不一样的!。(查了很久orz,然后去issue验证了猜想)</li>
<li>初始化挂载在iframe下的tinymce需要使用当前document挂载的tinymce实例,使用父级窗体加载进来的tinymce在子iframe中是用不了的,因为tinymce在操作格式时会获取当前document下的数据。</li>
<li>如果想要在toolbar添加自定义按钮可以使用ui.addButton.因为看见有人是通过直接操作dom的方式来添加自定义按钮</li>
<li>如果要修改某个类的样式可以在content_style中进行修改,同样看见有人通过获取editor的容器然后遍历子节点来动态修改样式。</li>
<li>假如iframe所在的vue组件加载成功了而加载了tinymce文件的iframe的window没有挂载tinymce时,这时候去初始化inline模式是初始化失败的,用vue的watch貌似是不起作用的,我用的方案是raf来定时获取tinymce,然后初始化数据。(假如有更好的方法告诉我。)</li>
</ol>
]]></content>
<tags>
<tag>JavaScript</tag>
<tag>Tinymce</tag>
</tags>
</entry>
<entry>
<title>docker</title>
<url>/2020/07/essay-3/</url>
<content><![CDATA[<h2 id="介绍"><a href="#介绍" class="headerlink" title="介绍"></a>介绍</h2><p>Docker 是由开发人员和系统管理员 构建 、运行和容器共享的应用程序的一个平台。使用容器部署应用程序称之为集装箱化。</p>
<h2 id="特点"><a href="#特点" class="headerlink" title="特点"></a>特点</h2><p>docker 为什么能够越来越受欢迎,那是因为:</p>
<ol>
<li>灵活性:即使再复杂的应用也能够被容器化。</li>
<li>轻量性:容器共享主机内核,并且在系统资源利用方面比虚拟机更加的高效</li>
<li>便携性:你可以在本地将应用打包成镜像,然后上传到云端,然后就可以在任何地方运行这个镜像</li>
<li>解耦:容器拥有高度自治权以及封闭性,你可以在不干扰其他应用程序的情况下对其中一个进行升级或者替换</li>
<li>拓展性:可以在数据中心自动分发容器副本</li>
<li>容器对应用隔离,对用户来说完全是黑盒,不用关心容器内发配置<span id="more"></span></li>
</ol>
<h2 id="解决了哪些问题"><a href="#解决了哪些问题" class="headerlink" title="解决了哪些问题"></a>解决了哪些问题</h2><ol>
<li>有时候在测试环境程序运行正常,但是在生产环境却出现了问题。<code>docker</code>的出现让测试环境和生产环境保持了一致性。</li>
<li>对于每个新用户来说,在执行程序之前必须在本机环境安装对应的环境。<code>docker</code>保证了一次配置,一键部署</li>
<li>由于版本问题导致程序不能正常启动.<code>docker</code>保证在部署的时候安装的版本跟开发时候的版本是完全一致的,重新定义了交付环境,比如对于<code>node-sass</code>的安装,不同版本的<code>node-sass</code>要对应不同版本的<code>node</code>,否则在安装的时候就会出现错误,需要重新 rebuild</li>
</ol>
<h2 id="微服务"><a href="#微服务" class="headerlink" title="微服务"></a>微服务</h2><p>docker 常常与 微服务架构 一起使用<br>这是一个简单的单机架构,当需求简单时,可以采用单机架构进行开发<br><img src="/images/essay-3/esay.jpg" alt="简单需求"></p>
<p>但是当需求开始复杂时,如果还用单机架构进行开发</p>
<p><img src="/images/essay-3/complex.jpg" alt="复杂需求"></p>
<p>这样的设计是不太合理的</p>
<ol>
<li>对于网站和移动端来说,有很多相同逻辑的业务代码</li>
<li>数据有时候通过数据库共享,有时候通过调用接口传输。接口调用关系混乱。</li>
<li>单个应用为了给其他应用提供不同的结构,逐渐越改越大,越来越多的 ifelse,功能归属混乱</li>
<li>数据库为多个应用提供数据支持,难以重构和优化</li>
<li>所有应用都在同一个数据库进行操作,当数据量庞大时,容易出现性能瓶颈,需要分库分表</li>
<li>部署、维护、开发困难,即使只改动一个功能,也需要整体应用一起发布。如果不小心带上未经测试的代码,也有可能出现意料之外的错误</li>
</ol>
<p>将服务进行拆分,让每个容器能够各司其职,只负责一小部分模块,然后将各个服务进行拼接起来就组成一个完整的服务,并且在更新代码时也只需要更新其中一个容器而不用对整个应用进行更新<br><img src="/images/essay-3/micro_service.jpg" alt="micro_service"></p>
<h2 id="镜像和容器"><a href="#镜像和容器" class="headerlink" title="镜像和容器"></a>镜像和容器</h2><p>从根本上来说,容器只是一个正在运行的进程,应用了一些添加的封装特性以便它能和主机以及其他容器分离开。对于容器隔离最重要的概念之一就是每个容器和它自身的文件系统交互。文件系统是由<code>docker image</code>来提供的。一个<code>image</code>包含了一切运行所需的东西– 代码或者二进制,运行依赖以及其他任何文件系统对象。</p>
<h2 id="容器连接"><a href="#容器连接" class="headerlink" title="容器连接"></a>容器连接</h2><p><code>docker</code>实例之间虽然都是互相隔离的,但是隔离的只是它们的环境,但是它们容器之前也需要互相联系,数据之间的传递,不然做拆分就没有任何的意义,用–link 来做容器之间的连接。同时在创建容器时需要设定好宿主机和容器之间的端口映射,这样可以通过访问宿主机的端口来访问容器的服务。<br>对于容器来说,如果把一些数据存放在容器中,那么当容器被删除时,那么存放在容器中的数据也会被删除,这是不合理的,所以数据应该放在宿主机中,然后映射进容器中,这样当容器被删除时,数据仍然存在于宿主机中</p>
<h2 id="DockerFile"><a href="#DockerFile" class="headerlink" title="DockerFile"></a>DockerFile</h2><p>想要把应用编写成一个 docker 镜像,需要编写 DokcerFile 文件</p>
<p>这是一个 dockerFile 文件例子</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">FROM php:7.4.8-fpm</span><br><span class="line">MAINTAINER liubucai</span><br><span class="line">ENV REDIS_VERSION=5.3.1</span><br><span class="line">ENV SWOOLE_VERSION=4.4.16</span><br><span class="line">ENV PROTOBUF_VERSION=0.12.3</span><br><span class="line">ENV PSR_VERSION=1.0.0</span><br><span class="line"></span><br><span class="line">RUN <span class="built_in">mv</span> /etc/apt/sources.list /etc/apt/sources.list.bak \</span><br><span class="line">&& <span class="built_in">echo</span> <span class="string">"deb http://mirrors.163.com/debian/ jessie main non-free contri</span></span><br><span class="line"><span class="string">b"</span> >> /etc/apt/sources.list \</span><br><span class="line">&& <span class="built_in">echo</span> <span class="string">"deb-src http://mirrors.163.com/debian/ jessie main non-free co</span></span><br><span class="line"><span class="string">ntrib"</span> >>/etc/apt/sources.list \</span><br><span class="line"><span class="comment"># \</span></span><br><span class="line">&& apt-get update && apt-get upgrade \</span><br><span class="line">&& <span class="built_in">printf</span> <span class="string">"%s %s %s %s %s\n"</span> Yes, <span class="keyword">do</span> as I say! | apt-get install libtin</span><br><span class="line">fo5=5.9+20140913-1+deb8u3 \</span><br><span class="line">&& apt-get install -y libncurses5 procps \</span><br><span class="line">&& <span class="built_in">printf</span> <span class="string">"%s %s %s %s %s\n"</span> Yes, <span class="keyword">do</span> as I say! | apt-get install zlib1g</span><br><span class="line">=1:1.2.8.dfsg-2+b1 \</span><br><span class="line">&& apt-get install -y libssl-dev libzip-dev wget zip vim \</span><br><span class="line"><span class="comment"># \</span></span><br><span class="line">&& docker-php-source extract \</span><br><span class="line">&& docker-php-ext-install bcmath sockets pdo_mysql pcntl opcache \</span><br><span class="line"><span class="comment"># \</span></span><br><span class="line">&& wget https://github.com/allegro/php-protobuf/archive/master.zip \</span><br><span class="line">&& unzip master.zip && <span class="built_in">rm</span> -rf master.zip \</span><br><span class="line">&& <span class="built_in">mv</span> php-protobuf-master /usr/src/php/ext/ \</span><br><span class="line">&& docker-php-ext-install php-protobuf-master \</span><br><span class="line">&& curl -sS https://getcomposer.org/installer | php \</span><br><span class="line">&& <span class="built_in">mv</span> composer.phar /usr/local/bin/composer \</span><br><span class="line">&& <span class="built_in">cd</span> /usr/src/php/ext/php-protobuf-master/ && composer install \</span><br><span class="line">&& wget https://github.com/protocolbuffers/protobuf/releases/download/v</span><br><span class="line">3.12.3/protobuf-php-3.12.3.zip \</span><br><span class="line">&& unzip protobuf-php-3.12.3.zip \</span><br><span class="line">&& <span class="built_in">cd</span> protobuf-3.12.3/ \</span><br><span class="line">&& ./configure --prefix=/usr/local/protobuf \</span><br><span class="line">&& make && make install \</span><br><span class="line">&& <span class="built_in">export</span> PATH=/usr/local/protobuf/bin:<span class="variable">$PATH</span> \</span><br><span class="line">&& apt-get -y install npm \</span><br><span class="line">&& npm install -g require && npm install -g browserify && npm install g</span><br><span class="line">oogle-protobuf \</span><br><span class="line"><span class="comment"># \</span></span><br><span class="line">&& pecl install redis-<span class="variable">${REDIS_VERSION}</span> && docker-php-ext-enable redis \</span><br><span class="line">&& <span class="built_in">echo</span> <span class="string">"install redis ok !"</span> \</span><br><span class="line"><span class="comment"># \</span></span><br><span class="line">&& <span class="built_in">printf</span> <span class="string">"yes\n yes\n yes\n yes\n"</span> | pecl install swoole-<span class="variable">${SWOOLE_VE</span></span><br><span class="line"><span class="variable">RSION}</span> \</span><br><span class="line">&& docker-php-ext-enable swoole \</span><br><span class="line">&& <span class="built_in">echo</span> <span class="string">"install swoole ok !"</span> \</span><br><span class="line"><span class="comment"># \</span></span><br><span class="line">&& pecl install psr-<span class="variable">${PSR_VERSION}</span> && docker-php-ext-enable psr \</span><br><span class="line">&& <span class="built_in">echo</span> <span class="string">"install psr ok !"</span> \</span><br><span class="line"><span class="comment"># \</span></span><br><span class="line">&& pecl install zip && docker-php-ext-enable zip</span><br><span class="line"><span class="comment">#VOLUME ["/var/log","/usr/local/etc/","/var/run","/var/www/html"]</span></span><br><span class="line">WORKDIR /var/www/html</span><br><span class="line"></span><br><span class="line">EXPOSE 9000</span><br><span class="line"><span class="comment">#CMD php-fpm -R -D && tail -f /dev/null</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h2 id="docker-compose"><a href="#docker-compose" class="headerlink" title="docker compose"></a>docker compose</h2><p>当宿主机中拥有几十个 docker 服务时,如果一个一个的执行<code>docker run</code> 无疑是很让人崩溃的以及怀疑世界 ing,因此可以采用 docker compose 才对 docker 实例进行管理,只要写好 docker compose 的配置文件, 然后执行 <code>docker compose start</code> 那么就会执行配置文件中的 docker 实例(假设宿主机中已经启动对应的容器)</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">version: <span class="string">'3'</span></span><br><span class="line">networks:</span><br><span class="line"> xxx-game-net:</span><br><span class="line"> driver: bridge <span class="comment"># 以网桥的形式连接docker</span></span><br><span class="line">services:</span><br><span class="line"> nginx:</span><br><span class="line"> image: nginx:latest <span class="comment"># 安装的版本</span></span><br><span class="line"> container_name: nginx-xxx</span><br><span class="line"> restart: always</span><br><span class="line"> ports:</span><br><span class="line"> - 6688:80</span><br><span class="line"> volumes: <span class="comment"># 映射配置文件到容器中</span></span><br><span class="line"> - ./conf/nginx/conf.d/:/etc/nginx/conf.d</span><br><span class="line"> - ../html:/usr/share/nginx/html</span><br><span class="line"> - ./log/nginx:/var/log/nginx</span><br><span class="line"> depends_on: <span class="comment"># 启动的依赖</span></span><br><span class="line"> - mysql</span><br><span class="line"> - redis</span><br><span class="line"> - php-fpm</span><br><span class="line"> networks:</span><br><span class="line"> - xxx-game-net</span><br><span class="line"> mysql:</span><br><span class="line"> image: mysql:latest</span><br><span class="line"> container_name: mysql-xxx</span><br><span class="line"> <span class="built_in">command</span>: --default-authentication-plugin=mysql_native_password</span><br><span class="line"> restart: always</span><br><span class="line"> ports:</span><br><span class="line"> - 6666:3306</span><br><span class="line"> volumes:</span><br><span class="line"> - ./conf/mysql/conf.d/:/etc/mysql/conf.d</span><br><span class="line"> - ./data/mysql:/var/lib/mysql</span><br><span class="line"> environment:</span><br><span class="line"> MYSQL_ROOT_PASSWORD: 123456</span><br><span class="line"> networks:</span><br><span class="line"> - xxx-game-net</span><br><span class="line">php-fpm:</span><br><span class="line"> build: .</span><br><span class="line"> container_name: php-fpm-xxx</span><br><span class="line"> volumes:</span><br><span class="line"> - ../:/data/www</span><br><span class="line"> networks:</span><br><span class="line"> - xxx-game-net</span><br><span class="line">redis:</span><br><span class="line"> image: redis:latest</span><br><span class="line"> container_name: redis-xxx</span><br><span class="line"> restart: always</span><br><span class="line"> ports:</span><br><span class="line"> - 6668:6379</span><br><span class="line"> volumes:</span><br><span class="line"> - ./data/redis:/data</span><br><span class="line"> networks:</span><br><span class="line"> - xxx-game-net</span><br></pre></td></tr></table></figure>
<p>—–OVER</p>
]]></content>
<categories>
<category>essay</category>
<category>docker</category>
</categories>
<tags>
<tag>docker</tag>
</tags>
</entry>
<entry>
<title>今日随笔(2020-10-11)</title>
<url>/2020/10/essay-5/</url>
<content><![CDATA[<h3 id="命令行文件的上传与下载"><a href="#命令行文件的上传与下载" class="headerlink" title="命令行文件的上传与下载"></a>命令行文件的上传与下载</h3><p>文件的上传和下载命令都是scp</p>
<p><strong>上传</strong><br>从服务器上下载文件 scp username@servername:/path/filename /Users/mac/Desktop(本地目录,例如:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">scp root@47.98.37.170:/root/test.txt /Users/mac/Desktop就是将服务器上的/root/test.txt下载到本地的/Users/mac/Desktop目录下。注意两个地址之间有空格!</span><br></pre></td></tr></table></figure>
<p><strong>下载</strong><br>上传本地文件到服务器 scp /path/filename username@servername:/path ;</p>
<p>note: 下载命令就是将两个路径换一个位置就行了。</p>
<h3 id="TS-4-0的一些更新"><a href="#TS-4-0的一些更新" class="headerlink" title="TS 4.0的一些更新"></a>TS 4.0的一些更新</h3><h4 id="类型解构"><a href="#类型解构" class="headerlink" title="类型解构"></a>类型解构</h4><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">type</span> Strings = [string, string];</span><br><span class="line"><span class="built_in">type</span> Numbers = number[]</span><br><span class="line"></span><br><span class="line"><span class="built_in">type</span> Unbounded = [...Strings, ...Numbers, boolean];</span><br><span class="line"><span class="comment"># // [string, string, ...Array<number | boolean>]</span></span><br><span class="line"><span class="comment"># 按照官方的解释就是解构一个已知长度的类型的时候,那么最后的结果类型也是没有任何限制的,在解构类型之后添加的类型声明都要添加到被解构类型的类型中去</span></span><br></pre></td></tr></table></figure>
<p>—待续哈,明天更新</p>
]]></content>
<tags>
<tag>TypeScript Upload</tag>
</tags>
</entry>
<entry>
<title>今日随笔(8-6)</title>
<url>/2020/08/essay-4/</url>
<content><![CDATA[<p>先看代码</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">const a = 1</span><br><span class="line">[...[1,2,3]].forEach(item=>console.log(item))</span><br></pre></td></tr></table></figure>
<p>乍一看,是不是感觉挺正常的,在浏览器的log窗口应该能输出1,2,3,才对<br>然后在浏览器跑一下,发现</p>
<p><img src="/images/essay-4/unexpected_error.png.png" alt="error"></p>
<p>然后emm排查了一下,语法是没问题的,浏览器版本是最新的开发版本,es6的语法肯定是支持的,那问题其实就是a=1 后面漏了分号,所以代码就成了这样</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">const a = 1[...[1,2,3]].forEach(item=>console.log(item))</span><br></pre></td></tr></table></figure>
<p>那代码成了这样那肯定不能正确解析了~</p>
<p>果然,漏写分号不是好习惯~</p>
]]></content>
</entry>
<entry>
<title>今日随笔(2020-12-27)</title>
<url>/2020/12/essay-6/</url>
<content><![CDATA[<ol>
<li>在vue ts class给数组添加值时报错<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">export</span> default class App{</span><br><span class="line"> list =[]</span><br><span class="line"> <span class="function"><span class="title">_push</span></span>(){</span><br><span class="line"> this.list.push(1)</span><br><span class="line"> <span class="comment"># error </span></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
由于定义的list是never类型的数组,所以不能够直接添加元素,所以在定义数组的时候需要显示定义类型<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">list = [] as number[]</span><br></pre></td></tr></table></figure></li>
<li>line-height 属性同样会影响伪元素的高度</li>
<li>ts class 自定义vue双向绑定<br>v-model默认监听input事件,如果是checkbox或者radio<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">@Modle(<span class="string">'change'</span>) value:any</span><br><span class="line"><span class="comment"># 这样vue会监听change,$emit('change')改变外部绑定的值</span></span><br></pre></td></tr></table></figure></li>
</ol>
]]></content>
</entry>
<entry>
<title>今日随笔</title>
<url>/2021/01/essay-7/</url>
<content><![CDATA[<p><img src="/images/essay-7/essay.png" alt="essay"></p>
]]></content>
</entry>
<entry>
<title>今日随笔(1-31)</title>
<url>/2021/01/essay-8/</url>
<content><![CDATA[<h3 id="null-vs-undefined"><a href="#null-vs-undefined" class="headerlink" title="null vs undefined"></a>null vs undefined</h3><p>The ECMAScript language specification describes them as follows:</p>
<ul>
<li>undefined 是被使用但是没有被赋值</li>
<li>null 是对变量一个显示对声明一个值</li>
</ul>
<p>在JS中,每个变量能够同时被赋值引用类型和原始类型。因此,如果null意味着 不是一个对象,JS也需要一个初值意味着 既不是 引用类型 也不是 原始类型。那个值就是undefined。</p>
<span id="more"></span>
<p>If a variable myVar has not been initialized yet, its value is undefined:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">let</span> myVar;</span><br><span class="line">assert.equal(myVar, undefined);</span><br></pre></td></tr></table></figure>
<p>If a property .unknownProp is missing, accessing the property produces the values undefined:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">const obj = {};</span><br><span class="line">assert.equal(obj.unknownProp, undefined);</span><br></pre></td></tr></table></figure>
<p>If a function does not explicitly return anything, the function implicitly returns undefined:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="function"><span class="title">myFunc</span></span>() {}</span><br><span class="line">assert.equal(myFunc(), undefined);</span><br></pre></td></tr></table></figure>
<p>If a function has a return statement without an argument, the function implicitly returns undefined:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="function"><span class="title">myFunc</span></span>() {</span><br><span class="line"> <span class="built_in">return</span>;</span><br><span class="line">}</span><br><span class="line">assert.equal(myFunc(), undefined);</span><br></pre></td></tr></table></figure>
<p>If a parameter x is omitted, the language initializes that parameter with undefined:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="keyword">function</span> myFunc(x) {</span><br><span class="line"> assert.equal(x, undefined);</span><br><span class="line">}</span><br><span class="line">myFunc();</span><br></pre></td></tr></table></figure>
<p>Optional chaining via obj?.someProp returns undefined if obj is undefined or null:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"> > undefined?.someProp</span><br><span class="line">undefined</span><br><span class="line">> null?.someProp</span><br><span class="line">undefined</span><br></pre></td></tr></table></figure>
<p>The prototype of an object is either an object or, at the end of a chain of prototypes, null. Object.prototype does not have a prototype:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">> Object.getPrototypeOf(Object.prototype)</span><br><span class="line">null</span><br></pre></td></tr></table></figure>
<p>If we match a regular expression (such as /a/) against a string (such as ‘x’), we either get an object with matching data (if matching was successful) or null (if matching failed)(有结果就返回匹配对象,没结果返回null):</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">> /a/.exec(<span class="string">'x'</span>)</span><br><span class="line">null</span><br></pre></td></tr></table></figure>
<p>The JSON data format does not support undefined, only null:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">> JSON.stringify({a: undefined, b: null})</span><br><span class="line"><span class="string">'{"b":null}'</span></span><br></pre></td></tr></table></figure>
<h3 id="Operators-that-treat-undefined-and-x2F-or-null-specially"><a href="#Operators-that-treat-undefined-and-x2F-or-null-specially" class="headerlink" title="Operators that treat undefined and/or null specially"></a>Operators that treat undefined and/or null specially</h3><h4 id="undefined-and-parameter-default-values"><a href="#undefined-and-parameter-default-values" class="headerlink" title="undefined and parameter default values"></a>undefined and parameter default values</h4><p>参数默认值的使用情况:</p>
<ul>
<li>参数没传</li>
<li>参数的值是undefined</li>
</ul>
<p>For example</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="keyword">function</span> myFunc(arg=<span class="string">'abc'</span>) {</span><br><span class="line"> <span class="built_in">return</span> arg;</span><br><span class="line">}</span><br><span class="line">assert.equal(myFunc(<span class="string">'hello'</span>), <span class="string">'hello'</span>);</span><br><span class="line">assert.equal(myFunc(), <span class="string">'abc'</span>);</span><br><span class="line">assert.equal(myFunc(undefined), <span class="string">'abc'</span>);</span><br></pre></td></tr></table></figure>
<h4 id="undefined-and-destructuring-default-values"><a href="#undefined-and-destructuring-default-values" class="headerlink" title="undefined and destructuring default values"></a>undefined and destructuring default values</h4><p>解构给默认值跟参数给默认值一样,匹配到undefined给默认值<br>Default values in destructuring work similarly to parameter default values – they are used if a variable either has no match in the data or if it matches undefined:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">const [a=<span class="string">'a'</span>] = [];</span><br><span class="line">assert.equal(a, <span class="string">'a'</span>);</span><br><span class="line"></span><br><span class="line">const [b=<span class="string">'b'</span>] = [undefined];</span><br><span class="line">assert.equal(b, <span class="string">'b'</span>);</span><br><span class="line"></span><br><span class="line">const {prop: c=<span class="string">'c'</span>} = {};</span><br><span class="line">assert.equal(c, <span class="string">'c'</span>);</span><br><span class="line"></span><br><span class="line">const {prop: d=<span class="string">'d'</span>} = {prop: undefined};</span><br><span class="line">assert.equal(d, <span class="string">'d'</span>);</span><br></pre></td></tr></table></figure>
<h4 id="undefined-and-null-and-optional-chaining"><a href="#undefined-and-null-and-optional-chaining" class="headerlink" title="undefined and null and optional chaining"></a>undefined and null and optional chaining</h4><p>When there is optional chaining via value?.prop:</p>
<ul>
<li>If value is undefined or null, return undefined. That is, this happens whenever value.prop would throw an exception.</li>
<li>Otherwise, return value.prop.</li>
</ul>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="keyword">function</span> getProp(value) {</span><br><span class="line"> <span class="comment"># optional static property access</span></span><br><span class="line"> <span class="built_in">return</span> value?.prop;</span><br><span class="line">}</span><br><span class="line">assert.equal(</span><br><span class="line"> getProp({prop: 123}), 123);</span><br><span class="line">assert.equal(</span><br><span class="line"> getProp(undefined), undefined);</span><br><span class="line">assert.equal(</span><br><span class="line"> getProp(null), undefined);</span><br></pre></td></tr></table></figure>
<p>The following two operations work similarly:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">obj?.[«<span class="built_in">expr</span>»] // optional dynamic property access</span><br><span class="line">func?.(«arg0», «arg1») // optional <span class="keyword">function</span> or method call</span><br></pre></td></tr></table></figure>
<h4 id="undefined-and-null-and-nullish-coalescing"><a href="#undefined-and-null-and-nullish-coalescing" class="headerlink" title="undefined and null and nullish coalescing"></a>undefined and null and nullish coalescing</h4><p>nullish coalescing 的使用比较 简单,如果值是undefined 或者null的时候取后者</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">> undefined ?? <span class="string">'default value'</span></span><br><span class="line"><span class="string">'default value'</span></span><br><span class="line">> null ?? <span class="string">'default value'</span></span><br><span class="line"><span class="string">'default value'</span></span><br><span class="line"></span><br><span class="line">> 0 ?? <span class="string">'default value'</span></span><br><span class="line">0</span><br><span class="line">> 123 ?? <span class="string">'default value'</span></span><br><span class="line">123</span><br><span class="line">> <span class="string">''</span> ?? <span class="string">'default value'</span></span><br><span class="line"><span class="string">''</span></span><br><span class="line">> <span class="string">'abc'</span> ?? <span class="string">'default value'</span></span><br><span class="line"><span class="string">'abc'</span></span><br></pre></td></tr></table></figure>
<p>The nullish coalescing assignment operator ??= combines nullish coalescing with assignment:</p>
<p>??= 就是把 取值和赋值合起来</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="keyword">function</span> setName(obj) {</span><br><span class="line"> obj.name ??= <span class="string">'(Unnamed)'</span>;</span><br><span class="line"> <span class="built_in">return</span> obj;</span><br><span class="line">}</span><br><span class="line">assert.deepEqual(</span><br><span class="line"> setName({}),</span><br><span class="line"> {name: <span class="string">'(Unnamed)'</span>}</span><br><span class="line">);</span><br><span class="line">assert.deepEqual(</span><br><span class="line"> setName({name: undefined}),</span><br><span class="line"> {name: <span class="string">'(Unnamed)'</span>}</span><br><span class="line">);</span><br><span class="line">assert.deepEqual(</span><br><span class="line"> setName({name: null}),</span><br><span class="line"> {name: <span class="string">'(Unnamed)'</span>}</span><br><span class="line">);</span><br><span class="line">assert.deepEqual(</span><br><span class="line"> setName({name: <span class="string">'Jane'</span>}),</span><br><span class="line"> {name: <span class="string">'Jane'</span>}</span><br><span class="line">);</span><br></pre></td></tr></table></figure>]]></content>
<tags>
<tag>JavaScript</tag>
</tags>
</entry>
<entry>
<title>今日随笔(2-10)</title>
<url>/2021/02/essay-9/</url>
<content><![CDATA[<h4 id="NaN-和-Number-isNaN"><a href="#NaN-和-Number-isNaN" class="headerlink" title="NaN 和 Number.isNaN"></a>NaN 和 Number.isNaN</h4><hr>
<p>全局属性 NaN 的值表示不是一个数字(Not-A-Number)。</p>
<p>NaN 属性的初始值就是 NaN,和 Number.NaN 的值一样。在现代浏览器中(ES5中), NaN 属性是一个不可配置(non-configurable),不可写(non-writable)的属性。但在ES3中,这个属性的值是可以被更改的,但是也应该避免覆盖。 — mdn</p>
<span id="more"></span>
<p>NaN是唯一一个自身不相等的数字,判断一个值是否是NaN,主要是用两种方法来判断,一个是NaN,一个是Number.isNaN。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">NaN === NaN; // <span class="literal">false</span></span><br><span class="line">Number.NaN === NaN; // <span class="literal">false</span></span><br><span class="line">isNaN(NaN); // <span class="literal">true</span></span><br><span class="line">isNaN(Number.NaN); // <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> valueIsNaN(v) { <span class="built_in">return</span> v !== v; }</span><br><span class="line">valueIsNaN(1); // <span class="literal">false</span></span><br><span class="line">valueIsNaN(NaN); // <span class="literal">true</span></span><br><span class="line">valueIsNaN(Number.NaN); // <span class="literal">true</span></span><br></pre></td></tr></table></figure>
<p>对于两个方法还是有所不同的:如果当前值是NaN,或者将其强制转换为数字后将是NaN,则前者将返回true。而后者仅当值当前为NaN时才为true:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">isNaN(<span class="string">'hello world'</span>); // <span class="literal">true</span> <span class="string">'hello world'</span>转数字失败变成NaN。</span><br><span class="line">Number.isNaN(<span class="string">'hello world'</span>); // <span class="literal">false</span></span><br></pre></td></tr></table></figure>
<p>对于NaN方法:</p>
<ul>
<li>Let num be ? ToNumber(number).</li>
<li>If num is NaN, return true.</li>
<li>Otherwise, return false.</li>
</ul>
<p>而对于Number.isNaN来说:</p>
<ul>
<li>If Type(number) is not Number, return false.</li>
<li>If number is NaN, return true.</li>
<li>Otherwise, return false.</li>
</ul>
<p>可以看到规范中定义的两个方法在第一步中对传递进来对参数的处理方式并不一样。因此这两个方法是有所区别的。</p>
]]></content>
<tags>
<tag>JavaScript</tag>
</tags>
</entry>
<entry>
<title>今日随笔</title>
<url>/2021/12/essay12-22/</url>
<content><![CDATA[<p><img src="/images/essay12-22/xianxiang.png" alt="现象"></p>
<p>全局调用g函数发现this为undefined,按照我的理解在全局调用的函数this应该是指向windows,然而这里却输出的是undefined<br>因此我去查了资料,发现在规范上是这么写的</p>
<p><img src="/images/essay12-22/class.jpg" alt="class"><br>如果所示class中默认为严格模式,而在严格模式中,未指明this指向的话this是等于undefined的,this是在运行时确定的,而不是在声明的时候确定的,因此这里的<code>g()</code>在全局环境中调用未指明this指向,因此此时输出undefined。<br><img src="/images/essay12-22/function.jpg" alt="function"><br>而在function中是可以指定是否是严格模式的</p>
]]></content>
<tags>
<tag>TypeScript</tag>
<tag>Class</tag>
<tag>This</tag>
</tags>
</entry>
<entry>
<title>排序算法</title>
<url>/2022/01/essay2022-1-13/</url>
<content><![CDATA[<h3 id="冒泡排序"><a href="#冒泡排序" class="headerlink" title="冒泡排序"></a>冒泡排序</h3><p>每次排序找到最大的那个</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">bubble</span>(<span class="params">arr</span>){</span><br><span class="line"> <span class="keyword">let</span> swapped = <span class="literal">false</span></span><br><span class="line"> <span class="keyword">do</span>{</span><br><span class="line"> swapped = <span class="literal">false</span></span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">let</span> i =<span class="number">0</span>;i<arr.<span class="property">length</span>-<span class="number">1</span>;i++){</span><br><span class="line"> <span class="keyword">if</span>(arr[i] > arr[i+<span class="number">1</span>]){</span><br><span class="line"> [arr[i],arr[i+<span class="number">1</span>]] =[arr[i+<span class="number">1</span>],arr[i]]</span><br><span class="line"> swapped = <span class="literal">true</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }<span class="keyword">while</span>(swapped)</span><br><span class="line"> <span class="keyword">return</span> arr</span><br><span class="line">}</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">bubble</span>([<span class="number">9</span>,<span class="number">6</span>,<span class="number">3</span>,<span class="number">6</span>,<span class="number">8</span>,<span class="number">0</span>,<span class="number">6</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">5</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"> 0, 2, 3, 3, 5,</span></span><br><span class="line"><span class="comment"> 6, 6, 6, 8, 9</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><br></pre></td></tr></table></figure>
<span id="more"></span>
<h3 id="选择排序"><a href="#选择排序" class="headerlink" title="选择排序"></a>选择排序</h3><p>每次循环要跟当前循环的最小值交换数据</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">selectionsort</span>(<span class="params">arr</span>){</span><br><span class="line"> <span class="keyword">const</span> len = arr.<span class="property">length</span>;</span><br><span class="line"> <span class="keyword">let</span> sortIndex = <span class="number">0</span></span><br><span class="line"> <span class="keyword">while</span>(sortIndex < len){</span><br><span class="line"> <span class="comment">// 将第一个没有排序的元素设置为最小值</span></span><br><span class="line"> <span class="comment">// let min = arr[sortIndex]</span></span><br><span class="line"> <span class="keyword">let</span> minIndex = sortIndex</span><br><span class="line"> <span class="comment">// 遍历每个没有排序过的元素</span></span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">let</span> i=sortIndex;i<len;i++){</span><br><span class="line"> <span class="comment">// 更新最小值</span></span><br><span class="line"> <span class="keyword">if</span>(arr[i] < arr[minIndex]){</span><br><span class="line"> minIndex = i</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> }</span><br><span class="line"> [arr[sortIndex],arr[minIndex]] = [arr[minIndex],arr[sortIndex]]</span><br><span class="line"> sortIndex++</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> arr</span><br><span class="line">}</span><br><span class="line"><span class="title function_">selectionsort</span>([<span class="number">45</span>,</span><br><span class="line"> <span class="number">50</span>,</span><br><span class="line"> <span class="number">32</span>,</span><br><span class="line"> <span class="number">4</span>,</span><br><span class="line"> <span class="number">37</span>,</span><br><span class="line"> <span class="number">10</span>,</span><br><span class="line"> <span class="number">47</span>,</span><br><span class="line"> <span class="number">44</span>,</span><br><span class="line"> <span class="number">17</span>,</span><br><span class="line"> <span class="number">38</span>,</span><br><span class="line"> <span class="number">26</span>,</span><br><span class="line"> <span class="number">25</span>,</span><br><span class="line"> <span class="number">37</span>,</span><br><span class="line"> <span class="number">17</span>,</span><br><span class="line"> <span class="number">1</span>,</span><br><span class="line"> <span class="number">3</span>,</span><br><span class="line"> <span class="number">7</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"> 1, 3, 4, 7, 10, 17, 17,</span></span><br><span class="line"><span class="comment"> 25, 26, 32, 37, 37, 38, 44,</span></span><br><span class="line"><span class="comment"> 45, 47, 50</span></span><br><span class="line"><span class="comment">]</span></span><br><span class="line"><span class="comment"> * /</span></span><br></pre></td></tr></table></figure>
<h3 id="插入排序"><a href="#插入排序" class="headerlink" title="插入排序"></a>插入排序</h3><figure class="highlight js"><table><tr><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">insertsort</span>(<span class="params">arr</span>){</span><br><span class="line"> <span class="keyword">let</span> sortIndex = <span class="number">0</span></span><br><span class="line"> <span class="keyword">const</span> len = arr.<span class="property">length</span></span><br><span class="line"> <span class="comment">// 遍历每个没有排序过的元素ß </span></span><br><span class="line"> <span class="keyword">while</span>(sortIndex < len){</span><br><span class="line"> <span class="keyword">let</span> currentIndex = sortIndex </span><br><span class="line"> <span class="keyword">const</span> x = arr[currentIndex] </span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">let</span> i = sortIndex-<span class="number">1</span>;i>=<span class="number">0</span>;i--){</span><br><span class="line"> <span class="keyword">if</span>(x < arr[i]){</span><br><span class="line"> <span class="comment">// 元素交换之后更新索引,将较小的元素往左移动</span></span><br><span class="line"> [arr[i],arr[currentIndex]] = [arr[currentIndex],arr[i]]</span><br><span class="line"> currentIndex = i</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> sortIndex++</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> arr</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>应该还有几个排序。。。等这段时间忙完再补上</p>
]]></content>
</entry>
<entry>
<title>今日随笔</title>
<url>/2021/12/essay12-29/</url>
<content><![CDATA[<h3 id="同源策略"><a href="#同源策略" class="headerlink" title="同源策略"></a>同源策略</h3><p>同源的定义:如果两个 URL 的 protocol、port (en-US) (如果有指定的话)和 host 都相同的话,则这两个 URL 是同源。这个方案也被称为“协议/主机/端口元组”,或者直接是 “元组”。(“元组” 是指一组项目构成的整体,双重/三重/四重/五重/等的通用形式)。</p>
<h3 id="哪些请求不受同源策略控制"><a href="#哪些请求不受同源策略控制" class="headerlink" title="哪些请求不受同源策略控制"></a>哪些请求不受同源策略控制</h3><p>image(对一半),script嵌入的跨域脚本 , link,video和audio加载的媒体资源,applet等嵌入的插件,@font-face引入的字体 and iframe载入的任何资源</p>
<h4 id="为什么不受控制"><a href="#为什么不受控制" class="headerlink" title="为什么不受控制"></a>为什么不受控制</h4><p>so 要提到浏览器的跨域网络访问</p>
<p>同源策略控制不同源之间的交互,例如在使用XMLHttpRequest 或 <img> 标签时则会受到同源策略的约束。这些交互通常分为三类:</p>
<ul>
<li>跨域写操作(Cross-origin writes)一般是被允许的。例如链接(links),重定向以及表单提交。特定少数的HTTP请求需要添加 preflight。</li>
<li>跨域资源嵌入(Cross-origin embedding)一般是被允许(后面会举例说明)。</li>
<li>跨域读操作(Cross-origin reads)一般是不被允许的,但常可以通过内嵌资源来巧妙的进行读取访问。例如,你可以读取嵌入图片的高度和宽度,调用内嵌脚本的方法,或availability of an embedded resource.</li>
</ul>
<h4 id="允许跨域访问"><a href="#允许跨域访问" class="headerlink" title="允许跨域访问"></a>允许跨域访问</h4><ul>
<li>用cors</li>
<li>nginx</li>
<li>webpack的devserver</li>
</ul>
<h4 id="题外话"><a href="#题外话" class="headerlink" title="题外话"></a>题外话</h4><p>如果在canvas调用drawImage跨域的image,canvas是不能把图片导出成base64d,需要给图片添加<code>crossOrigin=anonymous</code>,这样canvas写入的图片才能正确被导出。</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">The image is then configured to allow cross-origin downloading by setting its crossOrigin attribute to "Anonymous"</span><br></pre></td></tr></table></figure>
<p>引入mdn的解释,图片在设置了这个属性之后就被配置成允许跨域下载了。</p>
]]></content>
<tags>
<tag>同源策略</tag>
</tags>
</entry>
<entry>
<title>理解 flex-basis</title>
<url>/2020/11/flex/</url>
<content><![CDATA[<p>上个html代码</p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"parent"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"child"</span>></span>Child<span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"child"</span>></span>Child<span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"child"</span>></span>Child<span class="tag"></<span class="name">div</span>></span></span><br><span class="line"><span class="tag"></<span class="name">div</span>></span></span><br></pre></td></tr></table></figure>
<p>css≠</p>
<figure class="highlight css"><table><tr><td class="code"><pre><span class="line"><span class="selector-class">.parent</span> {</span><br><span class="line"> <span class="attribute">display</span>: flex;</span><br><span class="line">}</span><br><span class="line"><span class="selector-class">.child</span> {</span><br><span class="line"> <span class="attribute">flex</span>: <span class="number">0</span> <span class="number">1</span> auto; <span class="comment">/* Default flex value */</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<html>
<style>
body{
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}
}
.parent {
display: flex;
}
.child {
flex: 0 1 auto; /* Default flex value */
/* 上面的代码相当于是
*flex-grow:0; flex-shrink:1;flex-basis:auto;s
*
*/
}
.child-grow{
flex:1 0 auto;
}
.child-flex{
flex:1 1 auto
}
</style>
<div class="parent">
<div class="child">Child</div>
<div class="child">Child</div>
<div class="child">Child</div>
</div>
</html>
<figure class="highlight css"><table><tr><td class="code"><pre><span class="line"><span class="selector-class">.child</span> {</span><br><span class="line"> <span class="attribute">flex</span>: [flex-grow] [flex-shrink] [flex-basis];</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><span id="showCssText"><span></p>
<p><button id="toggle">toggle</button></p>
<script>
const btn = document.getElementById("toggle");
btn.addEventListener('click',function(){
const span = document.getElementById('showCssText');
[...document.getElementsByClassName('child')].forEach(item=>{
const classList = item.classList;
// console.log(classList)
if(classList.length === 1 ){
classList.add('child-grow')
span.innerText = 'flex:1 0 auto;'
}else if(classList.length === 2){
classList.add('child-flex')
span.innerText = 'flex:1 1 auto'
}else{
classList.remove('child-flex')
classList.remove('child-grow')
span.innerText = 'flex: 0 1 auto; '
}
})
})
</script>
<p>flex-basic 默认是auto,告诉元素保持一个理想的尺寸;但是默认情况下的元素宽度是多少?auto告诉元素它的宽度由它的内容决定。为了让子元素占据父元素的所有空间,可以给子元素的宽度设置为<code>width:100%</code>,或者<code>flex-basis:100%</code>,或者<code>flex-grow:1</code>。假如有个宽为700px的容器,里面两个子元素分别设置了<code>flex-basic:200px</code>和<code>flex-basic:300px</code>,那么占据空间的计算会以700 - 200 - 300 之后再进行分配空间。</p>
<p>当给flex 的第三值 ,也就是 flex-basis 设置成1000px时,它会试着占据1000px的空间,如果不行,它会等比例占据其他元素的空间,但是其他元素内的文本长度同样会影响这个元素的位置分配;但是在更小的屏幕上可能会发现实际宽度并没有1000px,这是因为给了shrink,这个值告诉元素需要它等值缩小</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">.child-three {</span><br><span class="line"> flex: 0 1 1000px;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>如果grow 和 shrink都是0,那么元素不会等比例压缩,basis如果超出父元素宽度,那直接超出</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">.child-three {</span><br><span class="line"> flex: 0 0 1000px;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<tags>
<tag>css</tag>
</tags>
</entry>
<entry>
<title>git常用命令集合</title>
<url>/2019/08/git-command/</url>
<content><![CDATA[<h5 id="查看当前工作区状态"><a href="#查看当前工作区状态" class="headerlink" title="查看当前工作区状态"></a>查看当前工作区状态</h5><p><code>git status </code></p>
<h5 id="提交当前工作区文件到暂存区"><a href="#提交当前工作区文件到暂存区" class="headerlink" title="提交当前工作区文件到暂存区"></a>提交当前工作区文件到暂存区</h5><p><code>git add</code></p>
<h5 id="提交暂存区的修改到当前分支"><a href="#提交暂存区的修改到当前分支" class="headerlink" title="提交暂存区的修改到当前分支"></a>提交暂存区的修改到当前分支</h5><p><code>git commit </code></p>
<span id="more"></span>
<h5 id="把当前分支提交的修改推送到远程仓库去"><a href="#把当前分支提交的修改推送到远程仓库去" class="headerlink" title="把当前分支提交的修改推送到远程仓库去"></a>把当前分支提交的修改推送到远程仓库去</h5><p><code>git push origin master</code></p>
<h5 id="查看仓库提交记录"><a href="#查看仓库提交记录" class="headerlink" title="查看仓库提交记录"></a>查看仓库提交记录</h5><p><code>git log</code></p>
<h5 id="回退提交记录和工作区"><a href="#回退提交记录和工作区" class="headerlink" title="回退提交记录和工作区"></a>回退提交记录和工作区</h5><p><code>git reset --hard <commitid></code></p>
<h5 id="回退提交记录"><a href="#回退提交记录" class="headerlink" title="回退提交记录"></a>回退提交记录</h5><p><code>git reset --soft <commitid></code></p>
<h5 id="保存当前尚未添加到暂存区以及尚未提交到本地分支的代码-一般用于当修改文件的时候突然想要拉取远程仓库代码的尴尬情况-,stash是本地的,当push-pull的时候不会把statsh的代码传输到远程仓库去"><a href="#保存当前尚未添加到暂存区以及尚未提交到本地分支的代码-一般用于当修改文件的时候突然想要拉取远程仓库代码的尴尬情况-,stash是本地的,当push-pull的时候不会把statsh的代码传输到远程仓库去" class="headerlink" title="保存当前尚未添加到暂存区以及尚未提交到本地分支的代码(一般用于当修改文件的时候突然想要拉取远程仓库代码的尴尬情况),stash是本地的,当push pull的时候不会把statsh的代码传输到远程仓库去"></a>保存当前尚未添加到暂存区以及尚未提交到本地分支的代码(一般用于当修改文件的时候突然想要拉取远程仓库代码的尴尬情况),stash是本地的,当push pull的时候不会把statsh的代码传输到远程仓库去</h5><p><code>git stash</code></p>
<h5 id="在工作区显示刚刚在statsh保存的代码以及文件"><a href="#在工作区显示刚刚在statsh保存的代码以及文件" class="headerlink" title="在工作区显示刚刚在statsh保存的代码以及文件"></a>在工作区显示刚刚在statsh保存的代码以及文件</h5><p><code>git stash apply</code></p>
<h5 id="查看保存在stash的记录"><a href="#查看保存在stash的记录" class="headerlink" title="查看保存在stash的记录"></a>查看保存在stash的记录</h5><p><code>git stash list</code></p>
<h5 id="撤销某一个操作,并且把当前撤销操作当成一次新的commit提交"><a href="#撤销某一个操作,并且把当前撤销操作当成一次新的commit提交" class="headerlink" title="撤销某一个操作,并且把当前撤销操作当成一次新的commit提交"></a>撤销某一个操作,并且把当前撤销操作当成一次新的commit提交</h5><p><code>git revert HEAD|<commitid></code></p>
<h5 id="删除远程分支"><a href="#删除远程分支" class="headerlink" title="删除远程分支"></a>删除远程分支</h5><p><code>git push origin --delete <branchName></code></p>
<h5 id="删除本地分支"><a href="#删除本地分支" class="headerlink" title="删除本地分支"></a>删除本地分支</h5><p><code>git branch -d|-D <branchName></code></p>
<h5 id="查看本地分支"><a href="#查看本地分支" class="headerlink" title="查看本地分支"></a>查看本地分支</h5><p><code>git branch</code></p>
<h5 id="查看远程分支"><a href="#查看远程分支" class="headerlink" title="查看远程分支"></a>查看远程分支</h5><p><code>git branch -a</code></p>
<h5 id="切换分支(如果本地要新建并且切换一个新的分支,要新加上-b参数,查看分支不需要加-b参数)"><a href="#切换分支(如果本地要新建并且切换一个新的分支,要新加上-b参数,查看分支不需要加-b参数)" class="headerlink" title="切换分支(如果本地要新建并且切换一个新的分支,要新加上-b参数,查看分支不需要加-b参数)"></a>切换分支(如果本地要新建并且切换一个新的分支,要新加上-b参数,查看分支不需要加-b参数)</h5><p><code>git checkout (-b) <branchName></code></p>
<h5 id="删除文件"><a href="#删除文件" class="headerlink" title="删除文件"></a>删除文件</h5><p><code>git rm <fileName></code></p>
<h5 id="删除文件夹"><a href="#删除文件夹" class="headerlink" title="删除文件夹"></a>删除文件夹</h5><p><code>git rm -r <fileName></code></p>
<h5 id="下载指定仓库-这个就不用多说了"><a href="#下载指定仓库-这个就不用多说了" class="headerlink" title="下载指定仓库(这个就不用多说了)"></a>下载指定仓库(这个就不用多说了)</h5><p><code>git clone <repoUrl></code></p>
<h5 id="添加子模块到当前仓库中"><a href="#添加子模块到当前仓库中" class="headerlink" title="添加子模块到当前仓库中"></a>添加子模块到当前仓库中</h5><p><code>git submodule add <repo url></code></p>
<h5 id="clone带有子模块的仓库时需要更新子模块"><a href="#clone带有子模块的仓库时需要更新子模块" class="headerlink" title="clone带有子模块的仓库时需要更新子模块"></a>clone带有子模块的仓库时需要更新子模块</h5><p><code>git submodule update --init --recursive</code></p>
<h5 id="初始化本地仓库"><a href="#初始化本地仓库" class="headerlink" title="初始化本地仓库"></a>初始化本地仓库</h5><p><code>git init</code></p>
<h5 id="添加远程仓库"><a href="#添加远程仓库" class="headerlink" title="添加远程仓库"></a>添加远程仓库</h5><p><code>git remote add [option_name] [repo_url]</code></p>
<h5 id="从远程仓库拉取文件"><a href="#从远程仓库拉取文件" class="headerlink" title="从远程仓库拉取文件"></a>从远程仓库拉取文件</h5><p><code>git pull origin master</code><br><code>git pull origin master --allow-unrelated-histories</code></p>
<h5 id="查看远程仓库地址"><a href="#查看远程仓库地址" class="headerlink" title="查看远程仓库地址"></a>查看远程仓库地址</h5><p><code>git remote -v</code></p>
<html>
<head>
<style>
.weather {
width: 100%;
height: 500px;
/* background: #212125; */
display: flex;
justify-content: flex-start;
align-content: center;
color: #e6e8db;
}
.cloudy {
position: relative;
width: 300px;
height: 300px;
border-radius: 100%;
background: linear-gradient(to top right, #1b9ce2 0, #e0e2e5 90%);
box-shadow: 0 0 0 10px currentColor inset, 0 0 100px -10px;
}
.cloud {
position: absolute;
top: 25%;
left: 40%;
width: 100px;
height: 30px;