-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinterview.html
3522 lines (2925 loc) · 385 KB
/
interview.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="字符串扩展的方法 includes():返回布尔值,表示是否找到了参数字符串。数组也可以 a[1]=1 且能判断undefined123456var a=[1,2,3]a[4]=5 // [1, 2, 3, undefined × 1, 5] empty// a[3]=undefined [1, 2, 3, undefined, 5] a.indexOf(undefined) // -1a.inc">
<meta property="og:type" content="article">
<meta property="og:title" content="面试题整理归纳">
<meta property="og:url" content="http://mydearest.cn/interview.html">
<meta property="og:site_name" content="cosyer's Blog">
<meta property="og:description" content="字符串扩展的方法 includes():返回布尔值,表示是否找到了参数字符串。数组也可以 a[1]=1 且能判断undefined123456var a=[1,2,3]a[4]=5 // [1, 2, 3, undefined × 1, 5] empty// a[3]=undefined [1, 2, 3, undefined, 5] a.indexOf(undefined) // -1a.inc">
<meta property="og:image" content="http://cdn.mydearest.cn/blog/images/boardcast.png">
<meta property="og:image" content="http://cdn.mydearest.cn/blog/images/get-post-diff.png">
<meta property="og:image" content="http://cdn.mydearest.cn/blog/images/tcp.png">
<meta property="og:image" content="http://cdn.mydearest.cn/blog/images/w3c-box.jpg">
<meta property="og:image" content="http://cdn.mydearest.cn/blog/images/ie-box.jpg">
<meta property="og:image" content="http://cdn.mydearest.cn/blog/images/ast.png">
<meta property="og:image" content="http://cdn.mydearest.cn/blog/images/mvc.png">
<meta property="og:image" content="http://cdn.mydearest.cn/blog/images/mvvm.png">
<meta property="og:image" content="http://cdn.mydearest.cn/blog/images/bff.png">
<meta property="article:published_time" content="2018-06-23T02:58:48.000Z">
<meta property="article:modified_time" content="2021-02-18T08:39:04.521Z">
<meta property="article:author" content="陈宇(cosyer)">
<meta property="article:tag" content="面试">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://cdn.mydearest.cn/blog/images/boardcast.png">
<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/interview.html"/>
<title>面试题整理归纳 | 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="2021-02-18T16:39:04+08:00">
<div class="post-time-text">2月</div>
<div class="post-time-count">18</div>
<div class="text-desc">
<div class="date-text">更新于</div>
<div class="post-tiem">2月18</div>
<div class="post-year">2021</div>
</div>
</div>
<div class="post-badge">
<span class="post-category" >
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/%E7%9F%A5%E8%AF%86/" itemprop="url" rel="index">
<span itemprop="name">知识</span>
</a>
</span>
</span>
</div>
<div class="post-block">
<link itemprop="mainEntityOfPage" href="http://mydearest.cn/interview.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">面试题整理归纳</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-23T10:58:48+08:00">
2018-06-23
</time>
</span>
<span id="/interview.html" class="leancloud_visitors" data-flag-title="面试题整理归纳">
<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="字数统计:">
7,921 (字)
</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="阅读时长:">
30 (分钟)
</span>
</div>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h2 id="字符串扩展的方法"><a href="#字符串扩展的方法" class="headerlink" title="字符串扩展的方法"></a>字符串扩展的方法</h2><ul>
<li>includes():返回布尔值,表示是否找到了参数字符串。数组也可以 a[1]=1 且能判断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></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a=[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]</span><br><span class="line">a[<span class="number">4</span>]=<span class="number">5</span> <span class="comment">// [1, 2, 3, undefined × 1, 5] empty</span></span><br><span class="line"><span class="comment">// a[3]=undefined [1, 2, 3, undefined, 5] </span></span><br><span class="line"></span><br><span class="line">a.indexOf(<span class="literal">undefined</span>) <span class="comment">// -1</span></span><br><span class="line">a.includes(<span class="literal">undefined</span>) <span class="comment">// true</span></span><br></pre></td></tr></table></figure></li>
<li>startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。<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="comment">// polyfill</span></span><br><span class="line"><span class="keyword">if</span> (<span class="built_in">String</span>.prototype.startsWith) {</span><br><span class="line"> <span class="built_in">String</span>.prototype.startsWith = <span class="function"><span class="keyword">function</span> (<span class="params">search, index</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">this</span>.substr((!index || index < <span class="number">0</span>) ? <span class="number">0</span> : index, search.length) === search;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li>
<li>endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。
str | index</li>
<li>repeat():返回一个新字符串,表示将原字符串重复n次。参数如果是小数,会被取整(不四舍五入)。参数是负数或者Infinity,会报错。0/NaN返回空字符串,参数是字符串,则会先转换成数字,不传则为空字符串。</li>
<li>padStart():头部补全。</li>
<li>padEnd():尾部补全<figure class="highlight plain"><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">'x'.padStart(5, 'ab') // 'ababx'</span><br><span class="line">'x'.padStart(4, 'ab') // 'abax'</span><br><span class="line"></span><br><span class="line">'x'.padEnd(5, 'ab') // 'xabab'</span><br><span class="line">'x'.padEnd(4, 'ab') // 'xaba'</span><br></pre></td></tr></table></figure>
如果原字符串的长度,等于或大于指定的最小长度,则返回原字符串。默认使用空格</li>
</ul>
<hr>
<a id="more"></a>
<ul>
<li>模板字符串(template string)是增强版的字符串,用反引号`标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。`${表达式、变量}`</li>
<li>commonjs 服务器端 amd 浏览器端</li>
<li>const 必须赋值定义 let 在同一作用于无法重复命名 无法变量提升</li>
<li>split(字符串或者正则,设置长度) 字符串=>数组</li>
<li>substr(开始的索引//splice可以为负数-1则为字符串最后一个字符,length字符数)方法不同的是,substring(开始索引,结束索引+1)负的参数有区别
只有单参数时到字符串结尾
String exd=filePath.substring(filePath.lastIndexOf(“.”)+1,filePath.length)</li>
</ul>
<h2 id="声明函数作用提升-声明变量和声明函数的提升有什么区别"><a href="#声明函数作用提升-声明变量和声明函数的提升有什么区别" class="headerlink" title="声明函数作用提升?声明变量和声明函数的提升有什么区别?"></a>声明函数作用提升?声明变量和声明函数的提升有什么区别?</h2><p>(1) 变量声明提升:变量申明在进入执行上下文就完成了。
只要变量在代码中进行了声明,无论它在哪个位置上进行声明, js引擎都会将它的声明放在范围作用域的顶部;</p>
<p>(2) 函数声明提升:执行代码之前会先读取函数声明,意味着可以把函数申明放在调用它的语句后面。
只要函数在代码中进行了声明,无论它在哪个位置上进行声明, js引擎都会将它的声明放在范围作用域的顶部;</p>
<p>(3) 变量or函数声明:函数声明会覆盖变量声明,但不会覆盖变量赋值。
同一个名称标识a,即有变量声明var a,又有函数声明function a() {},不管二者声明的顺序,函数声明会覆盖变量声明,也就是说,此时a的值是声明的函数function a() {}。注意:如果在变量声明的同时初始化a,或是之后对a进行赋值,此时a的值变量的值。
<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">eg: <span class="keyword">var</span> a; <span class="keyword">var</span> c = <span class="number">1</span>; a = <span class="number">1</span>; <span class="function"><span class="keyword">function</span> <span class="title">a</span>(<span class="params"></span>) </span>{ <span class="keyword">return</span> <span class="literal">true</span>; } <span class="built_in">console</span>.log(a);</span><br></pre></td></tr></table></figure></p>
<h2 id="如何判断数据类型?"><a href="#如何判断数据类型?" class="headerlink" title="如何判断数据类型?"></a>如何判断数据类型?</h2><p>typeof返回的类型都是字符串形式,可以判断function的类型;在判断除Object类型的对象时比较方便。
判断已知对象类型的方法: instanceof,后面一定要是对象类型,并且大小写不能错,该方法适合一些条件选择或分支。
<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">typeof</span> <span class="literal">null</span> <span class="comment">// object null instanceof Object // false</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> str = <span class="string">'abc'</span>; </span><br><span class="line"><span class="built_in">console</span>.log(<span class="keyword">typeof</span> str++); <span class="comment">//number NaN</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="keyword">typeof</span> (<span class="string">'abc'</span> + <span class="number">1</span>)); <span class="comment">//string 'abc1'</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(<span class="keyword">typeof</span> <span class="keyword">new</span> <span class="built_in">Date</span>()); <span class="comment">//object</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="keyword">typeof</span> <span class="built_in">Date</span>()); <span class="comment">//string</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="keyword">typeof</span> <span class="built_in">Date</span>); <span class="comment">//function</span></span><br></pre></td></tr></table></figure></p>
<h3 id="typeof原理"><a href="#typeof原理" class="headerlink" title="typeof原理"></a>typeof原理</h3><ul>
<li>js在底层存储变量的时候,会在变量的机器码的低位1-3位存储类型信息<ul>
<li>对象 000开头</li>
<li>null 都为0</li>
<li>浮点数 010</li>
<li>字符串 100</li>
<li>布尔 110</li>
<li>整数 1</li>
<li>undefined -2^30</li>
</ul>
</li>
</ul>
<h2 id="异步编程?"><a href="#异步编程?" class="headerlink" title="异步编程?"></a>异步编程?</h2><ul>
<li><p>方法1:回调函数,优点是简单、容易理解和部署,缺点是不利于代码的阅读和维护,各个部分之间高度耦合(Coupling),流程会很混乱,而且每个任务只能指定一个回调函数。</p>
</li>
<li><p>方法2:事件监听,可以绑定多个事件,每个事件可以指定多个回调函数,而且可以“去耦合”(Decoupling),有利于实现模块化。缺点是整个程序都要变成事件驱动型,运行流程会变得很不清晰。</p>
</li>
<li><p>方法3:事件发布/订阅,性质与“事件监听”类似,但是明显优于后者。</p>
</li>
<li><p>方法4:Promises对象,是CommonJS工作组提出的一种规范,目的是为异步编程提供统一接口。简单说,它的思想是,每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。</p>
<ul>
<li>generator</li>
<li>async/await</li>
</ul>
</li>
</ul>
<h2 id="事件流?事件捕获?事件冒泡?"><a href="#事件流?事件捕获?事件冒泡?" class="headerlink" title="事件流?事件捕获?事件冒泡?"></a>事件流?事件捕获?事件冒泡?</h2><p>事件流:从页面中接收事件的顺序。也就是说当一个事件产生时,这个事件的传播过程,就是事件流。</p>
<p>事件的传播分为3个阶段:</p>
<ol>
<li>捕获阶段:事件从window对象自上而下向目标节点传播的阶段;</li>
<li>目标阶段:真正的目标节点正在处理事件的阶段;</li>
<li>冒泡阶段:事件从目标节点自下而上向window对象传播的阶段;</li>
</ol>
<p>事件捕获是不太具体的元素应该更早接受到事件,而最具体的节点应该最后接收到事件。他们的用意是在事件到达目标之前就捕获它。
事件冒泡:事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点(文档)。</p>
<blockquote>
<p>并不是所有的事件都能冒泡</p>
<ul>
<li>onblur</li>
<li>onfocus</li>
<li>onmouseenter</li>
<li>onmouseleave</li>
</ul>
</blockquote>
<p><img src="http://cdn.mydearest.cn/blog/images/boardcast.png" alt="boardcast"></p>
<figure class="highlight html"><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="tag"><<span class="name">nav</span> <span class="attr">id</span>=<span class="string">"root_b"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">ul</span> <span class="attr">id</span>=<span class="string">"first_b"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">li</span> <span class="attr">id</span>=<span class="string">"second_b"</span>></span><span class="tag"><<span class="name">a</span> <span class="attr">id</span>=<span class="string">"target_b"</span> <span class="attr">href</span>=<span class="string">"#"</span>></span>冒泡<span class="tag"></<span class="name">a</span>></span><span class="tag"></<span class="name">li</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">ul</span>></span></span><br><span class="line"><span class="tag"></<span class="name">nav</span>></span></span><br><span class="line"><span class="tag"><<span class="name">nav</span> <span class="attr">id</span>=<span class="string">"root_c"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">ul</span> <span class="attr">id</span>=<span class="string">"first_c"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">li</span> <span class="attr">id</span>=<span class="string">"second_c"</span>></span><span class="tag"><<span class="name">a</span> <span class="attr">id</span>=<span class="string">"target_c"</span> <span class="attr">href</span>=<span class="string">"#"</span>></span>捕获<span class="tag"></<span class="name">a</span>></span><span class="tag"></<span class="name">li</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">ul</span>></span></span><br><span class="line"><span class="tag"></<span class="name">nav</span>></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></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* listen</span></span><br><span class="line"><span class="comment">* <span class="doctag">@param <span class="type">{string[]}</span> </span>ids </span></span><br><span class="line"><span class="comment">* <span class="doctag">@param <span class="type">{boolean}</span> </span>isCatch </span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">const</span> listen = <span class="function">(<span class="params">ids, isCatch</span>) =></span> ids.forEach(<span class="function"><span class="params">id</span> =></span> <span class="built_in">document</span>.getElementById(id).addEventListener(<span class="string">'click'</span>, () => alert(id), isCatch))</span><br><span class="line"></span><br><span class="line"><span class="comment">// BubbleEvent</span></span><br><span class="line">listen([<span class="string">'root_b'</span>, <span class="string">'first_b'</span>, <span class="string">'second_b'</span>, <span class="string">'target_b'</span>], <span class="literal">false</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// CatchEvent</span></span><br><span class="line">listen([<span class="string">'root_c'</span>, <span class="string">'first_c'</span>, <span class="string">'second_c'</span>, <span class="string">'target_c'</span>], <span class="literal">true</span>)</span><br></pre></td></tr></table></figure>
<h2 id="如何添加一个dom对象到body中-innerHTML、document-write和innerText区别"><a href="#如何添加一个dom对象到body中-innerHTML、document-write和innerText区别" class="headerlink" title="如何添加一个dom对象到body中?innerHTML、document.write和innerText区别?"></a>如何添加一个dom对象到body中?innerHTML、document.write和innerText区别?</h2><p>body.appendChild(dom元素);<br>innerHTML:从对象的起始位置到终止位置的全部内容,包括Html标签。
innerText:从起始位置到终止位置的内容, 但它去除Html标签
document.write只能重绘整个页面</p>
<h2 id="简述ajax流程"><a href="#简述ajax流程" class="headerlink" title="简述ajax流程"></a>简述ajax流程</h2><p>1)客户端产生触发js的事件<br>2)创建XMLHttpRequest对象<br><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="keyword">var</span> client=<span class="literal">null</span></span><br><span class="line"><span class="keyword">if</span>(<span class="built_in">window</span>.XMLHttpRequest){</span><br><span class="line"> client = <span class="keyword">new</span> XMLHttpRequest();</span><br><span class="line">}<span class="keyword">else</span>{</span><br><span class="line"> client = <span class="keyword">new</span> ActiveXObject(<span class="string">"Microsoft.XMLHTTP"</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
3)对XMLHttpRequest进行配置
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">client.open(<span class="string">"GET"</span>, url);</span><br><span class="line">client.onreadystatechange = <span class="function"><span class="keyword">function</span>(<span class="params">e</span>) </span>{</span><br><span class="line"> <span class="keyword">if</span> (client.readyState !== <span class="number">4</span>) { <span class="comment">// client状态</span></span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (client.status === <span class="number">200</span>) { <span class="comment">// HTTP状态码</span></span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'success'</span>, client.responseText);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="built_in">console</span>.warn(<span class="string">'error'</span>);</span><br><span class="line"> }</span><br><span class="line">}; <span class="comment">// 指定回调函数</span></span><br><span class="line">client.responseType = <span class="string">"json"</span>;</span><br><span class="line">client.setRequestHeader(<span class="string">"Accept"</span>, <span class="string">"application/json;"</span>);</span><br><span class="line">client.setRequestHeader(<span class="string">"Content-Type"</span>, <span class="string">"application/json;charset=utf-8"</span>);</span><br></pre></td></tr></table></figure>
4)通过AJAX引擎发送异步请求
<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">client.send()</span><br></pre></td></tr></table></figure>
<code>promise 封装</code>
<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></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param <span class="type">{string}</span> <span class="variable">url</span></span></span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param <span class="type">{string}</span> <span class="variable">method</span></span></span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param <span class="type">{object}</span> <span class="variable">params</span></span></span></span><br><span class="line"><span class="comment"> * <span class="doctag">@returns</span></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">request</span>(<span class="params">url, method = <span class="string">'GET'</span>, params = null</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =></span> {</span><br><span class="line"> <span class="keyword">const</span> xhr = <span class="keyword">new</span> XMLHttpRequest()</span><br><span class="line"> xhr.open(method, url)</span><br><span class="line"> xhr.addEventListener(<span class="string">'readystatechange'</span>, () => {</span><br><span class="line"> <span class="keyword">if</span> (xhr.readyState === <span class="number">4</span>) {</span><br><span class="line"> <span class="keyword">if</span> (xhr.status === <span class="number">200</span>) {</span><br><span class="line"> resolve(xhr.responseText)</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> reject({</span><br><span class="line"> code: xhr.status,</span><br><span class="line"> response: xhr.response</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"> setTimeout(<span class="function"><span class="params">()</span> =></span> reject(<span class="string">'timeout:1000'</span>), <span class="number">1000</span>)</span><br><span class="line"> xhr.send(<span class="built_in">JSON</span>.stringify(params))</span><br><span class="line"> })</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
5)服务器端接收请求并且处理请求,返回html或者xml内容<br>6)XML调用一个callback()处理响应回来的内容<br>7)使用JS和DOM实现局部刷新</p>
<h2 id="自执行函数?用于什么场景?好处?"><a href="#自执行函数?用于什么场景?好处?" class="headerlink" title="自执行函数?用于什么场景?好处?"></a>自执行函数?用于什么场景?好处?</h2><p>1、声明一个匿名函数<br>2、马上调用这个匿名函数。<br>作用:创建一个独立的作用域。 </p>
<p>好处:防止变量弥散到全局,以免各种js库冲突。隔离作用域避免污染,或者截断作用域链,避免闭包造成引用变量无法释放。利用立即执行特性,返回需要的业务函数或对象,避免每次通过条件判断来处理。</p>
<p>场景:一般用于框架、插件等场景,设计私有变量和方法,封闭私有作用域。</p>
<h2 id="立即执行函数表达式-IIFE"><a href="#立即执行函数表达式-IIFE" class="headerlink" title="立即执行函数表达式(IIFE)"></a>立即执行函数表达式(IIFE)</h2><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><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">2</span>;</span><br><span class="line">(<span class="function"><span class="keyword">function</span> <span class="title">IIFE</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="keyword">var</span> a = <span class="number">3</span>;</span><br><span class="line"> <span class="built_in">console</span>.log(a);<span class="comment">//3</span></span><br><span class="line">})();</span><br><span class="line"><span class="built_in">console</span>.log(a);<span class="comment">//2</span></span><br></pre></td></tr></table></figure>
<h3 id="当作函数调用并传递参数进去"><a href="#当作函数调用并传递参数进去" class="headerlink" title="当作函数调用并传递参数进去"></a>当作函数调用并传递参数进去</h3><figure class="highlight js"><table><tr><td class="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="keyword">var</span> a = <span class="number">2</span>;</span><br><span class="line">(<span class="function"><span class="keyword">function</span> <span class="title">IIFE</span>(<span class="params">global</span>)</span>{</span><br><span class="line"> <span class="keyword">var</span> a = <span class="number">3</span>;</span><br><span class="line"> <span class="built_in">console</span>.log(a);<span class="comment">//3</span></span><br><span class="line"> <span class="built_in">console</span>.log(global.a);<span class="comment">//2</span></span><br><span class="line">})(<span class="built_in">window</span>);</span><br><span class="line"><span class="built_in">console</span>.log(a);<span class="comment">//2</span></span><br></pre></td></tr></table></figure>
<h3 id="解决undefined标识符默认值被错误覆盖"><a href="#解决undefined标识符默认值被错误覆盖" class="headerlink" title="解决undefined标识符默认值被错误覆盖"></a>解决undefined标识符默认值被错误覆盖</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><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="literal">undefined</span> = <span class="literal">true</span>;</span><br><span class="line">(<span class="function"><span class="keyword">function</span> <span class="title">IIFE</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="keyword">var</span> a ;</span><br><span class="line"> <span class="keyword">if</span>(a === <span class="literal">undefined</span>){</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'Undefined is safe here!'</span>);</span><br><span class="line"> }</span><br><span class="line">})();</span><br></pre></td></tr></table></figure>
<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><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="number">2</span>;</span><br><span class="line">(<span class="function"><span class="keyword">function</span> <span class="title">IIFE</span>(<span class="params">def</span>)</span>{</span><br><span class="line"> def(<span class="built_in">window</span>);</span><br><span class="line">})(<span class="function"><span class="keyword">function</span> <span class="title">def</span>(<span class="params">global</span>)</span>{</span><br><span class="line"> <span class="keyword">var</span> a = <span class="number">3</span>;</span><br><span class="line"> <span class="built_in">console</span>.log(a);<span class="comment">//3</span></span><br><span class="line"> <span class="built_in">console</span>.log(global.a);<span class="comment">//2</span></span><br><span class="line">});</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> i = <span class="number">1</span>;</span><br><span class="line"><span class="keyword">var</span> IFun = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="keyword">var</span> i = <span class="number">1</span>;</span><br><span class="line"> <span class="built_in">console</span>.log(i);</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"> 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">IFun();</span><br><span class="line">IFun();</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="keyword">return</span> 返回值以及自执行函数将函数返回给IFun变量,使得在第一次操作过程后,将返回函数直接赋给IFun。</span><br></pre></td></tr></table></figure>
<h3 id="作用"><a href="#作用" class="headerlink" title="作用"></a>作用</h3><ol>
<li>创建作用域,内部保存一些大量临时变量的代码防止命名冲突。</li>
<li>一些库的外层用这种形式包起来防止作用域污染。</li>
<li>运行一些只执行一次的代码</li>
</ol>
<h2 id="回调函数?(传递地址,由非实现方调用)"><a href="#回调函数?(传递地址,由非实现方调用)" class="headerlink" title="回调函数?(传递地址,由非实现方调用)"></a>回调函数?(传递地址,由非实现方调用)</h2><p>回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函
数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。</p>
<h2 id="什么是闭包-堆栈溢出有什么区别?-内存泄漏-那些操作会造成内存泄漏?怎么样防止内存泄漏?impression"><a href="#什么是闭包-堆栈溢出有什么区别?-内存泄漏-那些操作会造成内存泄漏?怎么样防止内存泄漏?impression" class="headerlink" title="什么是闭包?堆栈溢出有什么区别? 内存泄漏? 那些操作会造成内存泄漏?怎么样防止内存泄漏?impression"></a>什么是闭包?堆栈溢出有什么区别? 内存泄漏? 那些操作会造成内存泄漏?怎么样防止内存泄漏?impression</h2><p>闭包:就是能够读取其他函数内部变量的函数。一般是指内层函数。(子函数在外调用,子函数所在的父函数的作用域不会被释放。) </p>
<p>堆栈溢出:就是不顾堆栈中分配的局部数据块大小,向该数据块写入了过多的数据,导致数据越界,结果覆盖了别的数据。经常会在递归中发生。</p>
<p>内存泄漏是指:用动态存储分配函数内存空间,在使用完毕后未释放,导致一直占据该内存单元。直到程序结束。指任何对象在您不再拥有或需要它之后仍然存在。</p>
<p>造成内存泄漏:
setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。
闭包、控制台日志、循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)</p>
<p>防止内存泄漏:<br>1、不要动态绑定事件;<br>2、不要在动态添加,或者会被动态移除的dom上绑事件,用事件冒泡在父容器监听事件;<br>3、如果要违反上面的原则,必须提供destroy方法,保证移除dom后事件也被移除,这点可以参考Backbone的源代码,做的比较好;<br>4、单例化,少创建dom,少绑事件。</p>
<p>原因:
全局变量没有手动销毁,因为全局变量不会被回收
闭包:闭包中的变量被全局对象引用,则闭包中的局部变量不能释放
监听事件添加后,没有移除,会导致内存泄漏</p>
<ul>
<li>意外的全局变量无法被回收</li>
<li>闭包</li>
<li>定时器未删除被正确关闭</li>
<li>dom事件未清除</li>
<li>dom元素删除内存存在引用</li>
</ul>
<h2 id="html和xhtml有什么区别"><a href="#html和xhtml有什么区别" class="headerlink" title="html和xhtml有什么区别?"></a>html和xhtml有什么区别?</h2><p>HTML是一种基本的WEB网页设计语言,XHTML是一个基于XML的标记语言。</p>
<p>1.XHTML 元素必须被正确地嵌套。</p>
<p>2.XHTML 元素必须被关闭。</p>
<p>3.标签名必须用小写字母。</p>
<p>4.空标签也必须被关闭。</p>
<p>5.XHTML 文档必须拥有根元素。</p>
<h2 id="什么是构造函数?与普通函数有什么区别"><a href="#什么是构造函数?与普通函数有什么区别" class="headerlink" title="什么是构造函数?与普通函数有什么区别?"></a>什么是构造函数?与普通函数有什么区别?</h2><p>构造函数:是一种特殊的方法(函数、对象)、主要用来创建对象时初始化对象,总与new运算符一起使用,创建对象的语句中构造函数的函数名必须与类名完全相同。</p>
<p>与普通函数相比只能由new关键字调用,构造函数是类的标识。</p>
<h2 id="通过new创建一个对象的时候,函数内部有哪些改变?"><a href="#通过new创建一个对象的时候,函数内部有哪些改变?" class="headerlink" title="通过new创建一个对象的时候,函数内部有哪些改变?"></a>通过new创建一个对象的时候,函数内部有哪些改变?</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></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">Person.prototype.friend = [];</span><br><span class="line">Person.prototype.age = <span class="number">18</span>;</span><br><span class="line"> <span class="keyword">var</span> a = <span class="keyword">new</span> Person();</span><br><span class="line"> a.friend[<span class="number">0</span>] = <span class="string">'方涛'</span>; <span class="comment">// a.friend=['123'] 指向新对象 b.friend // []</span></span><br><span class="line"> a.age = <span class="number">18</span>;</span><br><span class="line"> <span class="keyword">var</span> b = <span class="keyword">new</span> Person();</span><br><span class="line"> b.friend <span class="comment">// ['方涛'] </span></span><br><span class="line"> b.age <span class="comment">// 18</span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>1、创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。<br>2、属性和方法被加入到 this 引用的对象中。<br>3、新创建的对象由 this 所引用,并且最后隐式的返回 this 。</p>
</blockquote>
<p><code>new 操作符新建了一个空对象,这个对象原型指向构造函数的prototype,执行构造函数后返回这个对象。</code></p>
<ul>
<li><p>创建一个空对象:var obj = {}</p>
</li>
<li><p>将空对象的<strong>proto</strong>指向构造函数的 prototype:obj.<strong>proto</strong> = Person().prototype</p>
</li>
<li><p>使用空对象作为上下文调用构造函数: Person.call(obj)</p>
</li>
</ul>
<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="function"><span class="keyword">function</span> <span class="title">myNew</span> (<span class="params">fn, ...args</span>) </span>{</span><br><span class="line"> <span class="keyword">let</span> instance = <span class="built_in">Object</span>.create(fn.prototype);</span><br><span class="line"> <span class="keyword">let</span> result = fn.call(instance, ...args)</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">typeof</span> result === <span class="string">'object'</span> ? result : instance;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="事件委托的好处都有啥?说对了都给它-3"><a href="#事件委托的好处都有啥?说对了都给它-3" class="headerlink" title="事件委托的好处都有啥?说对了都给它=3="></a>事件委托的好处都有啥?说对了都给它=3=</h2><ul>
<li><p>利用冒泡的原理,把事件加到父级上,触发执行效果 </p>
</li>
<li><p>好处:新添加的元素还会有之前的事件;提高性能。</p>
</li>
</ul>
<h2 id="节点类型-判断当前节点类型"><a href="#节点类型-判断当前节点类型" class="headerlink" title="节点类型?判断当前节点类型?"></a>节点类型?判断当前节点类型?</h2><ul>
<li>元素节点 </li>
<li>属性节点 </li>
<li>文本节点 </li>
<li>注释节点 </li>
<li>文档节点</li>
</ul>
<p>通过nodeObject.nodeType判断节点类型:其中,nodeObject 为DOM节点(节点对象)。该属性返回以数字表示的节点类型,例如,元素节点返回 1,属性节点返回 2 。</p>
<h2 id="数组合并的方法?"><a href="#数组合并的方法?" class="headerlink" title="数组合并的方法?"></a>数组合并的方法?</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><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="comment">// 四种方法。</span></span><br><span class="line"><span class="keyword">var</span> arr1=[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>];</span><br><span class="line"><span class="keyword">var</span> arr2=[<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>];</span><br><span class="line">arr1 = arr1.concat(arr2);</span><br><span class="line"><span class="built_in">console</span>.log(arr1); </span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> arr1=[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>];</span><br><span class="line"><span class="keyword">var</span> arr2=[<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>];</span><br><span class="line"><span class="built_in">Array</span>.prototype.push.apply(arr1,arr2);</span><br><span class="line"><span class="built_in">console</span>.log(arr1);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> arr1=[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>];</span><br><span class="line"><span class="keyword">var</span> arr2=[<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>];</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">var</span> i=<span class="number">0</span>; i < arr2.length; i++) {</span><br><span class="line">arr1.push( arr2[i] );</span><br><span class="line">}</span><br><span class="line"><span class="built_in">console</span>.log(arr1); </span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> arr1=[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>];</span><br><span class="line"><span class="keyword">var</span> arr2=[<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>];</span><br><span class="line"></span><br><span class="line">arr1.push(...arr2)</span><br></pre></td></tr></table></figure>
<h2 id="jquery和zepto有什么区别"><a href="#jquery和zepto有什么区别" class="headerlink" title="jquery和zepto有什么区别?"></a>jquery和zepto有什么区别?</h2><ul>
<li><p>针对移动端程序,Zepto有一些基本的触摸事件可以用来做触摸屏交互(tap事件、swipe事件),Zepto是不支持IE浏览器的,这不是Zepto的开发者Thomas Fucks在跨浏览器问题上犯了迷糊,而是经过了认真考虑后为了降低文件尺寸而做出的决定,就像jQuery的团队在2.0版中不再支持旧版的IE(6 7 8)一样。因为Zepto使用jQuery句法,所以它在文档中建议把jQuery作为IE上的后备库。那样程序仍能在IE中,而其他浏览器则能享受到Zepto在文件大小上的优势,然而它们两个的API不是完全兼容的,所以使用这种方法时一定要小心,并要做充分的测试。</p>
</li>
<li><p>Dom操作的区别:添加id时jQuery不会生效而Zepto会生效。</p>
</li>
<li><p>zepto主要用在移动设备上,只支持较新的浏览器,好处是代码量比较小,性能也较好。
jquery主要是兼容性好,可以跑在各种pc,移动上,好处是兼容各种浏览器,缺点是代码量大,同时考虑兼容,性能也不够好。</p>
</li>
</ul>
<h2 id="function-和window-onload-和-document-ready-function"><a href="#function-和window-onload-和-document-ready-function" class="headerlink" title="$(function(){})和window.onload 和 $(document).ready(function(){})"></a>$(function(){})和window.onload 和 $(document).ready(function(){})</h2><ul>
<li><p>window.onload:用于当页面的所有元素,包括外部引用文件,图片等都加载完毕时运行函数内的函数。load方法只能执行一次,如果在js文件里写了多个,只能执行最后一个。</p>
</li>
<li><p>$(document).ready(function(){})和$(function(){})都是用于当页面的标准DOM元素被解析成DOM树后就执行内部函数。这个函数是可以在js文件里多次编写的,对于多人共同编写的js就有很大的优势,因为所有行为函数都会执行到。而且$(document).ready()函数在HMTL结构加载完后就可以执行,不需要等大型文件加载或者不存在的连接等耗时工作完成才执行,效率高。</p>
</li>
</ul>
<h2 id="简述下-this-和定义属性和方法的时候有什么区别-Prototype?"><a href="#简述下-this-和定义属性和方法的时候有什么区别-Prototype?" class="headerlink" title="简述下 this 和定义属性和方法的时候有什么区别?Prototype?"></a>简述下 this 和定义属性和方法的时候有什么区别?Prototype?</h2><ul>
<li><p>this表示当前对象,如果在全局作用范围内使用this,则指代当前页面对象window; 如果在函数中使用this,则this指代什么是根据运行时此函数在什么对象上被调用。 我们还可以使用apply和call两个全局方法来改变函数中this的具体指向。</p>
</li>
<li><p>prototype本质上还是一个JavaScript对象。 并且每个函数都有一个默认的prototype属性。</p>
</li>
<li><p>在prototype上定义的属性方法为所有实例共享,所有实例皆引用到同一个对象,单一实例对原型上的属性进行修改,也会影响到所有其他实例。</p>
</li>
</ul>
<h2 id="ajax和jsonp的区别?"><a href="#ajax和jsonp的区别?" class="headerlink" title="ajax和jsonp的区别?"></a>ajax和jsonp的区别?</h2><ul>
<li>相同点:都是请求一个url</li>
<li>不同点:ajax的核心是通过XMLHttpRequest获取内容,jsonp只能get请求</li>
<li>jsonp的核心则是动态添加<code><script></code>标签来调用服务器提供的js脚本。</li>
</ul>
<h2 id="常见的http协议状态码?"><a href="#常见的http协议状态码?" class="headerlink" title="常见的http协议状态码?"></a>常见的http协议状态码?</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></pre></td><td class="code"><pre><span class="line"><span class="number">1</span>xx (临时响应)</span><br><span class="line"><span class="number">100</span>: 继续(正在加载)</span><br><span class="line"><span class="number">101</span>:切换协议 </span><br><span class="line"><span class="number">200</span>:请求成功</span><br><span class="line"><span class="number">201</span>:请求成功并且服务器创建了新的资源</span><br><span class="line"><span class="number">302</span>:服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来响应以后的请求。</span><br><span class="line"><span class="number">304</span>:自从上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容。</span><br><span class="line"><span class="number">400</span>:服务器不理解请求的语法。</span><br><span class="line"><span class="number">403</span>:该状态表示服务器理解了本次请求但是拒绝执行该任务</span><br><span class="line"><span class="number">404</span>:请求的资源(网页等)不存在</span><br><span class="line"><span class="number">405</span>:方法不被允许</span><br><span class="line"><span class="number">500</span>:内部服务器错误</span><br><span class="line"><span class="number">502</span>:网关错误</span><br><span class="line"><span class="number">504</span>:网关超时</span><br></pre></td></tr></table></figure>
<h2 id="sessionStorage和localstroage与cookie之间有什么关联-cookie最大存放多少字节?"><a href="#sessionStorage和localstroage与cookie之间有什么关联-cookie最大存放多少字节?" class="headerlink" title="sessionStorage和localstroage与cookie之间有什么关联, cookie最大存放多少字节?"></a>sessionStorage和localstroage与cookie之间有什么关联, cookie最大存放多少字节?</h2><p>三者共同点:都是保存在浏览器端,且同源的。</p>
<p>区别:
1、cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存</p>
<h3 id="cookie的作用"><a href="#cookie的作用" class="headerlink" title="cookie的作用"></a>cookie的作用</h3><ul>
<li>保存用户登录状态(存储sessionId来标识唯一用户)</li>
<li>跟踪用户行为</li>
<li>定制页面</li>
</ul>
<p>2、存储大小限制也不同,cookie数据不能超过4k,sessionStorage和localStorage 但比cookie大得多,可以达到5M</p>
<p>3、数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭</p>
<p>4、作用域不同,sessionStorage只在同源的同窗口(或标签页)中共享数据,也就是只在当前会话中共享;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的( 即数据共享 )。</p>
<h2 id="ajax的get与post区别?"><a href="#ajax的get与post区别?" class="headerlink" title="ajax的get与post区别?"></a>ajax的get与post区别?</h2><ul>
<li>get和post都是数据提交的方式。</li>
<li>get的数据是通过网址问号后边拼接的字符串进行传递的。post是通过一个HTTP包(request body)进行传递数据的。</li>
<li>get的传输量是有限制的,post是没有限制的。(实际上HTTP 协议从未规定 GET/POST 的请求长度限制是多少。对get请求参数的限制是来源与浏览器或web服务器,浏览器或web服务器限制了url的长度)</li>
<li>get的安全性可能没有post高,所以我们一般用get来获取数据,post一般用来修改数据。</li>
<li>get请求, 倒退按钮是无害的, post会重新发起请求</li>
<li>get会主动缓存, post不会</li>
<li>get请求只能进行url编码,而post请求支持多种编码</li>
<li><strong><em>get产生一个TCP数据包,POST产生两个TCP数据包</em></strong></li>
<li>get比较快且有历史记录</li>
</ul>
<p>get就是将货品放在车顶,post放在车内。</p>
<p><img src="http://cdn.mydearest.cn/blog/images/get-post-diff.png" alt="get-post-diff"></p>
<h2 id="GC机制?为什么闭包不会被回收变量和函数?"><a href="#GC机制?为什么闭包不会被回收变量和函数?" class="headerlink" title="GC机制?为什么闭包不会被回收变量和函数?"></a>GC机制?为什么闭包不会被回收变量和函数?</h2><ul>
<li>GC垃圾回收机制:将内存中不再使用的数据进行清理,释放出内存空间。</li>
</ul>
<p>引用类型是在没有引用之后, 通过 v8 的 GC 自动回收, 值类型如果是处于闭包的情况下, 要等闭包没有引用才会被 GC 回收, 非闭包的情况下等待 v8 的新生代
(new space) 切换的时候回收。</p>
<p>v8 的垃圾回收机制基于分代回收机制,这个机制又基于世代假说,这个假说有两个特点,一是新生的对象容易早死,另一个是不死的对象会活得更久。基于这个假说,v
8 引擎将内存分为了新生代和老生代。</p>
<p>新创建的对象或者只经历过一次的垃圾回收的对象被称为新生代。经历过多次垃圾回收的对象被称为老生代。</p>
<p>V8 将内存分成 新生代空间 和 老生代空间。</p>
<p>回收方法有两种:标记清除、计数引用</p>
<p>老生代采用了标记清除法和标记压缩法。标记清除简单讲就是变量存储在内存中,当变量进入执行环境的时候,垃圾回收器会给它加上标记,这个变量离开执行环境,将其标记为“清除”,不可
追踪,不被其他对象引用,或者是两个对象互相引用,不被第三个对象引用,然后由垃圾回收器收回,释放内存空间。。</p>
<p>由于在进行垃圾回收的时候会暂停应用的逻辑,对于新生代方法由于内存小,每次停顿的时间不会太长,但对于老生代来说每次垃圾回收的时间长,停顿会造成很大的影
响。 为了解决这个问题 V8 引入了增量标记的方法,将一次停顿进行的过程分为了多步,每次执行完一小步就让运行逻辑执行一会,就这样交替运行。</p>
<h2 id="面向对象?"><a href="#面向对象?" class="headerlink" title="面向对象?"></a>面向对象?</h2><p>万物皆对象,把一个对象抽象成类,具体上就是把一个对象的静态特征和动态特征抽象成属性(属性名、属性值)和方法,也就是把一类事物的算法和数据结构封装在一
个类之中,程序就是多个对象和互相之间的通信组成的。</p>
<p>面向对象具有封装性,继承性,多态性。
封装:隐蔽了对象内部不需要暴露的细节,使得内部细节的变动跟外界脱离,只依靠接口进行通信。封装性降低了编程的复杂性。通过继承,使得新建一个类变得容易,一个类从派生类那里获得其非私有的方法和公用属性的繁琐工作交给了编译器。而继承和实现接口和运行时的类型绑定机制所产生的多态,使得不同的类所产生的对象能够对相同的消息作出不同的反应,极大地提高了代码的通用性。</p>
<p>总之,面向对象的特性提高了大型程序的重用性和可维护性。</p>
<h2 id="jsonp的原理和缺点?"><a href="#jsonp的原理和缺点?" class="headerlink" title="jsonp的原理和缺点?"></a>jsonp的原理和缺点?</h2><ul>
<li>原理:使用script标签实现跨域访问,可在url中指定回调函数,获取JSON数据并在指定的回调函数中执行jquery实现jsop。</li>
<li>缺点:只支持GET方式的jsonp实现,是一种脚本注入行为存在一定的安全隐患。如果返回的数据格式有问题或者返回失败了,并不会报错。</li>
</ul>
<h2 id="call和apply两者的区别和好处?"><a href="#call和apply两者的区别和好处?" class="headerlink" title="call和apply两者的区别和好处?"></a>call和apply两者的区别和好处?</h2><ul>
<li>call和apply都是改变this指向的方法,区别在于call可以写多个参数,而apply只能写两个参数,第二个参数是一个数组,用于存放要传的参数。</li>
<li>用call和apply实现更好的继承和扩展,更安全。</li>
</ul>
<h2 id="压缩合并目的?http请求的优化方式?"><a href="#压缩合并目的?http请求的优化方式?" class="headerlink" title="压缩合并目的?http请求的优化方式?"></a>压缩合并目的?http请求的优化方式?</h2><ul>
<li><p>Web性能优化最佳实践中最重要的一条是减少HTTP请求。而减少HTTP请求的最主要的方式就是,合并并压缩JavaScript和CSS文件。 </p>
</li>
<li><p>CSS Sprites(雪碧图、CSS精灵):把全站的图标都放在一个图像文件中,然后用CSS的background-image和background-position属性定位来显示其中的一小部分。</p>
</li>
</ul>
<p>优点:</p>
<ol>
<li>减少 HTTP 请求数,极大地提高页面加载速度</li>
<li>增加图片信息重复度,提高压缩比,减少图片大小</li>
<li>更换风格方便,只需在一张或几张图片上修改颜色或样式即可实现</li>
</ol>
<p>缺点:</p>
<ol>
<li>图片合并麻烦</li>
<li>维护麻烦,修改一个图片可能需要重新布局整个图片,样式</li>
</ol>
<ul>
<li><p>合并脚本和样式表; 图片地图:利用image map标签定义一个客户端图像映射,(图像映射指带有可点击区域的一幅图像)具体看:<a href="http://club.topsage.com/thread-2527479-1-1.html" target="_blank" rel="noopener">http://club.topsage.com/thread-2527479-1-1.html</a> </p>
</li>
<li><p>图片js/css等静态资源放在静态服务器或CDN服务器时,尽量采用不用的域名,这样能防止cookie不会互相污染,减少每次请求的往返数据。 </p>
</li>
<li><p>css替代图片, 缓存一些数据 </p>
</li>
<li><p>少用location.reload():使用location.reload() 会刷新页面,刷新页面时页面所有资源 (css,js,img等) 会重新请求服务器。建议使用location.href=”当前页url” 代替location.reload() ,使用location.href 浏览器会读取本地缓存资源。</p>
</li>
<li><p>图片懒加载 </p>
</li>
</ul>
<h2 id="commonjs-requirejs-AMD-CMD-UMD"><a href="#commonjs-requirejs-AMD-CMD-UMD" class="headerlink" title="commonjs?requirejs?AMD|CMD|UMD?"></a>commonjs?requirejs?AMD|CMD|UMD?</h2><ul>
<li><p>CommonJS就是为JS的表现来制定规范,NodeJS是这种规范的实现,webpack 也是以CommonJS的形式来书写。因为js没有模块的功能,所以CommonJS应运而生。但它不能在浏览器中运行。 CommonJS定义的模块分为:{模块引用(require)} {模块定义(exports)} {模块标识(module)} </p>
</li>
<li><p>RequireJS 是一个JavaScript模块加载器。 RequireJS有两个主要方法(method): define()和require()。这两个方法基本上拥有相同的定义(declaration) 并且它们都知道如何加载的依赖关系,然后执行一个回调函数(callback function)。与require()不同的是, define()用来存储代码作为一个已命名的模块。 因此define()的回调函数需要有一个返回值作为这个模块定义。这些类似被定义的模块叫作AMD (Asynchronous Module Definition,异步模块定义)。 </p>
</li>
<li><p>AMD 是 RequireJS 在推广过程中对模块定义的规范化产出 AMD异步加载模块。它的模块支持对象 函数 构造器 字符串 JSON等各种类型的模块。 适用AMD规范适用define方法定义模块。</p>
</li>
<li><p>CMD是SeaJS 在推广过程中对模块定义的规范化产出
AMD与CMD的区别:
(1)对于于依赖的模块,AMD 是提前执行(requirejs2.0+可以延迟执行了),CMD 是延迟执行。
(2)AMD 推崇依赖前置,CMD 推崇依赖就近。
(3)AMD 推崇复用接口,CMD 推崇单用接口。
(4)书写规范的差异。</p>
</li>
<li><p>umd是AMD和CommonJS的糅合。
AMD 浏览器第一的原则发展 异步加载模块。
CommonJS模块以服务器第一原则发展,选择同步加载,它的模块无需包装(unwrapped modules)。这迫使人们又想出另一个更通用的模式UMD ( Universal Module Definition ), 希望解决跨平台的解决方案。UMD先判断是否支持Node.js的模块( exports )是否存在,存在则使用Node.js模块模式。</p>
</li>
</ul>
<h3 id="差异"><a href="#差异" class="headerlink" title="差异"></a>差异</h3><ol>
<li><p><code>CommonJS 模块输出的是一个值的浅拷贝,ES6 模块输出的是值的引用。</code>也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。ES6 模块的运行机制与
CommonJS 不一样。JS 引擎对脚本静态分析的时候,遇到模块加载命令 import,就会生成一个只读引用。等到脚本真正执行时,再根据这个只读引用,到被加载的那
个模块里面去取值。</p>
</li>
<li><p><code>CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。</code>CommonJS 模块就是对象,即在输入时是先加载整个模块,生成一个对象,然后再从这个对象上面读
取方法,这种加载称为“运行时加载”。而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。</p>
</li>
<li><p>CommonJs导入的模块路径可以是一个表达式,因为它使用的是require()方法;而ES6 Modules只能是字符串。</p>
</li>
<li><p>CommonJS this指向当前模块,ES6 Modules this指向undefined</p>
</li>
<li><p>ES6 Modules中没有这些顶层变量:arguments、require、module、exports、<strong>filename、</strong>dirname</p>
</li>
</ol>
<h2 id="js的几种继承方式?"><a href="#js的几种继承方式?" class="headerlink" title="js的几种继承方式?"></a>js的几种继承方式?</h2><ul>
<li>使用对象冒充实现继承</li>
<li>call、apply改变函数上下文实现继承</li>
<li>原型链方式实现继承</li>
</ul>
<h2 id="js原型、原型链,有什么特点?"><a href="#js原型、原型链,有什么特点?" class="headerlink" title="js原型、原型链,有什么特点?"></a>js原型、原型链,有什么特点?</h2><p>在JavaScript中,一共有两种类型的值,原始值和对象值.每个对象都有一个内部属性[[prototype]],我们通常称之为原型.原型的值可以是一个对象,也可以是null.如果它的值是一个对象,则这个对象也一定有自己的原型.这样就形成了一条线性的链,我们称之为原型链. </p>
<p>访问一个对象的原型可以使用ES5中的Object.getPrototypeOf方法,或者ES6中的<strong>proto</strong>属性. 原型链的作用是用来实现继承,比如我们新建一个数组,数组的方法就是从数组的原型上继承而来的。</p>
<p>类的继承
特点:基于原型链,既是父类的实例,也是子类的实例
缺点:无法实现多继承</p>
<p>构造继承、组合继承、实例继承和拷贝继承…</p>
<h2 id="eval是做什么的?"><a href="#eval是做什么的?" class="headerlink" title="eval是做什么的?"></a>eval是做什么的?</h2><ul>
<li>将把对应的字符串解析成JS代码并运行; 应该避免使用eval,不安全,非常耗性能(2次,一次解析成js语句,一次执行)。</li>
<li>由JSON字符串转换为JSON对象的时候可以用eval,var obj =eval(‘(‘+ str +’)’);</li>
</ul>
<h2 id="null和undefined"><a href="#null和undefined" class="headerlink" title="null和undefined"></a>null和undefined</h2><ul>
<li>null 表示一个对象是“没有值”的值,也就是值为“空”;</li>
<li>undefined 表示一个变量声明了没有初始化(赋值);<blockquote>
<p>Number(null)为0,而undefined为NaN</p>
</blockquote>
</li>
</ul>
<h2 id="json的理解?"><a href="#json的理解?" class="headerlink" title="json的理解?"></a>json的理解?</h2><ul>
<li>JSON(轻量级的数据交换格式),基于JS的子集,数据格式简单,易于读写,占用带宽小。<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="built_in">JSON</span>.parse() <span class="comment">// 解析成JSON对象</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">JSON</span>.strinify() <span class="comment">// 解析成JSON字符串</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<h2 id="script-引入方式:"><a href="#script-引入方式:" class="headerlink" title="script 引入方式:"></a>script 引入方式:</h2><ul>
<li>html 静态<script>引入</li>
<li>js 动态插入<script></li>
<li><script defer>: 延迟加载,元素解析完成后执行</li>
<li><script async>: 异步加载,但执行时会阻塞元素渲染只是它的加载过程不会阻塞</li>
</ul>
<h2 id="ajax(异步的js和xml)"><a href="#ajax(异步的js和xml)" class="headerlink" title="ajax(异步的js和xml)"></a>ajax(异步的js和xml)</h2><ul>
<li>ajax是指一种创建交互式网页应用的网页开发技术。通过后台与服务器进行少量数据交换,AJAX可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。</li>
</ul>
<h2 id="同异步的区别?"><a href="#同异步的区别?" class="headerlink" title="同异步的区别?"></a>同异步的区别?</h2><ul>
<li>同步(sync):按顺序执行。</li>
<li>异步(async):不按顺序执行,可以跳过执行下面的代码。</li>
</ul>
<h3 id="什么是异步"><a href="#什么是异步" class="headerlink" title="什么是异步"></a>什么是异步</h3><p>当前一个任务被执行时,不会等待任务执行完成后就去执行下一个任务,等前一个任务执行完成后,将去执行其返回的回调函数,这是异步操作。</p>
<h3 id="为什么要异步"><a href="#为什么要异步" class="headerlink" title="为什么要异步"></a>为什么要异步</h3><p>js是单线程的,因此必须等前一个任务完成后,后一个任务才会被执行。因此当执行一段耗时的程序时,会影响整个程序的执行,异步的方法就是为了解决这个问题。</p>
<h2 id="ajax的缺点?"><a href="#ajax的缺点?" class="headerlink" title="ajax的缺点?"></a>ajax的缺点?</h2><ul>
<li>不支持浏览器的back按钮(事件由浏览器内核控制)</li>
<li>ajax暴露了与服务器的交互</li>
<li>对搜索引擎的支持较弱</li>
<li>破坏了程序的异常机制</li>
<li>不容易调试</li>
</ul>
<h2 id="跨域问题?"><a href="#跨域问题?" class="headerlink" title="跨域问题?"></a>跨域问题?</h2><h3 id="同源策略"><a href="#同源策略" class="headerlink" title="同源策略"></a>同源策略</h3><p>同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键安全机制。</p>
<ul>
<li>协议不同</li>
<li>端口不同</li>
<li>域名不同</li>
<li>常用解决方案:</li>
</ul>
<ol>
<li>jsonp<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"http://example.com/data.php?callback=do"</span>></span><span class="tag"></<span class="name">script</span>></span></span><br></pre></td></tr></table></figure></li>
<li>iframe</li>
<li>window.name
在一个窗口中,窗口载入的所有页面共享一个window.name,每个页面都对window.name具有读写权限,可以在window.name中设置想要的数据。</li>
<li>window.postMessage<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="comment">// iframe通信</span></span><br><span class="line">iframe.contentWindow.postMessage(msg);</span><br><span class="line"><span class="built_in">window</span>.onmessage = <span class="function"><span class="keyword">function</span> (<span class="params">e</span>) </span>{</span><br><span class="line"> e = e || event;</span><br><span class="line"> alert(e.data);</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li>
<li>document.domain
将两个页面的document.domain设置成相同域名即可,js中设置,形如:
document.domain = “”;</li>
<li>服务器设置代理页面/响应header配置cors access-control-allow-origin
CORS全称“ Cross-origin resource sharing ”(跨域资源共享),相比JSONP, CORS允许任何类型的请求 。</li>
</ol>
<blockquote>
<p>CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。</p>
</blockquote>
<blockquote>
<p>整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨
源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。</p>
</blockquote>
<blockquote>
<p>因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。</p>
</blockquote>
<ol start="7">
<li>nginx反向代理、nodejs反向代理</li>
</ol>
<ul>
<li><p>http-proxy-middleware 插件</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">'express'</span>);</span><br><span class="line"><span class="keyword">var</span> proxy = <span class="built_in">require</span>(<span class="string">'http-proxy-middleware'</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> app = express();</span><br><span class="line"></span><br><span class="line">app.use(<span class="string">'/cosyer'</span>, proxy({<span class="attr">target</span>: <span class="string">'http://39.105.136.190:3000/'</span>, <span class="attr">changeOrigin</span>: <span class="literal">true</span>}));</span><br><span class="line">app.listen(<span class="number">3000</span>);</span><br></pre></td></tr></table></figure>
</li>
<li><p>webpack-dev-server</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></pre></td><td class="code"><pre><span class="line">devServer: {</span><br><span class="line"> port: <span class="number">3000</span>,</span><br><span class="line"> inline: <span class="literal">true</span>,</span><br><span class="line"> proxy: {</span><br><span class="line"> <span class="string">"/cosyer"</span>: {</span><br><span class="line"> target: <span class="string">"http://39.105.136.190:3000/"</span>,</span><br><span class="line"> changeOrigin: <span class="literal">true</span> <span class="comment">//必须配置为true,才能正确代理</span></span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>webpack 的 devServer.proxy 就是使用了非常强大的 http-proxy-middleware 包来实现代理的,所以本质上是相通的。</p>
</li>
<li><p>nginx</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">server {</span><br><span class="line"> listen <span class="number">80</span>;</span><br><span class="line"> server_name client.com;</span><br><span class="line"> location /api {</span><br><span class="line"> proxy_pass server.com;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
</li>
</ul>
<ol start="8">
<li>WebSocket
WebSocket是一种通信协议,使用ws://(非加密)和wss://(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。</li>
</ol>
<p>由于发出的WebSocket请求中有有一个字段是Origin,表示该请求的请求源(origin),即发自哪个域名。</p>
<p>正是因为有了Origin这个字段,所以WebSocket才没有实行同源政策。因为服务器可以根据这个字段,判断是否许可本次通信。
<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">var</span> ws = <span class="keyword">new</span> WebSocket(<span class="string">'wss://echo.websocket.org'</span>);</span><br><span class="line">ws.onopen = <span class="function"><span class="keyword">function</span> (<span class="params">evt</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'Connection open ...'</span>);</span><br><span class="line"> ws.send(<span class="string">'Hello WebSockets!'</span>);</span><br><span class="line">};</span><br><span class="line">ws.onmessage = <span class="function"><span class="keyword">function</span> (<span class="params">evt</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'Received Message: '</span>, evt.data);</span><br><span class="line"> ws.close();</span><br><span class="line">};</span><br><span class="line">ws.onclose = <span class="function"><span class="keyword">function</span> (<span class="params">evt</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'Connection closed.'</span>);</span><br><span class="line">};</span><br></pre></td></tr></table></figure></p>
<figure class="highlight plain"><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><br><span class="line">Ajax 支持同源通信</span><br><span class="line">WebSocket 不受同源策略影响</span><br><span class="line">CORS 既支持同源通信也支持跨域通信</span><br></pre></td></tr></table></figure>
<h2 id="解决异步回调地狱有哪些方案?"><a href="#解决异步回调地狱有哪些方案?" class="headerlink" title="解决异步回调地狱有哪些方案?"></a>解决异步回调地狱有哪些方案?</h2><ul>
<li>promise</li>
<li>generator</li>
<li>async/await(优缺点)
<code>async 和await</code> 相比直接使用 <code>Promise</code> 来说,优势在于处理 then 的调用链,能够更清晰准确的写出代码。缺点在于滥用 await 可能会导致性能问题,因为 await 会阻塞代码,也许之后的异步代码并不依赖于前者,但仍然需要等待前者完成,导致代码失去了并发性,导致性能的降低。</li>
</ul>
<h2 id="图片的预加载和懒加载?"><a href="#图片的预加载和懒加载?" class="headerlink" title="图片的预加载和懒加载?"></a>图片的预加载和懒加载?</h2><ul>
<li>预加载:提前加载图片,当用户需要查看时可直接从本地缓存中渲染,加快响应速度。</li>
<li>懒加载:懒加载的主要目的是作为服务器前端的优化,减少请求数或延迟请求数。</li>
</ul>
<p>两种技术的本质:两者的行为是相反的,一个是提前加载,一个是迟缓甚至不加载。 懒加载对服务器前端有一定的缓解压力作用,预加载则会增加服务器前端压力。</p>
<h2 id="mouseover和mouseenter的区别?"><a href="#mouseover和mouseenter的区别?" class="headerlink" title="mouseover和mouseenter的区别?"></a>mouseover和mouseenter的区别?</h2><ul>
<li><p>mouseover:当鼠标移入元素或其子元素都会触发事件,所以有一个重复触发,冒泡的过程。对应的移除事件是mouseout</p>
</li>
<li><p>mouseenter:当鼠标移入元素本身(不包含元素的子元素)会触发事件,也就是不会冒泡,对应的移除事件是mouseleave</p>
</li>
<li><p>onmousedown 当元素上按下鼠标按钮时出发</p>
</li>
<li>onmousemove 当鼠标指针移动到元素上移动触发</li>
<li>onmouseover 当鼠标指针移动元素上时触发</li>
<li>onmouseout 当鼠标指针移出指定的对象时发生。</li>
<li>onmouseup 当在元素上释放鼠标按钮时触发</li>
<li>onmouseenter 事件在鼠标指针移动到元素上时触发。(不冒泡)</li>
<li>onmouseleave 事件在鼠标移除元素时触发。(不冒泡)</li>
</ul>
<h2 id="改变函数内部this指针的指向函数(bind,apply,call的区别)?"><a href="#改变函数内部this指针的指向函数(bind,apply,call的区别)?" class="headerlink" title="改变函数内部this指针的指向函数(bind,apply,call的区别)?"></a>改变函数内部this指针的指向函数(bind,apply,call的区别)?</h2><ul>