-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathatom.xml
More file actions
1146 lines (1002 loc) · 388 KB
/
atom.xml
File metadata and controls
1146 lines (1002 loc) · 388 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Sagittarius Love Libra</title>
<link href="/atom.xml" rel="self"/>
<link href="http://www.i0011.com/"/>
<updated>2017-06-24T05:45:16.000Z</updated>
<id>http://www.i0011.com/</id>
<author>
<name>徐祁</name>
<email>github.xq@gmail.com</email>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>lodash源码祭</title>
<link href="http://www.i0011.com/2017/04/03/lodash/"/>
<id>http://www.i0011.com/2017/04/03/lodash/</id>
<published>2017-04-03T14:08:37.000Z</published>
<updated>2017-06-24T05:45:16.000Z</updated>
<content type="html"><![CDATA[<blockquote>
<p>巧妙的函数实现吸引着你想去看看他的实现方法,里面会有更多奇思妙想让你欣喜若狂…</p>
</blockquote>
<h1 id="Array"><a href="#Array" class="headerlink" title="Array"></a>Array</h1><h2 id="chunk"><a href="#chunk" class="headerlink" title="chunk"></a>chunk</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.chunk(array, [size=1])</div></pre></td></tr></table></figure>
<p>猜想下实现方法,功能就是将数组拆分成<code>arrar.length / size</code>个数组,每个数组<code>size</code>个元素,剩余的元素作为最后一个分组,数组操作中<code>slice</code>不改变原数组并实现数组切分:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> chunk = <span class="function">(<span class="params">array, size = <span class="number">1</span></span>) =></span> {</div><div class="line"> <span class="keyword">let</span> count = <span class="built_in">Math</span>.ceil(array.length / size);</div><div class="line"></div><div class="line"> <span class="keyword">let</span> _chunk = <span class="keyword">new</span> <span class="built_in">Array</span>(count);</div><div class="line"></div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"> <span class="keyword">let</span> start = <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">while</span> (++index < count) {</div><div class="line"> _chunk[index] = array.slice(start, start += size);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> _chunk;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<a id="more"></a>
<p>验证下,功能OK,再来看下lodash的实现方法:</p>
<ul>
<li>首先,<strong>对参数进行验证</strong><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">size = <span class="built_in">Math</span>.max(size, <span class="number">0</span>)</div><div class="line"><span class="keyword">const</span> length = array == <span class="literal">null</span> ? <span class="number">0</span> : array.length</div><div class="line"><span class="keyword">if</span> (!length || size < <span class="number">1</span>) {</div><div class="line"> <span class="keyword">return</span> []</div><div class="line">}</div></pre></td></tr></table></figure>
</li>
</ul>
<p>确保size非负以及length为合法值…</p>
<p>虽然处理了数组,但是需不需要考虑ArrayLike的Object伪装Array的情况<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.chunk({<span class="attr">a</span>:<span class="number">1</span>, <span class="attr">b</span>:<span class="number">2</span>, <span class="attr">length</span>:<span class="number">2</span>}, <span class="number">2</span>)</div></pre></td></tr></table></figure></p>
<p>将得到一个包含两个undefined的数组的数组,是否加上数组判断是更nice呢:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">if</span> (!length || !(array <span class="keyword">instanceof</span> <span class="built_in">Array</span>) || size < <span class="number">1</span>) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>再看<code>import baseSlice from './.internal/baseSlice.js'</code>,lodash并未用Array.prototype.slice去做数组切割,而是自己写了一个,为啥?slice是基础特性啊,浏览器都支持的,咋不直接用的…实现上首先将<code>start</code>和<code>end</code>都转化为正值并做start <= end的验证,在算切割的数组length的时候,用了这样的语句,可以关注一下:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">length = start > end ? <span class="number">0</span> : ((end - start) >>> <span class="number">0</span>)</div></pre></td></tr></table></figure></p>
<p><code>>>> 0</code>有什么用?Check <a href="http://stackoverflow.com/questions/1822350/what-is-the-javascript-operator-and-how-do-you-use-it" target="_blank" rel="external">stackoverlfow</a>…其实就是将值转化为32位无符号整数,即Array.length的合法值,参见<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length" target="_blank" rel="external">MDN</a>,非”数字”转化后值为0,比如:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="literal">null</span> >>> <span class="number">0</span> <span class="comment">// 0</span></div><div class="line"></div><div class="line"><span class="string">'1'</span> >>> <span class="number">0</span> <span class="comment">// 1 数字字符串将转化为对应的数字</span></div></pre></td></tr></table></figure></p>
<h2 id="compact"><a href="#compact" class="headerlink" title="compact"></a>compact</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.compact(array)</div></pre></td></tr></table></figure>
<p>compact -> “压紧、简化”,这个就简单了,移除数组中所有的<code>falsey</code>值:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> compact = <span class="function"><span class="params">array</span> =></span> {</div><div class="line"> <span class="keyword">let</span> _compact = [];</div><div class="line"> <span class="keyword">if</span> (array && array.length && array <span class="keyword">instanceof</span> <span class="built_in">Array</span>) {</div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"> <span class="keyword">let</span> length = array.length;</div><div class="line"></div><div class="line"> <span class="keyword">while</span> (index++ <span class="xml"><span class="tag">< <span class="attr">length</span>) {</span></span></div><div class="line"> <span class="attr">if</span> (<span class="attr">array</span>[<span class="attr">index</span>]) {</div><div class="line"> <span class="attr">_compact.push</span>(<span class="attr">array</span>[<span class="attr">index</span>]);</div><div class="line"> }</div><div class="line"> }</div><div class="line"> }</div><div class="line"> <span class="attr">return</span> <span class="attr">_compact</span>;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>下意识的用<code>push</code>插入数组项,而源码惯用下标递增:<code>result[resIndex++] = value</code>。性能有影响?</p>
<h2 id="concat"><a href="#concat" class="headerlink" title="concat"></a>concat</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.concat(array, [values])</div></pre></td></tr></table></figure>
<p>实现的就是原生concat的功能,参数处理一下即可:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> concat = <span class="function">(<span class="params">array, ...values</span>) =></span> {</div><div class="line"> <span class="keyword">if</span> (array && array <span class="keyword">instanceof</span> <span class="built_in">Array</span>) {</div><div class="line"> <span class="keyword">return</span> array.concat(...values);</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>Done! rest参数和数组析构教你做人…对比对比源码看看自己的实现漏了些啥…</p>
<ul>
<li>基础方法实现es6提供的一些便利,包括arguments对象的参数拆分、数组flatten</li>
<li>array参数可以接受非数组,若array非数组,[array]将作为基础数组参与运算<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">return</span> arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, <span class="number">1</span>));</div></pre></td></tr></table></figure>
</li>
</ul>
<p>关于<strong>数组类型</strong>的判断,我们上面用了<code>array instanceof Array</code>这种方式,lodash中<code>isArray</code>即<code>Array.isArray</code>,来看MDN关于isArray的Polyfill:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">if</span> (!<span class="built_in">Array</span>.isArray) {</div><div class="line"> <span class="built_in">Array</span>.isArray = <span class="function"><span class="keyword">function</span>(<span class="params">arg</span>) </span>{</div><div class="line"> <span class="keyword">return</span> <span class="built_in">Object</span>.prototype.toString.call(arg) === <span class="string">'[object Array]'</span>;</div><div class="line"> };</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>如果toString能吐出<code>[object Array]</code>我们就认为他是一个数组,那<code>instanceof Array</code>和<code>isArray</code>有啥区别?</p>
<blockquote>
<p>When checking for Array instance, Array.isArray is preferred over instanceof because it works through iframes.<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">let</span> xArray = otherFrame.Array();</div><div class="line"></div><div class="line"><span class="keyword">let</span> arr = <span class="keyword">new</span> xArray(<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>);</div><div class="line"></div><div class="line">arr <span class="keyword">instanceof</span> <span class="built_in">Array</span>; <span class="comment">// false</span></div><div class="line"></div><div class="line"><span class="built_in">Array</span>.isArray(arr); <span class="comment">// true</span></div></pre></td></tr></table></figure></p>
</blockquote>
<p>显然,arr只是xArray(ohterFrame的Array)的instance而并非当前frame的Array的instance,而isArray不受此影响</p>
<h2 id="difference"><a href="#difference" class="headerlink" title="difference"></a>difference</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.difference(array, [values])</div></pre></td></tr></table></figure>
<p>生成一个从array中过滤掉values中所有元素的数组,即做个数组去重:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> difference = <span class="function">(<span class="params">array, values</span>) =></span> {</div><div class="line"> <span class="keyword">if</span> (!values || values.length === <span class="number">0</span>) {</div><div class="line"> <span class="keyword">return</span> array;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> result = [];</div><div class="line"></div><div class="line"> <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i < array.length; i++) {</div><div class="line"> <span class="keyword">let</span> the = array[i];</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (values.indexOf(the) === <span class="number">-1</span>) {</div><div class="line"> result.push(the);</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result;</div><div class="line">};</div></pre></td></tr></table></figure></p>
<p>源码如何实现,坑有点深啊…</p>
<h2 id="differenceBy"><a href="#differenceBy" class="headerlink" title="differenceBy"></a>differenceBy</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.differenceBy(array, [values], [iteratee=_.identity])</div></pre></td></tr></table></figure>
<p>不同于difference的是,differenceBy接受第三个参数iteratee,会按照array中每项转化后的值进行去重,比如:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.differenceBy([<span class="number">2.1</span>, <span class="number">1.2</span>], [<span class="number">2.3</span>, <span class="number">3.4</span>], <span class="built_in">Math</span>.floor); <span class="comment">// [1.2]</span></div></pre></td></tr></table></figure></p>
<p>另外,对于对象数组,iteratee可以为属性字符串,这其实是_.property的简写</p>
<p>不严谨实现方法:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> differenceBy = <span class="function">(<span class="params">array, ...params</span>) =></span> {</div><div class="line"> <span class="keyword">if</span> (params.length === <span class="number">1</span>) {</div><div class="line"> <span class="keyword">return</span> difference(array, params);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> result = [];</div><div class="line"></div><div class="line"> <span class="keyword">let</span> ite = params.pop();</div><div class="line"></div><div class="line"> <span class="keyword">let</span> exclude = params.shift().map(<span class="function"><span class="params">i</span> =></span> ite(i));</div><div class="line"></div><div class="line"> <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i < array.length; i++) {</div><div class="line"> <span class="keyword">let</span> computed = ite(array[i]);</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (exclude.indexOf(computed)) {</div><div class="line"> result.push(array[i]);</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>还有一个difference方法…</p>
<h2 id="differenceWith"><a href="#differenceWith" class="headerlink" title="differenceWith"></a>differenceWith</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.differenceWith(array, [values], [comparator])</div></pre></td></tr></table></figure>
<p>differenceWith通过指定comparator,改变默认比较方式去得到相应的去重数组</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> differenceWith = <span class="function">(<span class="params">array, ...params</span>) =></span> {</div><div class="line"> <span class="keyword">if</span> (params.length === <span class="number">1</span>) {</div><div class="line"> <span class="keyword">return</span> difference(array, params);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> result = [];</div><div class="line"></div><div class="line"> <span class="keyword">let</span> comparator = params.pop();</div><div class="line"></div><div class="line"> <span class="keyword">let</span> exclude = params.shift();</div><div class="line"></div><div class="line"> <span class="keyword">let</span> eLen = exclude.length;</div><div class="line"></div><div class="line"> outer:</div><div class="line"> <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i < array.length; i++) {</div><div class="line"> <span class="keyword">let</span> the = array[i];</div><div class="line"> <span class="keyword">let</span> index = <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">while</span> (index++ <span class="xml"><span class="tag">< <span class="attr">eLen</span>) {</span></span></div><div class="line"> <span class="attr">if</span> (<span class="attr">comparator</span>(<span class="attr">the</span>, <span class="attr">exclude</span>[<span class="attr">index</span>])) {</div><div class="line"> <span class="attr">continue</span> <span class="attr">outer</span>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="attr">result.push</span>(<span class="attr">the</span>);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="attr">return</span> <span class="attr">result</span>;</div><div class="line">}</div></pre></td></tr></table></figure>
<p>上述三个difference方法在去重操作上统一,可以抽象出来个baseDifference基础方法,且上面我们只考虑了简单的值类型的比较,并未考虑引用类型和NaN这种特殊类型的情况<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div><div class="line">64</div><div class="line">65</div></pre></td><td class="code"><pre><div class="line"><span class="comment">/**</span></div><div class="line"> * base difference</div><div class="line"> * @param array [Array]</div><div class="line"> * @param exclude [Array]</div><div class="line"> * @param iteratee [function] 迭代器,对每个元素转化后进行比较</div><div class="line"> * @param comparator [function] 比较器,比较方法</div><div class="line"> * @param return [array]</div><div class="line"> */</div><div class="line"><span class="keyword">const</span> isArray = <span class="built_in">Array</span>.isArray;</div><div class="line"></div><div class="line"><span class="keyword">const</span> baseDifference = <span class="function">(<span class="params">array, exclude, iteratee, comparator</span>) =></span> {</div><div class="line"></div><div class="line"> <span class="comment">// 非数组或者数组为空</span></div><div class="line"> <span class="keyword">if</span> (!isArray(array) || !array.length) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// 非数组或为空直接返回源数组</span></div><div class="line"> <span class="keyword">if</span> (!isArray(exclude) || !exclude.length) {</div><div class="line"> <span class="keyword">return</span> array;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> result = [];</div><div class="line"> <span class="keyword">let</span> {length} = array;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (iteratee) {</div><div class="line"> exclude = exclude.map(<span class="function"><span class="params">i</span> =></span> iteratee(i));</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!comparator) {</div><div class="line"> comparator = <span class="function"><span class="keyword">function</span>(<span class="params">a, b</span>) </span>{</div><div class="line"> <span class="keyword">if</span> (a === b) {</div><div class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"></div><div class="line"> outer:</div><div class="line"> <span class="keyword">while</span> (++index < length) {</div><div class="line"> <span class="keyword">let</span> val = array[index];</div><div class="line"></div><div class="line"> <span class="keyword">let</span> iteVal = iteratee ? iteratee(val) : val;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (iteVal === iteVal) {</div><div class="line"> <span class="comment">// 值类型</span></div><div class="line"></div><div class="line"> <span class="keyword">let</span> excludeLength = exclude.length;</div><div class="line"> <span class="keyword">while</span> (excludeLength--) {</div><div class="line"> <span class="keyword">let</span> excludei = exclude[excludeLength];</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (comparator(iteVal, iteratee ? iteratee(excludei) : excludei)) {</div><div class="line"> <span class="keyword">continue</span> outer;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> result.push(val);</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result;</div><div class="line">};</div></pre></td></tr></table></figure></p>
<h2 id="drop"><a href="#drop" class="headerlink" title="drop"></a>drop</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.drop(array, [n=<span class="number">1</span>])</div></pre></td></tr></table></figure>
<p>生成一个从array开头移除n个元素后剩余的元素的切片,相当于<code>array.slice(n)</code>,源数组不变<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> drop = <span class="function">(<span class="params">array, n = <span class="number">1</span></span>) =></span> {</div><div class="line"> <span class="keyword">if</span> (!<span class="built_in">Array</span>.isArray(array)) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> n = n < <span class="number">0</span> ? <span class="number">0</span> : n;</div><div class="line"></div><div class="line"> <span class="keyword">return</span> array.slice(n);</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>同理,可以从右侧移除n个元素…</p>
<h2 id="dropRight"><a href="#dropRight" class="headerlink" title="dropRight"></a>dropRight</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.dropRight(array, [n=<span class="number">1</span>])</div></pre></td></tr></table></figure>
<p>与drop类似,从右侧移除n个元素后返回剩余元素的切片即可</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> dropRight = <span class="function">(<span class="params">array, [n = <span class="number">1</span>]</span>) =></span> {</div><div class="line"> <span class="keyword">if</span> (!<span class="built_in">Array</span>.isArray(array)) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> n = n < <span class="number">0</span> ? <span class="number">0</span> : n;</div><div class="line"></div><div class="line"> <span class="keyword">let</span> {length} = array;</div><div class="line"></div><div class="line"> <span class="keyword">return</span> array.slice(<span class="number">0</span>, length - n);</div><div class="line"> <span class="comment">//return array.reverse().slice(n).reverse();</span></div><div class="line">}</div></pre></td></tr></table></figure>
<p>在某些情况下,我们需要drop的可能不是从头或者从尾的N个元素这么简单,而是需要从满足某一条件的元素开始,此时就需要用到<code>dropWhile</code>和<code>dropRightWhile</code></p>
<h2 id="dropWhile-和-dropRightWhile"><a href="#dropWhile-和-dropRightWhile" class="headerlink" title="dropWhile 和 dropRightWhile"></a>dropWhile 和 dropRightWhile</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.drop[Right]While(array, [predicate=_.identity])</div></pre></td></tr></table></figure>
<p>接受参数<code>predicate</code>,接受三个参数<code>(value, key, array)</code>,从左/右找到满足条件的第一个元素后返回切片<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> baseDropWhile = <span class="function">(<span class="params">array, predicate, fromRight</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> {length} = array;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length || !<span class="built_in">Array</span>.isArray(array) ||</div><div class="line"> !predicate || <span class="keyword">typeof</span> predicate !== <span class="string">'function'</span>) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> index = fromRight ? length : <span class="number">-1</span>;</div><div class="line"></div><div class="line"> <span class="comment">// nice code</span></div><div class="line"> <span class="keyword">while</span> ((fromRight ? index-- : ++index < length) && predicate(array[index], index, array)) {}</div><div class="line"></div><div class="line"> <span class="comment">// 注意从右slice时index的值需要+1</span></div><div class="line"> <span class="comment">// slice(start, end)是不包括end元素的</span></div><div class="line"> <span class="keyword">return</span> fromRight ? array.slice(<span class="number">0</span>, index + <span class="number">1</span>) : array.slice(index);</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="fill"><a href="#fill" class="headerlink" title="fill"></a>fill</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.fill(array, value, [start=<span class="number">0</span>], [end=array.length])</div></pre></td></tr></table></figure>
<p>将array从start到end位置填充value</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> fill = <span class="function">(<span class="params">array, value, start = <span class="number">0</span>, end = array.length >>> <span class="number">0</span></span>) =></span> {</div><div class="line"></div><div class="line"> <span class="keyword">let</span> {length} = array;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// 确保正确的start和end</span></div><div class="line"> <span class="keyword">if</span> (start < <span class="number">0</span>) {</div><div class="line"> start = -start > length ? <span class="number">0</span> : (length + start);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (end < <span class="number">0</span>) {</div><div class="line"> end += length;</div><div class="line"> }</div><div class="line"></div><div class="line"> end = start > end ? <span class="number">0</span> : end;</div><div class="line"></div><div class="line"> <span class="keyword">while</span> (start < end) {</div><div class="line"> array[start++] = value;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> array;</div><div class="line">};</div></pre></td></tr></table></figure>
<h2 id="findLastIndex"><a href="#findLastIndex" class="headerlink" title="findLastIndex"></a>findLastIndex</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.findIndex(array, [predicate=_.identity], [fromIndex=<span class="number">0</span>])</div></pre></td></tr></table></figure>
<p>找到array中满足predicate返回为true值的条件的第一个元素的index,可指定查找的起始索引<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> findIndex = <span class="function">(<span class="params">array, predicate, fromIndex = <span class="number">0</span></span>) =></span> {</div><div class="line"> <span class="keyword">let</span> {length} = array;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> <span class="number">-1</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!predicate || <span class="keyword">typeof</span> predicate !== <span class="string">'function'</span>) {</div><div class="line"> <span class="keyword">return</span> <span class="number">-1</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> index = fromIndex >> <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (index < <span class="number">0</span>) {</div><div class="line"> index += length;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (index > length) {</div><div class="line"> <span class="keyword">return</span> <span class="number">-1</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">while</span> (index < length) {</div><div class="line"> <span class="keyword">if</span> (predicate(array[index])) {</div><div class="line"> <span class="keyword">return</span> index;</div><div class="line"> }</div><div class="line"> index++;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> <span class="number">-1</span>;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>同理,也可用findLastIndex从数组尾部找第一个满足条件的元素的index,不赘述</p>
<p>另外,lodash也提供了一些针对predicate的快捷方法,例如:predicate为字符串时,默认使用_.property(predicate)去做条件判断</p>
<h2 id="flatten"><a href="#flatten" class="headerlink" title="flatten"></a>flatten</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.flatten(array)</div></pre></td></tr></table></figure>
<p>扁平array,一层<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> flatten = <span class="function">(<span class="params">array</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> {length} = array;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length || !<span class="built_in">Array</span>.isArray(array)) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> result = [];</div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"> <span class="keyword">while</span> (++index < length) {</div><div class="line"> <span class="keyword">let</span> item = array[index];</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (<span class="built_in">Array</span>.isArray(item)) {</div><div class="line"> result.push(...item);</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> result.push(item);</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>关于flatten,还有2个方法flattenDeep(array)和flattenDepth(array, [depth=1]),前者递归扁平所有嵌套数组,后者可指定扁平层级,可以实现baseFlatten基础功能<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> baseFlatten = <span class="function">(<span class="params">array, depth = <span class="number">1</span>, result = []</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> {length} = array;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"> <span class="keyword">while</span>(++index < length) {</div><div class="line"> <span class="keyword">let</span> item = array[index];</div><div class="line"> <span class="keyword">if</span> (depth > <span class="number">0</span>) {</div><div class="line"> <span class="keyword">if</span> (<span class="built_in">Array</span>.isArray(item)) {</div><div class="line"> baseFlatten(item, depth - <span class="number">1</span>, result);</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> result.push(item);</div><div class="line"> }</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>flattenDepth即直接调用baseFlatten并传入array和depth参数;flattenDeep的depth为无穷大,lodash使用<code>const INFINITY = 1 / 0</code>重新算出来Infinity,怕覆盖么</p>
<h2 id="fromPairs"><a href="#fromPairs" class="headerlink" title="fromPairs"></a>fromPairs</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.fromPairs(pairs)</div></pre></td></tr></table></figure>
<p>将[[key, value]…]转化为键值对对象{key: value…}<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> fromPairs = <span class="function"><span class="params">pairs</span> =></span> {</div><div class="line"> <span class="keyword">let</span> {length} = pairs;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"></div><div class="line"> <span class="keyword">let</span> result = {};</div><div class="line"> <span class="keyword">while</span> (++index < length) {</div><div class="line"> <span class="keyword">let</span> item = pairs[index];</div><div class="line"></div><div class="line"> <span class="keyword">let</span> key = item[<span class="number">0</span>];</div><div class="line"> <span class="keyword">let</span> val = item[<span class="number">1</span>];</div><div class="line"></div><div class="line"> result[key] = val;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="head"><a href="#head" class="headerlink" title="head"></a>head</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.head(array)</div></pre></td></tr></table></figure>
<p>获取数组的第一个元素<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> head = <span class="function"><span class="params">array</span> =></span> {</div><div class="line"> <span class="keyword">if</span> (array && array.length) {</div><div class="line"> <span class="keyword">return</span> array[<span class="number">0</span>];</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span>;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="indexOf"><a href="#indexOf" class="headerlink" title="indexOf"></a>indexOf</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.indexOf(array, value, [fromIndex=<span class="number">0</span>])</div></pre></td></tr></table></figure>
<p>从array的指定位置fromIndex开始查找value值的索引,若无则返回-1<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> indexOf = <span class="function">(<span class="params">array, value, fromIndex = <span class="number">0</span></span>) =></span> {</div><div class="line"> <span class="keyword">let</span> length = array ? array.length : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> <span class="number">-1</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// index转化为正整数</span></div><div class="line"> <span class="keyword">let</span> index = fromIndex >> <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (index < <span class="number">0</span>) {</div><div class="line"> index = <span class="built_in">Math</span>.max(index + length, <span class="number">0</span>);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// 需要考虑NaN的情况</span></div><div class="line"> <span class="keyword">if</span> (value === value) {</div><div class="line"> <span class="keyword">while</span> (index < length) {</div><div class="line"> <span class="keyword">if</span> (array[index] === value) {</div><div class="line"> <span class="keyword">return</span> index;</div><div class="line"> }</div><div class="line"></div><div class="line"> index++;</div><div class="line"> }</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> <span class="keyword">while</span> (index < length) {</div><div class="line"> <span class="keyword">if</span> (<span class="built_in">isNaN</span>(array[index])) {</div><div class="line"> <span class="keyword">return</span> index;</div><div class="line"> }</div><div class="line"></div><div class="line"> index++;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"></div><div class="line"> <span class="keyword">return</span> <span class="number">-1</span>;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="initial"><a href="#initial" class="headerlink" title="initial"></a>initial</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.initial(array)</div></pre></td></tr></table></figure>
<p>获取数组除最后一个元素外的切片<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> initial = <span class="function"><span class="params">array</span> =></span> {</div><div class="line"> <span class="keyword">let</span> length = array ? array.length : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> array.slice(<span class="number">0</span>, <span class="number">-1</span>);</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="intersection"><a href="#intersection" class="headerlink" title="intersection"></a>intersection</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">_.intersection([arrays])</div><div class="line">_.intersectionBy([arrays], [iteratee=_.identity])</div><div class="line">_.intersectionWith([arrays], [comparator])</div></pre></td></tr></table></figure>
<p>取数组的元素交集,并可以通过iteratee和comparator指定元素预处理或者比较方法来纠正计算结果,此处可以抽象下基础方法<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> include = <span class="function">(<span class="params">array, value, comparator</span>) =></span> {</div><div class="line"> <span class="keyword">if</span> (comparator) {</div><div class="line"> <span class="keyword">let</span> {length} = array;</div><div class="line"></div><div class="line"> <span class="keyword">while</span> (length--) {</div><div class="line"> <span class="keyword">if</span> (comparator(array[length], value)) {</div><div class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> <span class="keyword">return</span> array.indexOf(value) > <span class="number">-1</span></div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</div><div class="line">};</div><div class="line"></div><div class="line"><span class="keyword">const</span> baseIntersection = <span class="function">(<span class="params">arrays, iteratee, comparator</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> {length} = arrays;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (length < <span class="number">2</span>) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> first = arrays.shift();</div><div class="line"></div><div class="line"> <span class="keyword">let</span> result = [];</div><div class="line"></div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"></div><div class="line"> <span class="keyword">while</span> (++index < first.length) {</div><div class="line"> <span class="keyword">let</span> item = first[index];</div><div class="line"></div><div class="line"> <span class="keyword">let</span> computed = iteratee ? iteratee(item) : item;</div><div class="line"></div><div class="line"> <span class="keyword">let</span> i = <span class="number">-1</span>;</div><div class="line"></div><div class="line"> <span class="keyword">let</span> has = <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">while</span> (++i < length - <span class="number">1</span>) {</div><div class="line"> <span class="keyword">let</span> inner = arrays[i];</div><div class="line"></div><div class="line"> iteratee && (inner = inner.map(iteratee));</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (include(inner, computed, comparator)) {</div><div class="line"> has++;</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> <span class="keyword">continue</span>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (has === length - <span class="number">1</span>) {</div><div class="line"> result.push(item);</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="join"><a href="#join" class="headerlink" title="join"></a>join</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.join(array, [separator=<span class="string">','</span>])</div></pre></td></tr></table></figure>
<p>array join<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> join = <span class="function">(<span class="params">array, separator = <span class="string">','</span></span>) =></span> {</div><div class="line"> <span class="keyword">let</span> length = array && array.length;</div><div class="line"></div><div class="line"> length = length || <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (length) {</div><div class="line"> <span class="keyword">return</span> array.join(separator);</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> <span class="string">''</span>;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="last"><a href="#last" class="headerlink" title="last"></a>last</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.last(array)</div></pre></td></tr></table></figure>
<p>获取数组的最后一个元素<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> last = <span class="function"><span class="params">array</span> =></span> {</div><div class="line"> <span class="keyword">let</span> length = array && array.length;</div><div class="line"></div><div class="line"> length = length || <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (length) {</div><div class="line"> <span class="keyword">return</span> array[length - <span class="number">1</span>];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span>;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="lastIndexOf"><a href="#lastIndexOf" class="headerlink" title="lastIndexOf"></a>lastIndexOf</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.lastIndexOf(array, value, [fromIndex=array.length<span class="number">-1</span>])</div></pre></td></tr></table></figure>
<p>获取最后一个匹配的元素的index,可指定查找位置,默认length-1,即从后往前查找<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> lastIndexOf = <span class="function">(<span class="params">array, value, fromIndex</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> length = array && array.length;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> <span class="number">-1</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> fromIndex = fromIndex || length - <span class="number">1</span>;</div><div class="line"></div><div class="line"> <span class="keyword">let</span> index = indexOf(array.reverse(), value, (length - <span class="number">1</span> - fromIndex)); <span class="comment">// 调indexOf方法查找反转的数组</span></div><div class="line"></div><div class="line"> <span class="keyword">return</span> index === <span class="number">-1</span> ? <span class="number">-1</span> : ((length - <span class="number">1</span>) - index);</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="nth"><a href="#nth" class="headerlink" title="nth"></a>nth</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.nth(array, [n=<span class="number">0</span>])</div></pre></td></tr></table></figure>
<p>获取数组的第n个元素,n可为负数<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> nth = <span class="function">(<span class="params">array, n = <span class="number">0</span></span>) =></span> {</div><div class="line"> <span class="keyword">let</span> length = array && array.length;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// 转化or验证?</span></div><div class="line"></div><div class="line"> <span class="comment">// 数字</span></div><div class="line"> <span class="comment">// n < maxinter</span></div><div class="line"> <span class="comment">// /^(?:0|[1-9]\d*)$/ 验证无符号整数</span></div><div class="line"> <span class="comment">// n > -1 && n < length</span></div><div class="line"> <span class="comment">// n % 1 === 0</span></div><div class="line"> n = n >> <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (n < <span class="number">0</span>) {</div><div class="line"> n = n + length;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (n > length - <span class="number">1</span> || n < <span class="number">0</span>) {</div><div class="line"> <span class="keyword">return</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> array[n];</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="pullAll"><a href="#pullAll" class="headerlink" title="pullAll"></a>pullAll</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.pullAll(array, values)</div></pre></td></tr></table></figure>
<p>移除array中所有values包含的值,会改变目标数组,接受参数values为数组<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> pullAll = <span class="function">(<span class="params">array, values</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> {length} = array;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> values.forEach(<span class="function"><span class="params">value</span> =></span> {</div><div class="line"> <span class="keyword">while</span> (<span class="literal">true</span>) {</div><div class="line"></div><div class="line"> <span class="keyword">let</span> index = array.indexOf(value);</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (index === <span class="number">-1</span>) {</div><div class="line"> <span class="keyword">break</span>;</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> array.splice(index, <span class="number">1</span>);</div><div class="line"> }</div><div class="line"> }</div><div class="line"> });</div><div class="line"></div><div class="line"> <span class="keyword">return</span> array;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="pull"><a href="#pull" class="headerlink" title="pull"></a>pull</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.pull(array, [values])</div></pre></td></tr></table></figure>
<p>类似pullAll,只是接受的移除的参数为参数列表</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> pull = <span class="function">(<span class="params">array, ...values</span>) =></span> {</div><div class="line"> <span class="keyword">return</span> pullAll(array, values);</div><div class="line">}</div></pre></td></tr></table></figure>
<h2 id="pullAllBy"><a href="#pullAllBy" class="headerlink" title="pullAllBy"></a>pullAllBy</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.pullAllBy(array, values, [iteratee=_.identity])</div></pre></td></tr></table></figure>
<p>使用iteratee迭代每个元素进行后进行比较排除<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> pullAllBy = <span class="function">(<span class="params">array, values, iteratee</span>) =></span> {</div><div class="line"> <span class="keyword">if</span> (iteratee) {</div><div class="line"></div><div class="line"> values.forEach(<span class="function"><span class="params">value</span> =></span> {</div><div class="line"> <span class="keyword">while</span> (<span class="literal">true</span>) {</div><div class="line"></div><div class="line"> <span class="keyword">let</span> index = array.map(iteratee).indexOf(iteratee(value));</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (index === <span class="number">-1</span>) {</div><div class="line"> <span class="keyword">break</span>;</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> array.splice(index, <span class="number">1</span>);</div><div class="line"> }</div><div class="line"> }</div><div class="line"> });</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> <span class="keyword">return</span> pullAll(array, values)</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> array;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="pullAllWith"><a href="#pullAllWith" class="headerlink" title="pullAllWith"></a>pullAllWith</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.pullAllWith(array, values, [comparator])</div></pre></td></tr></table></figure>
<p>按指定比较规则进行排除<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> pullAllWith = <span class="function">(<span class="params">array, values, comparator</span>) =></span> {</div><div class="line"> <span class="keyword">if</span> (comparator) {</div><div class="line"></div><div class="line"> values.forEach(<span class="function"><span class="params">value</span> =></span> {</div><div class="line"></div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"> <span class="keyword">let</span> {length} = array;</div><div class="line"> <span class="keyword">let</span> removes = [];</div><div class="line"> <span class="keyword">while</span> (++index < length) {</div><div class="line"> <span class="keyword">if</span> (comparator(value, array[index])) {</div><div class="line"> removes.push(index);</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// removes为升序index的序列</span></div><div class="line"> <span class="keyword">let</span> offset = <span class="number">0</span>;</div><div class="line"> removes.forEach(<span class="function"><span class="params">i</span> =></span> {</div><div class="line"> array.splice(i - offset++, <span class="number">1</span>);</div><div class="line"> })</div><div class="line"></div><div class="line"> });</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> <span class="keyword">return</span> pullAll(array, values);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> array;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="pullAt"><a href="#pullAt" class="headerlink" title="pullAt"></a>pullAt</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.pullAt(array, [indexes])</div></pre></td></tr></table></figure>
<p>移除指定位置的元素,并返回移除元素的数组<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> pullAt = <span class="function">(<span class="params">array, indexes = []</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> {length} = array;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!array) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> offset = <span class="number">0</span>; <span class="comment">// index偏移修正 </span></div><div class="line"></div><div class="line"> <span class="keyword">let</span> result = [];</div><div class="line"></div><div class="line"> <span class="comment">// 从小到大排序,方便进行偏移修正</span></div><div class="line"> indexes.sort().forEach(<span class="function"><span class="params">i</span> =></span> {</div><div class="line"> <span class="keyword">if</span> (!(<span class="regexp">/^\d+$/</span>).test(i + <span class="string">''</span>)) {</div><div class="line"> <span class="keyword">return</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (i < <span class="number">0</span>) {</div><div class="line"> i += length;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (i >= length) {</div><div class="line"> <span class="keyword">return</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> result.push(...array.splice(i - offset++, <span class="number">1</span>));</div><div class="line"> });</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="remove"><a href="#remove" class="headerlink" title="remove"></a>remove</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.remove(array, [predicate=_.identity])</div></pre></td></tr></table></figure>
<p>移除array中满足predicate为truthy的元素,predicate接收三个参数(value, index, array);remove返回删除的元素,并会改变array<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> remove = <span class="function">(<span class="params">array, predicate</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> length = array ? array.length : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">let</span> result = [];</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length || !predicate) {</div><div class="line"> <span class="keyword">return</span> result;</div><div class="line"> }</div><div class="line"></div><div class="line"></div><div class="line"> <span class="keyword">let</span> indexes = [];</div><div class="line"> result = array.filter(<span class="function">(<span class="params">item, index</span>) =></span> {</div><div class="line"> <span class="keyword">if</span> (predicate(item, index, array)) {</div><div class="line"> indexes.push(index);</div><div class="line"></div><div class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</div><div class="line"> });</div><div class="line"></div><div class="line"> pullAt(array, indexes);</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="reverse"><a href="#reverse" class="headerlink" title="reverse"></a>reverse</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> reverse = <span class="function"><span class="params">array</span> =></span> {</div><div class="line"> <span class="keyword">let</span> length = array ? array.length : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> array.reverse();</div><div class="line">}</div></pre></td></tr></table></figure>
<h2 id="slice"><a href="#slice" class="headerlink" title="slice"></a>slice</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.slice(array, [start=<span class="number">0</span>], [end=array.length])</div></pre></td></tr></table></figure>
<p>slice的功能我们在实现chunk的时候就已经完整实现过了,在原生slice方法的基础上,做一些参数的限定和转化<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> slice = <span class="function">(<span class="params">array, start, end</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> length = array ? array.length : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!lenght) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> start = start ? start : <span class="number">0</span>;</div><div class="line"> end = end ? end : length;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (start < <span class="number">0</span>) {</div><div class="line"> start = -start > length ? <span class="number">0</span> : (start + length);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (end < <span class="number">0</span>) {</div><div class="line"> end += length;</div><div class="line"> }</div><div class="line"></div><div class="line"> end = end > length ? length : end;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (start > end) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> array.slice(start, end);</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="sortedIndex"><a href="#sortedIndex" class="headerlink" title="sortedIndex"></a>sortedIndex</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.sortedIndex(array, value)</div></pre></td></tr></table></figure>
<p>在已排序的array数组中,插入value后维持顺序,确定并返回最小的插入位置索引</p>
<p>实现sortIndex基础方法:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> baseSortedIndex = <span class="function">(<span class="params">array, value, iteratee</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> length = array ? array.length : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">let</span> low = <span class="number">0</span>;</div><div class="line"> <span class="keyword">let</span> high = length;</div><div class="line"></div><div class="line"> <span class="keyword">let</span> iteValue = iteratee ? iteratee(value) : value;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (<span class="keyword">typeof</span> iteValue === <span class="literal">undefined</span>) {</div><div class="line"> <span class="keyword">return</span> high;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// 二分查找</span></div><div class="line"> <span class="comment">// 即找第一个大于待插入元素值的元素的位置</span></div><div class="line"> <span class="keyword">while</span> (low < high) {</div><div class="line"> <span class="keyword">let</span> middle = (low + high) >>> <span class="number">1</span>;</div><div class="line"></div><div class="line"> <span class="keyword">let</span> midValue = iteratee ? iteratee(array[middle]) : array[middle];</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (midValue < iteValue) {</div><div class="line"> low = middle + <span class="number">1</span>;</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> high = middle;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> high;</div><div class="line">};</div><div class="line"></div><div class="line"><span class="keyword">const</span> sortedIndex = <span class="function">(<span class="params">array, value</span>) =></span> baseSortedIndex(array, value);</div></pre></td></tr></table></figure></p>
<p>源码中,利用位运算求中间值,可关注: <code>const mid = (low + high) >>> 1</code></p>
<h2 id="sortedIndexBy"><a href="#sortedIndexBy" class="headerlink" title="sortedIndexBy"></a>sortedIndexBy</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.sortedIndexBy(array, value, [iteratee=_.identity])</div></pre></td></tr></table></figure>
<p>iteratee转化后进行元素比较,iteratee接受一个参数<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> sortedIndexBy = <span class="function">(<span class="params">array, value, iteratee</span>) =></span> baseSortedIndex(array, value, iteratee);</div></pre></td></tr></table></figure></p>
<h2 id="sortedIndexOf"><a href="#sortedIndexOf" class="headerlink" title="sortedIndexOf"></a>sortedIndexOf</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.sortedIndexOf(array, value)</div></pre></td></tr></table></figure>
<p>使用<code>二分法</code>binary search查找一个value在已排序数组中的索引<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> sortedIndexOf = <span class="function">(<span class="params">array, value</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> length = array ? array.length : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (length) {</div><div class="line"> <span class="comment">// 调用baseSortedIndex找到value插入的位置,再判断插入位置的值是否与value相等</span></div><div class="line"> <span class="comment">// 若不等,则无对应值存在于数组中,返回-1</span></div><div class="line"> <span class="comment">// 另外,需要满足条件,得到的index需要小于length,排出插入到最后的情况</span></div><div class="line"> <span class="keyword">let</span> index = baseSortedIndex(array, value);</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (index < length && array[index] === value) {</div><div class="line"> <span class="keyword">return</span> index;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> <span class="number">-1</span>;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="sortedLastIndex、-sortedLastIndexBy、sortedLastIndexOf"><a href="#sortedLastIndex、-sortedLastIndexBy、sortedLastIndexOf" class="headerlink" title="sortedLastIndex、 sortedLastIndexBy、sortedLastIndexOf"></a>sortedLastIndex、 sortedLastIndexBy、sortedLastIndexOf</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">_.sortedLastIndex(array, value)</div><div class="line">_.sortedLastIndexBy(array, value, [iteratee=_.identity])</div><div class="line">_.sortedLastIndexOf(array, value)</div></pre></td></tr></table></figure>
<p>对于之前的三个sortedIndex的方法,还有三个对应的逆序,在原有的baseSortedIndex的基础上,将二分查找的条件修改下即可:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"></div><div class="line"> <span class="comment">//[ < ] ---> [<=]这样在遇到第一个相等的元素后会继续向右查找直到找到最后一个</span></div><div class="line"> <span class="keyword">if</span> (midValue <= iteValue) {</div><div class="line"> low = middle + <span class="number">1</span>;</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> high = middle;</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>在此要求下对baseSortedIndex做个修正并提取baseSortedIndexBy方法,控制一下参数:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> baseSortedIndex = <span class="function">(<span class="params">array, value, highest</span>) =></span> {</div><div class="line"> <span class="keyword">return</span> baseSortedIndexBy(array, value, val => val, highest);</div><div class="line">};</div><div class="line"></div><div class="line"><span class="keyword">const</span> baseSortedIndexBy = <span class="function">(<span class="params">array, value, iteratee, highest</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> length = array ? array.length : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">let</span> low = <span class="number">0</span>;</div><div class="line"> <span class="keyword">let</span> high = length;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!iteratee) {</div><div class="line"> iteratee = <span class="function"><span class="params">val</span> =></span> val;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> iteValue = iteratee(value);</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (<span class="keyword">typeof</span> iteValue === <span class="literal">undefined</span>) {</div><div class="line"> <span class="keyword">return</span> high;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// 二分查找</span></div><div class="line"> <span class="comment">// 即找第一个大于待插入元素值的元素的位置</span></div><div class="line"> <span class="keyword">while</span> (low < high) {</div><div class="line"> <span class="keyword">let</span> middle = (low + high) >>> <span class="number">1</span>;</div><div class="line"></div><div class="line"> <span class="keyword">let</span> midValue = iteratee(array[middle]);</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (highest ? (midValue <= iteValue) : (midValue < iteValue)) {</div><div class="line"> low = middle + <span class="number">1</span>;</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> high = middle;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> high;</div><div class="line">};</div><div class="line"></div><div class="line"><span class="comment">// 实现...</span></div><div class="line"><span class="keyword">const</span> sortedLastIndex = <span class="function">(<span class="params">array, value</span>) =></span> baseSortedIndex(array, value, <span class="literal">true</span>);</div><div class="line"><span class="keyword">const</span> sortedLastIndexBy = <span class="function">(<span class="params">array, value, ite</span>) =></span> baseSortedIndexBy(array, value, ite, <span class="literal">true</span>);</div><div class="line"><span class="comment">// sortedLastIndexOf类似</span></div></pre></td></tr></table></figure></p>
<h2 id="sortedUniq"><a href="#sortedUniq" class="headerlink" title="sortedUniq"></a>sortedUniq</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.sortedUniq(array)</div></pre></td></tr></table></figure>
<p>对已排序数组去重,返回新数组<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> sortedUniq = <span class="function"><span class="params">array</span> =></span> {</div><div class="line"> <span class="keyword">let</span> length = array ? array.length : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"> <span class="keyword">let</span> result = [];</div><div class="line"> <span class="keyword">let</span> seen;</div><div class="line"></div><div class="line"> <span class="keyword">while</span> (++index < length) {</div><div class="line"> <span class="keyword">let</span> value = array[index];</div><div class="line"></div><div class="line"> <span class="comment">// 相邻元素值不相等的</span></div><div class="line"> <span class="comment">// 注意:!index判断seen有没有被初始化,不可用!seen,因为seen可能是falsely值</span></div><div class="line"> <span class="keyword">if</span> (!index || !eq(value, seen)) {</div><div class="line"></div><div class="line"> seen = value;</div><div class="line"> result.push(seen);</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/**</span></div><div class="line"> * value与other是否相等,NaN !== NaN</div><div class="line"> */</div><div class="line"><span class="keyword">const</span> eq = <span class="function">(<span class="params">value, other</span>) =></span> {</div><div class="line"> <span class="keyword">return</span> value === other || (value !== value && other !== other);</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="sortedUniqBy"><a href="#sortedUniqBy" class="headerlink" title="sortedUniqBy"></a>sortedUniqBy</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.sortedUniqBy(array, [iteratee])</div></pre></td></tr></table></figure>
<p>功能类似,接受迭代器参数,将值转化后做比较,综合<code>sortedUniq</code>提取baseSortedUniq方法…<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> baseSortedUniq = <span class="function">(<span class="params">array, iteratee</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> length = array ? array.length : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!iteratee) {</div><div class="line"> iteratee = <span class="function"><span class="params">x</span> =></span> x;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"> <span class="keyword">let</span> result = [];</div><div class="line"> <span class="keyword">let</span> seen;</div><div class="line"></div><div class="line"> <span class="keyword">while</span> (++index < length) {</div><div class="line"> <span class="keyword">let</span> value = array[index];</div><div class="line"></div><div class="line"> <span class="keyword">let</span> computed = iteratee(value);</div><div class="line"></div><div class="line"> <span class="comment">// 相邻元素值不相等的</span></div><div class="line"> <span class="comment">// 注意:!index判断seen有没有被初始化,不可用!seen,因为seen可能是falsely值</span></div><div class="line"> <span class="keyword">if</span> (!index || !eq(computed, seen)) {</div><div class="line"></div><div class="line"> seen = computed;</div><div class="line"> result.push(value);</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">const</span> sortedUniqBy = <span class="function">(<span class="params">array, iteratee</span>) =></span> {</div><div class="line"> <span class="keyword">return</span> baseSortedUniq(array, iteratee);</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="tail"><a href="#tail" class="headerlink" title="tail"></a>tail</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.tail(array)</div></pre></td></tr></table></figure>
<p>获取除第一个元素的数组切片<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> tail = <span class="function"><span class="params">array</span> =></span> {</div><div class="line"> <span class="keyword">let</span> length = array ? array.length : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> array.slice(<span class="number">1</span>);</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>看了下源码的实现,直接用slice有点小low啊,别人都用数组的解构啦!<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> [head, ...res] = array; <span class="comment">// 666</span></div><div class="line"><span class="keyword">return</span> res;</div></pre></td></tr></table></figure></p>
<h2 id="take"><a href="#take" class="headerlink" title="take"></a>take</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.take(array, [n=<span class="number">1</span>])</div></pre></td></tr></table></figure>
<p>获取从数组开始的n个元素的切片<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> take = <span class="function">(<span class="params">array, n = <span class="number">1</span></span>) =></span> {</div><div class="line"> <span class="keyword">let</span> length = array ? array.length : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> n = n > <span class="number">0</span> ? n : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">return</span> array.slice(<span class="number">0</span>, n);</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="takeRight"><a href="#takeRight" class="headerlink" title="takeRight"></a>takeRight</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.takeRight(array, [n=<span class="number">1</span>])</div></pre></td></tr></table></figure>
<p>获取数组结尾的n个元素的切片<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> takeRight = <span class="function">(<span class="params">array, n = <span class="number">1</span></span>) =></span> {</div><div class="line"> <span class="keyword">let</span> length = array ? array.length : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (n > length) {</div><div class="line"> n = length;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> array.slice(length - n);</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="takeWhile"><a href="#takeWhile" class="headerlink" title="takeWhile"></a>takeWhile</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.takeWhile(array, [predicate=_.identity])</div></pre></td></tr></table></figure>
<p>从左侧开始切片数组,直到第一个predicate判断返回为false的值位置<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> takeWhile = <span class="function">(<span class="params">array, predicate</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> length = array ? array.length : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!predicate) {</div><div class="line"> <span class="keyword">return</span> array.slice(<span class="number">0</span>);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"> <span class="keyword">while</span> (++index < length) {</div><div class="line"> <span class="keyword">if</span> (!predicate(array[index])) {</div><div class="line"> <span class="keyword">break</span>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> array.slice(<span class="number">0</span>, index);</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="takeRightWhile"><a href="#takeRightWhile" class="headerlink" title="takeRightWhile"></a>takeRightWhile</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.takeRightWhile(array, [predicate=_.identity])</div></pre></td></tr></table></figure>
<p>类似takeWhile,takeRightWhile从数组右侧开始寻找,综合takeWhile,来一个<code>baseTakeWhile</code><br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> baseTakeWhile = <span class="function">(<span class="params">array, predicate, fromRight</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> length = array ? array.length : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!predicate) {</div><div class="line"> <span class="keyword">return</span> array.slice(<span class="number">0</span>);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> index = fromRight ? length : <span class="number">-1</span>;</div><div class="line"></div><div class="line"> <span class="keyword">while</span> (fromRight ? index-- : ++index < length) {</div><div class="line"> <span class="keyword">if</span> (!predicate(array[index])) {</div><div class="line"> <span class="keyword">break</span>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> fromRight ? array.slice(index + <span class="number">1</span>) : array.slice(<span class="number">0</span>, index);</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="union"><a href="#union" class="headerlink" title="union"></a>union</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.union([arrays])</div></pre></td></tr></table></figure>
<p>数组元素组合,参数接受n个数组<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> union = <span class="function">(<span class="params">...arrays</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> length = arrays ? arrays.length : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> result = [];</div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"> <span class="keyword">while</span> (++index < length) {</div><div class="line"> result.splice(result.length, <span class="number">0</span>, ...arrays[index]);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> <span class="built_in">Array</span>.from(<span class="keyword">new</span> <span class="built_in">Set</span>(result));</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="unionBy"><a href="#unionBy" class="headerlink" title="unionBy"></a>unionBy</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.unionBy([arrays], [iteratee=_.identity])</div></pre></td></tr></table></figure>
<p>接受迭代参数,迭代后相同的项入坑…这样就坑爹啦,上面那个简易的办法用不上啦<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> unionBy = <span class="function">(<span class="params">...arrays</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> length = arrays ? arrays.length : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// let iteratee = last(arrays);</span></div><div class="line"> <span class="keyword">let</span> iteratee = arrays[length - <span class="number">1</span>];</div><div class="line"></div><div class="line"> length--;</div><div class="line"></div><div class="line"> <span class="keyword">let</span> result = [];</div><div class="line"> <span class="keyword">let</span> seen = [];</div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"></div><div class="line"> <span class="keyword">while</span> (++index < length) {</div><div class="line"> <span class="keyword">let</span> array = arrays[index];</div><div class="line"></div><div class="line"> <span class="keyword">let</span> computed = array.map(iteratee);</div><div class="line"></div><div class="line"> <span class="keyword">let</span> inner = <span class="number">-1</span>;</div><div class="line"> <span class="keyword">let</span> innerLen = array.length;</div><div class="line"></div><div class="line"> <span class="keyword">while</span> (++inner < innerLen) {</div><div class="line"> <span class="keyword">if</span> (seen.indexOf(computed[inner]) === <span class="number">-1</span>) {</div><div class="line"> seen.push(computed[inner]);</div><div class="line"></div><div class="line"> result.push(array[inner]);</div><div class="line"> }</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result;</div><div class="line"></div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>上述方法时间复杂度O(n<sup>2</sup>),应该可以简化到O(n)<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div></pre></td><td class="code"><pre><div class="line"><span class="comment">// 先参考union的方法将所有元素合并到数组中,然后再针对iteratee做去重</span></div><div class="line"><span class="keyword">const</span> unionBy = <span class="function">(<span class="params">...arrays</span>) =></span> {</div><div class="line"> <span class="comment">// 参数拆解同上</span></div><div class="line"> <span class="keyword">let</span> length = arrays ? arrays.length : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> iteratee = arrays[length - <span class="number">1</span>];</div><div class="line"></div><div class="line"> length--;</div><div class="line"></div><div class="line"></div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"> <span class="keyword">let</span> inter = [];</div><div class="line"> <span class="keyword">while</span> (++index < length) {</div><div class="line"> inter.splice(inter.length, <span class="number">0</span>, ...arrays[index]);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// 去重</span></div><div class="line"> <span class="keyword">let</span> result = [];</div><div class="line"> <span class="keyword">let</span> seen = [];</div><div class="line"></div><div class="line"> index = <span class="number">-1</span>;</div><div class="line"> length = inter.length;</div><div class="line"></div><div class="line"> <span class="keyword">while</span> (++index < length) {</div><div class="line"> <span class="keyword">let</span> val = inter[index];</div><div class="line"> <span class="keyword">let</span> computed = iteratee(val);</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (seen.indexOf(computed) > <span class="number">-1</span>) {</div><div class="line"> <span class="keyword">continue</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> seen.push(computed);</div><div class="line"> result.push(val);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="unionWith"><a href="#unionWith" class="headerlink" title="unionWith"></a>unionWith</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.unionWith([arrays], [comparator])</div></pre></td></tr></table></figure>
<p>老三样,可指定元素间比较方式,只是O(n<sup>3</sup>)的复杂度啊…comparator也需要遍历比较</p>
<h2 id="uniq"><a href="#uniq" class="headerlink" title="uniq"></a>uniq</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.uniq(array)</div></pre></td></tr></table></figure>
<p>所以这是跟<code>union</code>是有什么区别呢?一个参数是数组,一个是参数别表,每个参数项是数组?<br>包括<code>uniqBy</code>和<code>uniqWith</code>都是同理的实现</p>
<h2 id="zip"><a href="#zip" class="headerlink" title="zip"></a>zip</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.zip([arrays])</div></pre></td></tr></table></figure>
<p>接受参数为n个数组的参数列表,将参数列表中的数组按照index进行分组,返回分组的新数组<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> zip = <span class="function">(<span class="params">...arrays</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> length = arrays.length ? arrays.length : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> max = <span class="number">0</span>;</div><div class="line"> arrays.forEach(<span class="function"><span class="params">array</span> =></span> {</div><div class="line"> max = <span class="built_in">Math</span>.max(max, array.length);</div><div class="line"> });</div><div class="line"></div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"> <span class="keyword">let</span> result = <span class="keyword">new</span> <span class="built_in">Array</span>(max);</div><div class="line"> <span class="keyword">while</span> (++index < max) {</div><div class="line"></div><div class="line"> <span class="keyword">let</span> sub = [];</div><div class="line"> <span class="keyword">let</span> inner = <span class="number">-1</span>;</div><div class="line"> <span class="keyword">while</span> (++inner < length) {</div><div class="line"> sub[inner] = arrays[inner][index];</div><div class="line"> }</div><div class="line"></div><div class="line"> result[index] = sub;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="unzip"><a href="#unzip" class="headerlink" title="unzip"></a>unzip</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.unzip(array)</div></pre></td></tr></table></figure>
<p>接收参数跟zip不同,其实功能与<code>zip</code>一样,把对应index的元素组合即可,这个操作可以理解为双向操作, 因此通过<code>...</code>将列表转化为数组后,执行过程就一致了,我们将上述zip的执行移植过来:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> unzip = <span class="function"><span class="params">array</span> =></span> {</div><div class="line"> <span class="keyword">let</span> length = array.length ? array.length : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> max = <span class="number">0</span>;</div><div class="line"> array.forEach(<span class="function"><span class="params">array</span> =></span> {</div><div class="line"> max = <span class="built_in">Math</span>.max(max, array.length);</div><div class="line"> });</div><div class="line"></div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"> <span class="keyword">let</span> result = <span class="keyword">new</span> <span class="built_in">Array</span>(max);</div><div class="line"> <span class="keyword">while</span> (++index < max) {</div><div class="line"></div><div class="line"> <span class="keyword">let</span> sub = [];</div><div class="line"> <span class="keyword">let</span> inner = <span class="number">-1</span>;</div><div class="line"> <span class="keyword">while</span> (++inner < length) {</div><div class="line"> sub[inner] = array[inner][index];</div><div class="line"> }</div><div class="line"></div><div class="line"> result[index] = sub;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>这样zip操作就可以直接调用unzip<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> zip = <span class="function">(<span class="params">...arrays</span>) =></span> {</div><div class="line"> <span class="keyword">return</span> unzip(arrays);</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="unzipWith"><a href="#unzipWith" class="headerlink" title="unzipWith"></a>unzipWith</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.unzipWith(array, [iteratee=_.identity])</div></pre></td></tr></table></figure>
<p>对位的元素使用iteratee进行结合后吐出来,可以先试用unzip转化,然后对没个数组元素进行组合, <code>iteratee</code>为接收参数列表的函数<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> unzipWith = <span class="function">(<span class="params">array, iteratee</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> length = array.length ? array.length : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> result = unzip(array);</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result.map(<span class="function"><span class="params">res</span> =></span> {</div><div class="line"></div><div class="line"> <span class="comment">// 数组参数转参数列表</span></div><div class="line"> <span class="keyword">return</span> iteratee ? iteratee.apply(<span class="literal">null</span>, res) : res</div><div class="line"> });</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>zip然后unzipWith能实现某种神奇的转化?yes…比如:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="comment">// iteratee</span></div><div class="line"><span class="keyword">const</span> add = <span class="function">(<span class="params">...arr</span>) =></span> arr.reduce(<span class="function">(<span class="params">acc, val</span>) =></span> acc + val, <span class="number">0</span>);</div><div class="line"></div><div class="line">unzipWith(zip([<span class="number">1</span>, <span class="number">2</span>], [<span class="number">10</span>, <span class="number">20</span>], [<span class="number">100</span>, <span class="number">200</span>]), add)</div></pre></td></tr></table></figure></p>
<p>可实现原数组转化为每项的元素和的数组</p>
<h2 id="without"><a href="#without" class="headerlink" title="without"></a>without</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.without(array, [values])</div></pre></td></tr></table></figure>
<p>生成一个数组中排出指定元素的新数组,与<code>pull</code>功能类似,pull会改变源数组<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> without = <span class="function">(<span class="params">array, ...values</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> length = array ? array.length : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> result = [];</div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"> <span class="keyword">while</span> (++index < length) {</div><div class="line"> <span class="keyword">if</span> (values.indexOf(array[index]) > <span class="number">-1</span>) {</div><div class="line"> <span class="keyword">continue</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> result.push(array[index]);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="xor"><a href="#xor" class="headerlink" title="xor"></a>xor</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.xor([arrays])</div></pre></td></tr></table></figure>
<p>亦或运算<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> xor = ...arrays => {</div><div class="line"> <span class="keyword">let</span> length = arrays.length;</div><div class="line"></div><div class="line"> <span class="comment">// 如果参数只传入一个数组,则对该数组元素去重后返回</span></div><div class="line"> <span class="keyword">if</span> (length < <span class="number">2</span>) {</div><div class="line"> <span class="keyword">return</span> length ? uniq(arrays[<span class="number">0</span>]) : [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"> <span class="keyword">let</span> result = [];</div><div class="line"></div><div class="line"> <span class="comment">// TODO</span></div><div class="line">}</div></pre></td></tr></table></figure></p>
<h1 id="Collection"><a href="#Collection" class="headerlink" title="Collection"></a>Collection</h1><h2 id="countBy"><a href="#countBy" class="headerlink" title="countBy"></a>countBy</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.countBy(collection, [iteratee=_.identity])</div></pre></td></tr></table></figure>
<p>collection中统计各项的数目,也可指定iteratee进行迭代处理<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> countBy = <span class="function">(<span class="params">collection, iteratee</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> result = {};</div><div class="line"></div><div class="line"> collection.forEach(<span class="function"><span class="params">key</span> =></span> {</div><div class="line"></div><div class="line"> <span class="keyword">let</span> ite = iteratee ? iteratee(key) : key;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (<span class="keyword">typeof</span> result[ite] === <span class="string">'undefined'</span>) {</div><div class="line"> result[ite] = <span class="number">1</span>;</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> result[ite] += <span class="number">1</span>;</div><div class="line"> }</div><div class="line"> });</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>reduce?</p>
<h2 id="forEach"><a href="#forEach" class="headerlink" title="forEach"></a>forEach</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.forEach(collection, [iteratee=_.identity])</div></pre></td></tr></table></figure>
<p>遍历元素,iteratee接受三个参数<code>value</code>,’key’,’collection’。但是对于对象的each,官方更推荐使用<code>forIn</code>或者<code>forOwn</code><br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> forEach = <span class="function">(<span class="params">collection, iteratee</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> isArr = <span class="built_in">Array</span>.isArray(collection);</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (isArr) {</div><div class="line"> collection.forEach(iteratee);</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> <span class="comment">// 对象情况,用forin遍历,顺序不可控</span></div><div class="line"> <span class="built_in">Object</span>.keys(collection).forEach(<span class="function"><span class="params">key</span> =></span> {</div><div class="line"> iteratee(collection[key], key, collection);</div><div class="line"> });</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> collection;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>有一点忽略了,某一次iteratee执行<code>return false</code>是可以终结整个的循环的,原生的就没有此功能了,因此在上面的基础上要略做改造<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> forEach = <span class="function">(<span class="params">collection, iteratee</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> isArr = <span class="built_in">Array</span>.isArray(collection);</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (isArr) {</div><div class="line"> <span class="keyword">let</span> length = collection.length;</div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"></div><div class="line"> <span class="keyword">while</span> (++index < length) {</div><div class="line"> <span class="keyword">let</span> res = iteratee(collection[index], index, collection);</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (res === <span class="literal">false</span>) {</div><div class="line"> <span class="keyword">break</span>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> <span class="comment">// 对象情况,用forin遍历,顺序不可控</span></div><div class="line"> <span class="keyword">let</span> keys = <span class="built_in">Object</span>.keys(collection);</div><div class="line"> <span class="keyword">let</span> length = keys.length;</div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"></div><div class="line"> <span class="keyword">while</span> (++index < length) {</div><div class="line"> <span class="keyword">let</span> key = keys[index];</div><div class="line"> <span class="keyword">let</span> res = iteratee(collection[key], key, collection);</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (res === <span class="literal">false</span>) {</div><div class="line"> <span class="keyword">break</span>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> collection;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="forEachRight"><a href="#forEachRight" class="headerlink" title="forEachRight"></a>forEachRight</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.forEachRight(collection, [iteratee=_.identity])</div></pre></td></tr></table></figure>
<p>与forEach类似,只是从尾向头迭代,不赘述</p>
<h2 id="every"><a href="#every" class="headerlink" title="every"></a>every</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.every(collection, [predicate=_.identity])</div></pre></td></tr></table></figure>
<p>若collection所有项通过predicate check则返回true,否则返回false。需要注意的是,对空的collection返回值为true,约定<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> every = <span class="function">(<span class="params">collection, predicate</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> isArr = <span class="built_in">Array</span>.isArray(collection);</div><div class="line"></div><div class="line"> <span class="keyword">let</span> keys = !isArr && <span class="built_in">Object</span>.keys(collection);</div><div class="line"> <span class="keyword">let</span> length = isArr ? collection.length : keys.length;</div><div class="line"></div><div class="line"> <span class="comment">// 空collection返回true</span></div><div class="line"> <span class="keyword">if</span> (length === <span class="number">0</span>) {</div><div class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"> <span class="keyword">while</span> (++index < length) {</div><div class="line"> <span class="keyword">let</span> key;</div><div class="line"> <span class="keyword">if</span> (isArr) {</div><div class="line"> key = index;</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> key = keys[index];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!predicate(collection[key], key, collection)) {</div><div class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="filter"><a href="#filter" class="headerlink" title="filter"></a>filter</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.filter(collection, [predicate=_.identity])</div></pre></td></tr></table></figure>
<p>满足preficate为truthy的元素的数组<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> filter = <span class="function">(<span class="params">collection, predicate</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> isArr = <span class="built_in">Array</span>.isArray(collection);</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (isArr) {</div><div class="line"> <span class="keyword">return</span> collection.filter(predicate);</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> <span class="keyword">let</span> result = [];</div><div class="line"></div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"> <span class="keyword">let</span> keys = <span class="built_in">Object</span>.keys(collection);</div><div class="line"></div><div class="line"> <span class="keyword">let</span> length = keys.length;</div><div class="line"></div><div class="line"> <span class="keyword">while</span> (++index < length) {</div><div class="line"> <span class="keyword">let</span> key = keys[index];</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (predicate(collection[key], key, collection)) {</div><div class="line"> result.push({</div><div class="line"> [key]: collection[key]</div><div class="line"> });</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result;</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="reject"><a href="#reject" class="headerlink" title="reject"></a>reject</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.reject(collection, [predicate=_.identity])</div></pre></td></tr></table></figure>
<p><code>filter</code>的反向操作,过滤掉predicate为truthy值的想,返回剩余项的数组集合<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> filter = <span class="function">(<span class="params">collection, predicate</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> result = [];</div><div class="line"></div><div class="line"> forEach(collection, (item, index, collection) => {</div><div class="line"> <span class="keyword">if</span> (predicate(item)) {</div><div class="line"> <span class="keyword">return</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"></div><div class="line"> result.push(<span class="built_in">Array</span>.isArray(collection) ? item : {</div><div class="line"> [index]: item</div><div class="line"> });</div><div class="line"> });</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="find"><a href="#find" class="headerlink" title="find"></a>find</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.find(collection, [predicate=_.identity], [fromIndex=<span class="number">0</span>])</div></pre></td></tr></table></figure>
<p>从指定的fromIndex开始查找满足predicate的项并返回,若无则返回undefined<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> find = <span class="function">(<span class="params">collection, predicate, fromIndex</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> isArr = <span class="built_in">Array</span>.isArray(collection);</div><div class="line"></div><div class="line"> <span class="keyword">let</span> keys = <span class="built_in">Object</span>.keys(collection); <span class="comment">// turn array key to string</span></div><div class="line"> <span class="keyword">let</span> length = keys.length;</div><div class="line"> <span class="keyword">let</span> index = fromIndex ? fromIndex - <span class="number">1</span> : <span class="number">-1</span>;</div><div class="line"></div><div class="line"> <span class="keyword">while</span> (++index < length) {</div><div class="line"> <span class="keyword">let</span> key = keys[index];</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (isArr) {</div><div class="line"> key = key >>> <span class="number">0</span>; <span class="comment">// turn key to number</span></div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (predicate(collection[key], key, collection)) {</div><div class="line"></div><div class="line"> <span class="keyword">return</span> isArr ? collection[key] : {</div><div class="line"> [key]: collection[key]</div><div class="line"> };</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span>;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="findLast"><a href="#findLast" class="headerlink" title="findLast"></a>findLast</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.findLast(collection, [predicate=_.identity], [fromIndex=collection.length<span class="number">-1</span>])</div></pre></td></tr></table></figure>
<p>与find类似,只是从右往左查找<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> findLast = <span class="function">(<span class="params">collection, predicate, fromIndex</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> isArr = <span class="built_in">Array</span>.isArray(collection);</div><div class="line"></div><div class="line"> <span class="keyword">let</span> keys = <span class="built_in">Object</span>.keys(collection); <span class="comment">// turn array key to string</span></div><div class="line"> <span class="keyword">let</span> length = keys.length;</div><div class="line"> <span class="keyword">let</span> index;</div><div class="line"></div><div class="line"> <span class="comment">// 下标为范围</span></div><div class="line"> <span class="keyword">if</span> (fromIndex !== <span class="literal">undefined</span>) {</div><div class="line"> index = fromIndex < <span class="number">0</span> ? <span class="built_in">Math</span>.max(fromIndex + length, <span class="number">0</span>) : <span class="built_in">Math</span>.min(length - <span class="number">1</span>, fromIndex);</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> index = length - <span class="number">1</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> index += <span class="number">1</span>;</div><div class="line"> <span class="keyword">while</span> (--index > <span class="number">0</span>) {</div><div class="line"> <span class="keyword">let</span> key = keys[index];</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (isArr) {</div><div class="line"> key = key >>> <span class="number">0</span>; <span class="comment">// turn key to number</span></div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (predicate(collection[key], key, collection)) {</div><div class="line"></div><div class="line"> <span class="keyword">return</span> isArr ? collection[key] : {</div><div class="line"> [key]: collection[key]</div><div class="line"> };</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span>;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="groupBy"><a href="#groupBy" class="headerlink" title="groupBy"></a>groupBy</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.groupBy(collection, [iteratee=_.identity])</div></pre></td></tr></table></figure>
<p>根据指定iteratee分组,iteratee迭代每个元素后的值为键,对应的值为之前的元素对应的值所组成的数组,这个借助之前的<code>forEach</code>可以很轻松的实现,但这个对单层数组还可以一用,对多层数组或者对象完全鸡肋啊…<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> groupBy = <span class="function">(<span class="params">collection, iteratee</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> result = {};</div><div class="line"></div><div class="line"> forEach(collection, <span class="function"><span class="keyword">function</span>(<span class="params">val, key, collection</span>) </span>{</div><div class="line"> <span class="keyword">let</span> tag = iteratee(val, key, collection);</div><div class="line"></div><div class="line"> tag = tag.toString();</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!result[tag]) {</div><div class="line"> result[tag] = [];</div><div class="line"> }</div><div class="line"></div><div class="line"> result[tag].push(val);</div><div class="line"> });</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="includes"><a href="#includes" class="headerlink" title="includes"></a>includes</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.includes(collection, value, [fromIndex=<span class="number">0</span>])</div></pre></td></tr></table></figure>
<p>检查collection中从指定的fromIndex开始是否包含value值,此处collection可以为数组、对象和<strong>字符串</strong>,字符串按照<code>substring</code>进行查找<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> includes = <span class="function">(<span class="params">collection, value, fromIndex = <span class="number">0</span></span>) =></span> {</div><div class="line"> <span class="keyword">let</span> length;</div><div class="line"></div><div class="line"> <span class="keyword">let</span> isStr = <span class="keyword">typeof</span> collection === <span class="string">'string'</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (isStr) {</div><div class="line"> length = collection.length;</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> length = <span class="built_in">Object</span>.keys(collection).length;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (fromIndex < <span class="number">0</span>) {</div><div class="line"> fromIndex += length;</div><div class="line"> }</div><div class="line"></div><div class="line"> fromIndex = (fromIndex >= length - <span class="number">1</span>) ? (length - <span class="number">1</span>) : fromIndex;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (isStr) {</div><div class="line"> <span class="keyword">return</span> collection.substring(fromIndex).indexOf(value) > <span class="number">-1</span>;</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> <span class="keyword">let</span> ite = <span class="number">-1</span>;</div><div class="line"> <span class="keyword">let</span> _include = <span class="literal">false</span>;</div><div class="line"> forEach(collection, <span class="function"><span class="keyword">function</span>(<span class="params">val</span>) </span>{</div><div class="line"> ite++;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (ite < fromIndex) {</div><div class="line"> <span class="keyword">return</span>;</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> <span class="keyword">if</span> (val === value) {</div><div class="line"> _include = <span class="literal">true</span>;</div><div class="line"> <span class="keyword">return</span> <span class="literal">false</span>; <span class="comment">// take it over</span></div><div class="line"> }</div><div class="line"> }</div><div class="line"> });</div><div class="line"></div><div class="line"> <span class="keyword">return</span> _include;</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="keyBy"><a href="#keyBy" class="headerlink" title="keyBy"></a>keyBy</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.keyBy(collection, [iteratee=_.identity])</div></pre></td></tr></table></figure>
<p>生成键值对,键名由iteratee迭代每个元素后生成,值为collection对应项,注意iteratee只接受一个参数value,并且对于迭代后重复的键名会覆盖,同样使用<code>forEach</code>可以简单的完成这个功能<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> keyBy = <span class="function">(<span class="params">collection, iteratee</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> result = {};</div><div class="line"> forEach(collection, (val, key, collection) => {</div><div class="line"> result[iteratee(val)] = val;</div><div class="line"> });</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="invokeMap"><a href="#invokeMap" class="headerlink" title="invokeMap"></a>invokeMap</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.invokeMap(collection, path, [args])</div></pre></td></tr></table></figure>
<p>path可接收<code>Array</code>、<code>String</code>和<code>Function</code>…接收数组参数是什么套路,没理解?先以函数为例吧,函数的this在迭代中绑定到collection中的每个元素。最后,还有一个可选参数args,可作为参数传给path<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> invokeMap = <span class="function">(<span class="params">collection, path, ...args</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> result = [];</div><div class="line"></div><div class="line"> forEach(collection, val => {</div><div class="line"> result.push(path.apply(val, args));</div><div class="line"> });</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="orderBy"><a href="#orderBy" class="headerlink" title="orderBy"></a>orderBy</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.orderBy(collection, [iteratees=[_.identity]], [orders])</div></pre></td></tr></table></figure>
<p>TODO留坑</p>
<h2 id="sample"><a href="#sample" class="headerlink" title="sample"></a>sample</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.sample(collection)</div></pre></td></tr></table></figure>
<p>任意返回collection中的一个抽样值<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> sample = <span class="function"><span class="params">collection</span> =></span> {</div><div class="line"> <span class="keyword">let</span> keys = <span class="built_in">Object</span>.keys(collection);</div><div class="line"></div><div class="line"> <span class="keyword">let</span> {length} = keys;</div><div class="line"></div><div class="line"> <span class="keyword">let</span> rand = keys[<span class="built_in">Math</span>.floor((<span class="built_in">Math</span>.random() * length))]; <span class="comment">// 0 ~ length-1</span></div><div class="line"></div><div class="line"> <span class="keyword">return</span> collection[<span class="built_in">Array</span>.isArray(collection) ? ~~rand : rand];</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="sampleSize"><a href="#sampleSize" class="headerlink" title="sampleSize"></a>sampleSize</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.sampleSize(collection, [n=<span class="number">1</span>])</div></pre></td></tr></table></figure>
<p>获取n个collection中的随机元素,扩展下<code>sample</code>方法,然后返回的是个数组<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> sampleSize = <span class="function">(<span class="params">collection, n = <span class="number">1</span></span>) =></span> {</div><div class="line"> <span class="keyword">let</span> result = [];</div><div class="line"> <span class="keyword">let</span> keys = <span class="built_in">Object</span>.keys(collection)</div><div class="line"></div><div class="line"> <span class="keyword">let</span> {length} = keys;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (n > length) {</div><div class="line"> n = length;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (n < <span class="number">1</span>) {</div><div class="line"> n = <span class="number">1</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// 生成n个不同的随机数</span></div><div class="line"> <span class="keyword">let</span> i = <span class="number">0</span>;</div><div class="line"> <span class="keyword">let</span> chosed = [];</div><div class="line"> <span class="keyword">while</span> (i < n) {</div><div class="line"> <span class="keyword">let</span> rand = keys[<span class="built_in">Math</span>.floor((<span class="built_in">Math</span>.random() * length))]; <span class="comment">// 随机数</span></div><div class="line"></div><div class="line"> <span class="comment">// 保证键值不同</span></div><div class="line"> <span class="keyword">if</span> (chosed.indexOf(rand) > <span class="number">-1</span>) {</div><div class="line"> <span class="keyword">continue</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> i++;</div><div class="line"></div><div class="line"> chosed.push(rand);</div><div class="line"></div><div class="line"> result.push(collection[<span class="built_in">Array</span>.isArray(collection) ? ~~rand : rand])</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="map"><a href="#map" class="headerlink" title="map"></a>map</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.map(collection, [iteratee=_.identity])</div></pre></td></tr></table></figure>
<p>返回映射后的数组<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> map = <span class="function">(<span class="params">collection, iteratee</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> result = [];</div><div class="line"></div><div class="line"> forEach(collection, (val, key, collection) => {</div><div class="line"> result.push(iteratee(val, key, collection));</div><div class="line"> });</div><div class="line"> </div><div class="line"> <span class="keyword">return</span> result;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="size"><a href="#size" class="headerlink" title="size"></a>size</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.size(collection)</div></pre></td></tr></table></figure>
<p>可求数组、对象和字符串的尺寸,包括Map和Set<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> size = <span class="function"><span class="params">collection</span> =></span> {</div><div class="line"> <span class="keyword">if</span> (<span class="keyword">typeof</span> collection === <span class="string">'string'</span>) {</div><div class="line"> <span class="keyword">return</span> collection.length;</div><div class="line"> }</div><div class="line"> </div><div class="line"> <span class="keyword">let</span> tag = collection.toString();</div><div class="line"> <span class="keyword">if</span> (tag === <span class="string">'[object Set]'</span> || tag === <span class="string">'[object Map]'</span>){</div><div class="line"> <span class="keyword">return</span> collection.size;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> <span class="built_in">Object</span>.keys(collection).length; <span class="comment">// 数组或者对象</span></div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>源码一直将包含<code>length</code>的非函数变量作为arrayLike,包括数组、字符串和含length属性的类数组对象,可以直接访问到length属性作为size返回。需要修正一下,要不然对于<code>{a: 1, length: 1}</code>这样的类数组会出现问题<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div></pre></td><td class="code"><pre><div class="line"><span class="comment">// length合法值</span></div><div class="line"><span class="keyword">const</span> isLength = <span class="function"><span class="params">val</span> =></span> {</div><div class="line"></div><div class="line"> <span class="comment">// 数字 && 非负 && 非负0 && 小于最大正整数</span></div><div class="line"> <span class="keyword">return</span> <span class="keyword">typeof</span> val === <span class="string">'number'</span> && val > <span class="number">-1</span> && val % <span class="number">1</span> === <span class="number">0</span> && val <= <span class="number">9007199254740991</span>;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">const</span> isArrayLike = <span class="function"><span class="params">arr</span> =></span> {</div><div class="line"> <span class="keyword">return</span> arr !== <span class="literal">null</span> && <span class="keyword">typeof</span> arr !== <span class="string">'function'</span> && isLength(arr.length);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">const</span> size = <span class="function"><span class="params">collection</span> =></span> {</div><div class="line"> <span class="keyword">if</span> (isArrayLike(collection)) {</div><div class="line"> <span class="keyword">return</span> collection.length;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> tag = collection.toString();</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (tag === <span class="string">'[object Set]'</span> || tag === <span class="string">'[object Map]'</span>){</div><div class="line"> <span class="keyword">return</span> collection.size;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> <span class="built_in">Object</span>.keys(collection).length;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="some"><a href="#some" class="headerlink" title="some"></a>some</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.some(collection, [predicate=_.identity])</div></pre></td></tr></table></figure>
<p>collection中任一元素predicate返回truthy值,循环<strong>终止</strong>并返回true,否则返回false<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> some = <span class="function">(<span class="params">collection, predicate</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> _some = <span class="literal">false</span>;</div><div class="line"></div><div class="line"> forEach(collection, (val, key, collection) => {</div><div class="line"> <span class="keyword">if</span> (predicate(val, key, collection)) {</div><div class="line"> _some = <span class="literal">true</span>;</div><div class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</div><div class="line"> }</div><div class="line"> });</div><div class="line"></div><div class="line"> <span class="keyword">return</span> _some;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h1 id="Date"><a href="#Date" class="headerlink" title="Date"></a>Date</h1><h2 id="now"><a href="#now" class="headerlink" title="now"></a>now</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.now()</div></pre></td></tr></table></figure>
<p>获取当前时间的毫秒时间戳<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> now () => {</div><div class="line"> <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Date</span>().getTime();</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h1 id="Number"><a href="#Number" class="headerlink" title="Number"></a>Number</h1><h2 id="random"><a href="#random" class="headerlink" title="random"></a>random</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.random([lower=<span class="number">0</span>], [upper=<span class="number">1</span>], [floating])</div></pre></td></tr></table></figure>
<p>返回lower-upper之间任意的随机数,若lower为传则从0开始,floating=true则会返回浮点数,另外,如果lower或者upper为浮点数,也会返回一个浮点数<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> random = <span class="function">(<span class="params">lower, upper, floating</span>) =></span> {</div><div class="line"> <span class="comment">// 接收参数情况较多,需进行参数校准</span></div><div class="line"></div><div class="line"> <span class="comment">// 参数不满</span></div><div class="line"> <span class="keyword">if</span> (<span class="keyword">typeof</span> floating === <span class="string">'undefined'</span>) {</div><div class="line"></div><div class="line"> <span class="comment">// 2个参数,第2个参数为浮点数,则第一个参数为upper</span></div><div class="line"> <span class="keyword">if</span> (<span class="keyword">typeof</span> upper === <span class="string">'boolean'</span>) {</div><div class="line"> floating = upper;</div><div class="line"></div><div class="line"> upper = lower;</div><div class="line"></div><div class="line"> lower = <span class="literal">undefined</span>;</div><div class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (<span class="keyword">typeof</span> lower === <span class="string">'boolean'</span>) {</div><div class="line"> <span class="comment">// 1个参数</span></div><div class="line"></div><div class="line"> floating = lower;</div><div class="line"> lower = <span class="literal">undefined</span>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (<span class="keyword">typeof</span> lower === <span class="string">'undefined'</span>) {</div><div class="line"> lower = <span class="number">0</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (<span class="keyword">typeof</span> upper === <span class="string">'undefined'</span>) {</div><div class="line"> upper = <span class="number">1</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// lower > upper的情况则交换</span></div><div class="line"> <span class="keyword">if</span> (lower > upper) {</div><div class="line"> [lower, upper] = [upper, lower];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// 通过number % 1判断是否为浮点数</span></div><div class="line"> <span class="keyword">if</span> (floating || lower % <span class="number">1</span> || upper % <span class="number">1</span>) {</div><div class="line"> <span class="comment">// 范围浮点数的方法有点诡异啊...</span></div><div class="line"> <span class="keyword">let</span> rand = <span class="built_in">Math</span>.random(); <span class="comment">// 0 - 1</span></div><div class="line"> <span class="keyword">let</span> len = <span class="string">`<span class="subst">${rand}</span>`</span>.length;</div><div class="line"></div><div class="line"> <span class="keyword">return</span> <span class="built_in">Math</span>.min(lower + (rand * (upper - lower + <span class="built_in">parseFloat</span>(<span class="string">`1e-<span class="subst">${len}</span>`</span>))), upper); <span class="comment">// ...</span></div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// 整数</span></div><div class="line"> <span class="keyword">return</span> lower + <span class="built_in">Math</span>.floor((<span class="built_in">Math</span>.random() * (upper - lower + <span class="number">1</span>)));</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="inRange"><a href="#inRange" class="headerlink" title="inRange"></a>inRange</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.inRange(number, [start=<span class="number">0</span>], end)</div></pre></td></tr></table></figure>
<p>判断一个数字是否在start和end(不包含end)之间,start为可选参数,默认为0,如果start大于end<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> inRange = <span class="function">(<span class="params">number, start, end</span>) =></span> {</div><div class="line"> <span class="keyword">if</span> (<span class="keyword">typeof</span> end === <span class="string">'undefined'</span>) {</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (<span class="keyword">typeof</span> start === <span class="string">'undefined'</span>) {</div><div class="line"> <span class="keyword">return</span> <span class="literal">false</span>; <span class="comment">// 无range</span></div><div class="line"> }</div><div class="line"></div><div class="line"> end = start;</div><div class="line"> start = <span class="number">0</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (end > start) {</div><div class="line"> <span class="keyword">return</span> number >= start && number < end;</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> <span class="keyword">return</span> number > end && number <= start;</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="clamp"><a href="#clamp" class="headerlink" title="clamp"></a>clamp</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.clamp(number, [lower], upper)</div></pre></td></tr></table></figure>
<p>名字好隐晦…保证返回值在lower和upper之间,小于lower则返回lower,大于upper则返回upper<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> clamp = <span class="function">(<span class="params">number, lower, upper</span>) =></span> {</div><div class="line"> number = ~~number;</div><div class="line"> lower = ~~lower;</div><div class="line"> upper = ~~upper;</div><div class="line"></div><div class="line"> <span class="comment">// 判断NaN</span></div><div class="line"> lower = lower === lower ? lower : <span class="number">0</span>;</div><div class="line"> upper = upper === upper ? upper : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (number === number) {</div><div class="line"> <span class="comment">// compare to upper</span></div><div class="line"> number = number <= upper ? number : upper;</div><div class="line"></div><div class="line"> <span class="comment">// compare to lower</span></div><div class="line"> number = number >= lower ? number : lower;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> number;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h1 id="Math"><a href="#Math" class="headerlink" title="Math"></a>Math</h1><h2 id="mean"><a href="#mean" class="headerlink" title="mean"></a>mean</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.mean(array)</div></pre></td></tr></table></figure>
<p>求数字平均数<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> mean = <span class="function"><span class="params">array</span> =></span> {</div><div class="line"> <span class="keyword">let</span> sum = array.reduce(<span class="function">(<span class="params">total, i</span>) =></span> {</div><div class="line"> <span class="keyword">return</span> total + i;</div><div class="line"> }, <span class="number">0</span>);</div><div class="line"> <span class="keyword">let</span> {length} = array;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> <span class="literal">NaN</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> sum / length;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="add"><a href="#add" class="headerlink" title="add"></a>add</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.add(augend, addend)</div></pre></td></tr></table></figure>
<p>不仅可以数字相加,也可以实现字符串的相加,并且参数为空时返回默认值0<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> add = <span class="function">(<span class="params">augend, addend</span>) =></span> {</div><div class="line"> <span class="keyword">if</span> (<span class="keyword">typeof</span> augend === <span class="string">'undefined'</span> && <span class="keyword">typeof</span> addend === <span class="string">'undefined'</span>) {</div><div class="line"> <span class="keyword">return</span> <span class="number">0</span>; <span class="comment">// default val</span></div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (<span class="keyword">typeof</span> addend === <span class="string">'undefined'</span>) {</div><div class="line"> addend = <span class="keyword">typeof</span> augend === <span class="string">'string'</span> ? <span class="string">''</span> : <span class="number">0</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> augend + addend;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="divide"><a href="#divide" class="headerlink" title="divide"></a>divide</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.divide(dividend, divisor)</div></pre></td></tr></table></figure>
<p>两数字相除,默认值为1<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> divide = <span class="function">(<span class="params">dividend, divisor</span>) =></span> {</div><div class="line"> <span class="keyword">if</span> (<span class="keyword">typeof</span> dividend === <span class="string">'undefined'</span> && <span class="keyword">typeof</span> divisor === <span class="string">'undefined'</span>) {</div><div class="line"> <span class="keyword">return</span> <span class="number">1</span>; <span class="comment">// default val</span></div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (<span class="keyword">typeof</span> divisor === <span class="string">'undefined'</span>) {</div><div class="line"> divisor = <span class="number">1</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> dividend / divisor;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="ceil"><a href="#ceil" class="headerlink" title="ceil"></a>ceil</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.ceil(number, [precision=<span class="number">0</span>])</div></pre></td></tr></table></figure>
<p>数字向上取整,并可指定精度<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> ceil = <span class="function">(<span class="params">number, precision = <span class="number">0</span></span>) =></span> {</div><div class="line"> <span class="comment">// 这一波precision操作666啊,保持关注</span></div><div class="line"> <span class="keyword">if</span> (precision) {</div><div class="line"></div><div class="line"> <span class="comment">// 排除科学计数法的数字影响?</span></div><div class="line"> <span class="keyword">let</span> pair = <span class="string">`<span class="subst">${number}</span>e`</span>.split(<span class="string">'e'</span>);</div><div class="line"></div><div class="line"> <span class="keyword">let</span> val = <span class="built_in">Math</span>.ceil(<span class="string">`<span class="subst">${pair[<span class="number">0</span>]}</span>e<span class="subst">${~~pair[<span class="number">1</span>] + precision}</span>`</span>); <span class="comment">// 可以接受字符串参数...</span></div><div class="line"></div><div class="line"> pair = <span class="string">`<span class="subst">${val}</span>e`</span>.split(<span class="string">'e'</span>);</div><div class="line"></div><div class="line"> <span class="keyword">return</span> +<span class="string">`<span class="subst">${pair[<span class="number">0</span>]}</span>e<span class="subst">${~~pair[<span class="number">1</span>] - precision}</span>`</span></div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> <span class="built_in">Math</span>.ceil(number);</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p><code>Math.ceil(4.231, -2) === 100</code>哈哈</p>
<h2 id="floor"><a href="#floor" class="headerlink" title="floor"></a>floor</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.floor(number, [precision=<span class="number">0</span>])</div></pre></td></tr></table></figure>
<p>同理ceil,方法换为<code>Math.floor</code>;还有<code>round</code>实现四舍五入的同理</p>
<h2 id="max"><a href="#max" class="headerlink" title="max"></a>max</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.max(array)</div></pre></td></tr></table></figure>
<p>接受数字数组,求max… 还有另外一个扩展的方法<code>_.maxBy(array, [iteratee=_.identity])</code>可以一起实现<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> baseMax = <span class="function">(<span class="params">array, iteratee</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> index = <span class="number">0</span>;</div><div class="line"> <span class="keyword">let</span> length = array ? array.length : <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!iteratee) {</div><div class="line"> iteratee = <span class="function"><span class="params">val</span> =></span> val;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> max = array[<span class="number">0</span>];</div><div class="line"> <span class="keyword">let</span> computedMax = iteratee(max);</div><div class="line"></div><div class="line"> <span class="keyword">while</span> (++index < length) {</div><div class="line"> <span class="keyword">let</span> cur = array[index];</div><div class="line"></div><div class="line"> <span class="keyword">let</span> computed = iteratee(cur);</div><div class="line"></div><div class="line"> <span class="comment">// NOTE:symbol不可隐式转化为数字参与比较</span></div><div class="line"> <span class="keyword">if</span> (<span class="keyword">typeof</span> computed !== <span class="string">'symbol'</span> && computed > computedMax) {</div><div class="line"> max = cur;</div><div class="line"> computedMax = computed;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> max;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>另外,同理的还有<code>min</code>和<code>minBy</code>,不赘述</p>
<h2 id="mean-1"><a href="#mean-1" class="headerlink" title="mean"></a>mean</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.mean(array)</div></pre></td></tr></table></figure>
<p>求数组的平均值… 同样也有扩展方法<code>_.meanBy(array, [iteratee=_.identity])</code>,iteratee接受一个参数value<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> baseMean = <span class="function">(<span class="params">array, iteratee</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> {length} = array;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> <span class="literal">NaN</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!iteratee) {</div><div class="line"> iteratee = <span class="function"><span class="params">val</span> =></span> val;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// 因为iteratee的因素,还不能直接用reduce来求sum值</span></div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"> <span class="keyword">let</span> sum = <span class="number">0</span>;</div><div class="line"> <span class="keyword">while</span>(++index < length) {</div><div class="line"> <span class="keyword">let</span> cur = iteratee(array[index]);</div><div class="line"> sum += (cur === <span class="literal">undefined</span> ? <span class="number">0</span> : cur);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> sum / length;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="multiply"><a href="#multiply" class="headerlink" title="multiply"></a>multiply</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.multiply(multiplier, multiplicand)</div></pre></td></tr></table></figure>
<p>两变量相乘,参数为空时默认值为1<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> multiply = <span class="function">(<span class="params">multiplier, multiplicand</span>) =></span> {</div><div class="line"> <span class="keyword">if</span> (multiplier === <span class="literal">undefined</span> && multiplicand === <span class="literal">undefined</span>) {</div><div class="line"> <span class="keyword">return</span> <span class="number">1</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (multiplicand === <span class="literal">undefined</span>) {</div><div class="line"> <span class="keyword">return</span> multiplier;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> multiplier * multiplicand;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="subtract"><a href="#subtract" class="headerlink" title="subtract"></a>subtract</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.subtract(minuend, subtrahend)</div></pre></td></tr></table></figure>
<p>减法,有默认值为0…类似乘法不赘述</p>
<h2 id="sum"><a href="#sum" class="headerlink" title="sum"></a>sum</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.sum(array)</div></pre></td></tr></table></figure>
<p>求数组的“加法”运算,也包括字符串,引用上面<code>mean</code>求值的sum算式即可。另外,也有<code>sumBy</code>方法,接收2个参数,另外一个参数<code>iteratee</code><br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> baseSum = <span class="function">(<span class="params">array, iteratee</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> {length} = array;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!length) {</div><div class="line"> <span class="keyword">return</span> <span class="number">0</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!iteratee) {</div><div class="line"> iteratee = <span class="function"><span class="params">val</span> =></span> val;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"> <span class="keyword">let</span> sum = <span class="number">0</span>;</div><div class="line"> <span class="keyword">while</span>(++index < length) {</div><div class="line"> <span class="keyword">let</span> cur = iteratee(array[index]);</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (cur === <span class="literal">undefined</span>) {</div><div class="line"> <span class="keyword">continue</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> sum += cur;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> sum;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h1 id="String"><a href="#String" class="headerlink" title="String"></a>String</h1><h2 id="loweFrirst"><a href="#loweFrirst" class="headerlink" title="loweFrirst"></a>loweFrirst</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.lowerFirst([string=<span class="string">''</span>])</div></pre></td></tr></table></figure>
<p>小写字符串的首字母<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> lowerFirst = <span class="function">(<span class="params">string = <span class="string">''</span></span>) =></span> {</div><div class="line"> <span class="keyword">if</span> (string !== <span class="literal">null</span>) {</div><div class="line"> string = <span class="keyword">typeof</span> string === <span class="string">'string'</span> ? string : string.toString();</div><div class="line"></div><div class="line"> <span class="keyword">let</span> head = string.match(<span class="regexp">/^[A-Z]/</span>);</div><div class="line"></div><div class="line"> head = head ? head[<span class="number">0</span>] : head;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (head) {</div><div class="line"> <span class="keyword">return</span> string.replace(<span class="regexp">/^([A-Z])(.*)/</span>, <span class="string">`<span class="subst">${head.toLowerCase()}</span>$2`</span>)</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> <span class="keyword">return</span> string;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> <span class="string">''</span>;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>同理,首字母大写是同样的实现,不赘述</p>
<h2 id="toLower-toUpper"><a href="#toLower-toUpper" class="headerlink" title="toLower / toUpper"></a>toLower / toUpper</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="comment">// 小写</span></div><div class="line">_.toLower([string=<span class="string">''</span>])</div><div class="line"><span class="comment">// 大写</span></div><div class="line">_.toUpper([string=<span class="string">''</span>])</div></pre></td></tr></table></figure>
<p>将字符串中的字母转换为小写或者大写,直接调用标准方法即可<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> toLower = <span class="function">(<span class="params">string = <span class="string">''</span></span>) =></span> {</div><div class="line"> <span class="keyword">if</span> (string !== <span class="literal">null</span>) {</div><div class="line"> string = <span class="keyword">typeof</span> string === <span class="string">'string'</span> ? string : string.toString();</div><div class="line"></div><div class="line"> <span class="keyword">return</span> string.toLowerCase();</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> <span class="string">''</span>;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="capitalize"><a href="#capitalize" class="headerlink" title="capitalize"></a>capitalize</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.capitalize([string=<span class="string">''</span>])</div></pre></td></tr></table></figure>
<p>首字母大写,剩余的小写。先全部转化为小写,再首字母大写就可以了<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> capitalize = <span class="function">(<span class="params">string = <span class="string">''</span></span>) =></span> {</div><div class="line"> <span class="keyword">return</span> upperFirst(toLower(string));</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="endsWith"><a href="#endsWith" class="headerlink" title="endsWith"></a>endsWith</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.endsWith([string=<span class="string">''</span>], [target], [position=string.length])</div></pre></td></tr></table></figure>
<p>判断字符串到position位置是否是以target结尾的<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> endsWith = <span class="function">(<span class="params">string, target, position</span>) =></span> {</div><div class="line"> <span class="keyword">if</span> (string === <span class="literal">undefined</span> || target === <span class="literal">undefined</span>) {</div><div class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> position = position === <span class="literal">undefined</span> ? string.length : +position;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (position < <span class="number">0</span> || position !== position) {</div><div class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// 正则</span></div><div class="line"> <span class="keyword">let</span> sliceStr = string.slice(<span class="number">0</span>, position);</div><div class="line"></div><div class="line"> <span class="keyword">let</span> regx = <span class="keyword">new</span> <span class="built_in">RegExp</span>(<span class="string">`<span class="subst">${target}</span>$`</span>);</div><div class="line"></div><div class="line"> <span class="keyword">return</span> regx.test(sliceStr);</div><div class="line"></div><div class="line"> <span class="comment">// 或者也可以通过字符串截取</span></div><div class="line"> <span class="comment">// let end = position;</span></div><div class="line"> <span class="comment">// position -= target.length;</span></div><div class="line"></div><div class="line"> <span class="comment">// return position >= 0 && string.slice(position, end) == target; // 未强等,'123'找数字3也是可以的</span></div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="pad"><a href="#pad" class="headerlink" title="pad"></a>pad</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.pad([string=<span class="string">''</span>], [length=<span class="number">0</span>], [chars=<span class="string">' '</span>])</div></pre></td></tr></table></figure>
<p>用chars补全字符串到指定length<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> repeat = <span class="function">(<span class="params">str, times</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> res = str;</div><div class="line"></div><div class="line"> <span class="keyword">while</span> (--times) {</div><div class="line"> res += str;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> res;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">const</span> pad = <span class="function">(<span class="params">string, length, chars</span>) =></span> {</div><div class="line"> <span class="keyword">if</span> (string === <span class="literal">undefined</span>) {</div><div class="line"> <span class="keyword">return</span> <span class="string">''</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> length = +length;</div><div class="line"></div><div class="line"> <span class="keyword">let</span> {<span class="attr">length</span>: len} = string;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (length <= len) {</div><div class="line"> <span class="keyword">return</span> string;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">let</span> offset = length - len;</div><div class="line"></div><div class="line"> <span class="keyword">let</span> left = <span class="built_in">Math</span>.floor(offset / <span class="number">2</span>);</div><div class="line"> <span class="keyword">let</span> right = offset - left;</div><div class="line"></div><div class="line"> chars = chars === <span class="literal">undefined</span> ? <span class="string">' '</span> : chars.toString();</div><div class="line"></div><div class="line"> <span class="keyword">let</span> charsLen = chars.length;</div><div class="line"></div><div class="line"> <span class="keyword">return</span> repeat(chars, <span class="built_in">Math</span>.ceil(left / charsLen)).slice(<span class="number">0</span>, left) +</div><div class="line"> string +</div><div class="line"> repeat(chars, <span class="built_in">Math</span>.ceil(right / charsLen)).slice(<span class="number">0</span>, right)</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="padEnd-padStart"><a href="#padEnd-padStart" class="headerlink" title="padEnd / padStart"></a>padEnd / padStart</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">_.padEnd([string=<span class="string">''</span>], [length=<span class="number">0</span>], [chars=<span class="string">' '</span>])</div><div class="line"><span class="comment">//</span></div><div class="line">_.padStart([string=<span class="string">''</span>], [length=<span class="number">0</span>], [chars=<span class="string">' '</span>])</div></pre></td></tr></table></figure>
<p>类似于pad,向字符串尾部或者头部补全指定字符串</p>
<h2 id="repeat"><a href="#repeat" class="headerlink" title="repeat"></a>repeat</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.repeat([string=<span class="string">''</span>], [n=<span class="number">1</span>])</div></pre></td></tr></table></figure>
<p>在实现<code>pad</code>功能的时候,我们有一个重复字符串的函数<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> repeat = <span class="function">(<span class="params">str, times</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> res = str;</div><div class="line"></div><div class="line"> <span class="keyword">while</span> (--times) {</div><div class="line"> res += str;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> res;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>So easy?no,至少不是那么完美。比如把’a’重复4次,上面做法需要执行4次字符串合并,那常规做法,我可以把第一次合并的结果再做一次合并就可以了。优化的算法:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> repeat = <span class="function">(<span class="params">str, times</span>) =></span> {</div><div class="line"> <span class="keyword">let</span> result = <span class="string">''</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (!str || times < <span class="number">1</span>) {</div><div class="line"> <span class="keyword">return</span> result;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">do</span> {</div><div class="line"> <span class="keyword">if</span> (times % <span class="number">2</span>) {</div><div class="line"> result += str;</div><div class="line"> }</div><div class="line"></div><div class="line"> times = <span class="built_in">Math</span>.floor(times / <span class="number">2</span>);</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (times) {</div><div class="line"> str += str;</div><div class="line"> }</div><div class="line"> } <span class="keyword">while</span> (times)</div><div class="line"></div><div class="line"> <span class="keyword">return</span> result;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="escape"><a href="#escape" class="headerlink" title="escape"></a>escape</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.escape([string=<span class="string">''</span>])</div></pre></td></tr></table></figure>
<p>转义特殊字符:<code>&</code>、<code><</code>、<code>></code>、<code>"</code>、<code>'</code><br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> escapeMap = {</div><div class="line"> <span class="string">'&'</span>: <span class="string">'&amp'</span>,</div><div class="line"> <span class="string">'<'</span>: <span class="string">'&lt'</span>,</div><div class="line"> <span class="string">'>'</span>: <span class="string">'&gt'</span>,</div><div class="line"> <span class="string">'"'</span>: <span class="string">'&quot'</span>,</div><div class="line"> <span class="string">"'"</span>: <span class="string">'&#39'</span></div><div class="line">};</div><div class="line"></div><div class="line"><span class="keyword">const</span> <span class="built_in">escape</span> = <span class="function">(<span class="params">string = <span class="string">''</span></span>) =></span> {</div><div class="line"> <span class="keyword">if</span> (string && <span class="regexp">/[&<>"']/g</span>.test(string)) {</div><div class="line"> <span class="keyword">return</span> string.replace(<span class="regexp">/[&<>"']/g</span>, char => escapeMap[char]);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> string;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="escapeRegExp"><a href="#escapeRegExp" class="headerlink" title="escapeRegExp"></a>escapeRegExp</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.escapeRegExp([string=<span class="string">''</span>])</div></pre></td></tr></table></figure>
<p>转义字符串中的正则表达式字符<code>^</code>、 <code>$</code>、 <code>.</code>、 <code>\</code>、 <code>*</code>、 <code>+</code>、 <code>?</code>、 <code>(</code>、 <code>)</code>、 <code>[</code>、 <code>]</code>、 <code>{</code>、 <code>}</code>、 <code>|</code><br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> reg = <span class="regexp">/[\\^$.*+?()[\]{}|]/g</span>; <span class="comment">// 这里注意\],防止闭合正则的前[</span></div><div class="line"></div><div class="line"><span class="keyword">const</span> escapeRegExp = <span class="function">(<span class="params">string = <span class="string">''</span></span>) =></span> {</div><div class="line"> <span class="keyword">if</span> (string && reg.test(string)) {</div><div class="line"> <span class="keyword">return</span> string.replace(reg, <span class="string">'\\$&'</span>); <span class="comment">// $& is matched substring</span></div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> string;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>顺带小case,除<code>$&</code>,字符串替换还有多种模式,Turn to <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_string_as_a_parameter" target="_blank" rel="external">MDN</a></p>
<h2 id="parseInt"><a href="#parseInt" class="headerlink" title="parseInt"></a>parseInt</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.parseInt(string, [radix=<span class="number">10</span>])</div></pre></td></tr></table></figure>
<p>字符串转化为数字<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> <span class="built_in">parseInt</span> = <span class="function">(<span class="params">string, radix</span>) =></span> {</div><div class="line"> <span class="keyword">if</span> (radix === <span class="literal">null</span>) {</div><div class="line"> radix = <span class="number">0</span>;</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> radix = +radix;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> nativeParseInt(string.replace(<span class="regexp">/^\s+/</span>, <span class="string">''</span>), radix); <span class="comment">// 调native的parseint实现,补:消除头尾空格</span></div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>脑补radix值的以及默认参数转化方法,如果radix是<code>undefined</code>或者<code>0</code>,会自动根据字符串的前缀进行对应的转换数字操作:</p>
<ul>
<li>If the input string begins with “0x” or “0X”, radix is 16 (hexadecimal) and the remainder of the string is parsed.</li>
<li>If the input string begins with “0”, radix is eight (octal) or 10 (decimal). Exactly which radix is chosen is implementation-dependent. ECMAScript 5 specifies that 10 (decimal) is used, but not all browsers support this yet. For this reason always specify a radix when using parseInt.(对于<code>0</code>开头的字符串,浏览器解析有差异,所以建议parseInt指定radix参数)</li>
<li>If the input string begins with any other value, the radix is 10 (decimal).</li>
</ul>
<h2 id="replace"><a href="#replace" class="headerlink" title="replace"></a>replace</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.replace([string=<span class="string">''</span>], pattern, replacement)</div></pre></td></tr></table></figure>
<p>字符串替换,pattern可以是正则表达式或者字符串<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> replace = <span class="function">(<span class="params">...args</span>) =></span> {</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (args.length < <span class="number">3</span>) {</div><div class="line"> <span class="keyword">return</span> <span class="string">`<span class="subst">${args[<span class="number">0</span>]}</span>`</span>;</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> <span class="keyword">let</span> [string, pattern, replacement] = args;</div><div class="line"></div><div class="line"> <span class="keyword">return</span> <span class="string">`<span class="subst">${string}</span>`</span>.replace(pattern, replacement);</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="split"><a href="#split" class="headerlink" title="split"></a>split</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.split([string=<span class="string">''</span>], separator, [limit])</div></pre></td></tr></table></figure>
<p>字符串分割,也可以指定界限(也就是最终得到的数组的元素个数,原生也有这个参数…);<br>另外,separator可以是字符串也可以是正则,原生也是支持的…当separator=undefined或者separator没有出现在string中时,返回原字符串;当separator=’’时,返回字符串分割成单个字母的数组<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> MAX_ARRAY_LENGTH = <span class="number">4294967295</span>;</div><div class="line"></div><div class="line"><span class="keyword">const</span> split = <span class="function">(<span class="params">string, separator, limit</span>) =></span> {</div><div class="line"> <span class="comment">// 确保limit是一个正整数</span></div><div class="line"> limit = limit === <span class="literal">undefined</span> ? MAX_ARRAY_LENGTH : limit >>> <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (limit === <span class="number">0</span>) {</div><div class="line"> <span class="keyword">return</span> [];</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (string === <span class="literal">undefined</span>) {</div><div class="line"> <span class="keyword">return</span> <span class="string">''</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> string.toString().split(separator, limit);</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>源码<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">if</span> (string && (</div><div class="line"> <span class="keyword">typeof</span> separator == <span class="string">'string'</span> ||</div><div class="line"> (separator != <span class="literal">null</span> && !isRegExp(separator))</div><div class="line"> )) {</div><div class="line"> <span class="keyword">if</span> (!separator && hasUnicode(string)) {</div><div class="line"> <span class="keyword">return</span> castSlice(stringToArray(string), <span class="number">0</span>, limit)</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>这是什么样的一个套路,没看明白…</p>
]]></content>
<summary type="html">
<blockquote>
<p>巧妙的函数实现吸引着你想去看看他的实现方法,里面会有更多奇思妙想让你欣喜若狂…</p>
</blockquote>
<h1 id="Array"><a href="#Array" class="headerlink" title="Array"></a>Array</h1><h2 id="chunk"><a href="#chunk" class="headerlink" title="chunk"></a>chunk</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">_.chunk(array, [size=1])</div></pre></td></tr></table></figure>
<p>猜想下实现方法,功能就是将数组拆分成<code>arrar.length / size</code>个数组,每个数组<code>size</code>个元素,剩余的元素作为最后一个分组,数组操作中<code>slice</code>不改变原数组并实现数组切分:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> chunk = <span class="function">(<span class="params">array, size = <span class="number">1</span></span>) =&gt;</span> &#123;</div><div class="line"> <span class="keyword">let</span> count = <span class="built_in">Math</span>.ceil(array.length / size);</div><div class="line"></div><div class="line"> <span class="keyword">let</span> _chunk = <span class="keyword">new</span> <span class="built_in">Array</span>(count);</div><div class="line"></div><div class="line"> <span class="keyword">let</span> index = <span class="number">-1</span>;</div><div class="line"> <span class="keyword">let</span> start = <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">while</span> (++index &lt; count) &#123;</div><div class="line"> _chunk[index] = array.slice(start, start += size);</div><div class="line"> &#125;</div><div class="line"></div><div class="line"> <span class="keyword">return</span> _chunk;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
</summary>
<category term="Lodash" scheme="http://www.i0011.com/tags/Lodash/"/>
</entry>
<entry>
<title>Https养成手记</title>
<link href="http://www.i0011.com/2016/10/09/https-config/"/>
<id>http://www.i0011.com/2016/10/09/https-config/</id>
<published>2016-10-09T09:48:42.000Z</published>
<updated>2017-04-07T01:46:44.000Z</updated>
<content type="html"><![CDATA[<p>把大象放进冰箱分三步,那么实现https化你的网站也可以分三步:</p>
<ol>
<li><code>openssl req -newkey rsa:2048 -keyout server.key -out server.csr</code>在服务器上生成key和csr,可以直接扔在nginx目录,方便。此处需要<strong>注意</strong>的是,生成的private key需要移除passphrase,就是运行前面命令时让输入的<code>PEM</code>的值,否则nginx error。<br>执行<code>openssl rsa -in server.key -out unencripted-server.key</code>就OK了,我们在nginx配置中就使用未加密的key文件</li>
<li>去<a href="https://www.startssl.com/Certificates/ApplySSLCert?level=1" target="_blank" rel="external">Startssl</a>,将刚才得到的server.csr文件内容填入表单中,Submit!<br><img src="https://dn-xuqi.qbox.me/https.png" alt="Startssl配置"><br>然后下载生成的证书,因为我用的是nginx,就将NginxServer下面的的crt文件scp到服务器中</li>
<li>配置nginx并将http80重定向到443即可<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div></pre></td><td class="code"><pre><div class="line">server {</div><div class="line"> listen 443 ssl;</div><div class="line"> ssl_certificate /path/to/crt;</div><div class="line"> ssl_certificate_key /path/to/unencripted/key;</div><div class="line"> ssl_session_tickets off;</div><div class="line"> ssl_session_cache shared:SSL:10m;</div><div class="line"> server_name yourdomain;</div><div class="line"></div><div class="line"> location / {</div><div class="line"> proxy_redirect off;</div><div class="line"> proxy_pass http://yourUpstream;</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line">server {</div><div class="line"> listen 80;</div><div class="line"> server_name yourdomain;</div><div class="line"> return 301 https://yourdomain$request_uri;</div><div class="line">}</div></pre></td></tr></table></figure>
</li>
</ol>
<p>Got it… nginx reload就可以了</p>
<p>Thanks to:<br><a href="https://segmentfault.com/a/1190000007024673?utm_source=weekly&utm_medium=email&utm_campaign=email_weekly" target="_blank" rel="external">给你的网站穿上外衣 - HTTPS 免费部署指南</a><br><a href="http://stackoverflow.com/questions/18101217/error-102-nginx-ssl" target="_blank" rel="external">Nginx 102 error ssl</a></p>
]]></content>
<summary type="html">
<p>把大象放进冰箱分三步,那么实现https化你的网站也可以分三步:</p>
<ol>
<li><code>openssl req -newkey rsa:2048 -keyout server.key -out server.csr</code>在服务器上生成key和csr,
</summary>
<category term="Https" scheme="http://www.i0011.com/tags/Https/"/>
<category term="Ubuntu" scheme="http://www.i0011.com/tags/Ubuntu/"/>
<category term="Nginx" scheme="http://www.i0011.com/tags/Nginx/"/>
</entry>
<entry>
<title>destructuring</title>
<link href="http://www.i0011.com/2016/09/25/destructuring/"/>
<id>http://www.i0011.com/2016/09/25/destructuring/</id>
<published>2016-09-25T03:48:01.000Z</published>
<updated>2016-11-25T00:34:34.000Z</updated>
<content type="html"><![CDATA[<p><strong>destructuring</strong>,解构,可以方便coder们从Object/Array中提取想要的数据,Es6大杀器…</p>
<p>按照阮老师的说法,解构其实就属于一种数据结构的模式匹配,匹配上的模式对应的值会从表达式右侧赋值给表达式左侧,比如:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">let</span> {name, <span class="attr">info</span>: {age}} = {</div><div class="line"> <span class="attr">name</span>: <span class="string">'xuqi'</span>,</div><div class="line"> <span class="attr">info</span>: {</div><div class="line"> <span class="attr">age</span>: <span class="number">27</span></div><div class="line"> }</div><div class="line">};</div><div class="line"></div><div class="line">name; <span class="comment">// 'xuqi'</span></div><div class="line">age; <span class="comment">// 27</span></div></pre></td></tr></table></figure></p>
<p>我们就能直接获取<strong>模式</strong>name和age的值,赋值给<strong>变量</strong>name和age,需要注意的是模式和变量的概念,这是理解解构的基础,<br><code>{mode: var}</code>,<code>:</code>左侧为模式,右侧为变量,上述例子是当模式和变量名相同时的缩写,实际上是:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">let</span> {<span class="attr">name</span>: name, <span class="attr">info</span>: {</div><div class="line"> <span class="attr">age</span>: age</div><div class="line">}} = ...</div></pre></td></tr></table></figure></p>
<p>这样理解起来就清楚了。解构可以从数组和对象中提取值,分别来说明…<br><a id="more"></a></p>
<h2 id="Array-destructuring"><a href="#Array-destructuring" class="headerlink" title="Array destructuring"></a>Array destructuring</h2><h3 id="basic-variable-assignment"><a href="#basic-variable-assignment" class="headerlink" title="basic variable assignment"></a>basic variable assignment</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">let</span> [one, two, three] = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>];</div></pre></td></tr></table></figure>
<p>当然,变量声明和解构赋值可以分开进行:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">let</span> one, two, three;</div><div class="line">[one, two, three] = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>];</div></pre></td></tr></table></figure></p>
<h3 id="default-values"><a href="#default-values" class="headerlink" title="default values"></a>default values</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">let</span> [a = <span class="number">1</span>, b = <span class="number">2</span>] = [<span class="number">3</span>];</div><div class="line"></div><div class="line">a; <span class="comment">// 3</span></div><div class="line">b; <span class="comment">// 2</span></div></pre></td></tr></table></figure>
<p>默认值生效的条件是右侧对应位置的值<strong>严格</strong>等于<code>undefined</code>,下述情况是不会发生默认值赋值的:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">let</span> [a = <span class="number">1</span>] = [<span class="literal">null</span>];</div><div class="line"></div><div class="line">a; <span class="comment">// null</span></div></pre></td></tr></table></figure></p>
<p>另外,阮老师的书里面说到的一种情况可能平时不太会经常用到,但是还是需要注意下:在默认值是通过函数返回值赋值的情况下,函数是惰性求职的,即在不使用默认值的情况下,函数是不会被执行的<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> fn = <span class="function"><span class="params">()</span> =></span> {</div><div class="line"> <span class="built_in">console</span>.log(<span class="string">'Hey, I am here'</span>);</div><div class="line"> <span class="keyword">return</span> <span class="number">1</span>;</div><div class="line">};</div><div class="line"></div><div class="line"><span class="keyword">let</span> [a = fn()] = [<span class="number">1</span>];</div><div class="line"></div><div class="line"><span class="comment">// fn didn't invoke</span></div></pre></td></tr></table></figure></p>
<p>当然默认值也可以引用变量(外部变量/解构变量),当默认值引用解构变量时,需要注意在设置默认值时必须确保引用的解构变量已经声明,否则将报错<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">let a = 1;</div><div class="line">let [x = a, y = x] = [];</div><div class="line"></div><div class="line">x; // 1</div><div class="line">y; // 1</div></pre></td></tr></table></figure></p>
<h3 id="swapping-variable"><a href="#swapping-variable" class="headerlink" title="swapping variable"></a>swapping variable</h3><p>轻松实现变量交换<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">let</span> a = <span class="number">1</span>;</div><div class="line"><span class="keyword">let</span> b = <span class="number">2</span>;</div><div class="line"></div><div class="line">[a, b] = [b, a];</div></pre></td></tr></table></figure></p>
<h3 id="parsing-an-array-returned-from-a-function-amp-ignore-some-variable"><a href="#parsing-an-array-returned-from-a-function-amp-ignore-some-variable" class="headerlink" title="parsing an array returned from a function & ignore some variable"></a>parsing an array returned from a function & ignore some variable</h3><p>我们常见的场景,需要通过函数返回多个变量,通过解构的话就可以拿到返回的多个值,并且可以忽略某个或多个值。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> fn = <span class="function"><span class="params">()</span> =></span> [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>];</div><div class="line"></div><div class="line"><span class="keyword">let</span> [a, , b] = fn();</div><div class="line"></div><div class="line">a; <span class="comment">// 1</span></div><div class="line">b; <span class="comment">// 3</span></div></pre></td></tr></table></figure></p>
<h2 id="Object-destructuring"><a href="#Object-destructuring" class="headerlink" title="Object destructuring"></a>Object destructuring</h2><p>同数组,对象也可以按照结构进行解构赋值,文章开头已经举了一个basic assignment的例子,这里就继续说明其他的使用场景和注意事项。</p>
<h3 id="assignment-without-declaration"><a href="#assignment-without-declaration" class="headerlink" title="assignment without declaration"></a>assignment without declaration</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">let</span> a, b;</div><div class="line">({a, b} = {<span class="attr">a</span>: <span class="number">1</span>, <span class="attr">b</span>: <span class="number">2</span>});</div></pre></td></tr></table></figure>
<p>需要注意的是,当解构赋值跟声明分开进行时,解构表达式外的<code>()</code>是必须得,否则解析左侧是会当成一个块级表达式,从而导致因=号的出现而报错。</p>
<h3 id="assignment-to-new-variable-name"><a href="#assignment-to-new-variable-name" class="headerlink" title="assignment to new variable name"></a>assignment to new variable name</h3><p>对象的解构可以指定赋值的变量名:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">let</span> {<span class="attr">name</span>: theName, <span class="attr">info</span>: {<span class="attr">age</span>: theAge}} = {</div><div class="line"> <span class="attr">name</span>: <span class="string">'xuqi'</span>,</div><div class="line"> <span class="attr">info</span>: {</div><div class="line"> <span class="attr">age</span>: <span class="number">27</span></div><div class="line"> }</div><div class="line">};</div><div class="line"></div><div class="line">theName; <span class="comment">// 'xuqi'</span></div><div class="line">theAge; <span class="comment">// 27</span></div></pre></td></tr></table></figure></p>
<p>之前已经介绍过模式和变量名的形式,这里就很好理解了,由于指定了变量名,name和age只是模式</p>
<h3 id="default-values-1"><a href="#default-values-1" class="headerlink" title="default values"></a>default values</h3><p>跟数组一样,对象解构也可以设置默认值<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">let</span> {a = <span class="number">1</span>, <span class="attr">b</span>:c = <span class="number">2</span>} = {<span class="attr">a</span>: <span class="number">2</span>};</div><div class="line"></div><div class="line">a; <span class="comment">// 2</span></div><div class="line">c; <span class="comment">// 2</span></div></pre></td></tr></table></figure></p>
<p>对象解构的默认值有一种比较重要的应用场景:函数的默认参数<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> fn = <span class="function">(<span class="params">{a = <span class="number">1</span>, b = <span class="number">2</span>} = {}</span>) =></span> {</div><div class="line"> <span class="keyword">return</span> [a, b];</div><div class="line">};</div><div class="line"></div><div class="line">fn();</div></pre></td></tr></table></figure></p>
<p>这篇流水账的起因是因为TS2.0发布了然后去看了下文档,瞬间被加了type的解构表达式搞晕了,然后就想着写个文章来捋一捋,毕竟看别人文章跟自己写出来还是有点差别的,想看详细的还是看文档或者阮老师的书比较好,想要了解下或者重新梳理思路,这篇文章适合你</p>
<p>参考资料:<br><a href="http://es6.ruanyifeng.com/#docs/destructuring" target="_blank" rel="external">阮一峰《ECMAScript6入门》变量的解构赋值</a><br><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment" target="_blank" rel="external">MDN Destructuring assignment</a></p>
]]></content>
<summary type="html">
<p><strong>destructuring</strong>,解构,可以方便coder们从Object/Array中提取想要的数据,Es6大杀器…</p>
<p>按照阮老师的说法,解构其实就属于一种数据结构的模式匹配,匹配上的模式对应的值会从表达式右侧赋值给表达式左侧,比如:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">let</span> &#123;name, <span class="attr">info</span>: &#123;age&#125;&#125; = &#123;</div><div class="line"> <span class="attr">name</span>: <span class="string">'xuqi'</span>,</div><div class="line"> <span class="attr">info</span>: &#123;</div><div class="line"> <span class="attr">age</span>: <span class="number">27</span></div><div class="line"> &#125;</div><div class="line">&#125;;</div><div class="line"></div><div class="line">name; <span class="comment">// 'xuqi'</span></div><div class="line">age; <span class="comment">// 27</span></div></pre></td></tr></table></figure></p>
<p>我们就能直接获取<strong>模式</strong>name和age的值,赋值给<strong>变量</strong>name和age,需要注意的是模式和变量的概念,这是理解解构的基础,<br><code>{mode: var}</code>,<code>:</code>左侧为模式,右侧为变量,上述例子是当模式和变量名相同时的缩写,实际上是:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">let</span> &#123;<span class="attr">name</span>: name, <span class="attr">info</span>: &#123;</div><div class="line"> <span class="attr">age</span>: age</div><div class="line">&#125;&#125; = ...</div></pre></td></tr></table></figure></p>
<p>这样理解起来就清楚了。解构可以从数组和对象中提取值,分别来说明…<br>
</summary>
<category term="Es6" scheme="http://www.i0011.com/tags/Es6/"/>
</entry>
<entry>
<title>What the f**k of Postcss</title>
<link href="http://www.i0011.com/2016/01/28/what-the-fuck-of-postcss/"/>
<id>http://www.i0011.com/2016/01/28/what-the-fuck-of-postcss/</id>
<published>2016-01-28T05:37:31.000Z</published>
<updated>2016-11-25T00:34:34.000Z</updated>
<content type="html"><![CDATA[<blockquote>
<p>PostCSS is a tool for transforming styles with JS plugins. These plugins can lint your CSS, support variables and mixins, transpile future CSS syntax, inline images, and more.</p>
</blockquote>
<p>对于Postcss,这样介绍来开启话题最合适不过。大部分人对Postcss的认知还是CSS pre-preprocessor,因此经常会有将Postcss和Sass/Less/Stylus进行对比的情况。那Postcss到底是什么?</p>
<p>Postcss只是一个工具,获取CSS内容并将其转化成JS插件可以处理的数据,如此基于Postcss的JS插件便可基于Postcss提供的数据进行对应的处理。目前Postcss Plugin的列表数目已经200+,提供诸于:auto-prefix、next-css、linter、short-name等功能。另外,由于Postcss的职能是类似于工具箱,用户可以选择自己的工具放进去,所以你可以根据自身的开发喜好和需求去开发自己的“工具”扔到工具箱里去,心有多大,世界就有多大,勇敢的少年啊,快去创造奇迹~<br><a id="more"></a></p>
<p>在认清Postcss的真实面目后,搬出下面这段摘抄的话,会显得逼格很高:</p>
<blockquote>
<ul>
<li>It’s not a pre-processor, though it can optionally behave like one.</li>
<li>It’s not a post-processor, though it can optionally behave like one.</li>
<li>It’s not about “future syntax”, though it can facilitate support for future syntax</li>
<li>It’s not a clean up / optimization tool, though it can provide such functionality.</li>
<li>It’s not any one thing; it’s a means to potentially unlimited functionality configured as you choose.</li>
</ul>
</blockquote>
<p>也就是,它看起来什么都是,然而本质上它什么都不是,但是它什么都能干。万剑归宗,万法归一,嗯,就是这种意思了…</p>
<p>口说无凭,祭出插件杀器:</p>
<ul>
<li><a href="https://github.com/postcss/autoprefixer" target="_blank" rel="external">autoprefixer</a> 为指定的browsers生成兼容性CSS,你只需按照W3C的标准去书写你的样式就好了,接下的事autoprefixer帮你摆平</li>
<li><a href="https://github.com/jonathantneal/precss" target="_blank" rel="external">precss</a> 如果你需要像Sass提供的:variables、mixins、conditionals等功能,precss是不二之选</li>
<li><a href="https://github.com/postcss/postcss-import" target="_blank" rel="external">postcss-import</a> 使用@import,并且可以获取第三方的样式(比如bower或者npm)</li>
<li><a href="https://github.com/ben-eb/cssnano" target="_blank" rel="external">cssnano</a> css<strong>优化</strong>(清除注释和尾分号、合并规则,字体权重优化等等等…),压缩…强大</li>
<li><a href="https://github.com/assetsjs/postcss-assets" target="_blank" rel="external">postcss-assets</a> img/font加载路径解决方案,另外还提供获取图片尺寸以及将图片转化为base64写入css的功能</li>
<li><a href="https://github.com/2createStudio/postcss-sprites" target="_blank" rel="external">postcss-sprites</a> image sprite</li>
<li>…颜色处理,可读性处理,简化输入,优化,打包,<a href="http://postcss.parts/" target="_blank" rel="external">自行探索>>></a></li>
</ul>
<p>怎么去用?Gulp!你应该享受现代工具~<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> gulp = <span class="built_in">require</span>(<span class="string">'gulp'</span>),</div><div class="line"> postcss = <span class="built_in">require</span>(<span class="string">'gulp-postcss'</span>),</div><div class="line"> sourcemap = <span class="built_in">require</span>(<span class="string">'gulp-sourcemaps'</span>);</div><div class="line">gulp.task(<span class="string">'css'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</div><div class="line"> gulp.src(<span class="string">'css/**/*.css'</span>)</div><div class="line"> .pipe(sourcemap.init())</div><div class="line"> .pipe(postcss([</div><div class="line"> <span class="built_in">require</span>(<span class="string">'autoprefixer'</span>)({</div><div class="line"> <span class="attr">browsers</span>: [<span class="string">'not ie < 8'</span>]</div><div class="line"> }),</div><div class="line"> <span class="built_in">require</span>(<span class="string">'precss'</span>),</div><div class="line"> <span class="built_in">require</span>(<span class="string">'postcss-assets'</span>)({</div><div class="line"> <span class="attr">loadPaths</span>: [<span class="string">'font/'</span>, <span class="string">'img/'</span>],</div><div class="line"> <span class="attr">relativeTo</span>: <span class="string">'css/post/'</span></div><div class="line"> }),</div><div class="line"> <span class="built_in">require</span>(<span class="string">'postcss-sprites'</span>).default({</div><div class="line"> <span class="attr">basePath</span>: <span class="string">'./img'</span>, <span class="comment">//img base path</span></div><div class="line"> stylesheetPath: <span class="string">'./css'</span>, <span class="comment">//path of css generated</span></div><div class="line"> spritePath: <span class="string">'./img'</span>, <span class="comment">//path of sprites generated</span></div><div class="line"> spritesmith: {</div><div class="line"> <span class="attr">padding</span>: <span class="number">2</span>,</div><div class="line"> },</div><div class="line"> <span class="attr">groupBy</span>: <span class="function"><span class="keyword">function</span>(<span class="params">file</span>) </span>{</div><div class="line"> <span class="keyword">var</span> group = file.url.split(<span class="string">'/'</span>)[<span class="number">1</span>]; <span class="comment">// 根据目录分组,防止合并后的图片太大</span></div><div class="line"> <span class="keyword">return</span> group ? <span class="built_in">Promise</span>.resolve(group) : <span class="built_in">Promise</span>.reject();</div><div class="line"> }</div><div class="line"> })</div><div class="line"> ]))</div><div class="line"> .pipe(sourcemap.write(<span class="string">'.'</span>))</div><div class="line"> .pipe(gulp.dest(<span class="string">'dist/'</span>))</div><div class="line">});</div></pre></td></tr></table></figure></p>
<h3 id="题外话"><a href="#题外话" class="headerlink" title="题外话"></a>题外话</h3><p>由于正在使用Compass,不自主会把这两个工具进行比较:<br>Compass是Sass的扩展,提供了很多牛X的Minix和功能(比如:无可比拟的image-sprite)。用过Compass的可能会有疑问了,你上面讲的在Compass都能做啊,而且我还不用去找很多插件来实现我的功能,去网站翻使用指南和它的API就可以了,不要太强大…然而,出问题的就是他的强,大:</p>
<ol>
<li>Compass需要依赖Ruby,这一点就足够判死刑</li>
<li>Compass提供了很多@mixin,其中也包括类似于autoprefix的功能,但是,前提是:我得知道我要写的属性需要进行prefix处理,所以对大部分人来说,这个功能属于鸡肋功能。对于一些辅助的功能实现的mixin,我们可能会想到去官网搜索,然而,这个比prefix的处理更让人头疼,在一个全站颜色统一,甚至对搜索结果都不做突出的网站上找到想要的API是有多难,搜索结果下你会发现不知所云的搜索结果</li>
<li>我们并不需要Compass提供的那么多内置mixin</li>
<li>对compass认知程度有限,上述叙述若有偏颇,勿怪,个人观点…当然,不可否认还是有很多出色的功能的~</li>
</ol>
<p>对比Compass,我更喜欢Postcss带来的体验,把一切交给npm,无需其他乱七八糟的环境的配置,通过一些基本的插件,可以实现从Compass到Postcss的无缝切换,而且Postcss的开放性必然会给以后带来诸多Compass所不会有的好处。插件多样性可以帮你处理各种常见问题:嫌每天重复输入相同的width,height…你可以用<code>postcss-short</code>或者<code>postcss-size</code>;嫌<code>#3f3f3f</code>这种输入浪费时间,<code>postcss-color-short</code>帮你解决后顾之忧,你只用输入<code>#3f</code>;想像写Es6那样享受超前的快感,<code>cssnext</code>带你装逼;想摆脱老是写水平居中或者垂直居中的困扰,<code>postcss-center</code>助你一臂之力;clearfix的功能在你只用写<code>clear:fix</code>的情况下,也有插件<code>postcss-clearfix</code>帮你铺平道路;甚至连css的语法检查,也有插件给你两肋插刀…总之大到模块化,小到画三角,应有尽有,各取所需就好…</p>
<p>灵活性+开放性+易用性+扩展性….足够了,写Postcss,挺好~</p>
]]></content>
<summary type="html">
<blockquote>
<p>PostCSS is a tool for transforming styles with JS plugins. These plugins can lint your CSS, support variables and mixins, transpile future CSS syntax, inline images, and more.</p>
</blockquote>
<p>对于Postcss,这样介绍来开启话题最合适不过。大部分人对Postcss的认知还是CSS pre-preprocessor,因此经常会有将Postcss和Sass/Less/Stylus进行对比的情况。那Postcss到底是什么?</p>
<p>Postcss只是一个工具,获取CSS内容并将其转化成JS插件可以处理的数据,如此基于Postcss的JS插件便可基于Postcss提供的数据进行对应的处理。目前Postcss Plugin的列表数目已经200+,提供诸于:auto-prefix、next-css、linter、short-name等功能。另外,由于Postcss的职能是类似于工具箱,用户可以选择自己的工具放进去,所以你可以根据自身的开发喜好和需求去开发自己的“工具”扔到工具箱里去,心有多大,世界就有多大,勇敢的少年啊,快去创造奇迹~<br>
</summary>
<category term="HandBook" scheme="http://www.i0011.com/tags/HandBook/"/>
<category term="Postcss" scheme="http://www.i0011.com/tags/Postcss/"/>
</entry>
<entry>
<title>React server side render</title>
<link href="http://www.i0011.com/2016/01/24/react-ssr/"/>
<id>http://www.i0011.com/2016/01/24/react-ssr/</id>
<published>2016-01-24T12:20:17.000Z</published>
<updated>2016-11-25T00:34:34.000Z</updated>
<content type="html"><![CDATA[<p>如何使用React开发高效可<del>装B</del>用的WEB应用:) … 融合React以及React-ssr、koa、Es6、Postcss,绽放吧,骚年…</p>
<p><a href="https://github.com/loveLibra/React-ssr-demo" target="_blank" rel="external">DEMO传送门>>>></a></p>
<ol>
<li><p>JSX支持Runtime<br><code>require('node-jsx').install({harmony: true});</code>。添加harmony选项可在JSX中使用部分ES6的特性,但是未完全支持.</p>
</li>
<li><p>browserify打包客户端脚本</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">browserify(<span class="string">'./js/index.js'</span>)</div><div class="line"> .transform(babelify, {</div><div class="line"> <span class="attr">presets</span>: [<span class="string">'es2015'</span>, <span class="string">'react'</span>]</div><div class="line"> })</div><div class="line"> .bundle()</div><div class="line"> .pipe(fs.createWriteStream(<span class="string">'dist/bundle.js'</span>));</div></pre></td></tr></table></figure>
</li>
<li><p>React服务端渲染<br>将一个纯View用在此处其实有点别扭,但是为了SEO以及一些页面渲染性能的考虑,需要服务端渲染。React-SSR就是通过<code>ReactDOMServer.renderToString</code>得到HTML渲染到页面中,然后在客户端重新初始化组件,React并不会蠢的去重新渲染页面,所以此处可以忽略前端再次初始化带来的性能和使用体验的问题…前端初始化组件也是需要带数据的,所以在后端渲染组件时,我们将数据也带带页面中,然后再前端初始化后再删除数据DOM即可.<br>另外,在渲染字符串到页面中时,<code>views/partials/content.html</code>中放置渲染好的HTML的标签:</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="comment"><!-- 不能有换行,否则客户端渲染时因为识别空白节点的问题在前端初始化失败。--></span></div><div class="line"><span class="tag"><<span class="name">div</span> <span class="attr">id</span>=<span class="string">"yoho-container"</span>></span>{{{content}}}<span class="tag"></<span class="name">div</span>></span></div></pre></td></tr></table></figure>
</li>
<li><p>Koa<br>koa + yield真的是太明智了,让代码不再一层层的去嵌套回调,棒!路由,接口取数据,数据格式化,页面渲染能对程序员展现以同步的形式去实现,跳出恶魔金字塔吧,Koa带你飞~</p>
</li>
<li>Postcss<br>Postcss相对于Compass的优势,在于其灵活性和轻便性,需要什么功能,扩展postcss插件就行了,autoprefixer,sprite-image应有尽有,Get what You Need…</li>
</ol>
<p>后记:前端现在愈发膨胀和夸张,无数的轮子和框架来方便你的开发,然而得有度,别让自己的程序失去控制…前端现在就像一匹飞奔的马,跑的很快,但是跑到哪你却不知道,你唯一能做的就是练好骑马的技术,别从马上摔下来。夯实基础,成就你的精湛马术吧</p>
<p>精彩的参考资料:<br><a href="http://www.crmarsh.com/react-ssr/" target="_blank" rel="external">Rendering React Components on the Server</a></p>
]]></content>
<summary type="html">
<p>如何使用React开发高效可<del>装B</del>用的WEB应用:) … 融合React以及React-ssr、koa、Es6、Postcss,绽放吧,骚年…</p>
<p><a href="https://github.com/loveLibra/React-ssr-
</summary>
<category term="Es6" scheme="http://www.i0011.com/tags/Es6/"/>
<category term="React" scheme="http://www.i0011.com/tags/React/"/>
<category term="Ssr" scheme="http://www.i0011.com/tags/Ssr/"/>
<category term="Koa" scheme="http://www.i0011.com/tags/Koa/"/>
<category term="Browserify" scheme="http://www.i0011.com/tags/Browserify/"/>
<category term="Postcss" scheme="http://www.i0011.com/tags/Postcss/"/>
</entry>
<entry>
<title>js-oop</title>
<link href="http://www.i0011.com/2016/01/11/js-oop/"/>
<id>http://www.i0011.com/2016/01/11/js-oop/</id>
<published>2016-01-11T07:50:22.000Z</published>
<updated>2016-11-25T00:34:34.000Z</updated>
<content type="html"><![CDATA[<p>Javascript可能是一门让人感觉“不适”的语言,实现<code>类</code>、<code>继承</code>等OOP概念竟然要通过<code>function</code>和<code>prototype</code>,Jser们可能理解原型机制就能伤半管子HP了。然而,这种情况随着ES6的到来变得好了起来,ES6提供了<code>class</code>、<code>extends</code>等语法糖可以帮你摆脱让人苦闷的原型(当然,如果你有高追求,你得理解),虽然JS的OOP的实现原理还是通过原型的,但是至少对开发者的友好性提升了很多,让JS更有OOP的味道也更接近于其他OOP的语言。现在我们也能很简单的来声明一个类:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">People</span> </span>{</div><div class="line"> <span class="keyword">constructor</span>(name, age) {</div><div class="line"> <span class="keyword">this</span>.name = name;</div><div class="line"> <span class="keyword">this</span>.age = age;</div><div class="line"> }</div><div class="line"></div><div class="line"> say() {</div><div class="line"> alert(<span class="string">`Hello, I am <span class="subst">${<span class="keyword">this</span>.name}</span>`</span>);</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p>
<a id="more"></a>
<p>这要是放ES5时代呢?<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">People</span>(<span class="params">name, age</span>) </span>{</div><div class="line"> <span class="keyword">this</span>.name = name;</div><div class="line"> <span class="keyword">this</span>.age = age;</div><div class="line">}</div><div class="line"></div><div class="line">People.prototype.say = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</div><div class="line"> alert(<span class="string">'Hello, I am '</span> + <span class="keyword">this</span>.name);</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>两者new对象的实现方式一致:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> p = <span class="keyword">new</span> People(<span class="string">'xuqi'</span>, <span class="number">26</span>);</div><div class="line">p.say();</div></pre></td></tr></table></figure></p>
<p>对比两者的实现,可以大致了解ES6提供的类的实现细节是怎样的。</p>
<p>接下来,我们来构建一个Woman类,继承自People类,并实现<code>buy</code>方法。先看ES5的两种实现方式(PS:可结合扩展,比如添加自己的factory方法等):<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//方法一:Prototype</span></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">Woman</span>(<span class="params"></span>) </span>{}</div><div class="line"></div><div class="line">Woman.prototype = <span class="keyword">new</span> People();</div><div class="line"></div><div class="line">Woman.prototype.buy = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</div><div class="line"> alert(<span class="string">'双11,买买买'</span>);</div><div class="line">};</div><div class="line"></div><div class="line">Woman.prototype.constructor = Woman; <span class="comment">//修正constructor</span></div></pre></td></tr></table></figure></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//方法二:call/apply</span></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">Woman</span>(<span class="params">name, age</span>) </span>{</div><div class="line"> People.call(<span class="keyword">this</span>, name, age);</div><div class="line">}</div><div class="line"></div><div class="line">Woman.prototype.buy = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</div><div class="line"> alert(<span class="string">'双11,买买买'</span>);</div><div class="line">};</div></pre></td></tr></table></figure>
<p>方法一通过原型机制实现继承,设置子类的prototype为父类的一个实例化对象即可;方法二通过call,在子类的上下文环境中执行父类的构造函数即可获得父类的属性和方法。两者的方法扩展都需通过prototype去实现。</p>
<p>但是上述两种方法在例子中都有问题:通过原型的实现在绑定子类prototype为父类的实例化对象时,必须初始化父类,要不然父类的参数(name, age)就不能使用了;通过call/apply方法实现的子类的实例化对象无法使用父类绑定在prototype上的方法(say)。因此我们需要结合两者:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">Woman</span>(<span class="params">name, age</span>) </span>{</div><div class="line"> People.call(<span class="keyword">this</span>, name, age);</div><div class="line">}</div><div class="line"></div><div class="line">Woman.prototype = <span class="keyword">new</span> People();</div><div class="line"></div><div class="line">Woman.prototype.constructor = Woman;</div><div class="line"></div><div class="line">Woman.prototype.buy = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</div><div class="line"> alert(<span class="string">'双11,买买买'</span>);</div><div class="line">};</div></pre></td></tr></table></figure></p>
<p>再来看看ES6的继承是怎样实现的:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">Woman</span> <span class="keyword">extends</span> <span class="title">People</span> </span>{</div><div class="line"> <span class="keyword">constructor</span>(name, age) {</div><div class="line"> <span class="keyword">super</span>(name, age);</div><div class="line"> }</div><div class="line"></div><div class="line"> buy() {</div><div class="line"> alert(<span class="string">'双11,买买买'</span>);</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>ES6的代码简洁明了,通过<code>extends</code>可以简单的实现类的继承。需要注意的是,子类的构造函数中需先调用<code>super()</code>从而生成一个父类的实例化对象即<code>this</code>,然后再对this进行扩展,因此在super调用前使用this会报错;在ES5中实现对象则相反,先生成子类实例化对象this,然后向this中扩展父类的方法和属性.</p>
<h3 id="扩展:"><a href="#扩展:" class="headerlink" title="扩展:"></a>扩展:</h3><ol>
<li>ES5的继承实现中为什么需要<code>Woman.prototype.constructor = Woman;</code>?<br>对象都有<code>constructor</code>属性,为一个函数,标识构造出该对象的构造函数,对象默认的constructor为<code>function Object(){...}</code>;<br>因此该问题中,若不重新制定constructor到Woman(){…},通过Woman实例化出来的对象的constructor = Woman.prototype.constructor = (new People()).constructor = People(){…}。这显然不是我们想看到的。</li>
<li><p>ES5中父类和子类的关系到底是怎样串联起来的?<br>构造两条<strong>继承链</strong>:<br>(1)实例继承<br>(2)构造函数继承/静态属性方法继承<br>实现模式:</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//实例继承</span></div><div class="line"><span class="built_in">Object</span>.setPrototypeOf(Sub.prototype, Parent.prototype);</div><div class="line"><span class="comment">//等同于</span></div><div class="line">Sub.prototype.__proto__ = Parent.prototype;</div><div class="line"></div><div class="line"><span class="comment">//构造函数继承</span></div><div class="line"><span class="built_in">Object</span>.setPrototypeOf(Sub, Parent);</div><div class="line"><span class="comment">//等同于</span></div><div class="line">Sub.__proto__ = Parent;</div></pre></td></tr></table></figure>
</li>
<li><p>在ES5的例子中,我们通过<code>Woman.prototype = new People();</code>实现了实例继承,推导式:Woman.prototype.__proto__ = (new People()).__proto__ = People.prototype;根据2,我们可以完善上述ES5的继承的实现–补充构造函数的继承,添加如下代码:</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">Object</span>.setPrototypeOf ?</div><div class="line"> <span class="built_in">Object</span>.setPrototypeOf(Woman, People) :</div><div class="line"> Woman.__proto__ = People;</div></pre></td></tr></table></figure>
</li>
<li><p>完整的继承实现后,我们可以得到如下等式:</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> sub = <span class="keyword">new</span> Sub();</div><div class="line"></div><div class="line"><span class="comment">//true</span></div><div class="line">sub.__proto__ === Sub.prototype;</div><div class="line">sub.constructor === Sub;</div><div class="line"></div><div class="line">sub <span class="keyword">instanceof</span> Sub;</div><div class="line">sub <span class="keyword">instanceof</span> Parent;</div><div class="line">Sub.prototype <span class="keyword">instanceof</span> Parent;</div><div class="line"></div><div class="line">Parent.prototype.constructor === Parent;</div><div class="line"></div><div class="line"><span class="built_in">Object</span>.getPrototypeOf(Sub) === Parent;</div></pre></td></tr></table></figure>
</li>
</ol>
<p>附:<br><img src="https://dn-xuqi.qbox.me/proto.jpg" alt="原型原理图"></p>
]]></content>
<summary type="html">
<p>Javascript可能是一门让人感觉“不适”的语言,实现<code>类</code>、<code>继承</code>等OOP概念竟然要通过<code>function</code>和<code>prototype</code>,Jser们可能理解原型机制就能伤半管子HP了。然而,这种情况随着ES6的到来变得好了起来,ES6提供了<code>class</code>、<code>extends</code>等语法糖可以帮你摆脱让人苦闷的原型(当然,如果你有高追求,你得理解),虽然JS的OOP的实现原理还是通过原型的,但是至少对开发者的友好性提升了很多,让JS更有OOP的味道也更接近于其他OOP的语言。现在我们也能很简单的来声明一个类:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">People</span> </span>&#123;</div><div class="line"> <span class="keyword">constructor</span>(name, age) &#123;</div><div class="line"> <span class="keyword">this</span>.name = name;</div><div class="line"> <span class="keyword">this</span>.age = age;</div><div class="line"> &#125;</div><div class="line"></div><div class="line"> say() &#123;</div><div class="line"> alert(<span class="string">`Hello, I am <span class="subst">$&#123;<span class="keyword">this</span>.name&#125;</span>`</span>);</div><div class="line"> &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
</summary>
<category term="Js Basic" scheme="http://www.i0011.com/tags/Js-Basic/"/>
<category term="Es6" scheme="http://www.i0011.com/tags/Es6/"/>
<category term="OOP" scheme="http://www.i0011.com/tags/OOP/"/>
</entry>
<entry>
<title>respondjs-proxy</title>
<link href="http://www.i0011.com/2016/01/08/respond-proxy/"/>
<id>http://www.i0011.com/2016/01/08/respond-proxy/</id>
<published>2016-01-08T02:47:43.000Z</published>
<updated>2016-11-25T00:34:34.000Z</updated>
<content type="html"><![CDATA[<p><strong>respond.js</strong>用来解决IE9以下不支持媒体查询的问题。</p>
<p>在静态资源(CSS)和网站在同一域名的情况下使用起来很简单:<br><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"stylesheet"</span> <span class="attr">href</span>=<span class="string">"path/to/cssfile.css"</span>></span></div><div class="line"><span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"path/to/respond.js"</span>></span><span class="undefined"></span><span class="tag"></<span class="name">script</span>></span></div></pre></td></tr></table></figure></p>
<p>引入HTML并置于css文件引用位置之后即可。<br><a id="more"></a><br>然而大部分情况下并非如此,静态资源都会放在cdn上进行访问加速,这样就产生了域名不一致而导致respondjs在跨域的情况下失效的问题。Github上作者对该<a href="https://github.com/scottjehl/Respond#cdnx-domain-setup" target="_blank" rel="external">问题</a>的产生给出了阐述,感兴趣的可以去看下。<a href="https://github.com/scottjehl/Respond/tree/master/cross-domain" target="_blank" rel="external">代码</a>中也给出了解决示例。此处给出解决方法:<br><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">link</span> <span class="attr">href</span>=<span class="string">"path/to/respond-proxy.html"</span> <span class="attr">id</span>=<span class="string">"respond-proxy"</span> <span class="attr">rel</span>=<span class="string">"respond-proxy"</span> /></span></div><div class="line"><span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"path/to/respond.proxy.js"</span>></span><span class="undefined"></span><span class="tag"></<span class="name">script</span>></span></div><div class="line"><span class="tag"><<span class="name">link</span> <span class="attr">href</span>=<span class="string">"path/to/respond.proxy.gif"</span> <span class="attr">id</span>=<span class="string">"respond-redirect"</span> <span class="attr">rel</span>=<span class="string">"respond-redirect"</span> /></span></div></pre></td></tr></table></figure></p>
<p>再加载上述三行代码到HTML中即可。需要注意的是<code>respond-proxy.html</code>需要与静态资源放在同一域名下。</p>
<p>Enjoy it~</p>
]]></content>
<summary type="html">
<p><strong>respond.js</strong>用来解决IE9以下不支持媒体查询的问题。</p>
<p>在静态资源(CSS)和网站在同一域名的情况下使用起来很简单:<br><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="tag">&lt;<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"stylesheet"</span> <span class="attr">href</span>=<span class="string">"path/to/cssfile.css"</span>&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"path/to/respond.js"</span>&gt;</span><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></div></pre></td></tr></table></figure></p>
<p>引入HTML并置于css文件引用位置之后即可。<br>
</summary>
<category term="Solution" scheme="http://www.i0011.com/tags/Solution/"/>
<category term="IE8" scheme="http://www.i0011.com/tags/IE8/"/>
</entry>
<entry>
<title>REM是个坑,精确控制不适合</title>
<link href="http://www.i0011.com/2015/06/18/bad-rem/"/>
<id>http://www.i0011.com/2015/06/18/bad-rem/</id>
<published>2015-06-18T06:56:05.000Z</published>
<updated>2016-11-25T00:34:34.000Z</updated>
<content type="html"><![CDATA[<p>前两天需要做一个涂鸦的活动页面,来瞅瞅<img src="https://dn-xuqi.qbox.me/yoho-q1.png" alt="年中大促"><br><a id="more"></a><br>简要介绍下这个页面,就是一个ABC选择,选中某项后加红色区分然后右侧动画闪动。<em>[图片版权声明:版权归YOHO所有]</em></p>
<p>拿到这个页面第一反应就是好*蛋啊,就是个图片页面了然后需要点击的地方就绝对定位一个div盖在上面。考虑是手机端的页面,那就可以使用REM神器了:</p>
<ol>
<li><p>加上脚本</p>
<pre><code>(function (doc, win) {
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function () {
var clientWidth = docEl.clientWidth;
if (!clientWidth) {
return;
}
docEl.style.fontSize = 20 * (clientWidth / 320) + 'px';
};
if (!doc.addEventListener) {
return;
}
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
</code></pre></li>
<li>使用方法<br>css中原来用px的换成rem就可以了,40px = 1rem</li>
<li>脚本根据屏幕尺寸会在html元素上生成个font-size的样式,然后页面渲染时都会根据这个值和rem的数值等比例生成对应屏幕的尺寸或者位置。</li>
</ol>
<p>大体功能都能满足,但是在进行选项图标200ms每帧切换的时候却出现了问题,会抖动,那找原因就是通过雪碧图切换background-position位置不准咯,而且在各个手机上不同的选项各有抖动与不抖动的情况。</p>
<p>就是使用rem的原因,不同的屏幕生成的根font-size不一样然后计算后就会出现定位不准的问题了,最后还是换成了直接切换background-image了,雪碧图用不了。(ps:如果用rem可以实现请告诉我…)</p>
<p>另外这个页面还有另外一个情况,看到会有选中项的颜色区分。最开始做的时候是把整个图片除掉选项右边的小图标(图标会有动画实现因此时单独的)作为底图然后选中后就在对应项上面加一个有颜色的div。事实肯定不如所意了,文字和ABC会被盖住….最后的解决办法是:灰色的底图单独是一层作为最底层,然后页面图片去底图在最上面,选中时的颜色div放在两层中间就可以了…但是这样对上层图切的要求就高了,要不然你会发现边边角角全是白色的锯齿。</p>
]]></content>
<summary type="html">
<p>前两天需要做一个涂鸦的活动页面,来瞅瞅<img src="https://dn-xuqi.qbox.me/yoho-q1.png" alt="年中大促"><br>
</summary>
<category term="CSS" scheme="http://www.i0011.com/tags/CSS/"/>
<category term="Solution" scheme="http://www.i0011.com/tags/Solution/"/>
</entry>
<entry>
<title>Handlebars使用指南</title>
<link href="http://www.i0011.com/2015/04/30/handlebars/"/>
<id>http://www.i0011.com/2015/04/30/handlebars/</id>
<published>2015-04-30T09:49:41.000Z</published>
<updated>2016-11-25T00:34:34.000Z</updated>
<content type="html"><![CDATA[<p><a href="http://handlebarsjs.com/" target="_blank" rel="external">Handlebars</a>为Mustache的超集,即:在完全兼容Mustache语法的基础上,提供了很多语法糖,不要太甜…</p>
<h2 id="Begin-Now"><a href="#Begin-Now" class="headerlink" title="Begin Now"></a>Begin Now</h2><h3 id="写在前面"><a href="#写在前面" class="headerlink" title="写在前面"></a>写在前面</h3><p>这里我们只介绍一些Handlebars中相对于Mustache超集的部分,若不了解Mustache,请<a href="http://i0011.com/2015/04/30/Mustache%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/" target="_blank" rel="external">移步</a><br><a id="more"></a></p>
<h3 id="Expressions"><a href="#Expressions" class="headerlink" title="Expressions"></a>Expressions</h3><p>表达式就是{{}}里面包的东西,Handlebars中语法的最小单位。{{xx}}表示在<strong>当前上下文环境</strong>中去寻找xx属性,并用xx属性的值去替换之。Handlebars支持<code>.</code>分隔的属性{{xx.yy}},但在有的情况下<code>.</code>不能解决我们的问题,比如:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div></pre></td><td class="code"><pre><div class="line">data = {</div><div class="line"> <span class="attr">articles</span>: [</div><div class="line"> {</div><div class="line"> <span class="string">'#comments'</span>: {</div><div class="line"> <span class="attr">author</span>: <span class="string">'dabai'</span>,</div><div class="line"> <span class="attr">date</span>: <span class="string">'2015.4.30'</span></div><div class="line"> }</div><div class="line"> },</div><div class="line"> {</div><div class="line"> <span class="string">'#comments'</span>: [</div><div class="line"> {</div><div class="line"> <span class="attr">author</span>: <span class="string">'xuqi'</span>,</div><div class="line"> <span class="attr">date</span>: <span class="string">'2015.4.30'</span></div><div class="line"> },</div><div class="line"> {</div><div class="line"> <span class="attr">author</span>: <span class="string">'xuqi-two'</span>,</div><div class="line"> <span class="attr">date</span>: <span class="string">'2015.4.30'</span></div><div class="line"> },</div><div class="line"> {</div><div class="line"> <span class="attr">author</span>: <span class="string">'xuqi-three'</span>,</div><div class="line"> <span class="attr">date</span>: <span class="string">'2015.4.30'</span></div><div class="line"> },</div><div class="line"> ...</div><div class="line"> ],</div><div class="line"> ...</div><div class="line"> }</div><div class="line"> ]</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>需要渲染articles数组第2项的’#comments’的数据,我们用<code>.</code>怎么分隔?<code>articles.2.#comments</code>?…呵呵哒…跟js一样嘛,我们可以用<code>[]</code>:<br><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">{{# each articles.[10].[#comment]}}</div><div class="line"> <span class="tag"><<span class="name">h1</span>></span>{{author}}{{date}}<span class="tag"></<span class="name">h1</span>></span></div><div class="line">{{/ each}}</div></pre></td></tr></table></figure></p>
<p>上述这种情况在需要取数据某一元素或者渲染的属性名不是合理的Handlebars标识名时适用。</p>
<h3 id="Helper"><a href="#Helper" class="headerlink" title="Helper"></a>Helper</h3><p>Handlebars中可以让我们体验飞一般感觉的重量级语法糖,精华所在,可以帮助我们现在前段时间因为使用简单Mustache语法而引入的很多不必要的数据嵌套的问题,我们可以用<code>if</code>了,可以用<code>each</code>了,可以自定义了Helper了~欢呼雀跃吧….好吧,冷静,回归正题。</p>
<p>先从一个例子引入,然后逐步强化,里面有干货:<br>Level1:<br><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line">//tpl</div><div class="line">{{link 'http://www.baidu.com' '百度'}}</div><div class="line"></div><div class="line">//helper</div><div class="line">Handlebars.registerHelper('link', function(url, name) {</div><div class="line"> return '<span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"' + url + '"</span>></span>' + name + '<span class="tag"></<span class="name">a</span>></span>';</div><div class="line">});</div></pre></td></tr></table></figure></p>
<p>Level2:<br><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line">//tpl</div><div class="line">{{link site}}</div><div class="line"> </div><div class="line">//helper</div><div class="line">Handlebars.registerHelper('link', function(site) {</div><div class="line"> return '<span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"' + site.url + '"</span>></span>' + site.name + '<span class="tag"></<span class="name">a</span>></span>'</div><div class="line">});</div><div class="line"> </div><div class="line">//data</div><div class="line">{</div><div class="line"> site: {</div><div class="line"> url: 'http://www.baidu.com',</div><div class="line"> name: '百度'</div><div class="line"> }</div><div class="line">};</div></pre></td></tr></table></figure></p>
<p>Level3:<br><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">//tpl</div><div class="line">{{link '百度' url='http://www.baidu.com' class='site'}}</div><div class="line"></div><div class="line">//helper</div><div class="line">Handlebars.registerHelper('link', function(name, options) {</div><div class="line"> var attrs = [],</div><div class="line"> prop;</div><div class="line"> for (prop in options.hash) {</div><div class="line"> attrs.push(prop + '="' + options.hash[prop] + '"');</div><div class="line"> }</div><div class="line"> </div><div class="line"> return '<span class="tag"><<span class="name">a</span> ' + <span class="attr">attrs.join</span>(' ') + '></span>' + name + '<span class="tag"></<span class="name">a</span>></span>'</div><div class="line">});</div></pre></td></tr></table></figure></p>
<p>上述三个等级分别演示了Helper中参数传递的方法的功能递进, 下面介绍两个Handlebars的API为Helper打辅助:<code>Handlebars.SafeString()</code> 和 <code>Handlebars.escapeExpression()</code>。 </p>
<p>Helper返回的HTML字符串会被默认转义, 显示在界面上的只是文本节点而不是元素节点。所以, 对于这种自定义的Helper, 因为我们能确保返回的字符串是安全的, 因此我们需要告诉编译器这是一个安全的字符串, 放心当成元素节点插进去吧, 使用的方法就是SafeString();<br>另外, 因为Helper函数中有输入参数而我们不能确定这些数据是否含有XSS脚本, 如此那我们便手动将你转化成安全的字符串吧, 如此escapeExpression()的用法也自然就知晓了, 现在用这两个方法完善下上述Level3的Helper的例子:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">Handlebars.registerHelper(<span class="string">'link'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">name, options</span>) </span>{</div><div class="line"> <span class="keyword">var</span> attrs = [],</div><div class="line"> prop;</div><div class="line"> <span class="keyword">for</span> (prop <span class="keyword">in</span> options.hash) {</div><div class="line"> attrs.push(</div><div class="line"> Handlebars.escapeExpression(prop) +<span class="string">'="'</span> +</div><div class="line"> Handlebars.escapeExpression(options.hash[prop]) + <span class="string">'"'</span></div><div class="line"> );</div><div class="line"> }</div><div class="line"> </div><div class="line"> <span class="keyword">return</span> <span class="keyword">new</span> Handlebars.SafeString(<span class="string">'<a '</span> + attrs.join(<span class="string">' '</span>) + <span class="string">'>'</span> +</div><div class="line"> Handlebars.escapeExpression(name) + <span class="string">'</a>'</span>);</div><div class="line">});</div></pre></td></tr></table></figure></p>
<p>Level4:BLOCK-Heplers<br><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line">{{#bold}}</div><div class="line"> My name is {{name}}</div><div class="line">{{/bold}}</div><div class="line"></div><div class="line">Handlebars.registerHelper('bold', function(options) {</div><div class="line"> return new Handlebars.SafeString('<span class="tag"><<span class="name">b</span>></span>' + options.fn(this) + '<span class="tag"></<span class="name">b</span>></span>');</div><div class="line">});</div><div class="line"></div><div class="line">{name: 'xuqi'}</div></pre></td></tr></table></figure></p>
<p>可以看到跟上述三个步骤中的Tpl不一样,这次好像不是简单的代码替换了,因为Helper变成了一个区块,区块中还有内容, 那该怎么办?注意本例中我需要一个文字加粗的功能,在返回字符串中我加了<code><b></code>标签实现加粗,中间那个options.fn(this)是干啥的?</p>
<p>前面讲了<code><b></code>实现了加粗,那加粗总该有个对象吧,也就是My name is {{name}};<br>那我也总不能直接把这个模板字符串给加粗输出吧,我得编译然后根据上下文环境的属性值name去生成My name is xuqi。所以呢,option.fn的功能就自然出来了,就是在this上下文中执行编译Block中的模板并填充数据得到HTML片段。<br>而this就是Block Helper执行的当前上下文环境。 </p>
<p>另外,可以通过this取得当前上下文的属性值手动进行某些操作,比如可以通过this.name获取name的属性值为xuqi。</p>
<h4 id="Ps-一些有用的Build-In-Helper"><a href="#Ps-一些有用的Build-In-Helper" class="headerlink" title="Ps: 一些有用的Build-In Helper"></a>Ps: 一些有用的Build-In Helper</h4><ul>
<li>{{#each arg}}
<p>循环内可以通过{{@index}}获取当前的循环的索引, 通过{{@../index}}可以获得父级遍历的索引;<br>{{@key}}可以获取当前遍历的数组或者对象的键值,数组中等同于{{@index}};<br>{{@first}},{{@last}}表示遍历中的第一个和最后一个的标识,返回true或false;<br>each可选择性插入{{else}}, 在遍历的list为<strong>空</strong>(遍历对象为非空数组或者对象时不为空值)时执行。</p>
</li>
<li>{{#if condition}} or {{else}} or {{else if conditionElse}}
</li>
<li>{{#unless condition}} inverse of the `if` helper
</li>
<li>{{#with ctx}}
<p>与Js的with一样,改变当前context,可以避免含有深层次嵌套属性时重复书写父级的名字</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div></pre></td><td class="code"><pre><div class="line">//tpl</div><div class="line"><span class="tag"><<span class="name">h1</span>></span>{{title}}<span class="tag"></<span class="name">h1</span>></span></div><div class="line">{{#with story}}</div><div class="line"> <span class="tag"><<span class="name">div</span>></span>{{intro}}<span class="tag"></<span class="name">div</span>></span></div><div class="line"> <span class="tag"><<span class="name">div</span>></span>{{body}}<span class="tag"></<span class="name">div</span>></span></div><div class="line">{{else}}</div><div class="line"> {{!-- 可选择性插入else,仅当story为false值时渲染 --}}</div><div class="line"> <span class="tag"><<span class="name">div</span>></span>I am Empty<span class="tag"></<span class="name">div</span>></span></div><div class="line">{{/with}}</div><div class="line"> </div><div class="line">//data</div><div class="line">{</div><div class="line"> title: 'Hello world',</div><div class="line"> story: {</div><div class="line"> intro: 'Before the jump',</div><div class="line"> body: 'After the jump'</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure>
</li>
<li>{{lookup context key}} 获取动态参数进行渲染,相当于获取context.key的值,看例子会容易理解点:<br><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div></pre></td><td class="code"><pre><div class="line"></div><div class="line">//tpl</div><div class="line">{{#each names}}</div><div class="line"> {{.}} : {{lookup ../foo @key}}</div><div class="line">{{/each}}</div><div class="line"> </div><div class="line">//data</div><div class="line">{</div><div class="line"> names: {</div><div class="line"> a: 'Name1',</div><div class="line"> b: 'Name2',</div><div class="line"> c:'Name3'</div><div class="line"> },</div><div class="line"> foo: {</div><div class="line"> a: 'Foo1',</div><div class="line"> b: 'Foo2',</div><div class="line"> c: 'Foo3'</div><div class="line"> }</div><div class="line">}</div><div class="line"> </div><div class="line">//output</div><div class="line">Name1 :Foo1</div><div class="line">Name2 :Foo2</div><div class="line">Name3 :Foo3</div></pre></td></tr></table></figure>
</li>
<li><p>{{log info}} 打印调试</p>
</li>
</ul>
<h3 id="Partials"><a href="#Partials" class="headerlink" title="Partials"></a>Partials</h3><p>Handlebars.registerPartial(‘parName’, ‘parContent’); 注册一个Partials;</p>
<p>需要调用Partials时{{> parName}}即可。</p>
<p>调用Partials时也可以传入参数:{{> parName parContext}}指定Partials的执行上下文;{{> parName attr=val}}</p>
<h3 id="Path"><a href="#Path" class="headerlink" title="Path"></a>Path</h3>{{xx}}中的xx可以不只是我们熟悉的一个属性的名字,或是xx.yy这样的嵌套路径。也能支持<code>../</code>这样的父级上下文环境和<code>./</code>这样的当前上下文环境的语法啦,来个例子:<br><br><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line">//tpl</div><div class="line">{{# nest}}</div><div class="line"> {{../hello}}</div><div class="line">{{/ nest}}</div><div class="line"></div><div class="line">//data</div><div class="line">{</div><div class="line"> nest: [</div><div class="line"> ...</div><div class="line"> ],</div><div class="line"> hello: 'I am Hello'</div><div class="line">}</div></pre></td></tr></table></figure>
<p>./是用来解决Helper名字和属性名重名的冲突的情况,例如./xx表示的是属性名而不是Helper名。另外this/name和this.name也实现相同的功能。</p>
<p>当然啦, 如果嵌套层级很深, 而我想访问到根作用域的时候是不是要写成<code>../../..</code>这样呢? 是不是sa! 那该咋办? Handlebars提供了一个@root变量轻轻松松访问到根作用域:<br><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">{{#each sub}}</div><div class="line"> {{@root.someAttr}}</div><div class="line">{{/each}}</div></pre></td></tr></table></figure></p>
<h3 id="Comments"><a href="#Comments" class="headerlink" title="Comments"></a>Comments</h3><p>{{!-- --}}和{{! }}不会将注释内容输出到HTML中,如果想输出注释到HTML中可以使用HTML的注释语法<code><!-- --></code>。另外,如果注释中有}},则必须使用{{!-- --}}。</p>
<h2 id="后语"><a href="#后语" class="headerlink" title="后语"></a>后语</h2><p>上面讲的只是一些基本用法,冰山一角,官网上面还有很多文章中没有提及但是也许会给你的不一样的快感的功能。Helper的实现方式需要着重理解,几个Build-In Helper在官网上都提供了Helper实现方式,明白思想->模仿实现->定义自己的Helper实现特定的功能,go ~</p>
]]></content>
<summary type="html">
<p><a href="http://handlebarsjs.com/">Handlebars</a>为Mustache的超集,即:在完全兼容Mustache语法的基础上,提供了很多语法糖,不要太甜…</p>
<h2 id="Begin-Now"><a href="#Begin-Now" class="headerlink" title="Begin Now"></a>Begin Now</h2><h3 id="写在前面"><a href="#写在前面" class="headerlink" title="写在前面"></a>写在前面</h3><p>这里我们只介绍一些Handlebars中相对于Mustache超集的部分,若不了解Mustache,请<a href="http://i0011.com/2015/04/30/Mustache%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/">移步</a><br>
</summary>
<category term="HandBook" scheme="http://www.i0011.com/tags/HandBook/"/>
</entry>
<entry>
<title>Mustache使用指南</title>
<link href="http://www.i0011.com/2015/04/30/mustache/"/>
<id>http://www.i0011.com/2015/04/30/mustache/</id>
<published>2015-04-30T05:59:45.000Z</published>
<updated>2016-11-25T00:34:34.000Z</updated>
<content type="html"><![CDATA[<p>先拐远一点:mustache,读[ˈmʌsˌtæʃ],而不是[ˈmʌstˌek],胡子的意思,取这名字大概是将模板引擎中的<code>{</code>顺时针转个90度就像个人的胡子了,嗯,大概是这样…</p>
<p>再进入正题:mustache是一个轻逻辑的模板引擎(为啥叫“轻逻辑”呢,因为没有if else for等逻辑语句,取而代之的是只用标签实现 )</p>
<p>mustache.js是mustache模板系统的js实现,或者叫解析器。下面介绍下使用方法,很简单的语法~<br><a id="more"></a></p>
<h2 id="quick-example"><a href="#quick-example" class="headerlink" title="quick example"></a>quick example</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">Mustache.render(<span class="string">'<p>I am {{name}}, I am {{age}} years old</p>'</span>, {</div><div class="line"> <span class="attr">name</span>: <span class="string">'xuqi'</span>,</div><div class="line"> <span class="attr">age</span>: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</div><div class="line"> <span class="keyword">return</span> <span class="number">24</span>;</div><div class="line"> }</div><div class="line">});</div></pre></td></tr></table></figure>
<p>上述例子输出一段HTML片段:<code><p>I am xuqi, I am 24 years old</p></code>。</p>
<p>首先上述例子给我们最直观的印象就是:templates + data => html-partials。使用render(tpls, dataObj)。使用dataObj去渲染tpls得到html片段。</p>
<h2 id="模板"><a href="#模板" class="headerlink" title="模板"></a>模板</h2><p>模板就是一段包含任意数目{{keyname}}的字符串~<br>{{keyname}}中的包裹的keyname即为mustache模板的键名(稍微了解下就好)。下面介绍三种加载模板的方法<br>1 直接在js中声明模板字符串,如quick example所示<br>2 从HTML中读取模板<br><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">script</span> <span class="attr">id</span>=<span class="string">"ex-tpl"</span> <span class="attr">type</span>=<span class="string">"x-tmpl-mustache"</span>></span><span class="undefined"></span></div><div class="line"> My name is {{name}}, I am {{age}} years old</div><div class="line"><span class="tag"></<span class="name">script</span>></span></div></pre></td></tr></table></figure></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"> <span class="comment">//example.js</span></div><div class="line"> <span class="keyword">var</span> tpl = $(<span class="string">'#ex-tpl'</span>).html(),</div><div class="line"> html;</div><div class="line"> html = Mustache.render(tpl, data);</div><div class="line"><span class="string">`</span></div></pre></td></tr></table></figure>
<p>3 从.mst文件中读取/通过ajax异步渲染<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">loadTpl</span>(<span class="params"></span>) </span>{</div><div class="line"> $.get(<span class="string">'tpl.mst'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">tpl</span>) </span>{</div><div class="line"> <span class="keyword">var</span> html = Mustache.render(tpl, data);</div><div class="line"> <span class="comment">//Operation of html</span></div><div class="line"> });</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="变量"><a href="#变量" class="headerlink" title="变量"></a>变量</h2><p>最简单的标签就是一个变量{{key}}…使用当前上下文环境中的key值替换标签,如果key不存在,则不会被渲染。</p>
{{key}}会默认转义一些HTML标记,如果不想使用转义, 可以使用{{{}}}或者{{&}}。<br><br>另外,JS中的<code>.</code>也可以在mustache中使用,比如:{{person.name}}
<h2 id="区块"><a href="#区块" class="headerlink" title="区块"></a>区块</h2><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">{{#section}}</div><div class="line"> {{name}}</div><div class="line"> //other code</div><div class="line">{{/section}}</div></pre></td></tr></table></figure>
<p>根据上下文环境中的section的值去渲染区块内的代码。如果section键名不存在或者存在但是值为’false’值(null,undefined,false,0,NaN,’’,[]),区块内代码不会被渲染。</p>
<p>键名存在也为’true’值的情况下,区块内代码被渲染1+次。比如:<br><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line">//view</div><div class="line">{</div><div class="line"> section: [</div><div class="line"> {name: 'xuqi'},</div><div class="line"> {name: 'xuqi2'}</div><div class="line"> ]</div><div class="line">}</div><div class="line"></div><div class="line">//template</div><div class="line">{{#section}}</div><div class="line"> <span class="tag"><<span class="name">b</span>></span>{{name}}<span class="tag"></<span class="name">b</span>></span></div><div class="line">{{/section}}</div><div class="line"></div><div class="line">//output</div><div class="line"><span class="tag"><<span class="name">b</span>></span>xuqi<span class="tag"></<span class="name">b</span>></span></div><div class="line"><span class="tag"><<span class="name">b</span>></span>xuqi2<span class="tag"></<span class="name">b</span>></span></div></pre></td></tr></table></figure></p>
<p>我们把上面的view简化一下:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">{</div><div class="line"> <span class="attr">section</span>: [<span class="string">'xuqi'</span>, <span class="string">'xuqi2'</span>]</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>对,就是把section的元素由对象简化为了字符串,那键名没了我怎么去渲染?{{.}}来帮你~<br><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">{{#section}}<span class="tag"><<span class="name">b</span>></span>{{.}}<span class="tag"></<span class="name">b</span>></span>{{/section}}</div></pre></td></tr></table></figure></p>
<p>这样就可以得到同样的output啦。</p>
<p>再来看一种稍微复杂一点的情况:外国人都有firstname和lastname,如果按照上面的情况去实现就得{{firstname}}.{{lastname}}去手动拼接。所以现在要引入函数来帮我们实现拼接了,而不是把逻辑扔在template中去实现。</p>
<p>如果section中有个变量是一个函数,那么会遍历对应上下文中的各个项并执行,例如:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div></pre></td><td class="code"><pre><div class="line">//view</div><div class="line">{</div><div class="line"> 'section': [</div><div class="line"> { 'firstName': 'qi', 'lastName': 'xu' },</div><div class="line"> { 'firstName': 'qi2', 'lastName': 'xu' }</div><div class="line"> ],</div><div class="line"> 'name': function () {</div><div class="line"> return this.firstName + '.' + this.lastName;</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line">//template</div><div class="line">{{#section}}</div><div class="line"> <b>{{name}}</b></div><div class="line">{{/section}}</div><div class="line"></div><div class="line">//output</div><div class="line"><b>qi.xu</b></div><div class="line"><b>qi2.xu</b></div></pre></td></tr></table></figure></p>
<h2 id="取反区块"><a href="#取反区块" class="headerlink" title="取反区块"></a>取反区块</h2>{{^section}}与区块的情况相反,section的值为’false’值时执行,否则不执行<br><br>## 区块函数<br>如果section键名为函数,即{{#sectionFn}}{{/sectionFn}}中sectionFn为函数时,是个奇葩,官方文档看不懂是什么意思,直接来看例子吧~~<br><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line">//view</div><div class="line">{</div><div class="line"> name: 'xuqi',</div><div class="line"> bold: function() {</div><div class="line"> return function(text, render) {</div><div class="line"> return '<span class="tag"><<span class="name">b</span>></span>' + render(text) + '<span class="tag"></<span class="name">b</span>></span>';</div><div class="line"> }</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line">//tpl</div><div class="line">{{#bold}}Hi {{name}}{{/bold}}</div><div class="line"></div><div class="line">//output</div><div class="line"><span class="tag"><<span class="name">b</span>></span>Hi xuqi<span class="tag"></<span class="name">b</span>></span></div></pre></td></tr></table></figure>
<p>function里面的实现意思就是:render(text)替换{{bold}}块中的内容并将数据渲染进去,然后把{{bold}}替换成<code><b></code>标签就行了</p>
<h2 id="注释"><a href="#注释" class="headerlink" title="注释"></a>注释</h2>{{!}}内容不显示<br><br>## Partials<br>{{> partial-name}}引入某个小部件到模板中,比如<br><br><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line">//base.mst</div><div class="line">{{#name}}</div><div class="line"> {{> user}}</div><div class="line">{{/name}}</div><div class="line"></div><div class="line">//user.mst</div><div class="line"><span class="tag"><<span class="name">b</span>></span>{{name}}<span class="tag"></<span class="name">b</span>></span></div></pre></td></tr></table></figure>
<p>mustache将user.mst的内容插入到base.mst中{{> user}}的位置。</p>
<p>如果在Mustache.render中使用partials的话,将partials当做render的第三个参数即可,即:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">Mustache.render(tpl, data, {</div><div class="line"> <span class="attr">user</span>: userTplText,</div><div class="line"> ...</div><div class="line">});</div></pre></td></tr></table></figure></p>
<h2 id="预编译和缓存模板"><a href="#预编译和缓存模板" class="headerlink" title="预编译和缓存模板"></a>预编译和缓存模板</h2><p>默认情况下Mustache在第一次编译模板后会缓存起来,如果第二次的模板没有变化,就直接从缓存中取编译后的模板去渲染,加快了渲染速度。如果你需要提前预编译和缓存,可调用Mustache.parse(tpl);…..一会儿以后,你就可以享受预编译模板带来的渲染快感了</p>
]]></content>
<summary type="html">
<p>先拐远一点:mustache,读[ˈmʌsˌtæʃ],而不是[ˈmʌstˌek],胡子的意思,取这名字大概是将模板引擎中的<code>{</code>顺时针转个90度就像个人的胡子了,嗯,大概是这样…</p>
<p>再进入正题:mustache是一个轻逻辑的模板引擎(为啥叫“轻逻辑”呢,因为没有if else for等逻辑语句,取而代之的是只用标签实现 )</p>
<p>mustache.js是mustache模板系统的js实现,或者叫解析器。下面介绍下使用方法,很简单的语法~<br>
</summary>
<category term="HandBook" scheme="http://www.i0011.com/tags/HandBook/"/>
</entry>
<entry>
<title>兼容性解决方案</title>
<link href="http://www.i0011.com/2015/04/13/compatibility-case/"/>
<id>http://www.i0011.com/2015/04/13/compatibility-case/</id>
<published>2015-04-13T07:40:22.000Z</published>
<updated>2016-11-25T00:34:34.000Z</updated>
<content type="html"><![CDATA[<p>开发中得到的一些IE/FF/Safari下的兼容性处理方案,请叫我兼容性处理大师,谢谢~</p>
<p>1 图片链接边框</p>
<pre><code><a href="signup.html">
<img class="banner" src="src/banner.jpg">
</a>
</code></pre><p>常用的图片链接,在IE8下,图片会被加上蓝色边框,什么鬼…这当然不是我们想要的结果了,加个</p>
<pre><code>img {
border: none;
}
</code></pre><p>干掉IE8给加的边框。All is well~<br><a id="more"></a><br>2 未设置背景的div真的只是四条边线<br>什么意思呢?就是IE8如果你一个普通的div,设置width,height后,恩,你想这个div应该有一个cursor:pointer,然后再绑定个click事件什么的….然后你会发现?wtf!鼠标移上去完全没作用啊!点击也完全没作用啊!诶,不对,似乎鼠标在经过边框的时候有反应…好吧,你已经发现真理了。来,解决这个问题,填充一下就可以了嘛:</p>
<pre><code>div {
height: 100px;
width: 100px;
cursor: pointer;
background-color: #fff;
opacity: 0;
filter: Alpha(opacity=0);
}
</code></pre><p>Perfect!</p>
<p>3 设置高度的select中的文字没有垂直居中<br>那你就加line-height去控制啊,look down:</p>
<pre><code>select {
height: 36px;
line-height: 18px;
padding: 9px 0;
}
</code></pre><p>4 placeholderIE10以下处理方案<br>简单的东西当然可以自己写了, 但是网上有那么多, 没必要啦…最基本的实现方式都是给输入框一个值然后在keyup的时候去清除, 但是这种情况, 因为是直接把内容填进去的, 对于有验证的输入框来说就有点痛苦了而且密码框要么就是placeholder=“密码”会被转成两个<code>..</code>, 要么就是输入密码直接给显示出来, 太恶心太麻烦。<br>我还是比较喜欢<a href="https://github.com/amerikan/placeholder-polyfill" target="_blank" rel="external">这个插件</a>的做法, 在input的外面包裹一个wrapper, 然后加一个input同级的label来显示placeholder, placeholder其实就是label, 然后控制label的显示与隐藏就可以了。但是label的样式可能需要手动去改一下, 要么直接在插件里面扩展, 要么传入参数扩展。 </p>
<p>另外, 当然也不是一帆风顺了, 当遇到<code>自动填入</code>(浏览器记住密码) 的时候就会发现IE10往下是全部不会让”placeholder”消失的, 估计写插件的人也没考虑这个, 于是乎就给他补了一个chang的事件监听….啊, IE10好了, IE9也好了….擦, IE8什么鬼, 不会触发change….苦苦寻找, 好吧有<code>propertychange</code> 可以用也一样…IE真坑爹</p>
<p>5 Mac safari输入框placeholder文字底部被截取<br>开始的输入框一直是:</p>
<pre><code>height: 43px;
line-height: 43px;
</code></pre><p>诶, 测试没有mac下了一个windows的safari, 怎么输入框placeholder全坏的啊…拿掉line-height好了…于是不用line-height, 用</p>
<pre><code>height: 18px;
padding: 12px 0;
</code></pre><p>这样的替代方案…其他的好了, 到mac上的safari就有文字截取了, 最后查了一下原因还是因为没有line-height的原因, 那就加上吧, 然后来个兼容方案:</p>
<pre><code>height: 43px;
font-size: 16px;
line-height: 1.2;
line-height: 43px\0/; /* for IE 8 */
</code></pre><p>6 windows safari的password输入框似乎不支持黑体这样的字体<br>对于设置了黑体的password-input, 你是看不到密码的黑点的, 输入也没有反应(其实已经有了) , 坑爹货。 </p>
<p>Windows safari已经停止更新了, 不要再用这个来折磨前端了…</p>
<p>7 IE8是不支持rgba的颜色的<br>因此只能用相近色去替代了, 或者直接不要用rgba了, 毛用, 就是来找麻烦的…这样写可以兼容:</p>
<pre><code>color: #9a9a9a;
color: rgba(0,0,0,.5);
</code></pre><p>上面是替换色, IE8下会执行, 其他浏览器使用下面的颜色, 按顺序写就行了。 </p>
<p>8 IE8下解决横向排列被换行的问题<br>比如下面这种情况:<img src="https://dn-xuqi.qbox.me/list.png" alt="CommodityList">,内容固定宽度横向排列,每个右侧有margin-right,:nth-child(4n)的margin-right:0。<br>好嘛,IE8下最后一个就下来了。ie8不认识:nth-child。</p>
<p><strong>解决办法</strong>:将他的父容器的宽度设置成4*(width+margin)就可以了,也就是比原宽度多个margin就可以保证最后一个不被挤下去。(开始时没设置父容器宽度的,但是有个外层容器设置了宽度)<br>另外还有一个没有注意的点是IE是不支持:last-child的。 </p>
<p>9 select显示靠右使用direction: rtl<br>direction有两个有效值:<code>rtl</code>和<code>ltr</code>…就是right to left 和 left to right,表示文本从左往右显示从右往左显示。默认ltr </p>
<p>10 新鲜出炉的问题H5的keyup在ios8.0下使用搜狗输入法不能被触发<br>好吧,换事件<code>input</code>,GAME OVER~<br>因为问题详细解决方案可参考<a href="http://segmentfault.com/q/1010000002608898" target="_blank" rel="external">参考资料</a></p>
<p>11 安卓机下FF34.0会显示select标签的三角号,就算你设置了appearance为none也没有<br>其实就这是单纯的FF的bug,你会发现39.0的没有这问题了,其他的版本我没试。所以遇到这样的问题,直接跳过吧,坑爹的很</p>
<p>12 为select或者input设置label并制定label的for在各浏览器中反应不一样<br>以ios为代表的是点击label就相当于点击了它for的对象,安卓机上也有部分有这样的情况…保持统一,拿掉label了(为什么当时脑袋抽风加了一个for呢…) </p>
<p>13 (移动Andriod)select在focus时在FF下会有边框<br>前提,已经写过常规样式<code>select:focus{border:none;outline:0;}</code>,事实证明这对firefox是无效了,查资料千辛万苦终于找到了:</p>
<pre><code>select:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 #fff;
}
</code></pre><p>这个解决方案来自:<a href="http://stackoverflow.com/questions/19451183/cannot-remove-outline-dotted-border-from-firefox-select-drop-down" target="_blank" rel="external">参考资料</a></p>
<p>IE8一生黑~~<br>End with: 没什么高深的东西,慢慢积累就会变成财富。</p>
]]></content>
<summary type="html">
<p>开发中得到的一些IE/FF/Safari下的兼容性处理方案,请叫我兼容性处理大师,谢谢~</p>
<p>1 图片链接边框</p>
<pre><code>&lt;a href=&quot;signup.html&quot;&gt;
&lt;img class=&quot;banner&quot; src=&quot;src/banner.jpg&quot;&gt;
&lt;/a&gt;
</code></pre><p>常用的图片链接,在IE8下,图片会被加上蓝色边框,什么鬼…这当然不是我们想要的结果了,加个</p>
<pre><code>img {
border: none;
}
</code></pre><p>干掉IE8给加的边框。All is well~<br>
</summary>
<category term="Solution" scheme="http://www.i0011.com/tags/Solution/"/>
<category term="IE8" scheme="http://www.i0011.com/tags/IE8/"/>
<category term="兼容性" scheme="http://www.i0011.com/tags/%E5%85%BC%E5%AE%B9%E6%80%A7/"/>
</entry>
<entry>
<title>Way To Pjax</title>
<link href="http://www.i0011.com/2015/03/16/way-to-pjax/"/>
<id>http://www.i0011.com/2015/03/16/way-to-pjax/</id>
<published>2015-03-16T05:11:37.000Z</published>
<updated>2016-11-25T00:34:34.000Z</updated>
<content type="html"><![CDATA[<h3 id="Pjax-PushState-Ajax"><a href="#Pjax-PushState-Ajax" class="headerlink" title="Pjax = PushState + Ajax"></a>Pjax = <strong>P</strong>ushState + A<strong>jax</strong></h3><p>Pjax使用在链接跳转页面的情形下,可以将跳转页面转化为页面内异步更新内容,并且同时浏览器URL、Title以及浏览器的回退等功能都能无异于页面跳转。效果可以参考Github上的文件/目录跳转加载,Github就是采用Pjax的方式去实现的。</p>
<p>Pjax的好处:</p>
<ul>
<li>用户体验提升<br>无刷新页面极大的提升了用户的体验</li>
<li>减少资源加载<br>只更新页面中需要替换的那部分资源,layout框架部分不用重新加载</li>
<li>浏览器支持处理<br>在不支持PushState或者Ajax的浏览器中,Pjax的功能不被支持,但是不影响正常使用,Pjax会使用原始的页面跳转来处理这种情况<a id="more"></a>
Pjax的实现原理:<br>pajx阻止链接的点击默认事件,转为通过ajax从服务器端抓取html并把html填充到需要变更内容的容器中,然后通过PushState更新页面URL。(easy to understand,uh?But we are not the first one to eat crab ~~)</li>
</ul>
<p>以上属于思想层面的东西,因为jquery.pjax的存在,下面将针对jquery.pjax做出使用说明。</p>
<hr>
<p><a href="https://github.com/defunkt/jquery-pjax" target="_blank" rel="external">Jquery.pjax</a></p>
<p>Start By An Example:</p>
<pre><code>//page1.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf8">
<title>Pjax Example</title>
</head>
<body>
<div id="container">
Nothing
<a id="switch-to-two" href="page2.html">Go to page2</a>
</div>
<div>Other parts</div>
<script src="bower_components/jquery/dist/jquery.min.js"></script>
<script src="bower_components/jquery-pjax/jquery.pjax.js"></script>
<script>
$(document).pjax('#switch-to-two', '#container');
</script>
</body>
</html>
//page2.html
<p>I am page2</p>
<a id="switch-to-one" href="page1.html">Go to pag1</a>
</code></pre><p>Tip:使用前bower安装一下jquery和jquery.pjax或者cdn引入下。动手运行感受下吧~</p>
<p>Usage:</p>
<ul>
<li>$.fn.pjax<br>初始化Pjax,可通过下述方法实现链接的pjax页面加载:</li>
</ul>
<pre><code>$(document).pjax(selector, [container], options)
</code></pre><p>selector可以指定为a[data-pjax],然后html中a标签中指定data-pjax为container即可省略列表中container参数。</p>
<p>还有另外一种方法初始化,但是不推荐:</p>
<pre><code>$('a[data-pjax]').pjax();
</code></pre><p>因为源码中初始化的过程是这样的:</p>
<pre><code>function fnPjax(selector, container, options) {
var context = this
return this.on('click.pjax', selector, function(event) {
var opts = $.extend({}, optionsFor(container, options))
if (!opts.container)
opts.container = $(this).attr('data-pjax') || context
handleClick(event, opts)
})
}
</code></pre><p>在上下文环境(此处为document)中为selector绑定click.pjax事件并执行回调,回调中会首先拼接opts即将container和options两个参数合并成一个对象(<code>{container: '#container', otherOpt: ...}</code>)。<br>如果参数列表中没有传入container则会去读上下文环境中的data-pjax属性(上述不推荐的例子就是属于这种情况)或者直接将上下文环境当成container。由代码可以看到,如果采用不推荐的那种写法,基本功能虽然可以实现,但是此时如果我在列表中传入了一个options对象,其实这个时候options是无效的(会被当成selector),或者传入一个字符串选择器(本意是container),但是会被绑定一个原来链接元素才会有的事件。上述所有情况都会造成不预期的错误,虽然仍然以跳转页面进行处理,但这不是我们想要的结果。所以,尽量避免…(我看到好多stackoverflow上的都是这么写的,难道是我技术拙劣得不能理解了…如果你很知道的话一定要不吝指教啊)</p>
<p>options:</p>
<table>
<thead>
<tr>
<th>Key</th>
<th style="text-align:center">Default</th>
<th style="text-align:right">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>timeout</td>
<td style="text-align:center">650</td>
<td style="text-align:right"><em>timeout</em>毫秒后的强制刷新</td>
</tr>
<tr>
<td>push</td>
<td style="text-align:center">true</td>
<td style="text-align:right">使用pushState添加一个浏览器记录</td>
</tr>
<tr>
<td>replace</td>
<td style="text-align:center">false</td>
<td style="text-align:right">url替换而不是添加(类比replaceState)</td>
</tr>
<tr>
<td>maxCacheLength</td>
<td style="text-align:center">20</td>
<td style="text-align:right">缓存以前container内容最大数目</td>
</tr>
<tr>
<td>version</td>
<td style="text-align:center"></td>
<td style="text-align:right">string/function,当前pjax版本</td>
</tr>
<tr>
<td>scrollTo</td>
<td style="text-align:center">0</td>
<td style="text-align:right">页面“刷新”后定位的scrollTop</td>
</tr>
<tr>
<td>type</td>
<td style="text-align:center">‘GET’</td>
<td style="text-align:right"></td>
</tr>
<tr>
<td>dataType</td>
<td style="text-align:center">‘html’</td>
<td style="text-align:right"></td>
</tr>
<tr>
<td>container</td>
<td style="text-align:center"></td>
<td style="text-align:right"></td>
</tr>
<tr>
<td>url</td>
<td style="text-align:center">link.href</td>
<td style="text-align:right">string/function,URL for ajax request</td>
</tr>
<tr>
<td>target</td>
<td style="text-align:center">link</td>
<td style="text-align:right">事件relatedTarget属性的值</td>
</tr>
<tr>
<td>fragment</td>
<td style="text-align:center"></td>
<td style="text-align:right">指定返回数据中某一段代码进行填充</td>
</tr>
</tbody>
</table>
<p>另外,pjax允许你通过<code>$.pjax.defaults.xx</code>去修改默认值。<br>Ps: relatedTarget是当前事件涉及到的相关联的其他元素。比如mouseover会涉及到多个元素,从元素1离开然后进入元素2,此时relatedTarget就是元素1…你明白了吗?反正我明白了…涉及到这个属性的事件比较少,列如下:mouseenter,mouseout,mouseover,mouseleave,focus,blur。</p>
<ul>
<li><p>$.pjax.click<br>pajx的底层函数,功能是手动去把链接click事件转移到pjax实现,可以增加一些使用者对事件句柄event的控制。</p>
<pre><code>if ($.support.pjax) {//使用前应该判断浏览器是否支持pjax
$(document).on('click', '#switch', function(event) {
$.pjax.click(event, {
container: $('#container')
});
});
}
</code></pre><p>通过上述可以同样实现上述例子的功能</p>
</li>
<li><p>$.pjax.submit<br>用于实现通过Pjax提交表单数据</p>
<pre><code>$(document).on('submit', '#form', function(e) {
$.pjax.submit(e, '#container');
});
</code></pre></li>
<li><p>$.pjax.reload<br>使用当前URL通过pjax机制向服务端请求数据并替换#container内的内容</p>
<pre><code>$.pjax.reload('#container', options);
</code></pre></li>
<li><p>$.pjax<br>手动触发pjax,用于非click事件触发的一个请求</p>
<pre><code>$.pjax({
url: url,
container: '#container'
});
</code></pre></li>
<li><p>pjax event<br>pjax提供了很多事件来供我们实现Pjax过程中需要处理的细节功能,比如,上述例子中,在pjax请求完成后我打印一个’Complete’,就可以这样实现:</p>
<pre><code>$(document).on('pjax:complete', function() {
console.log('Compelete');
});
</code></pre></li>
</ul>
<p>另外,pjax:send和pjax:complete是一对基友,可以帮我们实现类似于loading图标正确的显示和隐藏的功能,send时显示,complete时隐藏,语法同上,不赘述。</p>
<p>events list:<br>Ps:pjax:click和pjax:clicked是由链接元素触发的,其他事件由容器触发。</p>
<ul>
<li><code>pjax:click</code></li>
<li><code>pjax:beforeSend</code></li>
<li><code>pjax:start</code></li>
<li><code>pjax:send</code></li>
<li><code>pjax:clicked</code></li>
<li><code>pjax:beforeReplace</code></li>
<li><code>pjax:success</code></li>
<li><code>pjax:timeout</code></li>
<li><code>pjax:error</code></li>
<li><code>pjax:complete</code></li>
<li><code>pjax:end</code></li>
</ul>
<p>下列事件会在浏览器后退/前进按钮时触发</p>
<ul>
<li><code>pjax:popstate</code></li>
<li><code>pjax:start</code> – 内容替换前</li>
<li><code>pjax:beforeReplace</code> – 从缓存中读取HTML替换之前</li>
<li><code>pjax:end</code> – 内容替换后</li>
</ul>
<hr>
<p>另外,如果你使用spm,jquery.pjax也被简单了封装了一下放在了上面,你可以通过<code>spm install jquery-pjax --save</code>获取。</p>
]]></content>