-
Notifications
You must be signed in to change notification settings - Fork 0
/
jssummary.html
2108 lines (1511 loc) · 256 KB
/
jssummary.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<!--
_ooOoo_
o8888888o
88" . "88
(| -_- |)
O\ = /O
____/`---'\____
.' \\| |// `.
/ \\||| : |||// \
/ _||||| -:- |||||- \
| | \\\ - /// | |
| \_| ''\---/'' | |
\ .-\__ `-` ___/-. /
___`. .' /--.--\ `. . __
."" '< `.___\_<|>_/___.' >'"".
| | : `- \`.;`\ _ /`;.`/ - ` : | |
\ \ `-. \_ __\ /__ _/ .-` / /
======`-.____`-.___\_____/___.-`____.-'======
`=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
佛祖保佑 永无BUG
-->
<html class="theme-next mist use-motion" lang="zh-Hans">
<head>
<meta charset="UTF-8"/>
<link href="//mydearest.cn" rel="dns-prefetch">
<link href="//www.mydearest.cn" rel="dns-prefetch">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta name="theme-color" content="#222">
<meta name="description" content="陈宇的博客" />
<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
<link href="//fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic|Roboto Slab:300,300italic,400,400italic,700,700italic|Lobster Two:300,300italic,400,400italic,700,700italic|PT Mono:300,300italic,400,400italic,700,700italic&subset=latin,latin-ext" rel="stylesheet" type="text/css">
<meta name="keywords" content="整理," />
<link rel="alternate" href="/rss2.xml" title="cosyer's Blog" type="application/atom+xml" />
<link rel="shortcut icon" type="image/x-icon" href="/images/favicon.ico" />
<meta name="description" content="JS的相关知识点比较繁杂,特此开篇整理一波,方便回顾总结查阅。 运行在宿主环境环境中,比如浏览器或node环境 不用预编译,直接解释执行代码 是弱类型语言,较为灵活 与操作系统无关,跨平台的语言 脚本语言,解释性语言">
<meta property="og:type" content="article">
<meta property="og:title" content="JavaScript整理总结">
<meta property="og:url" content="http://mydearest.cn/jssummary.html">
<meta property="og:site_name" content="cosyer's Blog">
<meta property="og:description" content="JS的相关知识点比较繁杂,特此开篇整理一波,方便回顾总结查阅。 运行在宿主环境环境中,比如浏览器或node环境 不用预编译,直接解释执行代码 是弱类型语言,较为灵活 与操作系统无关,跨平台的语言 脚本语言,解释性语言">
<meta property="article:published_time" content="2018-06-21T11:37:27.000Z">
<meta property="article:modified_time" content="2020-09-08T11:14:21.056Z">
<meta property="article:author" content="陈宇(cosyer)">
<meta property="article:tag" content="整理">
<meta name="twitter:card" content="summary">
<script type="text/javascript" id="hexo.configurations">
var NexT = window.NexT || {};
var CONFIG = {
root: '/',
scheme: 'Mist',
sidebar: {"position":"left","display":"always","offset":12,"offset_float":12,"b2t":false,"scrollpercent":false,"onmobile":false},
fancybox: true,
tabs: true,
motion: true,
duoshuo: {
userId: '0',
author: '博主'
},
algolia: {
applicationID: '',
apiKey: '',
indexName: '',
hits: {"per_page":10},
labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
}
};
</script>
<link rel="canonical" href="http://mydearest.cn/jssummary.html"/>
<title>JavaScript整理总结 | cosyer's Blog</title>
<script type="text/javascript">
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?653a4be35cb6c7b26817038a17c3f0d6";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
<link href="https://mydearest.cn/css/all-9097fb9016.css" rel="stylesheet" type="text/css">
<style>
// scrollbar滚动条样式优化
::-webkit-scrollbar-corner {
background-color: transparent;
}
::-webkit-scrollbar-button {
width: 0;
height: 0;
display: none;
}
::-webkit-scrollbar-thumb {
width: 7px;
background-color: #b4babf;
border-radius: 7px;
}
::-webkit-scrollbar {
width: 7px;
height: 7px;
}
::-webkit-scrollbar-track {
width: 15px;
}
::-webkit-scrollbar:hover {
background-color: transparent;
}
* {
cursor: url("http://cdn.mydearest.cn/blog/images/miku1.png"),auto!important
}
:active {
cursor: url("http://cdn.mydearest.cn/blog/images/miku2.png"),auto!important
}
a:hover {
cursor: url("http://cdn.mydearest.cn/blog/images/miku2.png"),auto!important
}
</style>
<meta name="generator" content="Hexo 4.2.1"></head>
<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">
<div id="loader">
<div></div>
</div>
<div class="container sidebar-position-left page-post-detail ">
<div class="headband"></div>
<a href="https://github.com/cosyer" target="_blank" rel="noopener" class="github-corner" aria-label="View source on Github"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: absolute; top: 0; border: 0; left: 0; transform: scale(-1, 1);" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style></a>
<header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
<div class="header-inner"><div class="site-brand-wrapper">
<div class="site-meta ">
<div class="custom-logo-site-title">
<a href="/" class="brand" rel="start">
<span class="logo-line-before"><i></i></span>
<span class="site-title">cosyer's Blog</span>
<span class="logo-line-after"><i></i></span>
</a>
</div>
<h1 class="site-subtitle" itemprop="description">Blog</h1>
</div>
<div class="site-nav-toggle">
<button>
<span class="btn-bar"></span>
<span class="btn-bar"></span>
<span class="btn-bar"></span>
</button>
</div>
</div>
<nav class="site-nav">
<ul id="menu" class="menu">
<li class="menu-item menu-item-home">
<a href="/" class="faa-parent animated-hover" rel="section">
<i class="menu-item-icon fa fa-fw fa-home faa-wrench"></i> <br />
首页
</a>
</li>
<li class="menu-item menu-item-links">
<a href="/links/" class="faa-parent animated-hover" rel="section">
<i class="menu-item-icon fa fa-fw fa-link faa-shake"></i> <br />
友链
</a>
</li>
<li class="menu-item menu-item-guestbook">
<a href="/guestbook/" class="faa-parent animated-hover" rel="section">
<i class="menu-item-icon fa fa-fw fa-comment-o faa-tada"></i> <br />
留言板
</a>
</li>
<li class="menu-item menu-item-archives">
<a href="/archives/" class="faa-parent animated-hover" rel="section">
<i class="menu-item-icon fa fa-fw fa-archive faa-float"></i> <br />
归档
</a>
</li>
<li class="menu-item menu-item-about">
<a href="/about/" class="faa-parent animated-hover" rel="section">
<i class="menu-item-icon fa fa-fw fa-user faa-horizontal"></i> <br />
关于
</a>
</li>
<li class="menu-item menu-item-search">
<a href="javascript:;" class="popup-trigger faa-parent animated-hover">
<i class="menu-item-icon fa fa-search faa-burst fa-fw"></i> <br />
搜索
</a>
</li>
</ul>
<div class="site-search">
<div class="popup search-popup local-search-popup">
<div class="local-search-header clearfix">
<span class="search-icon">
<i class="fa fa-search"></i>
</span>
<span class="popup-btn-close">
<i class="fa fa-times-circle"></i>
</span>
<div class="local-search-input-wrapper">
<input autocomplete="off"
placeholder="搜索..." spellcheck="false"
type="text" id="local-search-input">
</div>
</div>
<div id="local-search-result"></div>
</div>
</div>
</nav>
</div>
</header>
<main id="main" class="main">
<div class="main-inner">
<div class="content-wrap">
<div id="content" class="content">
<div id="posts" class="posts-expand">
<article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
<div class="post-date" data-datetime="2020-09-08T19:14:21+08:00">
<div class="post-time-text">9月</div>
<div class="post-time-count">08</div>
<div class="text-desc">
<div class="date-text">更新于</div>
<div class="post-tiem">9月08</div>
<div class="post-year">2020</div>
</div>
</div>
<div class="post-badge">
<span class="post-category" >
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/JS/" itemprop="url" rel="index">
<span itemprop="name">JS</span>
</a>
</span>
</span>
</div>
<div class="post-block">
<link itemprop="mainEntityOfPage" href="http://mydearest.cn/jssummary.html">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="陈宇(cosyer)">
<meta itemprop="description" content="不去做的话永远也做不到。">
<meta itemprop="image" content="/images/avatar.jpg">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="cosyer's Blog">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">JavaScript整理总结</h2>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="发表于" itemprop="dateCreated datePublished" datetime="2018-06-21T19:37:27+08:00">
2018-06-21
</time>
</span>
<span id="/jssummary.html" class="leancloud_visitors" data-flag-title="JavaScript整理总结">
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-eye"></i>
</span>
<span class="post-meta-item-text">热度 </span>
<span class="leancloud-visitors-count"></span> ℃
</span>
<div class="post-wordcount">
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-pencil-square-o"></i>
</span>
<span class="post-meta-item-text">字数统计:</span>
<span title="字数统计:">
11,290 (字)
</span>
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-clock-o"></i>
</span>
<span class="post-meta-item-text">阅读时长:</span>
<span title="阅读时长:">
51 (分钟)
</span>
</div>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>JS的相关知识点比较繁杂,特此开篇整理一波,方便回顾总结查阅。</p>
<ul>
<li>运行在宿主环境环境中,比如浏览器或node环境</li>
<li>不用预编译,直接解释执行代码</li>
<li>是弱类型语言,较为灵活</li>
<li>与操作系统无关,跨平台的语言</li>
<li>脚本语言,解释性语言</li>
</ul>
<hr>
<a id="more"></a>
<h2 id="概念"><a href="#概念" class="headerlink" title="概念"></a>概念</h2><p>JavaScript 是一门跨平台、面向对象、基于原型的轻量级动态脚本语言。</p>
<p>与java的对比:</p>
<table>
<thead>
<tr>
<th style="text-align:left">JavaScript</th>
<th style="text-align:left">Java</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">面向对象。不区分对象类型。通过原型机制继承,任何对象的属性和方法均可以被动态添加。</td>
<td style="text-align:left">基于类系统。分为类和实例,通过类层级的定义实现继承。不能动态增加对象或类的属性或方法。</td>
</tr>
<tr>
<td style="text-align:left">变量类型不需要提前声明(动态类型)。</td>
<td style="text-align:left">变量类型必须提前声明(静态类型)。</td>
</tr>
<tr>
<td style="text-align:left">不能直接自动写入硬盘。</td>
<td style="text-align:left">可以直接自动写入硬盘。</td>
</tr>
</tbody>
</table>
<h2 id="变量声明"><a href="#变量声明" class="headerlink" title="变量声明"></a>变量声明</h2><h3 id="var-存在变量提升"><a href="#var-存在变量提升" class="headerlink" title="var(存在变量提升)"></a>var(存在变量提升)</h3><p>声明一个变量,可赋一个初始化值。</p>
<h3 id="let-let-同一变量在同一作用域不能同时声明"><a href="#let-let-同一变量在同一作用域不能同时声明" class="headerlink" title="let(let 同一变量在同一作用域不能同时声明)"></a>let(let 同一变量在同一作用域不能同时声明)</h3><p>声明一个块作用域的局部变量,可赋一个初始化值。</p>
<h3 id="const-const-声明时必须赋初始值-也不可以在脚本运行时重新声明"><a href="#const-const-声明时必须赋初始值-也不可以在脚本运行时重新声明" class="headerlink" title="const(const 声明时必须赋初始值,也不可以在脚本运行时重新声明)"></a>const(const 声明时必须赋初始值,也不可以在脚本运行时重新声明)</h3><p>声明一个块作用域的只读的命名常量。
const声明创建一个值的只读引用。但这并不意味着它所持有的值是不可变的,只是变量标识符不能重新分配。
如const a=[1,2,3] a[1]=4; const b={} b.name=”1” 数组元素和对象属性不受保护。</p>
<h2 id="变量的作用域"><a href="#变量的作用域" class="headerlink" title="变量的作用域"></a>变量的作用域</h2><p>在所有函数之外声明的变量,叫做全局变量,因为它可被当前文档中的任何其他代码所访问。在函数内部声明的变量,叫做局部变量,因为它只能在该函数内部访问。全区变量是全局对象的属性,在浏览器中可以用window.xx或xx来访问。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span>(<span class="literal">true</span>){</span><br><span class="line"> <span class="keyword">var</span> a=<span class="number">5</span></span><br><span class="line">}</span><br><span class="line"><span class="built_in">console</span>.log(a) <span class="comment">// 5 使用let声明块级则是undefined</span></span><br></pre></td></tr></table></figure>
<h2 id="变量提升"><a href="#变量提升" class="headerlink" title="变量提升"></a>变量提升</h2><p>JavaScript 变量的另一特别之处是,你可以引用稍后声明的变量而不会引发异常。这一概念称为变量声明提升(hoisting);
var ok ; let 和 const 则不会存在变量提升</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1.</span></span><br><span class="line"><span class="built_in">console</span>.log(x === <span class="literal">undefined</span>); <span class="comment">// true</span></span><br><span class="line"><span class="keyword">var</span> x = <span class="number">3</span>;</span><br><span class="line"></span><br><span class="line"><span class="number">2.</span></span><br><span class="line"><span class="keyword">var</span> myvar = <span class="string">"my value"</span>;</span><br><span class="line"></span><br><span class="line">(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(myvar); <span class="comment">// undefined</span></span><br><span class="line"> <span class="keyword">var</span> myvar = <span class="string">"local value"</span>;</span><br><span class="line">})();</span><br><span class="line"></span><br><span class="line"><span class="number">1.1</span> 也可写作</span><br><span class="line"><span class="keyword">var</span> x;</span><br><span class="line"><span class="built_in">console</span>.log(x === <span class="literal">undefined</span>); <span class="comment">// true</span></span><br><span class="line">x = <span class="number">3</span>;</span><br><span class="line"></span><br><span class="line"><span class="number">2.1</span></span><br><span class="line"><span class="keyword">var</span> myvar = <span class="string">"my value"</span>;</span><br><span class="line"> </span><br><span class="line">(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> myvar;</span><br><span class="line"> <span class="built_in">console</span>.log(myvar); <span class="comment">// undefined</span></span><br><span class="line"> myvar = <span class="string">"local value"</span>;</span><br><span class="line">})();</span><br></pre></td></tr></table></figure>
<h2 id="函数提升"><a href="#函数提升" class="headerlink" title="函数提升"></a>函数提升</h2><p>声明函数的3种方式:</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">foo</span>(<span class="params"></span>)</span>{} <span class="comment">// 函数声明 存在函数提升且大于变量提升</span></span><br><span class="line"><span class="keyword">var</span> foo=<span class="function"><span class="keyword">function</span> (<span class="params"></span>)</span>{} <span class="comment">// 函数表达式 var foo=function foo1(){} 函数名可写</span></span><br><span class="line"><span class="keyword">new</span> <span class="built_in">Function</span>(<span class="string">"参数1"</span>,<span class="string">"参数2"</span>,...,<span class="string">"参数n"</span>,<span class="string">"函数体"</span>); <span class="comment">// 使用Function构造函数</span></span><br></pre></td></tr></table></figure>
<p>从作用域上来说,函数声明式和函数表达式使用的是局部变量,而 Function()构造函数却是全局变量。
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> name = <span class="string">'我是全局变量 name'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 声明式</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">a</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> name = <span class="string">'我是函数a中的name'</span>;</span><br><span class="line"> <span class="keyword">return</span> name;</span><br><span class="line">}</span><br><span class="line"><span class="built_in">console</span>.log(a()); <span class="comment">// 打印: "我是函数a中的name"</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 表达式</span></span><br><span class="line"><span class="keyword">var</span> b = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> name = <span class="string">'我是函数b中的name'</span>;</span><br><span class="line"> <span class="keyword">return</span> name; <span class="comment">// 打印: "我是函数b中的name"</span></span><br><span class="line">}</span><br><span class="line"><span class="built_in">console</span>.log(b())</span><br><span class="line"></span><br><span class="line"><span class="comment">// Function构造函数</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">c</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> name = <span class="string">'我是函数c中的name'</span>;</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Function</span>(<span class="string">'return name'</span>)</span><br><span class="line">}</span><br><span class="line"><span class="built_in">console</span>.log(c()()) <span class="comment">// 打印:"我是全局变量 name",因为Function()返回的是全局变量 name,而不是函数体内的局部变量。</span></span><br></pre></td></tr></table></figure></p>
<p>从执行效率上来说,Function()构造函数的效率要低于其它两种方式,尤其是在循环体中,因为构造函数每执行一次都要重新编译,并且生成新的函数对象。</p>
<p>此时的3种递归调用自身的方式 </p>
<ul>
<li>foo()</li>
<li>foo1()</li>
<li>arguments.callee() </li>
</ul>
<p>现在已经不推荐使用arguments.callee();
原因:访问 arguments 是个很昂贵的操作,因为它是个很大的对象,每次递归调用时都需要重新创建。影响现代浏览器的性能,还会影响闭包。</p>
<h2 id="数据类型-8种"><a href="#数据类型-8种" class="headerlink" title="数据类型 8种"></a>数据类型 8种</h2><h3 id="原始类型"><a href="#原始类型" class="headerlink" title="原始类型"></a>原始类型</h3><ul>
<li>Boolean</li>
<li>null</li>
<li>undefined</li>
<li>String </li>
<li>Number 标识范围 -2^53~2^53 数字均为双精度浮点类型<ul>
<li>实质是一个 64 位的浮点数。使用 53 位表示小数位,10 位表示指数位,1 位表示符号位。</li>
</ul>
</li>
<li>Symbol(它的实例是唯一且不可改变)</li>
<li>bigint</li>
</ul>
<p>Object 是 JavaScript 中所有对象的父对象(object、array、function)</p>
<p>两种类型的区别是:存储位置不同;
原始数据类型直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储;
引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定,如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先
检索其在栈中的地址,取得地址后从堆中获得实体</p>
<p>数据封装类对象:Object、Array、Boolean、Number 和 String
其他对象:Function、Arguments、Math、Date、RegExp、Error</p>
<p>为什么 x=0.1 能得到 0.1?
恭喜你到了看山不是山的境界。因为 mantissa 固定长度是 52 位,再加上省略的一位,最多可以表示的数是 2^53=9007199254740992,对应科学计数尾数是 </p>
<p>9.007199254740992,这也是 JS 最多能表示的精度。它的长度是 16,所以可以使用 toPrecision(16) 来做精度运算,超过的精度会自动做凑整处理。</p>
<p>不仅 JavaScript,所有遵循 IEEE 754 规范的语言都是如此;</p>
<p><code>在JavaScript中,所有的Number都是以64-bit的双精度浮点数存储的,在用二进制存储时会存在精度误差;</code></p>
<p><code>原因:计算机不能精确表示0.1, 0.2这样的浮点数,计算时使用的是带有舍入误差的数,但不是所有的浮点数在计算机内部都存在舍入误差,比如0.5就没有舍入误差</code></p>
<p>双精度的浮点数在这64位上划分为3段,而这3段也就确定了一个浮点数的值,64bit的划分是“1-11-52”的模式,具体来说:</p>
<p>1.就是1位最高位(最左边那一位)表示符号位,0表示正,1表示负;</p>
<p>2.11位表示指数部分;52位表示尾数部分,也就是有效域部分</p>
<p>任何原始类型都有字面量形式,可以不被变量所存储。</p>
<p>JavaScript语言有”垃圾回收”功能,所以在使用引用类型的时候无需担心内存分配。但是为了防止”内存泄漏”还是应该在不实用对象的时候将该对</p>
<p>象的引用赋值为null。让”垃圾回收”器在特定的时间对那一块内存进行回收。</p>
<p>64位浮点数:1位符号位 + 52位整数位 + 11位小数位,如果符号位为1,其他各位均为0,那么这个数值会被表示成”-0”。同理还可以表示”+0”</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 二进制构造-0</span></span><br><span class="line"><span class="comment">// 首先创建一个8位的ArrayBuffer</span></span><br><span class="line"><span class="keyword">const</span> buffer = <span class="keyword">new</span> <span class="built_in">ArrayBuffer</span>(<span class="number">8</span>);</span><br><span class="line"><span class="comment">// 创建DataView对象操作buffer</span></span><br><span class="line"><span class="keyword">const</span> dataView = <span class="keyword">new</span> <span class="built_in">DataView</span>(buffer);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 将第1个字节设置为0x80,即最高位为1</span></span><br><span class="line">dataView.setUint8(<span class="number">0</span>, <span class="number">0x80</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 将buffer内容当做Float64类型返回</span></span><br><span class="line"><span class="built_in">console</span>.log(dataView.getFloat64(<span class="number">0</span>)); <span class="comment">// -0</span></span><br></pre></td></tr></table></figure>
<ul>
<li><p>判断+-0</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">0</span> === <span class="number">-0</span> <span class="comment">// true</span></span><br><span class="line"><span class="comment">// Object.is(-0, 0)返回false,Object.is(NaN, NaN)返回true</span></span><br><span class="line"><span class="comment">// 早期es利用1/-0为-Infinity的特点来判断</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">isNegativeZero</span>(<span class="params">num</span>) </span>{ </span><br><span class="line"> <span class="keyword">return</span> num === <span class="number">0</span> && (<span class="number">1</span> / num < <span class="number">0</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
</li>
<li><p>Object.is()方法的polyfill</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (!<span class="built_in">Object</span>.is) {</span><br><span class="line"> <span class="built_in">Object</span>.is = <span class="function"><span class="keyword">function</span>(<span class="params">x, y</span>) </span>{</span><br><span class="line"> <span class="comment">// SameValue algorithm</span></span><br><span class="line"> <span class="keyword">if</span> (x === y) { <span class="comment">// Steps 1-5, 7-10</span></span><br><span class="line"> <span class="comment">// Steps 6.b-6.e: +0 != -0</span></span><br><span class="line"> <span class="keyword">return</span> x !== <span class="number">0</span> || <span class="number">1</span> / x === <span class="number">1</span> / y;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="comment">// Step 6.a: NaN == NaN</span></span><br><span class="line"> <span class="keyword">return</span> x !== x && y !== y;</span><br><span class="line"> }</span><br><span class="line"> };</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h3 id="原始封装类型"><a href="#原始封装类型" class="headerlink" title="原始封装类型"></a>原始封装类型</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a =<span class="string">'qwer'</span>;</span><br><span class="line"><span class="keyword">var</span> firstChar = a.chatAt(<span class="number">0</span>);</span><br><span class="line"><span class="built_in">console</span>.log(firstChar);<span class="comment">// q</span></span><br></pre></td></tr></table></figure>
<p>在js引擎中发生了
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a =<span class="string">'qwer'</span>;</span><br><span class="line"><span class="keyword">var</span> temp = <span class="keyword">new</span> <span class="built_in">String</span>(a);</span><br><span class="line"><span class="keyword">var</span> firstChar = temp.chatAt(<span class="number">0</span>);</span><br><span class="line">temp =<span class="literal">null</span>;</span><br><span class="line"><span class="built_in">console</span>.log(firstChar);<span class="comment">// q</span></span><br></pre></td></tr></table></figure></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">0.10000000000000000555</span>.toPrecision(<span class="number">16</span>)</span><br><span class="line"><span class="comment">// 返回 0.1000000000000000,去掉末尾的零后正好为 0.1</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 但你看到的 `0.1` 实际上并不是 `0.1`。不信你可用更高的精度试试:</span></span><br><span class="line"><span class="number">0.1</span>.toPrecision(<span class="number">21</span>) = <span class="number">0.100000000000000005551</span></span><br></pre></td></tr></table></figure>
<p><code>"getters"/"setters"</code>可以想象一个给定的字符串就像一个附加了一堆方法和属性的对象。当访问数组的长度时,你只需调用相应的 getter。setter 函数用于设置操作:
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> array = {</span><br><span class="line"> value: [<span class="string">"Hello"</span>, <span class="number">89</span>, <span class="literal">false</span>, <span class="literal">true</span>],</span><br><span class="line"> push: <span class="function"><span class="keyword">function</span>(<span class="params">element</span>) </span>{</span><br><span class="line"> <span class="comment">//</span></span><br><span class="line"> },</span><br><span class="line"> shift: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="comment">//</span></span><br><span class="line"> },</span><br><span class="line"> <span class="keyword">get</span> length() {</span><br><span class="line"> <span class="comment">// gets the length</span></span><br><span class="line"> },</span><br><span class="line"> <span class="keyword">set</span> length(newLen) {</span><br><span class="line"> <span class="comment">// sets the length</span></span><br><span class="line"> }</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="comment">// Getter call</span></span><br><span class="line"><span class="keyword">var</span> len = array.length</span><br><span class="line"></span><br><span class="line"><span class="comment">// Setter call</span></span><br><span class="line">array.length = <span class="number">50</span>;</span><br></pre></td></tr></table></figure></p>
<h3 id="对象Object"><a href="#对象Object" class="headerlink" title="对象Object"></a>对象Object</h3><p>Object 是 JS 中最重要的类型,因此几乎所有其他实体都可以从中派生。 例如,函数和数组是专用对象。 JS 中的对象是键/值对的容器。</p>
<p>对象被定义为“无序属性的集合,其属性可以包含基本值,对象或者函数”。</p>
<p>只有null和undefined无法拥有方法</p>
<p>Function Array Number Boolean String Date Math RegExp类</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typeof</span> <span class="literal">null</span> === <span class="string">'object'</span> <span class="comment">// true</span></span><br><span class="line"><span class="literal">null</span> <span class="keyword">instanceof</span> <span class="built_in">Object</span> <span class="comment">// false </span></span><br><span class="line"><span class="literal">null</span> <span class="keyword">instanceof</span> <span class="literal">null</span> <span class="comment">// error</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 不同的对象在底层都表示为二进制</span></span><br><span class="line"><span class="comment">// 在JavaScript中二进制前三位为0的话都会被判断为object类型</span></span><br><span class="line"><span class="comment">// null的二进制表示全是0,自然前三位也是0</span></span><br><span class="line"><span class="comment">// 所以 typeof null === “object”</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typeof</span> <span class="built_in">Function</span>; <span class="comment">// 'function'</span></span><br><span class="line"><span class="keyword">typeof</span> <span class="keyword">new</span> <span class="built_in">Function</span>(); <span class="comment">// 'function'</span></span><br><span class="line"><span class="keyword">typeof</span> <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{}; <span class="comment">// 'function'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typeof</span> <span class="built_in">Array</span>; <span class="comment">// 'function'</span></span><br><span class="line"><span class="keyword">typeof</span> <span class="built_in">Array</span>(); <span class="comment">// 'object'</span></span><br><span class="line"><span class="keyword">typeof</span> <span class="keyword">new</span> <span class="built_in">Array</span>(); <span class="comment">// 'object'</span></span><br><span class="line"><span class="keyword">typeof</span> []; <span class="comment">// 'object'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typeof</span> <span class="built_in">Boolean</span>; <span class="comment">// "function"</span></span><br><span class="line"><span class="keyword">typeof</span> <span class="built_in">Boolean</span>(); <span class="comment">// "boolean"</span></span><br><span class="line"><span class="keyword">typeof</span> <span class="keyword">new</span> <span class="built_in">Boolean</span>(); <span class="comment">// "object"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typeof</span> <span class="built_in">Math</span>; <span class="comment">// 'object'</span></span><br><span class="line"><span class="keyword">typeof</span> <span class="built_in">Math</span>(); <span class="comment">// Math is not a function</span></span><br><span class="line"><span class="keyword">typeof</span> <span class="keyword">new</span> <span class="built_in">Math</span>(); <span class="comment">// Math is not a constructor</span></span><br><span class="line"></span><br><span class="line">[]+[] <span class="comment">// ""</span></span><br><span class="line">[]+{} <span class="comment">// "[object Object]"</span></span><br><span class="line">{}+[] <span class="comment">// 0</span></span><br><span class="line"></span><br><span class="line">!+[]+[]+![] <span class="comment">// "truefalse"</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">Math</span>.max() <span class="comment">// -Infinity</span></span><br><span class="line"><span class="built_in">Math</span>.min() <span class="comment">// Infinity</span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>构造函数 Array(..) 不要求必须带 new 关键字。不带时,它会被自动补上。 因此 Array(1,2,3) 和 new Array(1,2,3) 的效果是一样的</p>
</blockquote>
<h2 id="MDN基本数据类型的定义"><a href="#MDN基本数据类型的定义" class="headerlink" title="MDN基本数据类型的定义"></a>MDN基本数据类型的定义</h2><blockquote>
<p>除 Object 以外的所有类型都是不可变的(值本身无法被改变)。例如,与 C 语言不同,JavaScript 中字符串是不可变的
(译注:如,JavaScript 中对字符串的操作一定返回了一个新字符串,原始字符串并没有被改变)。我们称这些类型的值为“原始值”。</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="string">'string'</span></span><br><span class="line">a[<span class="number">0</span>] = <span class="string">'a'</span></span><br><span class="line"><span class="built_in">console</span>.log(a) <span class="comment">// string</span></span><br></pre></td></tr></table></figure>
<p>我们通常情况下都是对一个变量重新赋值,而不是改变基本数据类型的值。在 js 中是没有方法是可以改变布尔值和数字的。
倒是有很多操作字符串的方法,但是这些方法都是返回一个新的字符串,并没有改变其原有的数据。</p>
<h3 id="引用数据类型"><a href="#引用数据类型" class="headerlink" title="引用数据类型"></a>引用数据类型</h3><p>引用类型(object)是存放在堆heap内存中的,变量实际上是一个存放在栈内存的指针,这个指针指向堆内存中的地址。每个空间大小不一样,要根据情况开进行特定的分配。</p>
<h3 id="传值和传址"><a href="#传值和传址" class="headerlink" title="传值和传址"></a>传值和传址</h3><p>了解了基本数据类型与引用类型的区别之后,我们就应该能明白传值与传址的区别了。
在我们进行赋值操作的时候,基本数据类型的赋值(=)是在内存中新开辟一段栈内存,然后再将值赋值到新的栈中。例如:</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="number">10</span>;</span><br><span class="line"><span class="keyword">var</span> b = a;</span><br><span class="line"></span><br><span class="line">a ++ ;</span><br><span class="line"><span class="built_in">console</span>.log(a); <span class="comment">// 11</span></span><br><span class="line"><span class="built_in">console</span>.log(b); <span class="comment">// 10</span></span><br></pre></td></tr></table></figure>
<p>所以说,基本类型的赋值的两个变量是两个独立相互不影响的变量。</p>
<p>但是引用类型的赋值是传址。只是改变指针的指向,例如,也就是说引用类型的赋值是对象保存在栈中的地址的赋值,这样的话两个变量就指向同一个对象,因此两者之间操作互相有影响。例如:</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = {}; <span class="comment">// a保存了一个空对象的实例</span></span><br><span class="line"><span class="keyword">var</span> b = a; <span class="comment">// a和b都指向了这个空对象</span></span><br><span class="line"></span><br><span class="line">a.name = <span class="string">'jozo'</span>;</span><br><span class="line"><span class="built_in">console</span>.log(a.name); <span class="comment">// 'jozo'</span></span><br><span class="line"><span class="built_in">console</span>.log(b.name); <span class="comment">// 'jozo'</span></span><br><span class="line"></span><br><span class="line">b.age = <span class="number">22</span>;</span><br><span class="line"><span class="built_in">console</span>.log(b.age);<span class="comment">// 22</span></span><br><span class="line"><span class="built_in">console</span>.log(a.age);<span class="comment">// 22</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(a == b);<span class="comment">// true</span></span><br></pre></td></tr></table></figure>
<h2 id="字面量"><a href="#字面量" class="headerlink" title="字面量"></a>字面量</h2><p>字面量是由语法表达式定义的常量</p>
<ul>
<li>数组字面量(Array literals) []</li>
<li>布尔字面量(Boolean literals) true/false</li>
<li>浮点数字面量(Floating-point literals) 3.14</li>
<li>整数(Intergers) 5 </li>
<li>对象字面量(Object literals) {}</li>
<li>RegExp literals 一个正则表达式是字符被斜线(译注:正斜杠“/”)围成的表达式 /a+b/
RegExp.test() RegExp.exec() string.match() </li>
<li>字符串字面量(String literals) “1212” ‘1212’
JavaScript会自动将字符串字面值转换为一个临时字符串对象,调用该方法,然后废弃掉那个临时的字符串对象。你也能用对字符串字面值使用类似</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">String</span>.length的属性:</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">"John's cat"</span>.length)</span><br></pre></td></tr></table></figure>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> obj={</span><br><span class="line"> say:funciton(){</span><br><span class="line"></span><br><span class="line"> },</span><br><span class="line"> <span class="comment">// 简写</span></span><br><span class="line"> say(){</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>十进制整数字面量由一串数字序列组成,且没有前缀0。
八进制的整数以 0(或0O、0o)开头,只能包括数字0-7。
十六进制整数以0x(或0X)开头,可以包含数字(0-9)和字母 a~f 或 A~F。
二进制整数以0b(或0B)开头,只能包含数字0和1。</p>
<h2 id="模板字符串"><a href="#模板字符串" class="headerlink" title="模板字符串"></a>模板字符串</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> name = <span class="string">"Bob"</span>, time = <span class="string">"today"</span>;</span><br><span class="line"><span class="string">`Hello <span class="subst">${name}</span>, how are you <span class="subst">${time}</span>?`</span></span><br></pre></td></tr></table></figure>
<h2 id="布尔环境的假值"><a href="#布尔环境的假值" class="headerlink" title="布尔环境的假值"></a>布尔环境的假值</h2><ul>
<li>false</li>
<li>undefined</li>
<li>null</li>
<li>0</li>
<li>NaN</li>
<li>空字符串(””)</li>
</ul>
<h2 id="try-catch"><a href="#try-catch" class="headerlink" title="try-catch"></a>try-catch</h2><p>如果finally块返回一个值,该值会是整个try-catch-finally流程的返回值,不管在try和catch块中语句返回了什么:</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">f</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="number">0</span>);</span><br><span class="line"> <span class="keyword">throw</span> <span class="string">"bogus"</span>;</span><br><span class="line"> } <span class="keyword">catch</span>(e) {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="number">1</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>; <span class="comment">// this return statement is suspended</span></span><br><span class="line"> <span class="comment">// until finally block has completed</span></span><br><span class="line"> <span class="built_in">console</span>.log(<span class="number">2</span>); <span class="comment">// not reachable</span></span><br><span class="line"> } <span class="keyword">finally</span> {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="number">3</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>; <span class="comment">// overwrites the previous "return"</span></span><br><span class="line"> <span class="built_in">console</span>.log(<span class="number">4</span>); <span class="comment">// not reachable</span></span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// "return false" is executed now </span></span><br><span class="line"> <span class="built_in">console</span>.log(<span class="number">5</span>); <span class="comment">// not reachable</span></span><br><span class="line">}</span><br><span class="line">f(); <span class="comment">// console 0, 1, 3; returns false</span></span><br></pre></td></tr></table></figure>
<h2 id="for-of-和-for-in循环"><a href="#for-of-和-for-in循环" class="headerlink" title="for of 和 for in循环"></a>for of 和 for in循环</h2><ul>
<li>for in 更适合对象,遍历数组和对象</li>
<li>for of 适合遍历数组,遍历没有Symbol.iterator属性的对象是会报错的<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> arr = [<span class="number">3</span>, <span class="number">5</span>, <span class="number">7</span>];</span><br><span class="line">arr.foo = <span class="string">"hello"</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> i <span class="keyword">in</span> arr) {</span><br><span class="line"> <span class="built_in">console</span>.log(i); <span class="comment">// logs "0", "1", "2", "foo"</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 所有可枚举的属性名</span></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> i <span class="keyword">of</span> arr) {</span><br><span class="line"> <span class="built_in">console</span>.log(i); <span class="comment">// logs "3", "5", "7" // 注意这里没有 hello</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// for in 的循环顺序 => 遍历首先数字的可以接着按照创建顺序遍历</span></span><br><span class="line"><span class="comment">// 对象数字键名会转成字符串 对象的key值只有string和symbol类型</span></span><br><span class="line"><span class="comment">// 排序规则同样适用于下列API:</span></span><br><span class="line"><span class="comment">// Object.entries</span></span><br><span class="line"><span class="comment">// Object.values</span></span><br><span class="line"><span class="comment">// Object.keys</span></span><br><span class="line"><span class="comment">// Object.getOwnPropertyNames</span></span><br><span class="line"><span class="comment">// Reflect.ownKeys</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a = {<span class="number">1</span>:<span class="number">1</span>,<span class="attr">name</span>:<span class="string">'cosyer'</span>,<span class="number">2</span>:<span class="number">2</span>}</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> i <span class="keyword">in</span> a) {</span><br><span class="line"> <span class="keyword">if</span>(a.hasOwnProperty(i)){</span><br><span class="line"> <span class="built_in">console</span>.log(i)</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 1 2 name</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<h2 id="嵌套函数和闭包"><a href="#嵌套函数和闭包" class="headerlink" title="嵌套函数和闭包"></a>嵌套函数和闭包</h2><p>一个闭包是一个可以自己拥有独立的环境与变量的的表达式。</p>
<ul>
<li>内部函数包含外部函数的作用域。</li>
<li>内部函数只可以在外部函数中访问。</li>
<li>内部函数可以访问外部函数的参数和变量,但是外部函数却不能使用它的参数和变量。</li>
</ul>
<h2 id="多层嵌套函数"><a href="#多层嵌套函数" class="headerlink" title="多层嵌套函数"></a>多层嵌套函数</h2><p>函数可以被多层嵌套。例如,函数A可以包含函数B,函数B可以再包含函数C。B和C都形成了闭包,所以B可以访问A,C可以访问B和A。因此,闭包可以包含多个作用域;他们递归式的包含了所有包含它的函数作用域。这个称之为作用域链。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">A</span>(<span class="params">x</span>) </span>{</span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">B</span>(<span class="params">y</span>) </span>{</span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">C</span>(<span class="params">z</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(x + y + z);</span><br><span class="line"> }</span><br><span class="line"> C(<span class="number">3</span>);</span><br><span class="line"> }</span><br><span class="line"> B(<span class="number">2</span>);</span><br><span class="line">}</span><br><span class="line">A(<span class="number">1</span>); <span class="comment">// logs 6 (1 + 2 + 3)</span></span><br></pre></td></tr></table></figure>
<p>在这个例子里面,C可以访问B的y和A的x。这是因为:</p>
<ol>
<li>B形成了一个包含A的闭包,B可以访问A的参数和变量</li>
<li>C形成了一个包含B的闭包</li>
<li>B包含A,所以C也包含A,C可以访问B和A的参数和变量。换言之,C用这个顺序链接了B和A的作用域</li>
</ol>
<p>反过来却不是这样。A不能访问C,因为A看不到B中的参数和变量,C是B中的一个变量,所以C是B私有的。</p>
<h2 id="作用域链解释说明"><a href="#作用域链解释说明" class="headerlink" title="作用域链解释说明"></a>作用域链解释说明</h2><p>当同一个闭包作用域下两个参数或者变量同名时,就会产生命名冲突。更近的作用域有更高的优先权,所以最近的优先级最高,最远的优先级最低。这就是作用域链。链的第一个元素就是最里面的作用域,最后一个元素便是最外层的作用域。</p>
<p><code>全局函数无法查看局部函数的内部细节,但局部函数可以查看其上层的函数细节,直至全局细节。
当需要从局部函数查找某一属性或方法时,如果当前作用域没有找到,就会上溯到上层作用域查找,
直至全局函数,这种组织形式就是作用域链。</code></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">outside</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> x = <span class="number">5</span>;</span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">inside</span>(<span class="params">x</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> x * <span class="number">2</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> inside;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">outside()(<span class="number">10</span>); <span class="comment">// returns 20 instead of 10</span></span><br></pre></td></tr></table></figure>
<p>命名冲突发生在return x上,inside的参数x和outside变量x发生了冲突。这里的作用域链是{inside, outside, 全局对象}。因此inside的x具有最高优先权,返回了20(inside的x)而不是10(outside的x)。</p>
<h2 id="闭包"><a href="#闭包" class="headerlink" title="闭包"></a>闭包</h2><p>JavaScript 允许函数嵌套,并且内部函数可以访问定义在外部函数中的所有变量和函数,以及外部函数能访问的所有变量和函数。但是,外部函数却不能够访问定义在内部函数中的变量和函数。这给内部函数的变量提供了一定的安全性。此外,由于内部函数可以访问外部函数的作用域,因此当内部函数生存周期大于外部函数时,外部函数中定义的变量和函数将的生存周期比内部函数执行时间长。当内部函数以某一种方式被任何一个外部函数作用域访问时,一个闭包就产生了。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> pet = <span class="function"><span class="keyword">function</span>(<span class="params">name</span>) </span>{ <span class="comment">//外部函数定义了一个变量"name"</span></span><br><span class="line"> <span class="keyword">var</span> getName = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{ </span><br><span class="line"> <span class="comment">//内部函数可以访问 外部函数定义的"name"</span></span><br><span class="line"> <span class="keyword">return</span> name; </span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//返回这个内部函数,从而将其暴露在外部函数作用域</span></span><br><span class="line"> <span class="keyword">return</span> getName; </span><br><span class="line">};</span><br><span class="line">myPet = pet(<span class="string">"Vivie"</span>);</span><br><span class="line"> </span><br><span class="line">myPet(); <span class="comment">// 返回结果 "Vivie"</span></span><br></pre></td></tr></table></figure>
<h2 id="arguments-对象"><a href="#arguments-对象" class="headerlink" title="arguments 对象"></a>arguments 对象</h2><p>函数的实际参数会被保存在一个类似数组的arguments对象中。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">arguments</span>[i] <span class="comment">// 访问</span></span><br></pre></td></tr></table></figure>
<p>arguments变量只是 ”类数组对象“,并不是一个数组。称其为类数组对象是说它有一个索引编号和length属性。尽管如此,它并不拥有全部的Array对象的操作方法。</p>
<h2 id="函数参数-默认参数、剩余参数-rest"><a href="#函数参数-默认参数、剩余参数-rest" class="headerlink" title="函数参数(默认参数、剩余参数(rest))"></a>函数参数(默认参数、剩余参数(rest))</h2><p>剩余参数语法允许将不确定数量的参数表示为数组</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">multiply</span>(<span class="params">a, b = <span class="number">1</span>,...[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> a*b;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="箭头函数"><a href="#箭头函数" class="headerlink" title="箭头函数"></a>箭头函数</h2><p>箭头函数总是匿名的
引入箭头函数的原因</p>
<ol>
<li>更简洁的语法</li>
<li>捕捉闭包上下文的this值<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Person</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="keyword">this</span>.age = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"> setInterval(<span class="function"><span class="params">()</span> =></span> {</span><br><span class="line"> <span class="keyword">this</span>.age++; <span class="comment">// |this| properly refers to the person object</span></span><br><span class="line"> }, <span class="number">1000</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> p = <span class="keyword">new</span> Person();</span><br></pre></td></tr></table></figure>
</li>
</ol>
<h2 id="扩展语句"><a href="#扩展语句" class="headerlink" title="扩展语句"></a>扩展语句</h2><p>适用于对象,数组
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">f</span>(<span class="params">x, y, z</span>) </span>{ }</span><br><span class="line"><span class="keyword">var</span> args = [<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>];</span><br><span class="line">f(...args);</span><br></pre></td></tr></table></figure></p>
<h2 id="临时对象"><a href="#临时对象" class="headerlink" title="临时对象"></a>临时对象</h2><p>你可以在String字面值上使用String对象的任何方法—JavaScript自动把String字面值转换为一个临时的String对象, 然后调用其相应方法,最后丢弃销毁此临时对象.在String字面值上也可以使用String.length属性.</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> s1 = <span class="string">"2 + 2"</span>; <span class="comment">// Creates a string literal value</span></span><br><span class="line"><span class="keyword">var</span> s2 = <span class="keyword">new</span> <span class="built_in">String</span>(<span class="string">"2 + 2"</span>); <span class="comment">// Creates a String object</span></span><br><span class="line"><span class="built_in">eval</span>(s1); <span class="comment">// Returns the number 4</span></span><br><span class="line"><span class="built_in">eval</span>(s2); <span class="comment">// Returns the string "2 + 2"</span></span><br><span class="line"><span class="built_in">Number</span>(<span class="literal">null</span>) <span class="comment">// 0</span></span><br></pre></td></tr></table></figure>
<h2 id="数组方法"><a href="#数组方法" class="headerlink" title="数组方法"></a>数组方法</h2><h3 id="concat-连接两个数组并返回一个新的数组。"><a href="#concat-连接两个数组并返回一个新的数组。" class="headerlink" title="concat() 连接两个数组并返回一个新的数组。"></a>concat() 连接两个数组并返回一个新的数组。</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> myArray = <span class="keyword">new</span> <span class="built_in">Array</span>(<span class="string">"1"</span>, <span class="string">"2"</span>, <span class="string">"3"</span>);</span><br><span class="line">myArray = myArray.concat(<span class="string">"a"</span>, <span class="string">"b"</span>, <span class="string">"c"</span>); </span><br><span class="line"><span class="comment">// myArray is now ["1", "2", "3", "a", "b", "c"]</span></span><br></pre></td></tr></table></figure>
<h3 id="join-将数组的所有元素连接成一个字符串。"><a href="#join-将数组的所有元素连接成一个字符串。" class="headerlink" title="join() 将数组的所有元素连接成一个字符串。"></a>join() 将数组的所有元素连接成一个字符串。</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> myArray = <span class="keyword">new</span> <span class="built_in">Array</span>(<span class="string">"Wind"</span>, <span class="string">"Rain"</span>, <span class="string">"Fire"</span>);</span><br><span class="line"><span class="keyword">var</span> list = myArray.join(<span class="string">" - "</span>); <span class="comment">// list is "Wind - Rain - Fire"</span></span><br></pre></td></tr></table></figure>
<h3 id="push-在数组末尾添加一个或多个元素,并返回数组操作后的长度。"><a href="#push-在数组末尾添加一个或多个元素,并返回数组操作后的长度。" class="headerlink" title="push() 在数组末尾添加一个或多个元素,并返回数组操作后的长度。"></a>push() 在数组末尾添加一个或多个元素,并返回数组操作后的长度。</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> myArray = <span class="keyword">new</span> <span class="built_in">Array</span>(<span class="string">"1"</span>, <span class="string">"2"</span>);</span><br><span class="line">myArray.push(<span class="string">"3"</span>); <span class="comment">// myArray is now ["1", "2", "3"]</span></span><br></pre></td></tr></table></figure>
<h3 id="pop-从数组移出最后一个元素,并返回该元素。"><a href="#pop-从数组移出最后一个元素,并返回该元素。" class="headerlink" title="pop() 从数组移出最后一个元素,并返回该元素。"></a>pop() 从数组移出最后一个元素,并返回该元素。</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> myArray = <span class="keyword">new</span> <span class="built_in">Array</span>(<span class="string">"1"</span>, <span class="string">"2"</span>, <span class="string">"3"</span>);</span><br><span class="line"><span class="keyword">var</span> last = myArray.pop(); </span><br><span class="line"><span class="comment">// myArray is now ["1", "2"], last = "3"</span></span><br></pre></td></tr></table></figure>
<h3 id="shift-从数组移出第一个元素,并返回该元素。"><a href="#shift-从数组移出第一个元素,并返回该元素。" class="headerlink" title="shift() 从数组移出第一个元素,并返回该元素。"></a>shift() 从数组移出第一个元素,并返回该元素。</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> myArray = <span class="keyword">new</span> <span class="built_in">Array</span> (<span class="string">"1"</span>, <span class="string">"2"</span>, <span class="string">"3"</span>);</span><br><span class="line"><span class="keyword">var</span> first = myArray.shift(); </span><br><span class="line"><span class="comment">// myArray is now ["2", "3"], first is "1"</span></span><br></pre></td></tr></table></figure>
<h3 id="unshift-在数组开头添加一个或多个元素,并返回数组的新长度。"><a href="#unshift-在数组开头添加一个或多个元素,并返回数组的新长度。" class="headerlink" title="unshift()在数组开头添加一个或多个元素,并返回数组的新长度。"></a>unshift()在数组开头添加一个或多个元素,并返回数组的新长度。</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> myArray = <span class="keyword">new</span> <span class="built_in">Array</span> (<span class="string">"1"</span>, <span class="string">"2"</span>, <span class="string">"3"</span>);</span><br><span class="line">myArray.unshift(<span class="string">"4"</span>, <span class="string">"5"</span>); </span><br><span class="line"><span class="comment">// myArray becomes ["4", "5", "1", "2", "3"]</span></span><br></pre></td></tr></table></figure>
<h3 id="slice-开始索引,结束索引-从数组提取一个片段,并作为一个新数组返回。"><a href="#slice-开始索引,结束索引-从数组提取一个片段,并作为一个新数组返回。" class="headerlink" title="slice(开始索引,结束索引) 从数组提取一个片段,并作为一个新数组返回。"></a>slice(开始索引,结束索引) 从数组提取一个片段,并作为一个新数组返回。</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> myArray = <span class="keyword">new</span> <span class="built_in">Array</span> (<span class="string">"a"</span>, <span class="string">"b"</span>, <span class="string">"c"</span>, <span class="string">"d"</span>, <span class="string">"e"</span>);</span><br><span class="line">myArray = myArray.slice(<span class="number">1</span>, <span class="number">4</span>); <span class="comment">// until index 3, returning [ "b", "c", "d"]</span></span><br></pre></td></tr></table></figure>
<p>slice 方法可以用来将一个类数组(Array-like)对象/集合转换成一个新数组。只需将该方法绑定到这个对象上。 一个函数中的 arguments 就是一个类数组对象的例子。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">Array</span>.prototype.slice.call({<span class="number">0</span>:<span class="number">1</span>,<span class="number">1</span>:<span class="number">3</span>,<span class="attr">length</span>:<span class="number">2</span>});</span><br></pre></td></tr></table></figure>
<h3 id="splice-index-count-to-remove-addElement1-addElement2-…-从数组移出一些元素,(可选)并替换它们。"><a href="#splice-index-count-to-remove-addElement1-addElement2-…-从数组移出一些元素,(可选)并替换它们。" class="headerlink" title="splice(index, count_to_remove, addElement1, addElement2, …)从数组移出一些元素,(可选)并替换它们。"></a>splice(index, count_to_remove, addElement1, addElement2, …)从数组移出一些元素,(可选)并替换它们。</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> myArray = <span class="keyword">new</span> <span class="built_in">Array</span> (<span class="string">"1"</span>, <span class="string">"2"</span>, <span class="string">"3"</span>, <span class="string">"4"</span>, <span class="string">"5"</span>);</span><br><span class="line">myArray.splice(<span class="number">1</span>, <span class="number">3</span>, <span class="string">"a"</span>, <span class="string">"b"</span>, <span class="string">"c"</span>, <span class="string">"d"</span>); </span><br><span class="line"><span class="comment">// myArray is now ["1", "a", "b", "c", "d", "5"]</span></span><br></pre></td></tr></table></figure>
<h3 id="reverse-颠倒数组元素的顺序:第一个变成最后一个,最后一个变成第一个。"><a href="#reverse-颠倒数组元素的顺序:第一个变成最后一个,最后一个变成第一个。" class="headerlink" title="reverse() 颠倒数组元素的顺序:第一个变成最后一个,最后一个变成第一个。"></a>reverse() 颠倒数组元素的顺序:第一个变成最后一个,最后一个变成第一个。</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> myArray = <span class="keyword">new</span> <span class="built_in">Array</span> (<span class="string">"1"</span>, <span class="string">"2"</span>, <span class="string">"3"</span>);</span><br><span class="line">myArray.reverse(); </span><br><span class="line"><span class="comment">// transposes the array so that myArray = [ "3", "2", "1" ]</span></span><br></pre></td></tr></table></figure>
<h3 id="sort-给数组元素排序。"><a href="#sort-给数组元素排序。" class="headerlink" title="sort() 给数组元素排序。"></a>sort() 给数组元素排序。</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> arr=[<span class="number">2</span>,<span class="number">1</span>,<span class="number">3</span>]</span><br><span class="line">arr.sort() <span class="comment">// [1,2,3]</span></span><br></pre></td></tr></table></figure>
<p>sort() 也可以带一个回调函数来决定怎么比较数组元素。这个回调函数比较两个值,并返回3个值中的一个:</p>
<ul>
<li>如果 a 小于 b ,返回 -1(或任何负数) 降序</li>
<li>如果 a 大于 b ,返回 1 (或任何正数) 升序</li>
<li>如果 a 和 b 相等,返回 0。</li>
</ul>
<h3 id="indexOf-searchElement-fromIndex-在数组中搜索searchElement-并返回第一个匹配的索引。"><a href="#indexOf-searchElement-fromIndex-在数组中搜索searchElement-并返回第一个匹配的索引。" class="headerlink" title="indexOf(searchElement[, fromIndex]) 在数组中搜索searchElement 并返回第一个匹配的索引。"></a>indexOf(searchElement[, fromIndex]) 在数组中搜索searchElement 并返回第一个匹配的索引。</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = [<span class="string">'a'</span>, <span class="string">'b'</span>, <span class="string">'a'</span>, <span class="string">'b'</span>, <span class="string">'a'</span>];</span><br><span class="line"><span class="built_in">console</span>.log(a.indexOf(<span class="string">'b'</span>)); <span class="comment">// logs 1</span></span><br><span class="line"><span class="comment">// Now try again, starting from after the last match</span></span><br><span class="line"><span class="built_in">console</span>.log(a.indexOf(<span class="string">'b'</span>, <span class="number">2</span>)); <span class="comment">// logs 3</span></span><br><span class="line"><span class="built_in">console</span>.log(a.indexOf(<span class="string">'z'</span>)); <span class="comment">// logs -1, because 'z' was not found</span></span><br></pre></td></tr></table></figure>
<h3 id="lastIndexOf-searchElement-fromIndex-和-indexOf-差不多,但这是从结尾开始,并且是反向搜索。"><a href="#lastIndexOf-searchElement-fromIndex-和-indexOf-差不多,但这是从结尾开始,并且是反向搜索。" class="headerlink" title="lastIndexOf(searchElement[, fromIndex]) 和 indexOf 差不多,但这是从结尾开始,并且是反向搜索。"></a>lastIndexOf(searchElement[, fromIndex]) 和 indexOf 差不多,但这是从结尾开始,并且是反向搜索。</h3><h3 id="forEach-循环数组-不定的顺序-不能用break-return-false跳出循环遍历"><a href="#forEach-循环数组-不定的顺序-不能用break-return-false跳出循环遍历" class="headerlink" title="forEach() 循环数组 不定的顺序 不能用break,return false跳出循环遍历"></a>forEach() 循环数组 不定的顺序 不能用break,return false跳出循环遍历</h3><p>遍历都不会修改原来的基本类型(只能返回新数组)引用类型可以。</p>
<h3 id="map-循环数组返回新数组"><a href="#map-循环数组返回新数组" class="headerlink" title="map() 循环数组返回新数组"></a>map() 循环数组返回新数组</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a1 = [<span class="string">'a'</span>, <span class="string">'b'</span>, <span class="string">'c'</span>];</span><br><span class="line"><span class="keyword">var</span> a2 = a1.map(<span class="function"><span class="keyword">function</span>(<span class="params">item</span>) </span>{ <span class="keyword">return</span> item.toUpperCase(); });</span><br><span class="line"><span class="built_in">console</span>.log(a2); <span class="comment">// logs A,B,C</span></span><br></pre></td></tr></table></figure>
<h3 id="find-找到满足条件的第一个元素"><a href="#find-找到满足条件的第一个元素" class="headerlink" title="find() 找到满足条件的第一个元素"></a>find() 找到满足条件的第一个元素</h3><h3 id="filter-循环数组返回符合条件的元素"><a href="#filter-循环数组返回符合条件的元素" class="headerlink" title="filter() 循环数组返回符合条件的元素"></a>filter() 循环数组返回符合条件的元素</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a1 = [<span class="string">'a'</span>, <span class="number">10</span>, <span class="string">'b'</span>, <span class="number">20</span>, <span class="string">'c'</span>, <span class="number">30</span>];</span><br><span class="line"><span class="keyword">var</span> a2 = a1.filter(<span class="function"><span class="keyword">function</span>(<span class="params">item</span>) </span>{ <span class="keyword">return</span> <span class="keyword">typeof</span> item == <span class="string">'number'</span>; });</span><br><span class="line"><span class="built_in">console</span>.log(a2); <span class="comment">// logs 10,20,30</span></span><br></pre></td></tr></table></figure>
<h3 id="every-循环数组-如果全部元素满足条件则返回true-否则返回false"><a href="#every-循环数组-如果全部元素满足条件则返回true-否则返回false" class="headerlink" title="every() 循环数组 如果全部元素满足条件则返回true 否则返回false"></a>every() 循环数组 如果全部元素满足条件则返回true 否则返回false</h3><h3 id="some-循环数组-只要有一项满足条件则返回true-全部不满足返回false"><a href="#some-循环数组-只要有一项满足条件则返回true-全部不满足返回false" class="headerlink" title="some() 循环数组 只要有一项满足条件则返回true 全部不满足返回false"></a>some() 循环数组 只要有一项满足条件则返回true 全部不满足返回false</h3><h3 id="reduce-迭代-使用回调函数-callback-firstValue-secondValue-把数组列表计算成一个单一值-reduceRight-从右边开始"><a href="#reduce-迭代-使用回调函数-callback-firstValue-secondValue-把数组列表计算成一个单一值-reduceRight-从右边开始" class="headerlink" title="reduce() 迭代 使用回调函数 callback(firstValue, secondValue) 把数组列表计算成一个单一值 reduceRight() 从右边开始"></a>reduce() 迭代 使用回调函数 callback(firstValue, secondValue) 把数组列表计算成一个单一值 reduceRight() 从右边开始</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = [<span class="number">10</span>, <span class="number">20</span>, <span class="number">30</span>];</span><br><span class="line"><span class="keyword">var</span> total = a.reduce(<span class="function"><span class="keyword">function</span>(<span class="params">first, second</span>) </span>{ <span class="keyword">return</span> first + second; }, <span class="number">0</span>);</span><br><span class="line"><span class="built_in">console</span>.log(total) <span class="comment">// Prints 60</span></span><br><span class="line"></span><br><span class="line">[<span class="number">3</span>,<span class="number">2</span>,<span class="number">1</span>].reduce(<span class="built_in">Math</span>.pow) <span class="comment">// 9</span></span><br><span class="line">[].reduce(<span class="built_in">Math</span>.pow) <span class="comment">// error</span></span><br></pre></td></tr></table></figure>
<h3 id="填充fill-splice"><a href="#填充fill-splice" class="headerlink" title="填充fill/splice"></a>填充fill/splice</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> fruits = [<span class="string">"Banana"</span>, <span class="string">"Orange"</span>, <span class="string">"Apple"</span>, <span class="string">"Mango"</span>];</span><br><span class="line">fruits.fill(<span class="string">"cosyer"</span>, <span class="number">2</span>, <span class="number">4</span>); <span class="comment">// 开始和结束索引</span></span><br><span class="line">fruits.splice(<span class="number">2</span>,<span class="number">2</span>,<span class="string">'cosyer'</span>,<span class="string">'cosyer'</span>); <span class="comment">// splice方法需要手动添加多个</span></span><br><span class="line"><span class="comment">// ["Banana", "Orange", "cosyer", "cosyer"]</span></span><br></pre></td></tr></table></figure>
<h3 id="copyWithin"><a href="#copyWithin" class="headerlink" title="copyWithin"></a>copyWithin</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> fruits = [<span class="string">"Banana"</span>, <span class="string">"Orange"</span>, <span class="string">"Apple"</span>, <span class="string">"Mango"</span>];</span><br><span class="line">fruits.copyWithin(<span class="number">2</span>, <span class="number">0</span>); <span class="comment">// Banana,Orange,Banana,Orange</span></span><br><span class="line"><span class="comment">// copyWithin(target, start, end);</span></span><br></pre></td></tr></table></figure>
<h3 id="entries-一个数组的迭代对象,该对象包含数组的键值对"><a href="#entries-一个数组的迭代对象,该对象包含数组的键值对" class="headerlink" title="entries 一个数组的迭代对象,该对象包含数组的键值对"></a>entries 一个数组的迭代对象,该对象包含数组的键值对</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = [<span class="string">'a'</span>,<span class="string">'b'</span>,<span class="string">'c'</span>]</span><br><span class="line"><span class="keyword">var</span> iterator = a.entries()</span><br><span class="line"><span class="built_in">console</span>.log(iterator) <span class="comment">// Array Iterator{}</span></span><br><span class="line"><span class="built_in">console</span>.log(iterator.next().value) <span class="comment">// [0,'a']</span></span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">let</span> a <span class="keyword">of</span> iterator){</span><br><span class="line"> <span class="built_in">console</span>.log(a)</span><br><span class="line">}</span><br><span class="line"><span class="comment">//[0,'a']</span></span><br><span class="line"><span class="comment">//[1,'b']</span></span><br><span class="line"><span class="comment">//[2,'c']</span></span><br><span class="line"><span class="comment">// keys返回键() values()返回值</span></span><br></pre></td></tr></table></figure>
<h2 id="Map简单的键值对集合-字典的数字结构类似对象,键可以是各种类型的值"><a href="#Map简单的键值对集合-字典的数字结构类似对象,键可以是各种类型的值" class="headerlink" title="Map简单的键值对集合(字典的数字结构类似对象,键可以是各种类型的值)"></a>Map简单的键值对集合(字典的数字结构类似对象,键可以是各种类型的值)</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> sayings = <span class="keyword">new</span> <span class="built_in">Map</span>();</span><br><span class="line">sayings.set(<span class="string">'dog'</span>, <span class="string">'woof'</span>);</span><br><span class="line">sayings.set(<span class="string">'cat'</span>, <span class="string">'meow'</span>);</span><br><span class="line">sayings.set(<span class="string">'elephant'</span>, <span class="string">'toot'</span>);</span><br><span class="line">sayings.size; <span class="comment">// 3</span></span><br><span class="line">sayings.get(<span class="string">'fox'</span>); <span class="comment">// undefined</span></span><br><span class="line">sayings.has(<span class="string">'bird'</span>); <span class="comment">// false</span></span><br><span class="line">sayings.delete(<span class="string">'dog'</span>);</span><br><span class="line">sayings.has(<span class="string">'dog'</span>); <span class="comment">// false</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">var</span> [key, value] <span class="keyword">of</span> sayings) {</span><br><span class="line"> <span class="built_in">console</span>.log(key + <span class="string">' goes '</span> + value);</span><br><span class="line">}</span><br><span class="line"><span class="comment">// "cat goes meow"</span></span><br><span class="line"><span class="comment">// "elephant goes toot"</span></span><br><span class="line"></span><br><span class="line">sayings.clear();</span><br><span class="line">sayings.size; <span class="comment">// 0</span></span><br></pre></td></tr></table></figure>
<p>new Map() 参数可以是一个数组或者其他 iterable 对象,其元素或为键值对,或为两个元素的数组。 每个键值对都会添加到新的 Map。null 会被当做 undefined。
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="keyword">set</span> = new Set([</span><br><span class="line"> ['foo', 1],</span><br><span class="line"> ['bar', 2]</span><br><span class="line">]);</span><br><span class="line">const m1 = new Map(<span class="keyword">set</span>);</span><br><span class="line">m1.<span class="keyword">get</span>('foo') // 1</span><br><span class="line"></span><br><span class="line">const m2 = new Map([['baz', 3]]);</span><br><span class="line">const m3 = new Map(m2);</span><br><span class="line">m3.<span class="keyword">get</span>('baz') // 3</span><br></pre></td></tr></table></figure></p>
<h3 id="WeakMap(类似Map,只接受对象作为键名(null除外),WeakMap的键名所指向的对象,不计入垃圾回收机制)"><a href="#WeakMap(类似Map,只接受对象作为键名(null除外),WeakMap的键名所指向的对象,不计入垃圾回收机制)" class="headerlink" title="WeakMap(类似Map,只接受对象作为键名(null除外),WeakMap的键名所指向的对象,不计入垃圾回收机制)"></a>WeakMap(类似Map,只接受对象作为键名(null除外),WeakMap的键名所指向的对象,不计入垃圾回收机制)</h3><p><strong>Object和Map的比较</strong></p>
<ol>
<li>一般地,objects会被用于将字符串类型映射到数值。Object允许设置键值对、根据键获取值、删除键、检测某个键是否存在。而Map具有更多的优势。</li>
<li>Object的键均为Strings类型,在Map里键可以是任意类型。</li>
<li>必须手动计算Object的尺寸,但是可以很容易地获取使用Map的尺寸。</li>
<li>Map的遍历遵循元素的插入顺序。</li>
<li>Object有原型,所以映射中有一些缺省的键。(可以理解为map = Object.create(null))。</li>
</ol>
<p>如果键在运行时才能知道,或者所有的键类型相同,所有的值类型相同,那就使用Map。
如果需要将原始值存储为键,则使用Map,因为Object将每个键视为字符串,不管它是一个数字值、布尔值还是任何其他原始值。
如果需要对个别元素进行操作,使用Object。</p>
<h2 id="Set集合-类似数组,成员的值都是唯一且无序的"><a href="#Set集合-类似数组,成员的值都是唯一且无序的" class="headerlink" title="Set集合(类似数组,成员的值都是唯一且无序的)"></a>Set集合(类似数组,成员的值都是唯一且无序的)</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> mySet = <span class="keyword">new</span> <span class="built_in">Set</span>();</span><br><span class="line">mySet.add(<span class="number">1</span>);</span><br><span class="line">mySet.add(<span class="string">"some text"</span>);</span><br><span class="line">mySet.add(<span class="string">"foo"</span>);</span><br><span class="line"></span><br><span class="line">mySet.has(<span class="number">1</span>); <span class="comment">// true</span></span><br><span class="line">mySet.delete(<span class="string">"foo"</span>);</span><br><span class="line">mySet.size; <span class="comment">// 2</span></span><br><span class="line">mySet.clear(); <span class="comment">// 清空集合</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> item <span class="keyword">of</span> mySet) <span class="built_in">console</span>.log(item);</span><br><span class="line"><span class="comment">// 1</span></span><br><span class="line"><span class="comment">// "some text"</span></span><br><span class="line"></span><br><span class="line">mySet2 = <span class="keyword">new</span> <span class="built_in">Set</span>([<span class="number">1</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">4</span>]);</span><br><span class="line"><span class="built_in">Array</span>.from(mySet2); <span class="comment">// [1,2,3] 常用来去重</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// argument对象(类数组)转成数组</span></span><br><span class="line"><span class="comment">// Array.from({0:111,1:222,2:333,length:3}) [111,222,333]</span></span><br></pre></td></tr></table></figure>
<h3 id="WeakSet(类似Set,成员都是对象,弱引用)"><a href="#WeakSet(类似Set,成员都是对象,弱引用)" class="headerlink" title="WeakSet(类似Set,成员都是对象,弱引用)"></a>WeakSet(类似Set,成员都是对象,弱引用)</h3><p>WeakSet 对象中储存的对象值都是被弱引用的,即垃圾回收机制不考虑 WeakSet 对该对象的应用,如果没有其他的变量或属性引用这个对象值,则这个对象将会被垃圾回收掉(不考虑该对象还存在于 WeakSet 中),所以,WeakSet 对象里有多少个成员元素,取决于垃圾回收机制有没有运行,运行前后成员个数可能不一致,遍历结束之后,有的成员可能取不到了(被垃圾回收了),WeakSet 对象是无法被遍历的(ES6 规定 WeakSet 不可遍历),也没有办法拿到它包含的所有元素。</p>
<p><strong>Array和Set的比较</strong></p>
<ol>
<li>数组中用于判断元素是否存在的indexOf 函数效率低下。</li>
<li>Set对象允许根据值删除元素,而数组中必须使用基于下标的 splice 方法。</li>
<li>数组的indexOf方法无法找到NaN值。</li>
<li>Set对象存储不重复的值,所以不需要手动处理包含重复值的情况。</li>
<li>数组是特殊的对象,对象是关联数组 字符串是特殊的数组</li>
<li>方括弧取值为动态判定[],数字非有效的js标识符 </li>
</ol>
<h2 id="setter和getter-get-set修饰function"><a href="#setter和getter-get-set修饰function" class="headerlink" title="setter和getter (get set修饰function)"></a>setter和getter (get set修饰function)</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> o = {</span><br><span class="line"> a: <span class="number">7</span>,</span><br><span class="line"> <span class="keyword">get</span> b() { </span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">this</span>.a + <span class="number">1</span>;</span><br><span class="line"> },</span><br><span class="line"> <span class="keyword">set</span> c(x) {</span><br><span class="line"> <span class="keyword">this</span>.a = x / <span class="number">2</span></span><br><span class="line"> }</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(o.a); <span class="comment">// 7</span></span><br><span class="line"><span class="built_in">console</span>.log(o.b); <span class="comment">// 8 取b值时调用</span></span><br><span class="line">o.c = <span class="number">50</span>; <span class="comment">// 给c设置值调用</span></span><br><span class="line"><span class="built_in">console</span>.log(o.a); <span class="comment">// 25</span></span><br><span class="line">-----------------------</span><br><span class="line"><span class="keyword">var</span> o = {</span><br><span class="line"> a: <span class="number">7</span>,</span><br><span class="line"> b:<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{ </span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">this</span>.a + <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(o.b()); <span class="comment">// 8</span></span><br></pre></td></tr></table></figure>
<h2 id="访问所有可枚举对象属性"><a href="#访问所有可枚举对象属性" class="headerlink" title="访问所有可枚举对象属性"></a>访问所有可枚举对象属性</h2><ol>
<li>for in 无序</li>
<li>Object.keys() 不包括原型的属性名数组</li>
<li>Object.getOwnPropertyNames()</li>
</ol>
<h2 id="Symbol-原始数据类型-不可枚举的-符号类型"><a href="#Symbol-原始数据类型-不可枚举的-符号类型" class="headerlink" title="Symbol(原始数据类型) 不可枚举的 符号类型"></a>Symbol(原始数据类型) 不可枚举的 符号类型</h2><ul>
<li>应用于对象的属性,Symbol类型的属性具有一定的隐藏性。<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> myPrivateMethod = <span class="built_in">Symbol</span>(); <span class="comment">// 不能使用new Symbol()创建,它是一个不完整的类属于基本类型</span></span><br><span class="line"><span class="keyword">this</span>[myPrivateMethod] = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{...};</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>for in 和 Object.getOwnPropertyNames()访问不到,只能通过myPrivateMethod或者Object.getOwnPropertySymbols()来访问</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">Symbol</span>(<span class="string">"foo"</span>) !== <span class="built_in">Symbol</span>(<span class="string">"foo"</span>) <span class="comment">// true</span></span><br><span class="line"><span class="keyword">const</span> foo = <span class="built_in">Symbol</span>()</span><br><span class="line"><span class="keyword">const</span> bar = <span class="built_in">Symbol</span>()</span><br><span class="line"><span class="keyword">typeof</span> foo === <span class="string">"symbol"</span> <span class="comment">// true</span></span><br><span class="line"><span class="keyword">typeof</span> bar === <span class="string">"symbol"</span> <span class="comment">// true</span></span><br><span class="line"><span class="keyword">let</span> obj = {}</span><br><span class="line">obj[foo] = <span class="string">"foo"</span></span><br><span class="line">obj[bar] = <span class="string">"bar"</span></span><br><span class="line"><span class="built_in">JSON</span>.stringify(obj) <span class="comment">// {}</span></span><br><span class="line"><span class="built_in">Object</span>.keys(obj) <span class="comment">// []</span></span><br><span class="line"><span class="built_in">Object</span>.getOwnPropertyNames(obj) <span class="comment">// []</span></span><br><span class="line"><span class="built_in">Object</span>.getOwnPropertySymbols(obj) <span class="comment">// [ foo, bar ]</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">Symbol</span>.for(<span class="string">"foo"</span>); <span class="comment">// 创建一个 symbol 并放入 symbol 注册表中,键为 "foo"</span></span><br><span class="line"><span class="built_in">Symbol</span>.for(<span class="string">"foo"</span>); <span class="comment">// 从 symbol 注册表中读取键为"foo"的 symbol</span></span><br><span class="line"><span class="built_in">Symbol</span>.for(<span class="string">"bar"</span>) === <span class="built_in">Symbol</span>.for(<span class="string">"bar"</span>); <span class="comment">// true,证明了上面说的</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建一个 symbol 并放入 Symbol 注册表,key 为 "foo"</span></span><br><span class="line"><span class="keyword">var</span> globalSym = <span class="built_in">Symbol</span>.for(<span class="string">"foo"</span>); </span><br><span class="line"><span class="built_in">Symbol</span>.keyFor(globalSym); <span class="comment">// "foo"</span></span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> name = <span class="built_in">Symbol</span>(<span class="string">'name'</span>);</span><br><span class="line"><span class="keyword">let</span> obj = {</span><br><span class="line"> age:<span class="number">22</span>,</span><br><span class="line"> [name]:<span class="string">'Joh'</span></span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(<span class="built_in">Object</span>.keys(obj)); <span class="comment">// 打印不出 类型为Symbol的[name]属性</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用for-in也打印不出 类型为Symbol的[name]属性</span></span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">var</span> k <span class="keyword">in</span> obj) {</span><br><span class="line"> <span class="built_in">console</span>.log(k);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 Object.getOwnPropertyNames 同样打印不出 类型为Symbol的[name]属性</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="built_in">Object</span>.getOwnPropertyNames(obj)); </span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 Object.getOwnPropertySymbols 可以</span></span><br><span class="line"><span class="keyword">var</span> key = <span class="built_in">Object</span>.getOwnPropertySymbols(obj)[<span class="number">0</span>];</span><br><span class="line"><span class="built_in">console</span>.log(obj[key]); <span class="comment">// Joh</span></span><br></pre></td></tr></table></figure>
<ul>
<li>使用Symbol.iterator迭代器来逐个返回数组的单项<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">et arr = [<span class="string">'a'</span>, <span class="string">'b'</span>, <span class="string">'c'</span>];</span><br><span class="line"><span class="keyword">var</span> iterator = arr[<span class="built_in">Symbol</span>.iterator]();</span><br><span class="line"><span class="comment">// next 方法返回done表示是否完成</span></span><br><span class="line"><span class="built_in">console</span>.log(iterator.next()); <span class="comment">// {value: "a", done: false}</span></span><br><span class="line"><span class="built_in">console</span>.log(iterator.next()); <span class="comment">// {value: "b", done: false}</span></span><br><span class="line"><span class="built_in">console</span>.log(iterator.next()); <span class="comment">// {value: "c", done: false}</span></span><br><span class="line"><span class="built_in">console</span>.log(iterator.next()); <span class="comment">// {value: undefined, done: true}</span></span><br><span class="line"><span class="built_in">console</span>.log(iterator.next()); <span class="comment">// {value: undefined, done: true}</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<h2 id="Proxy-代理"><a href="#Proxy-代理" class="headerlink" title="Proxy 代理"></a>Proxy 代理</h2><p><code>let p= new Proxy(target,handler)</code></p>
<ul>
<li><p>target
用Proxy包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。</p>
</li>
<li><p>handler
一个对象,其属性是当执行一个操作时定义代理的行为的函数。</p>
</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 设置缺省值</span></span><br><span class="line"><span class="keyword">let</span> handler = {</span><br><span class="line"> <span class="keyword">get</span>: function(target, name){</span><br><span class="line"> <span class="keyword">return</span> name <span class="keyword">in</span> target ? target[name] : <span class="number">37</span>;</span><br><span class="line"> }</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> p = <span class="keyword">new</span> <span class="built_in">Proxy</span>({}, handler);</span><br><span class="line"></span><br><span class="line">p.a = <span class="number">1</span>;</span><br><span class="line">p.b = <span class="literal">undefined</span>;</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(p.a, p.b); <span class="comment">// 1, undefined</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'c'</span> <span class="keyword">in</span> p, p.c); <span class="comment">// false, 37</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 转发代理</span></span><br><span class="line"><span class="keyword">let</span> target = {};</span><br><span class="line"><span class="keyword">let</span> p = <span class="keyword">new</span> <span class="built_in">Proxy</span>(target, {});</span><br><span class="line"></span><br><span class="line">p.a = <span class="number">37</span>; <span class="comment">// 操作转发到目标</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(target.a); <span class="comment">// 37. 操作已经被正确地转发</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// demo</span></span><br><span class="line"><span class="keyword">let</span> book = {<span class="string">"name"</span>:<span class="string">"《ES6基础系列》"</span>,<span class="string">"price"</span>:<span class="number">56</span> };</span><br><span class="line"><span class="keyword">let</span> proxy = <span class="keyword">new</span> <span class="built_in">Proxy</span>(book,{</span><br><span class="line"> <span class="keyword">get</span>:function(target,property){</span><br><span class="line"> <span class="keyword">if</span>(property === <span class="string">"name"</span>){</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"《入门到懵逼》"</span>;</span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> <span class="keyword">return</span> target[property];</span><br><span class="line"> }</span><br><span class="line"> },</span><br><span class="line"> <span class="keyword">set</span>:function(target,property,value){</span><br><span class="line"> <span class="keyword">if</span>(property === <span class="string">'price'</span>){</span><br><span class="line"> target[property] = <span class="number">56</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">})</span><br></pre></td></tr></table></figure>
<h2 id="生成器-generator"><a href="#生成器-generator" class="headerlink" title="生成器 generator"></a>生成器 generator</h2><p>function* 来修饰GeneratorFunction函数</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span>* <span class="title">idMaker</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> index = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span>(<span class="literal">true</span>)</span><br><span class="line"> <span class="keyword">yield</span> index++;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> gen = idMaker();</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(gen.next().value); <span class="comment">// 0</span></span><br><span class="line"><span class="built_in">console</span>.log(gen.next().value); <span class="comment">// 1</span></span><br><span class="line"><span class="built_in">console</span>.log(gen.next().value); <span class="comment">// 2</span></span><br><span class="line"><span class="comment">// ...</span></span><br></pre></td></tr></table></figure>
<p>对象实现迭代行为</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> myIterable = {};</span><br><span class="line">myIterable[<span class="built_in">Symbol</span>.iterator] = <span class="function"><span class="keyword">function</span>* (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">yield</span> <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">yield</span> <span class="number">2</span>;</span><br><span class="line"> <span class="keyword">yield</span> <span class="number">3</span>;</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> value <span class="keyword">of</span> myIterable) { </span><br><span class="line"> <span class="built_in">console</span>.log(value); </span><br><span class="line">}</span><br><span class="line"><span class="comment">// 1</span></span><br><span class="line"><span class="comment">// 2</span></span><br><span class="line"><span class="comment">// 3</span></span><br><span class="line"></span><br><span class="line">or</span><br><span class="line">[...myIterable]; <span class="comment">// [1, 2, 3]</span></span><br></pre></td></tr></table></figure>
<h2 id="3行实现Promise"><a href="#3行实现Promise" class="headerlink" title="3行实现Promise"></a>3行实现Promise</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Promise</span> (<span class="params">fn</span>) </span>{</span><br><span class="line"> <span class="keyword">this</span>.then = <span class="function"><span class="params">cb</span> =></span> <span class="keyword">this</span>.cb = cb</span><br><span class="line"> <span class="keyword">this</span>.resolve = <span class="function"><span class="params">data</span> =></span> <span class="keyword">this</span>.cb(data)</span><br><span class="line"> fn(<span class="keyword">this</span>.resolve)</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 使用</span></span><br><span class="line"><span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve</span>) =></span> {</span><br><span class="line"> setTimeout(<span class="function"><span class="params">()</span> =></span> {</span><br><span class="line"> resolve(<span class="string">"延时执行"</span>)</span><br><span class="line"> }, <span class="number">1000</span>)</span><br><span class="line">}).then(<span class="function">(<span class="params">data</span>) =></span> {</span><br><span class="line"> <span class="built_in">console</span>.log(data)</span><br><span class="line">})</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Promise</span>(<span class="params">fn</span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> value = <span class="literal">null</span>,</span><br><span class="line"> callbacks = []; <span class="comment">//callbacks为数组,因为可能同时有很多个回调</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">this</span>.then = <span class="function"><span class="keyword">function</span> (<span class="params">onFulfilled</span>) </span>{</span><br><span class="line"> callbacks.push(onFulfilled);</span><br><span class="line"> };</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">resolve</span>(<span class="params">value</span>) </span>{</span><br><span class="line"> callbacks.forEach(<span class="function"><span class="keyword">function</span> (<span class="params">callback</span>) </span>{</span><br><span class="line"> callback(value);</span><br><span class="line"> });</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> fn(resolve);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<ul>
<li>简单版<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">myPromise</span>(<span class="params">constructor</span>) </span>{</span><br><span class="line"> <span class="keyword">let</span> self = <span class="keyword">this</span>;</span><br><span class="line"> self.status = <span class="string">"pending"</span>;</span><br><span class="line"> <span class="comment">// resolved时候的值</span></span><br><span class="line"> self.value = <span class="literal">undefined</span>;</span><br><span class="line"> <span class="comment">// rejected时候的值</span></span><br><span class="line"> self.reason = <span class="literal">undefined</span>;</span><br><span class="line"> <span class="comment">// 存放成功回调的数组</span></span><br><span class="line"> self.onResolveCallbacks = [];</span><br><span class="line"> <span class="comment">// 存放失败回调的数组</span></span><br><span class="line"> self.onRejectedCallbacks = [];</span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">resolve</span>(<span class="params">value</span>) </span>{</span><br><span class="line"> <span class="keyword">if</span>(self.status === <span class="string">'pending'</span>) {</span><br><span class="line"> self.value = value;</span><br><span class="line"> self.status = <span class="string">"resolved"</span>;</span><br><span class="line"> self.onResolveCallbacks.forEach(<span class="function"><span class="params">cb</span> =></span> cb(self.value))</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">reject</span>(<span class="params">reason</span>) </span>{</span><br><span class="line"> <span class="keyword">if</span>(self.status === <span class="string">'pending'</span>) {</span><br><span class="line"> self.reason = reason;</span><br><span class="line"> self.status = <span class="string">"rejected"</span>;</span><br><span class="line"> self.onRejectedCallbacks.forEach(<span class="function"><span class="params">cb</span> =></span> cb(self.value))</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// 捕获构造异常</span></span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">constructor</span>(resolve, reject);</span><br><span class="line"> } catch(e) {</span><br><span class="line"> reject(e);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">myPromise.prototype.then = <span class="function"><span class="keyword">function</span>(<span class="params">onFulfilled, onRejected</span>) </span>{</span><br><span class="line"> <span class="comment">// let self = this;</span></span><br><span class="line"> <span class="comment">// switch(self.status) {</span></span><br><span class="line"> <span class="comment">// case "resolved":</span></span><br><span class="line"> <span class="comment">// resolved(self.value);</span></span><br><span class="line"> <span class="comment">// break;</span></span><br><span class="line"> <span class="comment">// case "rejected":</span></span><br><span class="line"> <span class="comment">// rejected(self.reason);</span></span><br><span class="line"> <span class="comment">// break;</span></span><br><span class="line"> <span class="comment">// default:</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">// 如果成功和失败的回调没有传,表示这个then没有任何逻辑,只负责把值往后抛</span></span><br><span class="line"> onFulfilled = <span class="keyword">typeof</span> onFulfilled == <span class="string">'function'</span> ? onFulfilled : <span class="function"><span class="params">value</span> =></span> value</span><br><span class="line"> onRejected = <span class="keyword">typeof</span> onRejected == <span class="string">'function'</span> ? onRejected : <span class="function"><span class="params">reason</span> =></span> { <span class="keyword">throw</span> reason }</span><br><span class="line"> <span class="keyword">let</span> self = <span class="keyword">this</span>;</span><br><span class="line"> <span class="keyword">let</span> promise2;</span><br><span class="line"> <span class="comment">// 实现链式调用,每一种状态都要返回的是一个promise实例</span></span><br><span class="line"> <span class="keyword">if</span>(self.status == <span class="string">"resolved"</span>){ <span class="comment">// 如果promise状态已经是成功态,onFulfilled直接取值</span></span><br><span class="line"> <span class="keyword">return</span> promise2 = <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span>(<span class="params">resolve, reject</span>)</span>{</span><br><span class="line"> setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{ <span class="comment">// 保证返回的promise是异步</span></span><br><span class="line"> <span class="keyword">try</span>{</span><br><span class="line"> onFulfilled(self.value)</span><br><span class="line"> } <span class="keyword">catch</span> (e){</span><br><span class="line"> <span class="comment">// 如果执行成功的回调过程中出错,用错误原因把promise2 reject</span></span><br><span class="line"> reject(e)</span><br><span class="line"> }</span><br><span class="line"> })</span><br><span class="line"> })</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span>(self.status == <span class="string">"rejected"</span>){</span><br><span class="line"> <span class="keyword">return</span> promise2 = <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span>(<span class="params">resolve, reject</span>)</span>{</span><br><span class="line"> setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="keyword">try</span>{</span><br><span class="line"> onRejected(self.reason)</span><br><span class="line"> } <span class="keyword">catch</span> (e){</span><br><span class="line"> reject(e)</span><br><span class="line"> }</span><br><span class="line"> })</span><br><span class="line"> })</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span>(self.status === <span class="string">"pending"</span>){</span><br><span class="line"> <span class="keyword">return</span> promise2 = <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span>(<span class="params">resolve, reject</span>)</span>{</span><br><span class="line"> <span class="comment">// pending 状态时就会把所有的回调函数都添加到实例中的两个堆栈中暂存,等状态改变后依次执行,其实这个过程就是观察者模式</span></span><br><span class="line"> self.onResolveCallbacks.push(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="keyword">try</span>{</span><br><span class="line"> onFulfilled(self.value)</span><br><span class="line"> } <span class="keyword">catch</span>(e){</span><br><span class="line"> reject(e)</span><br><span class="line"> }</span><br><span class="line"> })</span><br><span class="line"> })</span><br><span class="line"> self.onRejectCallbacks.push(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="keyword">try</span>{</span><br><span class="line"> onRejected(self.reason)</span><br><span class="line"> } <span class="keyword">catch</span>(e){</span><br><span class="line"> reject(e)</span><br><span class="line"> }</span><br><span class="line"> })</span><br><span class="line"> })</span><br><span class="line"> })</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h2 id="现一个函数,将一个字符串中的空格替换成“-20”"><a href="#现一个函数,将一个字符串中的空格替换成“-20”" class="headerlink" title="现一个函数,将一个字符串中的空格替换成“%20”"></a>现一个函数,将一个字符串中的空格替换成“%20”</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">convertSpace2percent20</span>(<span class="params">str</span>)</span>{</span><br><span class="line"> <span class="keyword">return</span> str.replace(<span class="regexp">/\s+?/g</span>,<span class="string">"%20"</span>); <span class="comment">//开启非贪婪模式</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">convertSpace2percent20(<span class="string">"hellow world"</span>)</span><br><span class="line"><span class="comment">// "hellow%20world"</span></span><br></pre></td></tr></table></figure>
<h2 id="var-obj-1-“Hello”-2-“World”-打印Hello-World"><a href="#var-obj-1-“Hello”-2-“World”-打印Hello-World" class="headerlink" title="var obj = { 1: “Hello”, 2: “World” }打印Hello World"></a>var obj = { 1: “Hello”, 2: “World” }打印Hello World</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> obj = {</span><br><span class="line"> <span class="number">1</span>: <span class="string">"Hello"</span>,</span><br><span class="line"> <span class="number">2</span>: <span class="string">"World"</span></span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> str = <span class="string">''</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 方法1</span></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">1</span>; i < <span class="number">3</span>; i++) {</span><br><span class="line"> str += obj[i] + <span class="string">" "</span>; <span class="comment">//注意不能使用obj.i</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 方法2</span></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">var</span> key <span class="keyword">of</span> <span class="built_in">Object</span>.keys(obj)) {</span><br><span class="line"> str += obj[key] + <span class="string">" "</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 方法3</span></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> i <span class="keyword">in</span> obj) {</span><br><span class="line"> str += obj[i] + <span class="string">" "</span>; </span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 方法4</span></span><br><span class="line"><span class="built_in">Object</span>.values(obj).join(<span class="string">" "</span>)</span><br></pre></td></tr></table></figure>
<h2 id="循环"><a href="#循环" class="headerlink" title="循环"></a>循环</h2><ul>
<li>while - 只要指定的条件成立,则循环执行代码块</li>
<li>do…while - 首先执行一次代码块,然后在指定的条件成立时重复这个循环</li>
<li>for - 循环执行代码块指定的次数</li>
<li>foreach - 根据数组中每个元素来循环代码块<h3 id="forEach等函数的第二个参数的用法"><a href="#forEach等函数的第二个参数的用法" class="headerlink" title="forEach等函数的第二个参数的用法"></a>forEach等函数的第二个参数的用法</h3>forEach函数用得平时用得比较多,但是从来没想到forEach函数还有第二个参数。</li>
</ul>
<p>简单点来说,就是我们可以直接使用第二个参数来指定函数里的this的值,而不需要使用箭头函数或者在外面定义var that = this;等操作。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> obj = {</span><br><span class="line"> name: <span class="string">"小明"</span>,</span><br><span class="line"> say: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="keyword">this</span>.name); <span class="comment">// "小明"</span></span><br><span class="line"> },</span><br><span class="line"> think: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> arr = [<span class="number">1</span>];</span><br><span class="line"> arr.forEach(<span class="function"><span class="keyword">function</span>(<span class="params">item</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="keyword">this</span>); <span class="comment">// window</span></span><br><span class="line"> })</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'---------'</span>)</span><br><span class="line"> arr.forEach(<span class="function"><span class="keyword">function</span>(<span class="params">item</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="keyword">this</span>); <span class="comment">// obj</span></span><br><span class="line"> }, <span class="keyword">this</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">obj.say();</span><br><span class="line">obj.think();</span><br><span class="line"></span><br><span class="line">[<span class="number">3</span>,<span class="number">2</span>,<span class="number">4</span>,<span class="number">1</span>].sort(<span class="function">(<span class="params">a,b</span>)=></span>{</span><br><span class="line"> <span class="keyword">return</span> a > b ? <span class="number">1</span> : <span class="number">-1</span>; <span class="comment">// return a-b</span></span><br><span class="line">})</span><br></pre></td></tr></table></figure>
<h2 id="数组扁平化-将多维数组展开为一维数组"><a href="#数组扁平化-将多维数组展开为一维数组" class="headerlink" title="数组扁平化(将多维数组展开为一维数组)"></a>数组扁平化(将多维数组展开为一维数组)</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// es6 递归+判断是不是数组 也可以使用reduce进行遍历</span></span><br><span class="line"><span class="keyword">const</span> flattenES6 = <span class="function">(<span class="params">arr</span>) =></span> {</span><br><span class="line"> <span class="keyword">let</span> result = [];</span><br><span class="line"> arr.forEach(<span class="function">(<span class="params">item, i, arr</span>) =></span> {</span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">Array</span>.isArray(item)) {</span><br><span class="line"> result = result.concat(flattenES6(item));</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> result.push(arr[i])</span><br><span class="line"> }</span><br><span class="line"> })</span><br><span class="line"> <span class="keyword">return</span> result;</span><br><span class="line">};</span><br><span class="line"><span class="built_in">console</span>.log(flattenES6([<span class="number">1</span>, [<span class="number">2</span>, [<span class="number">3</span>, [<span class="number">4</span>]], <span class="number">5</span>]]))</span><br><span class="line"></span><br><span class="line"><span class="comment">// some+concat</span></span><br><span class="line"><span class="built_in">Array</span>.prototype.flat02 = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">let</span> arr = <span class="keyword">this</span></span><br><span class="line"> <span class="keyword">while</span> (arr.some(<span class="function"><span class="params">item</span> =></span> <span class="built_in">Array</span>.isArray(item))) {</span><br><span class="line"> arr = [].concat(...arr)</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> arr</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// toString方法</span></span><br><span class="line"><span class="keyword">const</span> flattenES6 = <span class="function">(<span class="params">arr</span>) =></span> arr.toString().split(<span class="string">','</span>).map(<span class="function">(<span class="params">item</span>) =></span> +item);</span><br><span class="line"><span class="built_in">console</span>.log(flattenES6([<span class="number">1</span>, [<span class="number">2</span>, [<span class="number">3</span>, [<span class="number">4</span>]], <span class="number">5</span>]]))</span><br><span class="line"></span><br><span class="line"><span class="comment">// ...</span></span><br><span class="line"><span class="keyword">var</span> entries = [<span class="number">1</span>, [<span class="number">2</span>, <span class="number">5</span>], [<span class="number">6</span>, <span class="number">7</span>], <span class="number">9</span>];</span><br><span class="line"><span class="keyword">var</span> flat_entries = [].concat(...entries);</span><br><span class="line"></span><br><span class="line"><span class="comment">// flat方法 返回新数组,不会改变原数组</span></span><br><span class="line">[<span class="number">1</span>, <span class="number">2</span>, [<span class="number">3</span>, <span class="number">4</span>]].flat()</span><br><span class="line"><span class="comment">// [1, 2, 3, 4] 默认拉平一层</span></span><br><span class="line"></span><br><span class="line">[<span class="number">1</span>, <span class="number">2</span>, [<span class="number">3</span>, [<span class="number">4</span>, <span class="number">5</span>]]].flat(<span class="number">2</span>)</span><br><span class="line"><span class="comment">// [1, 2, 3, 4, 5] 拉平两层的嵌套数组</span></span><br><span class="line"></span><br><span class="line">[<span class="number">1</span>, [<span class="number">2</span>, [<span class="number">3</span>]]].flat(<span class="literal">Infinity</span>)</span><br><span class="line"><span class="comment">// Infinity无论多少层都拉平</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// flatMap()方法对原数组的每个成员执行一个函数,相当于执行Array.prototype.map(),然后对返回值组成的数组执行flat()方法。该方法返回一个新数组,不改变原数组</span></span><br><span class="line"><span class="comment">// 相当于 [[2, 4], [3, 6], [4, 8]].flat() flatMap()只能展开一层数组</span></span><br><span class="line">[<span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>].flatMap(<span class="function">(<span class="params">x</span>) =></span> [x, x * <span class="number">2</span>])</span><br><span class="line"><span class="comment">// [2, 4, 3, 6, 4, 8]</span></span><br></pre></td></tr></table></figure>
<h2 id="自定义错误类型"><a href="#自定义错误类型" class="headerlink" title="自定义错误类型"></a>自定义错误类型</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// ES6</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">CustomError</span> <span class="keyword">extends</span> <span class="title">Error</span> </span>{</span><br><span class="line"> <span class="keyword">constructor</span>(message) {</span><br><span class="line"> <span class="keyword">super</span>(message)</span><br><span class="line"> <span class="keyword">this</span>.name = <span class="string">'CustomError'</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// ES5</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">CustomError</span>(<span class="params">message</span>) </span>{</span><br><span class="line"> <span class="keyword">this</span>.name = <span class="string">'CustomError'</span></span><br><span class="line"> <span class="keyword">this</span>.message = message</span><br><span class="line"> <span class="built_in">Error</span>.captureStackTrace(<span class="keyword">this</span>, CustomError)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">CustomError.prototype = <span class="keyword">new</span> <span class="built_in">Error</span>()</span><br><span class="line">CustomError.prototype.constructor = CustomError</span><br><span class="line"></span><br><span class="line"><span class="comment">// img标签来埋点处理错误日志</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">logError</span>(<span class="params">msg</span>) </span>{</span><br><span class="line"> <span class="keyword">const</span> img = <span class="keyword">new</span> Image()</span><br><span class="line"> img.src = <span class="string">`/log?<span class="subst">${<span class="built_in">encodeURIComponent</span>(msg)}</span>`</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="命令式编程和声明式编程"><a href="#命令式编程和声明式编程" class="headerlink" title="命令式编程和声明式编程"></a>命令式编程和声明式编程</h2><ul>
<li>纯粹性:纯函数不改变除当前作用域以外的值;</li>
<li>数据不可变性: Immutable</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 反面示例</span></span><br><span class="line"><span class="keyword">let</span> a = <span class="number">0</span></span><br><span class="line"><span class="keyword">const</span> add = <span class="function">(<span class="params">b</span>) =></span> a = a + b <span class="comment">// 两次 add(1) 结果不一致</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 正确示例</span></span><br><span class="line"><span class="keyword">const</span> add = <span class="function">(<span class="params">a, b</span>) =></span> a + b</span><br></pre></td></tr></table></figure>
<ul>
<li>函数柯里化 将多个入参的函数转化成1个入参的函数<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> add = <span class="function"><span class="params">a</span> =></span> <span class="function"><span class="params">b</span> =></span> <span class="function"><span class="params">c</span> =></span> a + b + c</span><br><span class="line">add(<span class="number">1</span>)(<span class="number">2</span>)(<span class="number">3</span>)</span><br></pre></td></tr></table></figure>
问题:sum(2, 3)实现sum(2)(3)的效果<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 闭包</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">sub_curry</span>(<span class="params">fn</span>) </span>{</span><br><span class="line"> <span class="keyword">let</span> args = [].slice.call(<span class="built_in">arguments</span>, <span class="number">1</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> fn.apply(<span class="keyword">this</span>, args.concat([].slice.call(<span class="built_in">arguments</span>)));</span><br><span class="line"> };</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">curry</span>(<span class="params">fn, length</span>) </span>{</span><br><span class="line"> <span class="comment">// 初始化时赋值为fn的形参个数,用以标示剩余需要传入参数的个数</span></span><br><span class="line"> length = length || fn.length;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> slice = <span class="built_in">Array</span>.prototype.slice;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">arguments</span>.length < length) {</span><br><span class="line"> <span class="keyword">const</span> combined = [fn].concat(slice.call(<span class="built_in">arguments</span>));</span><br><span class="line"> <span class="comment">// length - arguments.length用以计数当前已传入的参数</span></span><br><span class="line"> <span class="keyword">return</span> curry(sub_curry.apply(<span class="keyword">this</span>, combined), length - <span class="built_in">arguments</span>.length);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">return</span> fn.apply(<span class="keyword">this</span>, <span class="built_in">arguments</span>);</span><br><span class="line"> }</span><br><span class="line"> };</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">add</span>(<span class="params">a, b</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> a + b</span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> sum = curry(add)</span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p>偏函数 将多个入参的函数转化成两部分(返回一个包含预处理参数的新函数)</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> add = <span class="function"><span class="params">a</span> =></span> <span class="function">(<span class="params">b, c</span>) =></span> a + b + c</span><br><span class="line">add(<span class="number">1</span>)(<span class="number">2</span>, <span class="number">3</span>)</span><br></pre></td></tr></table></figure>
</li>
<li><p>组合函数</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> add = <span class="function">(<span class="params">x</span>) =></span> x + x</span><br><span class="line"><span class="keyword">const</span> mult = <span class="function">(<span class="params">x</span>) =></span> x * x</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> addAndMult = <span class="function">(<span class="params">x</span>) =></span> add(mult(x))</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h2 id="实现bind函数"><a href="#实现bind函数" class="headerlink" title="实现bind函数"></a>实现bind函数</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 第一种: 借助 call/apply</span></span><br><span class="line"><span class="built_in">Function</span>.prototype.bind1 = <span class="function"><span class="keyword">function</span> (<span class="params">context</span>) </span>{</span><br><span class="line"> <span class="keyword">const</span> self = <span class="keyword">this</span></span><br><span class="line"> <span class="keyword">return</span> <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> self.call(context)</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 测试:</span></span><br><span class="line"><span class="keyword">const</span> obj = {</span><br><span class="line"> value: <span class="string">'cosyer'</span>,</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">testBind</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="keyword">this</span>.value)</span><br><span class="line">}</span><br><span class="line"><span class="keyword">const</span> resultBind = testBind.bind1(obj)</span><br><span class="line">resultBind() <span class="comment">// cosyer</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 第二种: 借助 arguments</span></span><br><span class="line"><span class="built_in">Function</span>.prototype.bind2 = <span class="function"><span class="keyword">function</span> (<span class="params">context</span>) </span>{</span><br><span class="line"> <span class="keyword">const</span> arr = <span class="built_in">Array</span>.prototype.slice.call(<span class="built_in">arguments</span>, <span class="number">1</span>)</span><br><span class="line"> <span class="keyword">const</span> self = <span class="keyword">this</span></span><br><span class="line"> <span class="keyword">return</span> <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">const</span> restArr = <span class="built_in">Array</span>.prototype.slice.call(<span class="built_in">arguments</span>)</span><br><span class="line"> <span class="keyword">return</span> self.apply(context, arr.concat(restArr))</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 考虑到原型链 因为在new 一个bind过生成的新函数的时候,必须的条件是要继承原函数的原型</span></span><br><span class="line"><span class="built_in">Function</span>.prototype.bind2New = <span class="function"><span class="keyword">function</span>(<span class="params">context</span>)</span>{</span><br><span class="line"> <span class="keyword">var</span> arr = <span class="built_in">Array</span>.prototype.slice.call(<span class="built_in">arguments</span>, <span class="number">1</span>);</span><br><span class="line"> <span class="keyword">var</span> self = <span class="keyword">this</span>;</span><br><span class="line"> <span class="keyword">var</span> bound = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> restArr = restArr.concat(<span class="built_in">Array</span>.prototype.slice.call(<span class="built_in">arguments</span>));</span><br><span class="line"> <span class="keyword">return</span> self.apply(context, restArr);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">var</span> F = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{}</span><br><span class="line"> <span class="comment">// 这里需要一个寄生组合继承</span></span><br><span class="line"> F.prototype = context.prototype;</span><br><span class="line"> bound.prototype = <span class="keyword">new</span> F();</span><br><span class="line"> <span class="comment">// bound.prototype = Object.create(context.prototype);</span></span><br><span class="line"> <span class="keyword">return</span> bound;</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 这种方式的实现其实是函数柯里化的变版</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 比如在监听事件时可以这样子用:</span></span><br><span class="line"></span><br><span class="line">dom.addEventListener(<span class="string">'click'</span>, fn.bind(<span class="keyword">this</span>))</span><br><span class="line"><span class="comment">// 进行如下测试:</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> obj2 = {</span><br><span class="line"> value: <span class="string">'cosyer'</span>,</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">testBind2</span>(<span class="params">age, gender</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="keyword">this</span>.value) <span class="comment">// cosyer</span></span><br><span class="line"> <span class="built_in">console</span>.log(age) <span class="comment">// 23</span></span><br><span class="line"> <span class="built_in">console</span>.log(gender) <span class="comment">// male</span></span><br><span class="line">}</span><br><span class="line"><span class="keyword">const</span> resultBind2 = testBind2.bind2(obj2, <span class="number">23</span>)</span><br><span class="line">resultBind2(<span class="string">'male'</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 第三种: 区分环境, 是普通调用还是 new 调用</span></span><br><span class="line"><span class="built_in">Function</span>.prototype.bind3 = <span class="function"><span class="keyword">function</span> (<span class="params">context</span>) </span>{</span><br><span class="line"> <span class="keyword">const</span> arr = <span class="built_in">Array</span>.prototype.slice.call(<span class="built_in">arguments</span>, <span class="number">1</span>)</span><br><span class="line"> <span class="keyword">const</span> self = <span class="keyword">this</span></span><br><span class="line"> <span class="keyword">return</span> <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">const</span> restArr = <span class="built_in">Array</span>.prototype.slice.call(<span class="built_in">arguments</span>)</span><br><span class="line"> <span class="keyword">return</span> self.apply(<span class="keyword">this</span> !== windows ? <span class="keyword">this</span> : context, arr.concat(restArr))</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 测试: 使用 new 以后 this 会指向 newObj</span></span><br><span class="line"><span class="keyword">const</span> obj3 = {</span><br><span class="line"> value: <span class="string">'cosyer'</span>,</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">testBind3</span>(<span class="params">age, gender</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="keyword">this</span>.value)</span><br><span class="line"> <span class="built_in">console</span>.log(age)</span><br><span class="line"> <span class="built_in">console</span>.log(gender)</span><br><span class="line">}</span><br><span class="line"><span class="keyword">const</span> resultBind3 = testBind3.bind3(obj3, <span class="number">23</span>, <span class="string">'male'</span>)</span><br><span class="line"><span class="keyword">const</span> newObj = <span class="keyword">new</span> resultBind3()</span><br></pre></td></tr></table></figure>
<h2 id="call函数的实现"><a href="#call函数的实现" class="headerlink" title="call函数的实现"></a>call函数的实现</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 对象属性指向函数并调用</span></span><br><span class="line"><span class="comment">// 将函数引用到对象里</span></span><br><span class="line"><span class="comment">// 调用函数</span></span><br><span class="line"><span class="comment">// 删除对象里的函数</span></span><br><span class="line"><span class="built_in">Function</span>.prototype.call1 = <span class="function"><span class="keyword">function</span> (<span class="params">context, ...args</span>) </span>{</span><br><span class="line"> <span class="keyword">let</span> key = <span class="built_in">Symbol</span>(<span class="string">'KEY'</span>)</span><br><span class="line"> <span class="comment">// 把函数当成对象的某个成员,(成员名唯一:防止修改原始对象的结构值)</span></span><br><span class="line"> context[key] = <span class="keyword">this</span>;</span><br><span class="line"> <span class="keyword">let</span> result = context[key](...args) <span class="comment">// ...args</span></span><br><span class="line"> <span class="keyword">delete</span> context[key]</span><br><span class="line"> <span class="keyword">return</span> result</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> obj = {</span><br><span class="line"> value: <span class="string">'cosyer'</span>,</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">testCall</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="keyword">this</span>.value)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> resultCall = testCall.call1(obj) <span class="comment">// cosyer</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 传入函数的实现</span></span><br><span class="line"><span class="built_in">Function</span>.prototype.call2 = <span class="function"><span class="keyword">function</span> (<span class="params">context</span>) </span>{</span><br><span class="line"> <span class="keyword">const</span> arr = <span class="built_in">Array</span>.prototype.slice.call(<span class="built_in">arguments</span>, <span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"> context.fn = <span class="keyword">this</span> <span class="comment">// this 指向实例</span></span><br><span class="line"> context.fn(...arr)</span><br><span class="line"> <span class="keyword">delete</span> context.fn</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 测试:</span></span><br><span class="line"><span class="keyword">const</span> obj2 = {</span><br><span class="line"> value: <span class="string">'cosyer'</span>,</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">testCall2</span>(<span class="params">age</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="keyword">this</span>.value, age) <span class="comment">// cosyer 23</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> resultCall = testCall2.call2(obj2, <span class="number">23</span>)</span><br></pre></td></tr></table></figure>
<h2 id="稀疏数组"><a href="#稀疏数组" class="headerlink" title="稀疏数组"></a>稀疏数组</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> ary = [<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>];</span><br><span class="line">ary[<span class="number">10</span>] = <span class="number">10</span>;</span><br><span class="line">ary.filter(<span class="function"><span class="keyword">function</span>(<span class="params">x</span>) </span>{ <span class="keyword">return</span> x === <span class="literal">undefined</span>;}); <span class="comment">// []</span></span><br><span class="line"><span class="comment">// 3 - 9 都是没有初始化的'坑'!, 这些索引并不存在与数组中. 在 array 的函数调用的// 时候是会跳过这些'坑'的.</span></span><br></pre></td></tr></table></figure>
<h2 id="switch严格比较"><a href="#switch严格比较" class="headerlink" title="switch严格比较"></a>switch严格比较</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">showCase</span>(<span class="params">value</span>) </span>{</span><br><span class="line"> <span class="keyword">switch</span>(value) {</span><br><span class="line"> <span class="keyword">case</span> <span class="string">'A'</span>:</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'Case A'</span>);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> <span class="string">'B'</span>:</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'Case B'</span>);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> <span class="literal">undefined</span>:</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'undefined'</span>);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">default</span>:</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'Do not know!'</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line">showCase(<span class="keyword">new</span> <span class="built_in">String</span>(<span class="string">'A'</span>)); <span class="comment">// 'Do not know!'</span></span><br><span class="line"><span class="comment">// switch 是严格比较, String 实例和 字符串不一样.</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">showCase2</span>(<span class="params">value</span>) </span>{</span><br><span class="line"> <span class="keyword">switch</span>(value) {</span><br><span class="line"> <span class="keyword">case</span> <span class="string">'A'</span>:</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'Case A'</span>);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> <span class="string">'B'</span>:</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'Case B'</span>);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> <span class="literal">undefined</span>:</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'undefined'</span>);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">default</span>:</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'Do not know!'</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line">showCase2(<span class="built_in">String</span>(<span class="string">'A'</span>)); <span class="comment">// 'Case A'</span></span><br><span class="line"><span class="comment">// String 不仅是个构造函数 直接调用返回一个字符串哦.</span></span><br></pre></td></tr></table></figure>
<h2 id="为什么JS是单线程的"><a href="#为什么JS是单线程的" class="headerlink" title="为什么JS是单线程的"></a>为什么JS是单线程的</h2><blockquote>
<p>与用途有关,JavaScript的主要用途是与用户互动,以及操作DOM
假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?</p>
</blockquote>
<p>为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质。</p>
<h2 id="去重总集篇"><a href="#去重总集篇" class="headerlink" title="去重总集篇"></a>去重总集篇</h2><ol>
<li><p>Set</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">[...new <span class="built_in">Set</span>([<span class="number">1</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>])]</span><br><span class="line"><span class="built_in">Array</span>.from(<span class="keyword">new</span> <span class="built_in">Set</span>([<span class="number">1</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]))</span><br></pre></td></tr></table></figure>
</li>
<li><p>filter</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">[<span class="number">1</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>].filter(<span class="function">(<span class="params">element,index,array</span>)=></span>{</span><br><span class="line"> <span class="keyword">return</span> array.indexOf(element) === index;</span><br><span class="line">})</span><br></pre></td></tr></table></figure>
</li>
<li><p>Map</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> <span class="keyword">set</span> =new Set()</span><br><span class="line">[1,1,2,3].filter((item)=>{</span><br><span class="line"><span class="keyword">return</span> !<span class="keyword">set</span>.has(item)&&<span class="keyword">set</span>.add(item)</span><br><span class="line">})</span><br><span class="line">// 一个道理</span><br><span class="line">var map =new Map();</span><br><span class="line">[1,1,2,3].filter((item,index)=>{</span><br><span class="line"><span class="keyword">return</span> !map.has(item)&&map.set(item,index)</span><br><span class="line">})</span><br></pre></td></tr></table></figure>
</li>
<li><p>基础</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 不使用es6,考虑到(ie6-8)indexOf兼容性问题</span></span><br><span class="line"><span class="comment">// 对象容器</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">unique</span>(<span class="params">arr</span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> ret = []</span><br><span class="line"> <span class="keyword">var</span> hash = {}</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i < arr.length; i++) {</span><br><span class="line"> <span class="keyword">var</span> item = arr[i]</span><br><span class="line"> <span class="comment">// typeof 区分 1 与 ‘1’</span></span><br><span class="line"> <span class="keyword">var</span> key = <span class="keyword">typeof</span>(item) + item</span><br><span class="line"> <span class="keyword">if</span> (hash[key] !== <span class="number">1</span>) {</span><br><span class="line"> ret.push(item)</span><br><span class="line"> hash[key] = <span class="number">1</span></span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> ret</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 数组</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">unique</span>(<span class="params">arr</span>) </span>{</span><br><span class="line"> <span class="keyword">const</span> temp = []</span><br><span class="line"> arr.forEach(<span class="function"><span class="params">item</span> =></span> {</span><br><span class="line"> <span class="keyword">if</span> (temp.indexOf(item) === <span class="number">-1</span>) {</span><br><span class="line"> temp.push(item)</span><br><span class="line"> }</span><br><span class="line"> })</span><br><span class="line"> <span class="keyword">return</span> temp</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
</li>
<li><p>reduce</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">unique</span>(<span class="params">arr</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> arr.reduce(<span class="function">(<span class="params">pre, cur</span>) =></span> {</span><br><span class="line"> !pre.includes(cur) && pre.push(cur)</span><br><span class="line"> <span class="keyword">return</span> pre</span><br><span class="line"> }, [])</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
</li>
</ol>
<h2 id="2对象"><a href="#2对象" class="headerlink" title="2对象"></a>2对象</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">(<span class="number">2</span>).toString() <span class="comment">// '2'</span></span><br><span class="line"><span class="number">2</span> .toString() <span class="comment">// '2'</span></span><br><span class="line">[(<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>)] <span class="comment">// [3]</span></span><br></pre></td></tr></table></figure>
<h2 id="递归运用斐波那契数列-js-实现"><a href="#递归运用斐波那契数列-js-实现" class="headerlink" title="递归运用斐波那契数列 js 实现"></a>递归运用斐波那契数列 js 实现</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span>* <span class="title">fibo</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">let</span> [pre,curr] = [<span class="number">0</span>,<span class="number">1</span>];</span><br><span class="line"> <span class="keyword">for</span>(;;)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">yield</span> curr;</span><br><span class="line"> [pre,curr] = [curr,pre + curr];</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">let</span> i <span class="keyword">of</span> fibo())</span><br><span class="line">{</span><br><span class="line"> <span class="keyword">if</span>(i > <span class="number">10000</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">console</span>.log(i);</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 实现10000以内的数列</span></span><br></pre></td></tr></table></figure>
<p>爬楼梯问题
初始在第一级,到第一级有1种方法(s(1) = 1),到第二级也只有一种方法(s(2) = 1), 第三级(s(3) = s(1) + s(2))
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">cStairs</span>(<span class="params">n</span>) </span>{</span><br><span class="line"> <span class="keyword">if</span>(n === <span class="number">1</span> || n === <span class="number">2</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">return</span> cStairs(n<span class="number">-1</span>) + cStairs(n<span class="number">-2</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<h2 id="arguments对象的length属性显示实参的个数,函数的length属性显示形参的个数。"><a href="#arguments对象的length属性显示实参的个数,函数的length属性显示形参的个数。" class="headerlink" title="arguments对象的length属性显示实参的个数,函数的length属性显示形参的个数。"></a>arguments对象的length属性显示实参的个数,函数的length属性显示形参的个数。</h2><h2 id="在不改变原数组的前提下,添加或删除某个元素"><a href="#在不改变原数组的前提下,添加或删除某个元素" class="headerlink" title="在不改变原数组的前提下,添加或删除某个元素"></a>在不改变原数组的前提下,添加或删除某个元素</h2><ul>
<li><p>concat</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> arr = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>]</span><br><span class="line"><span class="keyword">let</span> newArr = [].concat(<span class="number">0</span>, arr)</span><br></pre></td></tr></table></figure>
</li>
<li><p>扩展运算符</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> arr = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>]</span><br><span class="line"><span class="keyword">let</span> newArr = [<span class="number">0</span>, ...arr]</span><br></pre></td></tr></table></figure>
</li>
<li><p>reduce</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> arr = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>]</span><br><span class="line">, newArr = arr.reduce(<span class="function">(<span class="params">acc, cur</span>) =></span> {</span><br><span class="line"> acc.push(cur)</span><br><span class="line"> <span class="keyword">return</span> acc</span><br><span class="line">}, [<span class="number">0</span>])</span><br></pre></td></tr></table></figure>
</li>
<li><p>slice</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> arr = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>]</span><br><span class="line">, newArr = arr.slice(<span class="number">0</span>, <span class="number">-1</span>)</span><br></pre></td></tr></table></figure>
<h3 id="总结·归纳"><a href="#总结·归纳" class="headerlink" title="总结·归纳"></a>总结·归纳</h3></li>
<li><p>不修改原数组</p>
<ul>
<li>slice</li>
<li>concat</li>
<li>forEach</li>
<li>map</li>
<li>every</li>
<li>some</li>
<li>filter</li>
<li>reduce</li>
<li>reduceRight</li>
<li>keys</li>
<li>values</li>
<li>entries</li>
<li>includes</li>
<li>find</li>
<li>findIndex</li>
<li>flat</li>
<li>flatMap</li>
</ul>
</li>
<li><p>修改原数组</p>
<ul>
<li>splice</li>
<li>pop</li>
<li>push</li>
<li>shift</li>
<li>unshift</li>
<li>sort</li>
<li>reverse</li>
<li>fill</li>
<li>copyWithin</li>
</ul>
</li>
</ul>
<h2 id="polyfill-腻子"><a href="#polyfill-腻子" class="headerlink" title="polyfill(腻子)"></a>polyfill(腻子)</h2><p>polyfill 是“在旧版浏览器上复制标准 API 的 JavaScript 补充”,可以动态地加载 JavaScript 代码或库,在不支持这些标准 API 的浏览器中模拟它们。</p>
<ul>
<li>常用的方案<blockquote>
<p>html5shiv、Geolocation、Placeholder</p>
</blockquote>
</li>
</ul>
</div>
<div>
<div>
<div class="text-center line pages-end">
<span>本文结束<i class="fa fa-meh-o fa-fw"></i>感谢您的阅读</span>
</div>
</div>
</div>
<div>
</div>
<div>
<div style="padding: 10px 0; margin: 20px auto; width: 90%; text-align: center;">
<div>坚持原创技术分享,您的支持将鼓励我继续创作!</div>
<button id="rewardButton" disable="enable" onclick="var qr = document.getElementById('QR'); if (qr.style.display === 'none') {qr.style.display='block';} else {qr.style.display='none'}">
<span>赏</span>
</button>
<div id="QR" style="display: none;">